feat: avcc和annexb格式转换的内存循环使用, 减少内存碎片, 降低gc压力

This commit is contained in:
ydajiang
2025-06-07 23:37:46 +08:00
parent 3553a1b582
commit 668ad3aca5

View File

@@ -87,13 +87,14 @@ type transStreamPublisher struct {
sinks map[SinkID]Sink // 保存所有Sink sinks map[SinkID]Sink // 保存所有Sink
transStreamSinks map[TransStreamID]map[SinkID]Sink // 输出流对应的Sink transStreamSinks map[TransStreamID]map[SinkID]Sink // 输出流对应的Sink
existVideo bool // 是否存在视频 existVideo bool // 是否存在视频
completed atomic.Bool // 所有推流track是否解析完毕, @see writeHeader 函数中赋值为true completed atomic.Bool // 所有推流track是否解析完毕, @see writeHeader 函数中赋值为true
closed atomic.Bool closed atomic.Bool
streamEndInfo *StreamEndInfo // 之前推流源信息 streamEndInfo *StreamEndInfo // 之前推流源信息
accumulateTimestamps bool // 是否累加时间戳 accumulateTimestamps bool // 是否累加时间戳
timestampModeDecided bool // 是否已经决定使用推流的时间戳,或者累加时间戳 timestampModeDecided bool // 是否已经决定使用推流的时间戳,或者累加时间戳
lastStreamEndTime time.Time // 最近拉流端结束拉流的时间 lastStreamEndTime time.Time // 最近拉流端结束拉流的时间
bitstreamFilterBuffer *collections.RBBlockBuffer // annexb和avcc转换的缓冲区
} }
func (t *transStreamPublisher) Post(event *StreamEvent) { func (t *transStreamPublisher) Post(event *StreamEvent) {
@@ -493,9 +494,7 @@ func (t *transStreamPublisher) doClose() {
// 释放GOP缓存 // 释放GOP缓存
if t.gopBuffer != nil { if t.gopBuffer != nil {
t.gopBuffer.PopAll(func(packet *collections.ReferenceCounter[*avformat.AVPacket]) { t.ClearGopBuffer()
packet.Release()
})
t.gopBuffer = nil t.gopBuffer = nil
} }
@@ -597,9 +596,7 @@ func (t *transStreamPublisher) WriteHeader() {
// 如果不存在视频帧, 清空GOP缓存 // 如果不存在视频帧, 清空GOP缓存
if !t.existVideo { if !t.existVideo {
t.gopBuffer.PopAll(func(c *collections.ReferenceCounter[*avformat.AVPacket]) { t.ClearGopBuffer()
c.Refer()
})
t.gopBuffer = nil t.gopBuffer = nil
} }
} }
@@ -616,14 +613,30 @@ func (t *transStreamPublisher) Sinks() []Sink {
return sinks return sinks
} }
func (t *transStreamPublisher) ClearGopBuffer() {
t.gopBuffer.PopAll(func(packet *collections.ReferenceCounter[*avformat.AVPacket]) {
packet.Release()
if t.bitstreamFilterBuffer != nil {
t.bitstreamFilterBuffer.Pop()
}
})
}
func (t *transStreamPublisher) OnPacket(packet *collections.ReferenceCounter[*avformat.AVPacket]) { func (t *transStreamPublisher) OnPacket(packet *collections.ReferenceCounter[*avformat.AVPacket]) {
// 保存到GOP缓存 // 保存到GOP缓存
if (AppConfig.GOPCache && t.existVideo) || !t.completed.Load() { if (AppConfig.GOPCache && t.existVideo) || !t.completed.Load() {
packet.Get().OnBufferAlloc = func(size int) []byte {
if t.bitstreamFilterBuffer == nil {
t.bitstreamFilterBuffer = collections.NewRBBlockBuffer(1024 * 1024 * 2)
}
return t.bitstreamFilterBuffer.Alloc(size)
}
// GOP队列溢出 // GOP队列溢出
if t.gopBuffer.RequiresClear(packet) { if t.gopBuffer.RequiresClear(packet) {
t.gopBuffer.PopAll(func(packet *collections.ReferenceCounter[*avformat.AVPacket]) { t.ClearGopBuffer()
packet.Release()
})
} }
t.gopBuffer.AddPacket(packet) t.gopBuffer.AddPacket(packet)
@@ -639,11 +652,11 @@ func (t *transStreamPublisher) OnPacket(packet *collections.ReferenceCounter[*av
t.DispatchPacket(transStream, packet.Get()) t.DispatchPacket(transStream, packet.Get())
} }
} }
}
// 未开启GOP缓存或只存在音频流, 立即释放 // 未开启GOP缓存或只存在音频流, 立即释放
if !AppConfig.GOPCache || !t.existVideo { if !AppConfig.GOPCache || !t.existVideo {
packet.Release() packet.Release()
}
} }
} }