diff --git a/pkg/rtc/mediatrack.go b/pkg/rtc/mediatrack.go index 266616e1b..1bdf69e47 100644 --- a/pkg/rtc/mediatrack.go +++ b/pkg/rtc/mediatrack.go @@ -133,7 +133,7 @@ func NewMediaTrack(params MediaTrackParams, ti *livekit.TrackInfo) *MediaTrack { t.dynacastManager.NotifySubscriberMaxQuality( subscriberID, mimeType, - buffer.SpatialLayerToVideoQuality(layer, t.MediaTrackReceiver.TrackInfo()), + buffer.GetVideoQualityForSpatialLayer(layer, t.MediaTrackReceiver.TrackInfo()), ) }, ) @@ -165,7 +165,7 @@ func (t *MediaTrack) OnSubscribedMaxQualityChange( for _, q := range maxSubscribedQualities { receiver := t.Receiver(q.CodecMime) if receiver != nil { - receiver.SetMaxExpectedSpatialLayer(buffer.VideoQualityToSpatialLayer(q.Quality, t.MediaTrackReceiver.TrackInfo())) + receiver.SetMaxExpectedSpatialLayer(buffer.GetSpatialLayerForVideoQuality(q.Quality, t.MediaTrackReceiver.TrackInfo())) } } } @@ -263,7 +263,7 @@ func (t *MediaTrack) AddReceiver(receiver *webrtc.RTPReceiver, track sfu.TrackRe t.lock.Lock() var regressCodec bool mimeType := mime.NormalizeMimeType(track.Codec().MimeType) - layer := buffer.RidToSpatialLayer(track.RID(), ti, buffer.DefaultVideoLayersRid) + layer := buffer.GetSpatialLayerForRid(track.RID(), ti) t.params.Logger.Debugw( "AddReceiver", "rid", track.RID(), @@ -272,6 +272,17 @@ func (t *MediaTrack) AddReceiver(receiver *webrtc.RTPReceiver, track sfu.TrackRe "codec", track.Codec(), "trackInfo", logger.Proto(ti), ) + // TODO-REMOVE-AFTER-DEBUG + if layer < 0 { + t.params.Logger.Infow( + "negative layer AddReceiver", + "rid", track.RID(), + "layer", layer, + "ssrc", track.SSRC(), + "codec", track.Codec(), + "trackInfo", logger.Proto(ti), + ) + } wr := t.MediaTrackReceiver.Receiver(mimeType) if wr == nil { priority := -1 diff --git a/pkg/rtc/mediatrackreceiver.go b/pkg/rtc/mediatrackreceiver.go index b32b6a3a2..a63386af1 100644 --- a/pkg/rtc/mediatrackreceiver.go +++ b/pkg/rtc/mediatrackreceiver.go @@ -174,7 +174,7 @@ func NewMediaTrackReceiver(params MediaTrackReceiverParams, ti *livekit.TrackInf } func (t *MediaTrackReceiver) Restart() { - hq := buffer.VideoQualityToSpatialLayer(livekit.VideoQuality_HIGH, t.TrackInfo()) + hq := buffer.GetSpatialLayerForVideoQuality(livekit.VideoQuality_HIGH, t.TrackInfo()) for _, receiver := range t.loadReceivers() { receiver.SetMaxExpectedSpatialLayer(hq) @@ -671,12 +671,12 @@ func (t *MediaTrackReceiver) updateTrackInfoOfReceivers() { func (t *MediaTrackReceiver) SetLayerSsrc(mimeType mime.MimeType, rid string, ssrc uint32) { t.lock.Lock() trackInfo := t.TrackInfoClone() - layer := buffer.RidToSpatialLayer(rid, trackInfo, buffer.DefaultVideoLayersRid) + layer := buffer.GetSpatialLayerForRid(rid, trackInfo) if layer == buffer.InvalidLayerSpatial { // non-simulcast case will not have `rid` layer = 0 } - quality := buffer.SpatialLayerToVideoQuality(layer, trackInfo) + quality := buffer.GetVideoQualityForSpatialLayer(layer, trackInfo) // set video layer ssrc info for i, ci := range trackInfo.Codecs { if mime.NormalizeMimeType(ci.MimeType) != mimeType { @@ -846,7 +846,7 @@ func (t *MediaTrackReceiver) TrackInfoClone() *livekit.TrackInfo { func (t *MediaTrackReceiver) NotifyMaxLayerChange(maxLayer int32) { trackInfo := t.TrackInfo() - quality := buffer.SpatialLayerToVideoQuality(maxLayer, trackInfo) + quality := buffer.GetVideoQualityForSpatialLayer(maxLayer, trackInfo) ti := &livekit.TrackInfo{ Sid: trackInfo.Sid, Type: trackInfo.Type, diff --git a/pkg/rtc/mediatracksubscriptions.go b/pkg/rtc/mediatracksubscriptions.go index 6c66fd238..94ee24688 100644 --- a/pkg/rtc/mediatracksubscriptions.go +++ b/pkg/rtc/mediatracksubscriptions.go @@ -181,7 +181,7 @@ func (t *MediaTrackSubscriptions) AddSubscriber(sub types.LocalParticipant, wr * if !wr.DetermineReceiver(codec) { if t.onSubscriberMaxQualityChange != nil { go func() { - spatial := buffer.VideoQualityToSpatialLayer(livekit.VideoQuality_HIGH, t.params.MediaTrack.ToProto()) + spatial := buffer.GetSpatialLayerForVideoQuality(livekit.VideoQuality_HIGH, t.params.MediaTrack.ToProto()) t.onSubscriberMaxQualityChange(downTrack.SubscriberID(), mime.NormalizeMimeType(codec.MimeType), spatial) }() } diff --git a/pkg/rtc/participant.go b/pkg/rtc/participant.go index 9703e743d..10445fe53 100644 --- a/pkg/rtc/participant.go +++ b/pkg/rtc/participant.go @@ -1140,7 +1140,7 @@ func (p *ParticipantImpl) handleMigrateTracks() []*MediaTrack { p.pubLogger.Warnw("too many pending migrated tracks", nil, "trackID", pti.trackInfos[0].Sid, "count", len(pti.trackInfos), "cid", cid) } - mt := p.addMigratedTrack(cid, pti.trackInfos[0], pti.sdpRids) + mt := p.addMigratedTrack(cid, pti.trackInfos[0]) if mt != nil { addedTracks = append(addedTracks, mt) } else { @@ -2843,7 +2843,7 @@ func (p *ParticipantImpl) mediaTrackReceived(track sfu.TrackRemote, rtpReceiver } } - mt = p.addMediaTrack(signalCid, track.ID(), ti, sdpRids) + mt = p.addMediaTrack(signalCid, track.ID(), ti) newTrack = true // if the addTrackRequest is sent before participant active then it means the client tries to publish @@ -2891,7 +2891,7 @@ func (p *ParticipantImpl) mediaTrackReceived(track sfu.TrackRemote, rtpReceiver return mt, newTrack } -func (p *ParticipantImpl) addMigratedTrack(cid string, ti *livekit.TrackInfo, sdpRids buffer.VideoLayersRid) *MediaTrack { +func (p *ParticipantImpl) addMigratedTrack(cid string, ti *livekit.TrackInfo) *MediaTrack { p.pubLogger.Infow("add migrated track", "cid", cid, "trackID", ti.Sid, "track", logger.Proto(ti)) rtpReceiver := p.TransportManager.GetPublisherRTPReceiver(ti.Mid) if rtpReceiver == nil { @@ -2899,7 +2899,7 @@ func (p *ParticipantImpl) addMigratedTrack(cid string, ti *livekit.TrackInfo, sd return nil } - mt := p.addMediaTrack(cid, cid, ti, sdpRids) + mt := p.addMediaTrack(cid, cid, ti) potentialCodecs := make([]webrtc.RTPCodecParameters, 0, len(ti.Codecs)) parameters := rtpReceiver.GetParameters() @@ -2944,7 +2944,7 @@ func (p *ParticipantImpl) addMigratedTrack(cid string, ti *livekit.TrackInfo, sd return mt } -func (p *ParticipantImpl) addMediaTrack(signalCid string, sdpCid string, ti *livekit.TrackInfo, sdpRids buffer.VideoLayersRid) *MediaTrack { +func (p *ParticipantImpl) addMediaTrack(signalCid string, sdpCid string, ti *livekit.TrackInfo) *MediaTrack { mt := NewMediaTrack(MediaTrackParams{ SignalCid: signalCid, SdpCid: sdpCid, diff --git a/pkg/rtc/subscribedtrack.go b/pkg/rtc/subscribedtrack.go index a45f4e177..35f0b4e85 100644 --- a/pkg/rtc/subscribedtrack.go +++ b/pkg/rtc/subscribedtrack.go @@ -257,7 +257,7 @@ func (t *SubscribedTrack) applySettings() { quality = mt.GetQualityForDimension(t.settings.Width, t.settings.Height) } - spatial = buffer.VideoQualityToSpatialLayer(quality, mt.ToProto()) + spatial = buffer.GetSpatialLayerForVideoQuality(quality, mt.ToProto()) if t.settings.Fps > 0 { temporal = mt.GetTemporalLayerForSpatialFps(spatial, t.settings.Fps, dt.Mime()) } diff --git a/pkg/sfu/buffer/videolayerutils.go b/pkg/sfu/buffer/videolayerutils.go index 1b6b3ff2e..4fafc7847 100644 --- a/pkg/sfu/buffer/videolayerutils.go +++ b/pkg/sfu/buffer/videolayerutils.go @@ -348,11 +348,8 @@ func GetSpatialLayerForRid(rid string, ti *livekit.TrackInfo) int32 { } } - if len(ti.Layers) == 1 { - // single layer without RID - return 0 - } else if len(ti.Layers) > 1 { - // RID present in codec, but not specified via signalling + if len(ti.Layers) != 0 { + // RID present in codec, but may not be specified via signalling // (happens with older browsers setting a rid for SVC codecs) hasRid := false for _, layer := range ti.Layers { diff --git a/pkg/sfu/buffer/videolayerutils_test.go b/pkg/sfu/buffer/videolayerutils_test.go index b4f545144..08b1bbad0 100644 --- a/pkg/sfu/buffer/videolayerutils_test.go +++ b/pkg/sfu/buffer/videolayerutils_test.go @@ -499,6 +499,20 @@ func TestGetSpatialLayerForRid(t *testing.T) { FullResolution: InvalidLayerSpatial, }, }, + { + "layers - no rid", + &livekit.TrackInfo{ + Layers: []*livekit.VideoLayer{ + {Quality: livekit.VideoQuality_LOW, SpatialLayer: 0}, + {Quality: livekit.VideoQuality_MEDIUM, SpatialLayer: 1}, + }, + }, + map[string]int32{ + QuarterResolution: 0, + HalfResolution: 0, + FullResolution: 0, + }, + }, } for _, test := range tests { diff --git a/pkg/sfu/receiver.go b/pkg/sfu/receiver.go index 1d27b97c0..f4cbd1a9b 100644 --- a/pkg/sfu/receiver.go +++ b/pkg/sfu/receiver.go @@ -383,7 +383,7 @@ func (w *WebRTCReceiver) AddUpTrack(track TrackRemote, buff *buffer.Buffer) erro layer := int32(0) if w.Kind() == webrtc.RTPCodecTypeVideo && !w.isSVC { - layer = buffer.RidToSpatialLayer(track.RID(), w.trackInfo.Load(), buffer.DefaultVideoLayersRid) + layer = buffer.GetSpatialLayerForRid(track.RID(), w.trackInfo.Load()) } if layer < 0 { w.logger.Warnw( @@ -499,8 +499,7 @@ func (w *WebRTCReceiver) notifyMaxExpectedLayer(layer int32) { expectedBitrate := int64(0) for _, vl := range ti.Layers { - l := buffer.VideoQualityToSpatialLayer(vl.Quality, ti) - if l <= layer { + if vl.SpatialLayer <= layer { expectedBitrate += int64(vl.Bitrate) } } diff --git a/pkg/sfu/streamtrackermanager.go b/pkg/sfu/streamtrackermanager.go index e0ffca67e..0258508ab 100644 --- a/pkg/sfu/streamtrackermanager.go +++ b/pkg/sfu/streamtrackermanager.go @@ -597,8 +597,7 @@ func (s *StreamTrackerManager) maxExpectedLayerFromTrackInfoLocked() { ti := s.trackInfo.Load() if ti != nil { for _, layer := range ti.Layers { - spatialLayer := buffer.VideoQualityToSpatialLayer(layer.Quality, ti) - if spatialLayer > s.maxExpectedLayer { + if layer.SpatialLayer > s.maxExpectedLayer { s.maxExpectedLayer = layer.SpatialLayer } }