diff --git a/go.mod b/go.mod index cd2c04e29..34f4c3d5f 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/jxskiss/base62 v1.1.0 github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1 github.com/livekit/mediatransportutil v0.0.0-20250310153736-45596af895b6 - github.com/livekit/protocol v1.35.1-0.20250321043517-157eda585c9a + github.com/livekit/protocol v1.36.1 github.com/livekit/psrpc v0.6.1-0.20250205181828-a0beed2e4126 github.com/mackerelio/go-osstat v0.2.5 github.com/magefile/mage v1.15.0 diff --git a/go.sum b/go.sum index 4d3109960..da1f8604d 100644 --- a/go.sum +++ b/go.sum @@ -170,8 +170,8 @@ github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1 h1:jm09419p0lqTkD github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1/go.mod h1:Rs3MhFwutWhGwmY1VQsygw28z5bWcnEYmS1OG9OxjOQ= github.com/livekit/mediatransportutil v0.0.0-20250310153736-45596af895b6 h1:6ZhtnY9I9knfm3ieIPpznQSEU2rDECO8yliW/ANLQ7U= github.com/livekit/mediatransportutil v0.0.0-20250310153736-45596af895b6/go.mod h1:36s+wwmU3O40IAhE+MjBWP3W71QRiEE9SfooSBvtBqY= -github.com/livekit/protocol v1.35.1-0.20250321043517-157eda585c9a h1:NmBLyIS7rW9Jd/8WXLbo/Lk7ZuMgkwJDJiE1+ixGyDE= -github.com/livekit/protocol v1.35.1-0.20250321043517-157eda585c9a/go.mod h1:WrT/CYRxtMNOVUjnIPm5OjWtEkmreffTeE1PRZwlRg4= +github.com/livekit/protocol v1.36.1 h1:0cShRQxZQBQ/VquXrQRVD0qFwD84/7pffAN5dQM55Iw= +github.com/livekit/protocol v1.36.1/go.mod h1:WrT/CYRxtMNOVUjnIPm5OjWtEkmreffTeE1PRZwlRg4= github.com/livekit/psrpc v0.6.1-0.20250205181828-a0beed2e4126 h1:fzuYpAQbCid7ySPpQWWePfQOWUrs8x6dJ0T3Wl07n+Y= github.com/livekit/psrpc v0.6.1-0.20250205181828-a0beed2e4126/go.mod h1:X5WtEZ7OnEs72Fi5/J+i0on3964F1aynQpCalcgMqRo= github.com/mackerelio/go-osstat v0.2.5 h1:+MqTbZUhoIt4m8qzkVoXUJg1EuifwlAJSk4Yl2GXh+o= diff --git a/pkg/config/config.go b/pkg/config/config.go index 1343544bc..58f395723 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -155,6 +155,8 @@ type PlayoutDelayConfig struct { type VideoConfig struct { DynacastPauseDelay time.Duration `yaml:"dynacast_pause_delay,omitempty"` StreamTrackerManager sfu.StreamTrackerManagerConfig `yaml:"stream_tracker_manager,omitempty"` + + CodecRegressionThreshold int `yaml:"codec_regression_threshold,omitempty"` } type RoomConfig struct { @@ -327,8 +329,9 @@ var DefaultConfig = Config{ }, Audio: sfu.DefaultAudioConfig, Video: VideoConfig{ - DynacastPauseDelay: 5 * time.Second, - StreamTrackerManager: sfu.DefaultStreamTrackerManagerConfig, + DynacastPauseDelay: 5 * time.Second, + StreamTrackerManager: sfu.DefaultStreamTrackerManagerConfig, + CodecRegressionThreshold: 5, }, Redis: redisLiveKit.RedisConfig{}, Room: RoomConfig{ diff --git a/pkg/rtc/mediatrack.go b/pkg/rtc/mediatrack.go index be58fea81..4be5466c3 100644 --- a/pkg/rtc/mediatrack.go +++ b/pkg/rtc/mediatrack.go @@ -55,7 +55,7 @@ type MediaTrack struct { rttFromXR atomic.Bool - enableRegression bool + backupCodecPolicy livekit.BackupCodecPolicy regressionTargetCodec mime.MimeType regressionTargetCodecReceived bool } @@ -78,16 +78,16 @@ type MediaTrackParams struct { OnRTCP func([]rtcp.Packet) ForwardStats *sfu.ForwardStats OnTrackEverSubscribed func(livekit.TrackID) + ShouldRegressCodec func() bool } func NewMediaTrack(params MediaTrackParams, ti *livekit.TrackInfo) *MediaTrack { t := &MediaTrack{ - params: params, + params: params, + backupCodecPolicy: ti.BackupCodecPolicy, } - // TODO: disable codec regression until simulcast-codec clients knows that - if ti.BackupCodecPolicy == livekit.BackupCodecPolicy_REGRESSION && len(ti.Codecs) > 1 { - t.enableRegression = true + if t.backupCodecPolicy != livekit.BackupCodecPolicy_SIMULCAST && len(ti.Codecs) > 1 { t.regressionTargetCodec = mime.NormalizeMimeType(ti.Codecs[1].MimeType) t.params.Logger.Debugw("track enabled codec regression", "regressionCodec", t.regressionTargetCodec) } @@ -372,7 +372,7 @@ func (t *MediaTrack) AddReceiver(receiver *webrtc.RTPReceiver, track sfu.TrackRe }) } - if newCodec && t.enableRegression { + if newCodec && t.enableRegression() { if mimeType == t.regressionTargetCodec { t.params.Logger.Infow("regression target codec received", "codec", mimeType) t.regressionTargetCodecReceived = true @@ -497,3 +497,8 @@ func (t *MediaTrack) OnTrackSubscribed() { go t.params.OnTrackEverSubscribed(t.ID()) } } + +func (t *MediaTrack) enableRegression() bool { + return t.backupCodecPolicy == livekit.BackupCodecPolicy_REGRESSION || + (t.backupCodecPolicy == livekit.BackupCodecPolicy_PREFER_REGRESSION && t.params.ShouldRegressCodec()) +} diff --git a/pkg/rtc/participant.go b/pkg/rtc/participant.go index f4d789dc8..1e0d09d11 100644 --- a/pkg/rtc/participant.go +++ b/pkg/rtc/participant.go @@ -144,6 +144,7 @@ type ParticipantParams struct { GetParticipantInfo func(pID livekit.ParticipantID) *livekit.ParticipantInfo GetRegionSettings func(ip string) *livekit.RegionSettings GetSubscriberForwarderState func(p types.LocalParticipant) (map[livekit.TrackID]*livekit.RTPForwarderState, error) + ShouldRegressCodec func() bool DisableSupervisor bool ReconnectOnPublicationError bool ReconnectOnSubscriptionError bool @@ -2216,7 +2217,7 @@ func (p *ParticipantImpl) addPendingTrackLocked(req *livekit.AddTrackRequest) *l } backupCodecPolicy := req.BackupCodecPolicy - if backupCodecPolicy == livekit.BackupCodecPolicy_REGRESSION && p.params.DisableCodecRegression { + if backupCodecPolicy != livekit.BackupCodecPolicy_SIMULCAST && p.params.DisableCodecRegression { backupCodecPolicy = livekit.BackupCodecPolicy_SIMULCAST } @@ -2574,6 +2575,7 @@ func (p *ParticipantImpl) addMediaTrack(signalCid string, sdpCid string, ti *liv OnRTCP: p.postRtcp, ForwardStats: p.params.ForwardStats, OnTrackEverSubscribed: p.sendTrackHasBeenSubscribed, + ShouldRegressCodec: p.params.ShouldRegressCodec, }, ti) mt.OnSubscribedMaxQualityChange(p.onSubscribedMaxQualityChange) diff --git a/pkg/service/roommanager.go b/pkg/service/roommanager.go index b48ac3b72..9b587a360 100644 --- a/pkg/service/roommanager.go +++ b/pkg/service/roommanager.go @@ -53,8 +53,6 @@ const ( tokenDefaultTTL = 10 * time.Minute ) -var affinityEpoch = time.Date(2000, 0, 0, 0, 0, 0, 0, time.UTC) - type iceConfigCacheKey struct { roomName livekit.RoomName participantIdentity livekit.ParticipantIdentity @@ -468,6 +466,9 @@ func (r *RoomManager) StartSession( DataChannelMaxBufferedAmount: r.config.RTC.DataChannelMaxBufferedAmount, DatachannelSlowThreshold: r.config.RTC.DatachannelSlowThreshold, FireOnTrackBySdp: true, + ShouldRegressCodec: func() bool { + return r.config.Video.CodecRegressionThreshold == 0 || room.GetParticipantCount() < r.config.Video.CodecRegressionThreshold + }, }) if err != nil { return err