diff --git a/pkg/rtc/mediatracksubscriptions.go b/pkg/rtc/mediatracksubscriptions.go index 1a4cc02d3..0eda270ed 100644 --- a/pkg/rtc/mediatracksubscriptions.go +++ b/pkg/rtc/mediatracksubscriptions.go @@ -212,7 +212,7 @@ func (t *MediaTrackSubscriptions) AddSubscriber(sub types.LocalParticipant, wr * } sub.VerifySubscribeParticipantInfo(subTrack.PublisherID(), subTrack.PublisherVersion()) - if sub.SupportsTransceiverReuse() { + if sub.SupportsTransceiverReuse(t.params.MediaTrack) { // // AddTrack will create a new transceiver or re-use an unused one // if the attributes match. This prevents SDP from bloating diff --git a/pkg/rtc/participant.go b/pkg/rtc/participant.go index 429cf1007..b50568d72 100644 --- a/pkg/rtc/participant.go +++ b/pkg/rtc/participant.go @@ -226,6 +226,7 @@ type ParticipantParams struct { EnableRTPStreamRestartDetection bool ForceBackupCodecPolicySimulcast bool RequireMediaSectionWithJoinResponse bool + DisableTransceiverReuseForE2EE bool } type ParticipantImpl struct { @@ -3752,12 +3753,12 @@ func (p *ParticipantImpl) SupportsSyncStreamID() bool { return p.ProtocolVersion().SupportsSyncStreamID() && !p.params.ClientInfo.isFirefox() && p.params.SyncStreams } -func (p *ParticipantImpl) SupportsTransceiverReuse() bool { +func (p *ParticipantImpl) SupportsTransceiverReuse(mt types.MediaTrack) bool { if p.params.UseOneShotSignallingMode { return p.ProtocolVersion().SupportsTransceiverReuse() } - return p.ProtocolVersion().SupportsTransceiverReuse() && !p.SupportsSyncStreamID() + return p.ProtocolVersion().SupportsTransceiverReuse() && !p.SupportsSyncStreamID() && (!mt.IsEncrypted() || !p.params.DisableTransceiverReuseForE2EE) } func (p *ParticipantImpl) SendDataMessage(kind livekit.DataPacket_Kind, data []byte, sender livekit.ParticipantID, seq uint32) error { diff --git a/pkg/rtc/types/interfaces.go b/pkg/rtc/types/interfaces.go index d8890dca8..18a0181da 100644 --- a/pkg/rtc/types/interfaces.go +++ b/pkg/rtc/types/interfaces.go @@ -382,7 +382,7 @@ type LocalParticipant interface { GetAdaptiveStream() bool ProtocolVersion() ProtocolVersion SupportsSyncStreamID() bool - SupportsTransceiverReuse() bool + SupportsTransceiverReuse(mt MediaTrack) bool IsUsingSinglePeerConnection() bool IsReady() bool ActiveAt() time.Time diff --git a/pkg/rtc/types/typesfakes/fake_local_participant.go b/pkg/rtc/types/typesfakes/fake_local_participant.go index 13e15a792..35e473f04 100644 --- a/pkg/rtc/types/typesfakes/fake_local_participant.go +++ b/pkg/rtc/types/typesfakes/fake_local_participant.go @@ -1283,9 +1283,10 @@ type FakeLocalParticipant struct { supportsSyncStreamIDReturnsOnCall map[int]struct { result1 bool } - SupportsTransceiverReuseStub func() bool + SupportsTransceiverReuseStub func(types.MediaTrack) bool supportsTransceiverReuseMutex sync.RWMutex supportsTransceiverReuseArgsForCall []struct { + arg1 types.MediaTrack } supportsTransceiverReuseReturns struct { result1 bool @@ -8296,17 +8297,18 @@ func (fake *FakeLocalParticipant) SupportsSyncStreamIDReturnsOnCall(i int, resul }{result1} } -func (fake *FakeLocalParticipant) SupportsTransceiverReuse() bool { +func (fake *FakeLocalParticipant) SupportsTransceiverReuse(arg1 types.MediaTrack) bool { fake.supportsTransceiverReuseMutex.Lock() ret, specificReturn := fake.supportsTransceiverReuseReturnsOnCall[len(fake.supportsTransceiverReuseArgsForCall)] fake.supportsTransceiverReuseArgsForCall = append(fake.supportsTransceiverReuseArgsForCall, struct { - }{}) + arg1 types.MediaTrack + }{arg1}) stub := fake.SupportsTransceiverReuseStub fakeReturns := fake.supportsTransceiverReuseReturns - fake.recordInvocation("SupportsTransceiverReuse", []interface{}{}) + fake.recordInvocation("SupportsTransceiverReuse", []interface{}{arg1}) fake.supportsTransceiverReuseMutex.Unlock() if stub != nil { - return stub() + return stub(arg1) } if specificReturn { return ret.result1 @@ -8320,12 +8322,19 @@ func (fake *FakeLocalParticipant) SupportsTransceiverReuseCallCount() int { return len(fake.supportsTransceiverReuseArgsForCall) } -func (fake *FakeLocalParticipant) SupportsTransceiverReuseCalls(stub func() bool) { +func (fake *FakeLocalParticipant) SupportsTransceiverReuseCalls(stub func(types.MediaTrack) bool) { fake.supportsTransceiverReuseMutex.Lock() defer fake.supportsTransceiverReuseMutex.Unlock() fake.SupportsTransceiverReuseStub = stub } +func (fake *FakeLocalParticipant) SupportsTransceiverReuseArgsForCall(i int) types.MediaTrack { + fake.supportsTransceiverReuseMutex.RLock() + defer fake.supportsTransceiverReuseMutex.RUnlock() + argsForCall := fake.supportsTransceiverReuseArgsForCall[i] + return argsForCall.arg1 +} + func (fake *FakeLocalParticipant) SupportsTransceiverReuseReturns(result1 bool) { fake.supportsTransceiverReuseMutex.Lock() defer fake.supportsTransceiverReuseMutex.Unlock()