diff --git a/pkg/sfu/forwarder.go b/pkg/sfu/forwarder.go index 1da413ee8..cee63f01f 100644 --- a/pkg/sfu/forwarder.go +++ b/pkg/sfu/forwarder.go @@ -1505,7 +1505,8 @@ func (f *Forwarder) processSourceSwitch(extPkt *buffer.ExtPacket, layer int32) e // 3. expectedTS -> expected timestamp of this packet calculated based on elapsed time since first packet // Ideally, refTS and expectedTS should be very close and lastTS should be before both of those. // But, cases like muting/unmuting, clock vagaries, pacing, etc. make them not satisfy those conditions always. - lastTS := f.rtpMunger.GetLast().LastTS + rtpMungerState := f.rtpMunger.GetLast() + lastTS := rtpMungerState.LastTS refTS := lastTS expectedTS := lastTS switchingAt := time.Now() @@ -1625,8 +1626,29 @@ func (f *Forwarder) processSourceSwitch(extPkt *buffer.ExtPacket, layer int32) e "jump", nextTS-lastTS, ) - f.rtpMunger.UpdateSnTsOffsets(extPkt, 1, nextTS-lastTS) + snOffset := uint16(1) + if !rtpMungerState.LastMarker { + // If last forwarded packet is not end of frame, synthesise a break in sequence number. + // Else, decoders could try to interpret consecutive packets as part of the same frame + // and potentially cause video corruption. + snOffset++ + } + f.rtpMunger.UpdateSnTsOffsets(extPkt, snOffset, nextTS-lastTS) f.codecMunger.UpdateOffsets(extPkt) + + f.logger.Infow( + "source switch", + "switchingAt", switchingAt.String(), + "layer", layer, + "lastTS", lastTS, + "refTS", refTS, + "refTSOffset", f.refTSOffset, + "referenceLayerSpatial", f.referenceLayerSpatial, + "expectedTS", expectedTS, + "nextTS", nextTS, + "tsOffset", nextTS-lastTS, + "snOffset", snOffset, + ) return nil } diff --git a/pkg/sfu/rtpmunger.go b/pkg/sfu/rtpmunger.go index 452019507..41b361496 100644 --- a/pkg/sfu/rtpmunger.go +++ b/pkg/sfu/rtpmunger.go @@ -41,8 +41,9 @@ type SnTs struct { // ---------------------------------------------------------------------- type RTPMungerState struct { - LastSN uint16 - LastTS uint32 + LastSN uint16 + LastTS uint32 + LastMarker bool } func (r RTPMungerState) String() string { @@ -92,14 +93,16 @@ func (r *RTPMunger) GetParams() RTPMungerParams { func (r *RTPMunger) GetLast() RTPMungerState { return RTPMungerState{ - LastSN: r.lastSN, - LastTS: r.lastTS, + LastSN: r.lastSN, + LastTS: r.lastTS, + LastMarker: r.lastMarker, } } func (r *RTPMunger) SeedLast(state RTPMungerState) { r.lastSN = state.LastSN r.lastTS = state.LastTS + r.lastMarker = state.LastMarker } func (r *RTPMunger) SetLastSnTs(extPkt *buffer.ExtPacket) {