Add a key frame seeder in up track. (#3524)

This commit is contained in:
Raja Subramanian
2025-03-12 22:11:27 +05:30
committed by GitHub
parent 0f61ff3a2f
commit c823320528
4 changed files with 78 additions and 22 deletions
+63 -4
View File
@@ -306,6 +306,10 @@ func (b *Buffer) Bind(params webrtc.RTPParameters, codec webrtc.RTPCodecCapabili
}
b.pPackets = nil
b.bound = true
if mime.IsMimeTypeVideo(b.mime) {
go b.seedKeyFrame()
}
}
func (b *Buffer) OnCodecChange(fn func(webrtc.RTPCodecParameters)) {
@@ -499,14 +503,18 @@ func (b *Buffer) Close() error {
b.closeOnce.Do(func() {
b.closed.Store(true)
if b.rtpStats != nil {
b.rtpStats.Stop()
b.RLock()
rtpStats := b.rtpStats
b.RUnlock()
if rtpStats != nil {
rtpStats.Stop()
b.logger.Debugw("rtp stats",
"direction", "upstream",
"stats", b.rtpStats,
"stats", rtpStats,
)
if cb := b.getOnFinalRtpStats(); cb != nil {
cb(b.rtpStats.ToProto())
cb(rtpStats.ToProto())
}
}
@@ -800,6 +808,10 @@ func (b *Buffer) handleCodecChange(newPT uint8) {
if f := b.onCodecChange; f != nil {
go f(newCodec)
}
if mime.IsMimeTypeVideo(b.mime) {
go b.seedKeyFrame()
}
}
func (b *Buffer) updateStreamState(p *rtp.Packet, arrivalTime int64) rtpstats.RTPFlowState {
@@ -1227,4 +1239,51 @@ func (b *Buffer) GetTemporalLayerFpsForSpatial(layer int32) []float32 {
return nil
}
func (b *Buffer) seedKeyFrame() {
// a key frame is needed especially when using Dependency Descriptor
// to get the DD structure which is used in parsing subsequent packets,
// till then packets are dropped which results in stream tracker not
// getting any data which means it does not declare layer start.
//
// send gratuitous PLIs for some time or until a key frame is seen to
// get the engine rolling
b.logger.Debugw("starting key frame seeder")
timer := time.NewTimer(time.Minute)
defer timer.Stop()
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for {
if b.closed.Load() {
return
}
select {
case <-timer.C:
b.logger.Infow("stopping key frame seeder: timeout")
return
case <-ticker.C:
b.RLock()
rtpStats := b.rtpStats
b.RUnlock()
if rtpStats != nil {
cnt, last := rtpStats.KeyFrame()
if cnt > 0 {
b.logger.Debugw(
"stopping key frame seeder: received key frame",
"keyFrameCount", cnt,
"lastKeyFrame", last,
)
return
}
b.SendPLI(true)
}
}
}
}
// ---------------------------------------------------------------