Files
lkm/stream/memory_pool.go
DESKTOP-COJOJSE\lenovo f932284313 完善rtmp server
2023-11-25 17:45:19 +08:00

117 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package stream
import (
"github.com/yangjiechina/avformat/utils"
)
// MemoryPool 从解复用阶段拼凑成完整的AVPacket开始(写)到GOP缓存结束(释放),整个过程都使用池中内存
// 类似环形缓冲区, 区别在于,写入的内存块是连续的、整块内存.
type MemoryPool interface {
// Mark 标记一块写的内存地址
//使用流程 Mark->Write/Allocate....->Fetch/Reset
Mark()
Write(data []byte)
Allocate(size int) []byte
Fetch() []byte
// Reset 清空此次Write的标记本次缓存的数据无效
Reset()
// FreeHead 从头部释放指定大小内存
FreeHead(size int)
// FreeTail 从尾部释放指定大小内存
FreeTail(size int)
}
func NewMemoryPool(capacity int) MemoryPool {
pool := &memoryPool{
data: make([]byte, capacity),
capacity: capacity,
}
return pool
}
type memoryPool struct {
data []byte
ptrStart uintptr
ptrEnd uintptr
//剩余的可用内存空间不足以为此次write
capacity int
head int
tail int
//保存开始索引
mark int
}
// 根据head和tail计算出可用的内存地址
func (m *memoryPool) allocate(size int) []byte {
if m.capacity-m.tail < size {
//使用从头释放的内存
if m.tail-m.mark+size <= m.head {
copy(m.data, m.data[m.mark:m.tail])
m.capacity = m.mark
m.tail = m.tail - m.mark
m.mark = 0
} else {
//扩容
capacity := (cap(m.data) + m.tail - m.mark + size) * 3 / 2
bytes := make([]byte, capacity)
//不对之前的内存进行复制, 已经被AVPacket引用, 自行GC
copy(bytes, m.data[m.mark:m.tail])
m.data = bytes
m.capacity = capacity
m.tail = m.tail - m.mark
m.mark = 0
m.head = 0
}
}
bytes := m.data[m.tail:]
m.tail += size
return bytes
}
func (m *memoryPool) Mark() {
m.mark = m.tail
}
func (m *memoryPool) Write(data []byte) {
allocate := m.allocate(len(data))
copy(allocate, data)
}
func (m *memoryPool) Allocate(size int) []byte {
return m.allocate(size)
}
func (m *memoryPool) Fetch() []byte {
return m.data[m.mark:m.tail]
}
func (m *memoryPool) Reset() {
m.tail = m.mark
}
func (m *memoryPool) FreeHead(size int) {
m.head += size
if m.head == m.tail {
m.head = 0
m.tail = 0
} else if m.head >= m.capacity {
m.head = 0
}
}
func (m *memoryPool) FreeTail(size int) {
m.tail -= size
utils.Assert(m.tail >= 0)
}