From c362e61d3c6c494da00a3f39928fc6344561d959 Mon Sep 17 00:00:00 2001 From: Raja Subramanian Date: Fri, 28 Aug 2026 00:27:50 +0530 Subject: [PATCH] Set up track info properly for dummy receiver. (#4807) In migration cases, dummy receiver trackInfo is used by relay tracks to set up the receivers and those need the proper track info. Also check for proper receiver when adding a migrated track. --- pkg/rtc/mediatrackreceiver.go | 2 +- pkg/rtc/participant.go | 60 ++++++++++++++++++++++++++++------- pkg/rtc/wrappedreceiver.go | 15 ++++++--- 3 files changed, 59 insertions(+), 18 deletions(-) diff --git a/pkg/rtc/mediatrackreceiver.go b/pkg/rtc/mediatrackreceiver.go index ad478d0d8..c6130e352 100644 --- a/pkg/rtc/mediatrackreceiver.go +++ b/pkg/rtc/mediatrackreceiver.go @@ -344,7 +344,7 @@ func (t *MediaTrackReceiver) SetPotentialCodecs(codecs []webrtc.RTPCodecParamete } if !exist { receivers = append(receivers, &simulcastReceiver{ - TrackReceiver: NewDummyReceiver(t.ID(), string(t.PublisherID()), c, headers), + TrackReceiver: NewDummyReceiver(t.TrackInfo(), string(t.PublisherID()), c, headers), priority: i, }) } diff --git a/pkg/rtc/participant.go b/pkg/rtc/participant.go index 7a6215f18..cdf7168de 100644 --- a/pkg/rtc/participant.go +++ b/pkg/rtc/participant.go @@ -2387,6 +2387,7 @@ func (p *ParticipantImpl) onMediaTrack(rtcTrack *webrtc.TrackRemote, rtpReceiver "ssrc", track.SSRC(), "rtxSsrc", track.RtxSSRC(), "mime", mime.NormalizeMimeType(codec.MimeType), + "isNewTrack", isNewTrack, "isReceiverAdded", isReceiverAdded, "sdpRids", logger.StringSlice(sdpRids[:]), ) @@ -3294,7 +3295,6 @@ func (p *ParticipantImpl) mediaTrackReceived( rtpReceiver *webrtc.RTPReceiver, ) (*MediaTrack, bool, bool, buffer.VideoLayersRid) { p.pendingTracksLock.Lock() - newTrack := false mid := p.TransportManager.GetPublisherMid(rtpReceiver) p.pubLogger.Debugw( @@ -3318,10 +3318,13 @@ func (p *ParticipantImpl) mediaTrackReceived( } // use existing media track to handle simulcast - var createdAt time.Time - var isMigrated bool - var ridsFromSdp buffer.VideoLayersRid - var pubTime time.Duration + var ( + createdAt time.Time + isNewTrack bool + isMigrated bool + ridsFromSdp buffer.VideoLayersRid + pubTime time.Duration + ) mt, ok := p.getPublishedTrackBySdpCid(track.ID()).(*MediaTrack) if !ok { var ( @@ -3351,7 +3354,14 @@ func (p *ParticipantImpl) mediaTrackReceived( } } if codecFound != len(ti.Codecs) { - p.pubLogger.Warnw("migrated track codec mismatched", nil, "track", logger.Proto(ti), "webrtcCodec", parameters) + p.pubLogger.Warnw( + "migrated track codec mismatched", nil, + "trackID", ti.Sid, + "track", logger.Proto(ti), + "webrtcCodec", parameters, + "codecFound", codecFound, + "codecCount", len(ti.Codecs), + ) p.pendingTracksLock.Unlock() p.IssueFullReconnect(types.ParticipantCloseReasonMigrateCodecMismatch) return nil, false, false, ridsFromSdp @@ -3375,7 +3385,7 @@ func (p *ParticipantImpl) mediaTrackReceived( } mt = p.addMediaTrack(signalCid, ti) - newTrack = true + isNewTrack = true } // a track might have been set up in migrate-in path and won't show up as a new track here, @@ -3387,12 +3397,12 @@ func (p *ParticipantImpl) mediaTrackReceived( } } } - if !newTrack { - newTrack = !mt.Published() + if !isNewTrack { + isNewTrack = !mt.Published() } mt.SetPublished(true) - if newTrack { + if isNewTrack { // if the addTrackRequest is sent before publisher peer connection is established, then it means the client tries to publish // before fully connected, in this case we only record the time when publisher peer connection is established since // we want this metric to represent the time cost by publishing. @@ -3406,7 +3416,7 @@ func (p *ParticipantImpl) mediaTrackReceived( _, isReceiverAdded := mt.AddReceiver(rtpReceiver, track, mid) - if newTrack { + if isNewTrack { go func() { // TODO: remove this after we know where the high delay is coming from if pubTime > 3*time.Second { @@ -3437,11 +3447,12 @@ func (p *ParticipantImpl) mediaTrackReceived( p.GetClientInfo().GetSdk(), p.Kind(), ) + p.handleTrackPublished(mt, isMigrated, false) }() } - return mt, newTrack, isReceiverAdded, ridsFromSdp + return mt, isNewTrack, isReceiverAdded, ridsFromSdp } func (p *ParticipantImpl) addMigratedTrack(cid string, ti *livekit.TrackInfo) *MediaTrack { @@ -3456,6 +3467,31 @@ func (p *ParticipantImpl) addMigratedTrack(cid string, ti *livekit.TrackInfo) *M return nil } + // check if the migrated track has correct codec + if len(ti.Codecs) > 0 { + parameters := rtpReceiver.GetParameters() + var codecFound int + for _, c := range ti.Codecs { + for _, nc := range parameters.Codecs { + if mime.IsMimeTypeStringEqual(nc.MimeType, c.MimeType) { + codecFound++ + break + } + } + } + if codecFound != len(ti.Codecs) { + p.pubLogger.Warnw( + "migrated track codec mismatched", nil, + "trackID", ti.Sid, + "track", logger.Proto(ti), + "webrtcCodec", parameters, + "codecFound", codecFound, + "codecCount", len(ti.Codecs), + ) + return nil + } + } + mt := p.addMediaTrack(cid, ti) mt.SetMigrated(true) diff --git a/pkg/rtc/wrappedreceiver.go b/pkg/rtc/wrappedreceiver.go index 4ff4da723..c9b9f4c30 100644 --- a/pkg/rtc/wrappedreceiver.go +++ b/pkg/rtc/wrappedreceiver.go @@ -184,7 +184,7 @@ func (r *WrappedReceiver) AddOnReady(f func()) { type DummyReceiver struct { receiver atomic.Value - trackID livekit.TrackID + trackInfo *livekit.TrackInfo streamId string codec webrtc.RTPCodecParameters headerExtensions []webrtc.RTPHeaderExtensionParameter @@ -201,9 +201,14 @@ type DummyReceiver struct { redReceiver, primaryReceiver *DummyRedReceiver } -func NewDummyReceiver(trackID livekit.TrackID, streamId string, codec webrtc.RTPCodecParameters, headerExtensions []webrtc.RTPHeaderExtensionParameter) *DummyReceiver { +func NewDummyReceiver( + trackInfo *livekit.TrackInfo, + streamId string, + codec webrtc.RTPCodecParameters, + headerExtensions []webrtc.RTPHeaderExtensionParameter, +) *DummyReceiver { return &DummyReceiver{ - trackID: trackID, + trackInfo: trackInfo, streamId: streamId, codec: codec, headerExtensions: headerExtensions, @@ -262,7 +267,7 @@ func (d *DummyReceiver) Upgrade(receiver sfu.TrackReceiver) { } func (d *DummyReceiver) TrackID() livekit.TrackID { - return d.trackID + return livekit.TrackID(d.trackInfo.Sid) } func (d *DummyReceiver) StreamID() string { @@ -391,7 +396,7 @@ func (d *DummyReceiver) TrackInfo() *livekit.TrackInfo { if receiver := d.getReceiver(); receiver != nil { return receiver.TrackInfo() } - return nil + return d.trackInfo } func (d *DummyReceiver) UpdateTrackInfo(ti *livekit.TrackInfo) {