Prevent leakage of previous codec after codec regression. (#4035)

* Prevent leakage of previous codec after codec regression.

In the window between forwarder restart and determining codec, the old
codec packet could leak through. Prevent tha by doing the restart and
codec determination atomically on a codec regression.

* tidy

* use locked function
This commit is contained in:
Raja Subramanian
2025-10-27 17:40:39 +05:30
committed by GitHub
parent 79b03f97a2
commit ab906d710c
3 changed files with 10 additions and 4 deletions

View File

@@ -709,9 +709,9 @@ func (d *DownTrack) handleUpstreamCodecChange(mimeType string) {
"oldCodec", oldCodec, "newCodec", codec.RTPCodecCapability,
)
d.forwarder.Restart()
receiver := d.Receiver()
d.forwarder.DetermineCodec(codec.RTPCodecCapability, receiver.HeaderExtensions(), receiver.VideoLayerMode())
d.forwarder.Restart(codec.RTPCodecCapability, receiver.HeaderExtensions(), receiver.VideoLayerMode())
d.connectionStats.UpdateCodec(d.Mime(), isFECEnabled)
}

View File

@@ -310,6 +310,10 @@ func (f *Forwarder) DetermineCodec(codec webrtc.RTPCodecCapability, extensions [
f.lock.Lock()
defer f.lock.Unlock()
f.determineCodecLocked(codec, extensions, videoLayerMode)
}
func (f *Forwarder) determineCodecLocked(codec webrtc.RTPCodecCapability, extensions []webrtc.RTPHeaderExtensionParameter, videoLayerMode livekit.VideoLayer_Mode) {
if videoLayerMode == livekit.VideoLayer_ONE_SPATIAL_LAYER_PER_STREAM_INCOMPLETE_RTCP_SR {
f.skipReferenceTS = true
}
@@ -1630,7 +1634,7 @@ func (f *Forwarder) CheckSync() (bool, int32) {
return f.vls.CheckSync()
}
func (f *Forwarder) Restart() {
func (f *Forwarder) Restart(codec webrtc.RTPCodecCapability, extensions []webrtc.RTPHeaderExtensionParameter, videoLayerMode livekit.VideoLayer_Mode) {
f.lock.Lock()
defer f.lock.Unlock()
@@ -1644,6 +1648,8 @@ func (f *Forwarder) Restart() {
}
f.lastSwitchExtIncomingTS = 0
f.refVideoLayerMode = livekit.VideoLayer_MODE_UNUSED
f.determineCodecLocked(codec, extensions, videoLayerMode)
}
func (f *Forwarder) FilterRTX(nacks []uint16) (filtered []uint16, disallowedLayers [buffer.DefaultMaxLayerSpatial + 1]bool) {

View File

@@ -602,7 +602,7 @@ func (w *WebRTCReceiver) GetLayeredBitrate() ([]int32, Bitrates) {
return w.streamTrackerManager.GetLayeredBitrate()
}
// OnCloseHandler method to be called on remote tracked removed
// OnCloseHandler method to be called on remote track removed
func (w *WebRTCReceiver) OnCloseHandler(fn func()) {
w.onCloseHandler = fn
}