From dde4fb498ea013eaf56a58982efb34cb4f2b2e0c Mon Sep 17 00:00:00 2001 From: Raja Subramanian Date: Mon, 29 Dec 2025 23:51:15 +0530 Subject: [PATCH] configurable dependency descriptor restart (#4207) * configurable dependency descriptor restart * KeyFrame -> IsKeyFrame * use the params directly --- pkg/sfu/buffer/buffer_base.go | 27 ++++++++++--------- pkg/sfu/downtrack.go | 2 +- pkg/sfu/rtpmunger.go | 2 +- pkg/sfu/testutils/data.go | 4 +-- .../dependencydescriptor.go | 4 +-- .../dependencydescriptor_test.go | 4 +-- pkg/sfu/videolayerselector/simulcast.go | 4 +-- pkg/sfu/videolayerselector/vp9.go | 2 +- 8 files changed, 25 insertions(+), 24 deletions(-) diff --git a/pkg/sfu/buffer/buffer_base.go b/pkg/sfu/buffer/buffer_base.go index dc54be875..f43084430 100644 --- a/pkg/sfu/buffer/buffer_base.go +++ b/pkg/sfu/buffer/buffer_base.go @@ -71,7 +71,7 @@ type ExtPacket struct { ExtTimestamp uint64 Packet *rtp.Packet Payload any - KeyFrame bool + IsKeyFrame bool RawPacket []byte DependencyDescriptor *ExtDependencyDescriptor AbsCaptureTimeExt *act.AbsCaptureTime @@ -145,6 +145,7 @@ type BufferBaseParams struct { SendPLI func() IsReportingEnabled bool IsOOBSequenceNumber bool + IsDDRestartEnabled bool } type BufferBase struct { @@ -546,7 +547,7 @@ func (b *BufferBase) createDDParserAndFrameRateCalculator() { func(spatial, temporal int32) { frc.SetMaxLayer(spatial, temporal) }, - false, + b.params.IsDDRestartEnabled, ) } } @@ -1046,11 +1047,11 @@ func (b *BufferBase) processVideoPacket(ep *ExtPacket) error { b.logger.Warnw("could not unmarshal VP8 packet", err) return err } - ep.KeyFrame = vp8Packet.IsKeyFrame + ep.IsKeyFrame = vp8Packet.IsKeyFrame if ep.DependencyDescriptor == nil { ep.Temporal = int32(vp8Packet.TID) - if ep.KeyFrame { + if ep.IsKeyFrame { if sz := ExtractVP8VideoSize(&vp8Packet, ep.Packet.Payload); sz.Width > 0 && sz.Height > 0 { videoSize = append(videoSize, sz) } @@ -1075,9 +1076,9 @@ func (b *BufferBase) processVideoPacket(ep *ExtPacket) error { Temporal: int32(vp9Packet.TID), } ep.Payload = vp9Packet - ep.KeyFrame = IsVP9KeyFrame(&vp9Packet, ep.Packet.Payload) + ep.IsKeyFrame = IsVP9KeyFrame(&vp9Packet, ep.Packet.Payload) - if ep.KeyFrame { + if ep.IsKeyFrame { for i := 0; i < len(vp9Packet.Width); i++ { videoSize = append(videoSize, VideoSize{ Width: uint32(vp9Packet.Width[i]), @@ -1086,25 +1087,25 @@ func (b *BufferBase) processVideoPacket(ep *ExtPacket) error { } } } else { - ep.KeyFrame = IsVP9KeyFrame(nil, ep.Packet.Payload) + ep.IsKeyFrame = IsVP9KeyFrame(nil, ep.Packet.Payload) } case mime.MimeTypeH264: - ep.KeyFrame = IsH264KeyFrame(ep.Packet.Payload) + ep.IsKeyFrame = IsH264KeyFrame(ep.Packet.Payload) ep.Spatial = InvalidLayerSpatial // h.264 don't have spatial scalability, reset to invalid // Check H264 key frame video size - if ep.KeyFrame { + if ep.IsKeyFrame { if sz := ExtractH264VideoSize(ep.Packet.Payload); sz.Width > 0 && sz.Height > 0 { videoSize = append(videoSize, sz) } } case mime.MimeTypeAV1: - ep.KeyFrame = IsAV1KeyFrame(ep.Packet.Payload) + ep.IsKeyFrame = IsAV1KeyFrame(ep.Packet.Payload) case mime.MimeTypeH265: - ep.KeyFrame = IsH265KeyFrame(ep.Packet.Payload) + ep.IsKeyFrame = IsH265KeyFrame(ep.Packet.Payload) if ep.DependencyDescriptor == nil { if len(ep.Packet.Payload) < 2 { b.logger.Warnw("invalid H265 packet", nil, "payloadLen", len(ep.Packet.Payload)) @@ -1115,7 +1116,7 @@ func (b *BufferBase) processVideoPacket(ep *ExtPacket) error { } ep.Spatial = InvalidLayerSpatial - if ep.KeyFrame { + if ep.IsKeyFrame { if sz := ExtractH265VideoSize(ep.Packet.Payload); sz.Width > 0 && sz.Height > 0 { videoSize = append(videoSize, sz) } @@ -1123,7 +1124,7 @@ func (b *BufferBase) processVideoPacket(ep *ExtPacket) error { } } - if ep.KeyFrame { + if ep.IsKeyFrame { if b.rtpStats != nil { b.rtpStats.UpdateKeyFrame(1) } diff --git a/pkg/sfu/downtrack.go b/pkg/sfu/downtrack.go index 9e619842d..d6a097e2a 100644 --- a/pkg/sfu/downtrack.go +++ b/pkg/sfu/downtrack.go @@ -1103,7 +1103,7 @@ func (d *DownTrack) WriteRTP(extPkt *buffer.ExtPacket, layer int32) int32 { } d.pacer.Enqueue(pacerPacket) - if extPkt.KeyFrame { + if extPkt.IsKeyFrame { d.isNACKThrottled.Store(false) d.rtpStats.UpdateKeyFrame(1) d.params.Logger.Debugw( diff --git a/pkg/sfu/rtpmunger.go b/pkg/sfu/rtpmunger.go index ef8bed6ad..882ae0468 100644 --- a/pkg/sfu/rtpmunger.go +++ b/pkg/sfu/rtpmunger.go @@ -185,7 +185,7 @@ func (r *RTPMunger) UpdateAndGetSnTs(extPkt *buffer.ExtPacket, marker bool) (Tra r.secondLastMarker = r.lastMarker r.lastMarker = marker - if extPkt.KeyFrame { + if extPkt.IsKeyFrame { r.extRtxGateSn = extMungedSN r.isInRtxGateRegion = true } diff --git a/pkg/sfu/testutils/data.go b/pkg/sfu/testutils/data.go index a4ebc7bed..c2835493c 100644 --- a/pkg/sfu/testutils/data.go +++ b/pkg/sfu/testutils/data.go @@ -69,7 +69,7 @@ func GetTestExtPacket(params *TestExtPacketParams) (*buffer.ExtPacket, error) { ExtTimestamp: uint64(params.TSCycles<<32) + uint64(params.Timestamp), Arrival: params.ArrivalTime.UnixNano(), Packet: &packet, - KeyFrame: params.IsKeyFrame, + IsKeyFrame: params.IsKeyFrame, RawPacket: raw, IsOutOfOrder: params.IsOutOfOrder, } @@ -85,7 +85,7 @@ func GetTestExtPacketVP8(params *TestExtPacketParams, vp8 *buffer.VP8) (*buffer. return nil, err } - ep.KeyFrame = vp8.IsKeyFrame + ep.IsKeyFrame = vp8.IsKeyFrame ep.Payload = *vp8 if ep.DependencyDescriptor == nil { ep.Temporal = int32(vp8.TID) diff --git a/pkg/sfu/videolayerselector/dependencydescriptor.go b/pkg/sfu/videolayerselector/dependencydescriptor.go index 88ebc7c34..3e2e090a2 100644 --- a/pkg/sfu/videolayerselector/dependencydescriptor.go +++ b/pkg/sfu/videolayerselector/dependencydescriptor.go @@ -291,7 +291,7 @@ func (d *DependencyDescriptor) Select(extPkt *buffer.ExtPacket, _layer int32) (r "fn", dd.FrameNumber, "efn", extFrameNum, "sn", extPkt.Packet.SequenceNumber, - "isKeyFrame", extPkt.KeyFrame, + "isKeyFrame", extPkt.IsKeyFrame, ) } @@ -308,7 +308,7 @@ func (d *DependencyDescriptor) Select(extPkt *buffer.ExtPacket, _layer int32) (r "fn", dd.FrameNumber, "efn", extFrameNum, "sn", extPkt.Packet.SequenceNumber, - "isKeyFrame", extPkt.KeyFrame, + "isKeyFrame", extPkt.IsKeyFrame, ) result.IsRelevant = true diff --git a/pkg/sfu/videolayerselector/dependencydescriptor_test.go b/pkg/sfu/videolayerselector/dependencydescriptor_test.go index a562988f9..91d78d882 100644 --- a/pkg/sfu/videolayerselector/dependencydescriptor_test.go +++ b/pkg/sfu/videolayerselector/dependencydescriptor_test.go @@ -143,7 +143,7 @@ func TestDependencyDescriptor(t *testing.T) { // non key frame, dropped ret = ddSelector.Select(&buffer.ExtPacket{ - KeyFrame: false, + IsKeyFrame: false, DependencyDescriptor: &buffer.ExtDependencyDescriptor{ Descriptor: &dd.DependencyDescriptor{ FrameNumber: 1, @@ -308,7 +308,7 @@ func createDDFrames(maxLayer buffer.VideoLayer, startFrameNumber uint16) []*buff } } keyFrame := &buffer.ExtPacket{ - KeyFrame: true, + IsKeyFrame: true, DependencyDescriptor: &buffer.ExtDependencyDescriptor{ Descriptor: &dd.DependencyDescriptor{ FrameNumber: startFrameNumber, diff --git a/pkg/sfu/videolayerselector/simulcast.go b/pkg/sfu/videolayerselector/simulcast.go index 9720bbe47..664b2a706 100644 --- a/pkg/sfu/videolayerselector/simulcast.go +++ b/pkg/sfu/videolayerselector/simulcast.go @@ -93,7 +93,7 @@ func (s *Simulcast) Select(extPkt *buffer.ExtPacket, layer int32) (result VideoL isActive := s.currentLayer.IsValid() found := false reason := "" - if extPkt.KeyFrame { + if extPkt.IsKeyFrame { if layer > s.currentLayer.Spatial && layer <= s.targetLayer.Spatial { reason = "upgrading layer" found = true @@ -124,7 +124,7 @@ func (s *Simulcast) Select(extPkt *buffer.ExtPacket, layer int32) (result VideoL } // if locked to higher than max layer due to overshoot, check if it can be dialed back - if s.currentLayer.Spatial > s.maxLayer.Spatial && layer <= s.maxLayer.Spatial && extPkt.KeyFrame { + if s.currentLayer.Spatial > s.maxLayer.Spatial && layer <= s.maxLayer.Spatial && extPkt.IsKeyFrame { s.previousLayer = s.currentLayer s.currentLayer.Spatial = layer diff --git a/pkg/sfu/videolayerselector/vp9.go b/pkg/sfu/videolayerselector/vp9.go index dc5999c48..4b11d37ab 100644 --- a/pkg/sfu/videolayerselector/vp9.go +++ b/pkg/sfu/videolayerselector/vp9.go @@ -50,7 +50,7 @@ func (v *VP9) Select(extPkt *buffer.ExtPacket, _layer int32) (result VideoLayerS updatedLayer := v.currentLayer if !v.currentLayer.IsValid() { - if !extPkt.KeyFrame { + if !extPkt.IsKeyFrame { return }