diff --git a/pkg/rtc/participant.go b/pkg/rtc/participant.go index aec54d291..f2866a411 100644 --- a/pkg/rtc/participant.go +++ b/pkg/rtc/participant.go @@ -1259,22 +1259,6 @@ func (p *ParticipantImpl) HandleOffer(sd *livekit.SessionDescription) error { } } - unmatchAudios, unmatchVideos := p.populateSdpCid(parsedOffer) - parsedOffer = p.setCodecPreferencesForPublisher(parsedOffer, unmatchAudios, unmatchVideos) - p.updateRidsFromSDP(parsedOffer, unmatchVideos) - - // put together munged offer after setting codec preferences - bytes, err := parsedOffer.Marshal() - if err != nil { - lgr.Errorw("failed to marshal offer", err, "parsedOffer", parsedOffer) - return err - } - - offer = webrtc.SessionDescription{ - Type: offer.Type, - SDP: string(bytes), - } - err = p.TransportManager.HandleOffer(offer, offerId, p.MigrateState() == types.MigrateStateInit) if err != nil { lgr.Warnw("could not handle offer", err, "mungedOffer", offer) @@ -1291,6 +1275,21 @@ func (p *ParticipantImpl) HandleOffer(sd *livekit.SessionDescription) error { return nil } +func (p *ParticipantImpl) onPublisherSetRemoteDescription() { + offer := p.TransportManager.LastPublisherOfferPending() + parsedOffer, err := offer.Unmarshal() + if err != nil { + p.pubLogger.Warnw("could not parse offer", err) + return + } + + // set publish codec preferences after remote description is set + // and required transceivers are created + unmatchAudios, unmatchVideos := p.populateSdpCid(parsedOffer) + p.setCodecPreferencesForPublisher(parsedOffer, unmatchAudios, unmatchVideos) + p.updateRidsFromSDP(parsedOffer, unmatchVideos) +} + func (p *ParticipantImpl) onPublisherAnswer(answer webrtc.SessionDescription, answerId uint32) error { if p.IsClosed() || p.IsDisconnected() { return nil @@ -1921,6 +1920,10 @@ type PublisherTransportHandler struct { AnyTransportHandler } +func (h PublisherTransportHandler) OnSetRemoteDescriptionOffer() { + h.p.onPublisherSetRemoteDescription() +} + func (h PublisherTransportHandler) OnAnswer(sd webrtc.SessionDescription, answerId uint32) error { return h.p.onPublisherAnswer(sd, answerId) } diff --git a/pkg/rtc/participant_internal_test.go b/pkg/rtc/participant_internal_test.go index ea1201777..7bf05045e 100644 --- a/pkg/rtc/participant_internal_test.go +++ b/pkg/rtc/participant_internal_test.go @@ -625,8 +625,12 @@ func TestPreferAudioCodecForRed(t *testing.T) { participant.SetMigrateState(types.MigrateStateComplete) me := webrtc.MediaEngine{} - me.RegisterDefaultCodecs() - require.NoError(t, me.RegisterCodec(RedCodecParameters, webrtc.RTPCodecTypeAudio)) + opusCodecParameters := OpusCodecParameters + opusCodecParameters.RTPCodecCapability.RTCPFeedback = []webrtc.RTCPFeedback{{Type: webrtc.TypeRTCPFBNACK}} + require.NoError(t, me.RegisterCodec(opusCodecParameters, webrtc.RTPCodecTypeAudio)) + redCodecParameters := RedCodecParameters + redCodecParameters.RTPCodecCapability.RTCPFeedback = []webrtc.RTCPFeedback{{Type: webrtc.TypeRTCPFBNACK}} + require.NoError(t, me.RegisterCodec(redCodecParameters, webrtc.RTPCodecTypeAudio)) api := webrtc.NewAPI(webrtc.WithMediaEngine(&me)) pc, err := api.NewPeerConnection(webrtc.Configuration{}) @@ -641,9 +645,17 @@ func TestPreferAudioCodecForRed(t *testing.T) { DisableRed: disableRed, Cid: trackCid, }) - track, err := webrtc.NewTrackLocalStaticRTP(webrtc.RTPCodecCapability{MimeType: "audio/opus"}, trackCid, trackCid) + track, err := webrtc.NewTrackLocalStaticRTP( + webrtc.RTPCodecCapability{MimeType: "audio/opus"}, + trackCid, + trackCid, + ) require.NoError(t, err) - transceiver, err := pc.AddTransceiverFromTrack(track, webrtc.RTPTransceiverInit{Direction: webrtc.RTPTransceiverDirectionSendrecv}) + + transceiver, err := pc.AddTransceiverFromTrack( + track, + webrtc.RTPTransceiverInit{Direction: webrtc.RTPTransceiverDirectionSendrecv}, + ) require.NoError(t, err) codecs := transceiver.Sender().GetParameters().Codecs for i, c := range codecs { @@ -683,7 +695,14 @@ func TestPreferAudioCodecForRed(t *testing.T) { Id: offerId, }) - require.Eventually(t, func() bool { return answerReceived.Load() && answerIdReceived.Load() == offerId }, 5*time.Second, 10*time.Millisecond) + require.Eventually( + t, + func() bool { + return answerReceived.Load() && answerIdReceived.Load() == offerId + }, + 5*time.Second, + 10*time.Millisecond, + ) var redPreferred bool parsed, err := answer.Unmarshal() diff --git a/pkg/rtc/participant_sdp.go b/pkg/rtc/participant_sdp.go index 0904b78c1..8dd5a4725 100644 --- a/pkg/rtc/participant_sdp.go +++ b/pkg/rtc/participant_sdp.go @@ -163,7 +163,7 @@ func (p *ParticipantImpl) populateSdpCid(parsedOffer *sdp.SessionDescription) ([ unmatchVideos, err := p.TransportManager.GetUnmatchMediaForOffer(parsedOffer, "video") if err != nil { - p.pubLogger.Warnw("could not get unmatch audios", err) + p.pubLogger.Warnw("could not get unmatch videos", err) return nil, nil } @@ -176,108 +176,41 @@ func (p *ParticipantImpl) setCodecPreferencesForPublisher( parsedOffer *sdp.SessionDescription, unmatchAudios []*sdp.MediaDescription, unmatchVideos []*sdp.MediaDescription, -) *sdp.SessionDescription { - parsedOffer, unprocessedUnmatchAudios := p.setCodecPreferencesForPublisherMedia( +) { + unprocessedUnmatchAudios := p.setCodecPreferencesForPublisherMedia( parsedOffer, unmatchAudios, livekit.TrackType_AUDIO, ) - parsedOffer = p.setCodecPreferencesOpusRedForPublisher(parsedOffer, unprocessedUnmatchAudios) - parsedOffer, _ = p.setCodecPreferencesForPublisherMedia( + p.setCodecPreferencesOpusRedForPublisher(parsedOffer, unprocessedUnmatchAudios) + _ = p.setCodecPreferencesForPublisherMedia( parsedOffer, unmatchVideos, livekit.TrackType_VIDEO, ) - return parsedOffer -} - -func (p *ParticipantImpl) setCodecPreferencesOpusRedForPublisher( - parsedOffer *sdp.SessionDescription, - unmatchAudios []*sdp.MediaDescription, -) *sdp.SessionDescription { - for _, unmatchAudio := range unmatchAudios { - streamID, ok := lksdp.ExtractStreamID(unmatchAudio) - if !ok { - continue - } - - p.pendingTracksLock.RLock() - _, ti, _, _, _ := p.getPendingTrack(streamID, livekit.TrackType_AUDIO, false) - p.pendingTracksLock.RUnlock() - if ti == nil { - continue - } - - codecs, err := lksdp.CodecsFromMediaDescription(unmatchAudio) - if err != nil { - p.pubLogger.Errorw( - "extract codecs from media section failed", err, - "media", unmatchAudio, - "parsedOffer", parsedOffer, - ) - continue - } - - var opusPayload uint8 - for _, codec := range codecs { - if mime.IsMimeTypeCodecStringOpus(codec.Name) { - opusPayload = codec.PayloadType - break - } - } - if opusPayload == 0 { - continue - } - - // if RED is disabled for this track, don't prefer RED codec in offer - var preferredCodecs, leftCodecs []string - for _, codec := range codecs { - // codec contain opus/red - if !ti.DisableRed && mime.IsMimeTypeCodecStringRED(codec.Name) && strings.Contains(codec.Fmtp, strconv.FormatInt(int64(opusPayload), 10)) { - preferredCodecs = append(preferredCodecs, strconv.FormatInt(int64(codec.PayloadType), 10)) - } else { - leftCodecs = append(leftCodecs, strconv.FormatInt(int64(codec.PayloadType), 10)) - } - } - - // ensure nack enabled for audio in publisher offer - var nackFound bool - for _, attr := range unmatchAudio.Attributes { - if attr.Key == "rtcp-fb" && strings.Contains(attr.Value, fmt.Sprintf("%d nack", opusPayload)) { - nackFound = true - break - } - } - if !nackFound { - unmatchAudio.Attributes = append(unmatchAudio.Attributes, sdp.Attribute{ - Key: "rtcp-fb", - Value: fmt.Sprintf("%d nack", opusPayload), - }) - } - - // no opus/red found - if len(preferredCodecs) == 0 { - continue - } - - unmatchAudio.MediaName.Formats = append(unmatchAudio.MediaName.Formats[:0], preferredCodecs...) - unmatchAudio.MediaName.Formats = append(unmatchAudio.MediaName.Formats, leftCodecs...) - } - - return parsedOffer } func (p *ParticipantImpl) setCodecPreferencesForPublisherMedia( parsedOffer *sdp.SessionDescription, unmatches []*sdp.MediaDescription, trackType livekit.TrackType, -) (*sdp.SessionDescription, []*sdp.MediaDescription) { +) []*sdp.MediaDescription { unprocessed := make([]*sdp.MediaDescription, 0, len(unmatches)) - // unmatched media is pending for publish, set codec preference for _, unmatch := range unmatches { var ti *livekit.TrackInfo var mimeType string + mid := lksdp.GetMidValue(unmatch) + if mid == "" { + unprocessed = append(unprocessed, unmatch) + continue + } + transceiver := p.TransportManager.GetPublisherRTPTransceiver(mid) + if transceiver == nil { + unprocessed = append(unprocessed, unmatch) + continue + } + streamID, ok := lksdp.ExtractStreamID(unmatch) if !ok { unprocessed = append(unprocessed, unmatch) @@ -313,61 +246,74 @@ func (p *ParticipantImpl) setCodecPreferencesForPublisherMedia( continue } - codecs, err := lksdp.CodecsFromMediaDescription(unmatch) + configureReceiverCodecs( + transceiver, + mimeType, + p.params.ClientInfo.ComplyWithCodecOrderInSDPAnswer(), + ) + } + + return unprocessed +} + +func (p *ParticipantImpl) setCodecPreferencesOpusRedForPublisher( + parsedOffer *sdp.SessionDescription, + unmatchAudios []*sdp.MediaDescription, +) { + for _, unmatchAudio := range unmatchAudios { + mid := lksdp.GetMidValue(unmatchAudio) + if mid == "" { + continue + } + transceiver := p.TransportManager.GetPublisherRTPTransceiver(mid) + if transceiver == nil { + continue + } + + streamID, ok := lksdp.ExtractStreamID(unmatchAudio) + if !ok { + continue + } + + p.pendingTracksLock.RLock() + _, ti, _, _, _ := p.getPendingTrack(streamID, livekit.TrackType_AUDIO, false) + p.pendingTracksLock.RUnlock() + if ti == nil { + continue + } + + codecs, err := lksdp.CodecsFromMediaDescription(unmatchAudio) if err != nil { p.pubLogger.Errorw( "extract codecs from media section failed", err, - "media", unmatch, + "media", unmatchAudio, "parsedOffer", parsedOffer, ) - unprocessed = append(unprocessed, unmatch) continue } - var codecIdx int - var preferredCodecs, leftCodecs []string - for idx, c := range codecs { - if mime.GetMimeTypeCodec(mimeType) == mime.NormalizeMimeTypeCodec(c.Name) { - preferredCodecs = append(preferredCodecs, strconv.FormatInt(int64(c.PayloadType), 10)) - codecIdx = idx - } else { - leftCodecs = append(leftCodecs, strconv.FormatInt(int64(c.PayloadType), 10)) + var opusPayload uint8 + for _, codec := range codecs { + if mime.IsMimeTypeCodecStringOpus(codec.Name) { + opusPayload = codec.PayloadType + break } } - - // could not find preferred mime in the offer - if len(preferredCodecs) == 0 { - unprocessed = append(unprocessed, unmatch) + if opusPayload == 0 { continue } - unmatch.MediaName.Formats = append(unmatch.MediaName.Formats[:0], preferredCodecs...) - if trackType == livekit.TrackType_VIDEO { - // if the client don't comply with codec order in SDP answer, only keep preferred codecs to force client to use it - if p.params.ClientInfo.ComplyWithCodecOrderInSDPAnswer() { - unmatch.MediaName.Formats = append(unmatch.MediaName.Formats, leftCodecs...) + // if RED is disabled for this track, don't prefer RED codec in offer + for _, codec := range codecs { + // codec contain opus/red + if !ti.DisableRed && + mime.IsMimeTypeCodecStringRED(codec.Name) && + strings.Contains(codec.Fmtp, strconv.FormatInt(int64(opusPayload), 10)) { + configureReceiverCodecs(transceiver, "audio/red", true) + break } - } else { - // ensure nack enabled for audio in publisher offer - var nackFound bool - for _, attr := range unmatch.Attributes { - if attr.Key == "rtcp-fb" && strings.Contains(attr.Value, fmt.Sprintf("%d nack", codecs[codecIdx].PayloadType)) { - nackFound = true - break - } - } - if !nackFound { - unmatch.Attributes = append(unmatch.Attributes, sdp.Attribute{ - Key: "rtcp-fb", - Value: fmt.Sprintf("%d nack", codecs[codecIdx].PayloadType), - }) - } - - unmatch.MediaName.Formats = append(unmatch.MediaName.Formats, leftCodecs...) } } - - return parsedOffer, unprocessed } // configure publisher answer for audio track's dtx and stereo settings @@ -419,7 +365,7 @@ func (p *ParticipantImpl) configurePublisherAnswer(answer webrtc.SessionDescript } } - if ti == nil || (ti.DisableDtx && !ti.Stereo) { + if ti == nil || (ti.DisableDtx && !slices.Contains(ti.AudioFeatures, livekit.AudioTrackFeature_TF_STEREO)) { // no need to configure continue } diff --git a/pkg/rtc/transport.go b/pkg/rtc/transport.go index 43c32d09a..e593d01a9 100644 --- a/pkg/rtc/transport.go +++ b/pkg/rtc/transport.go @@ -956,9 +956,9 @@ func (t *PCTransport) AddTrack( return } - configureTransceiverCodecs(transceiver, enabledCodecs, rtcpFeedbackConfig, !t.params.IsOfferer) + configureSenderCodecs(transceiver, enabledCodecs, rtcpFeedbackConfig, !t.params.IsOfferer) if trackLocal.Kind() == webrtc.RTPCodecTypeAudio { - configureAudioTransceiver(transceiver, params.Stereo, !params.Red || !t.params.ClientInfo.SupportsAudioRED()) + configureSenderAudio(transceiver, params.Stereo, !params.Red || !t.params.ClientInfo.SupportsAudioRED()) } t.adjustNumOutstandingMedia(transceiver) return @@ -981,9 +981,9 @@ func (t *PCTransport) AddTransceiverFromTrack( return } - configureTransceiverCodecs(transceiver, enabledCodecs, rtcpFeedbackConfig, !t.params.IsOfferer) + configureSenderCodecs(transceiver, enabledCodecs, rtcpFeedbackConfig, !t.params.IsOfferer) if trackLocal.Kind() == webrtc.RTPCodecTypeAudio { - configureAudioTransceiver(transceiver, params.Stereo, !params.Red || !t.params.ClientInfo.SupportsAudioRED()) + configureSenderAudio(transceiver, params.Stereo, !params.Red || !t.params.ClientInfo.SupportsAudioRED()) } t.adjustNumOutstandingMedia(transceiver) return @@ -1020,6 +1020,16 @@ func (t *PCTransport) CurrentRemoteDescription() *webrtc.SessionDescription { return &rd } +func (t *PCTransport) PendingRemoteDescription() *webrtc.SessionDescription { + prd := t.pc.PendingRemoteDescription() + if prd == nil { + return nil + } + + rd := *prd + return &rd +} + func (t *PCTransport) GetMid(rtpReceiver *webrtc.RTPReceiver) string { for _, tr := range t.pc.GetTransceivers() { if tr.Receiver() == rtpReceiver { @@ -1030,6 +1040,16 @@ func (t *PCTransport) GetMid(rtpReceiver *webrtc.RTPReceiver) string { return "" } +func (t *PCTransport) GetRTPTransceiver(mid string) *webrtc.RTPTransceiver { + for _, tr := range t.pc.GetTransceivers() { + if tr.Mid() == mid { + return tr + } + } + + return nil +} + func (t *PCTransport) GetRTPReceiver(mid string) *webrtc.RTPReceiver { for _, tr := range t.pc.GetTransceivers() { if tr.Mid() == mid { @@ -2124,6 +2144,7 @@ func (t *PCTransport) handleICEGatheringCompleteAnswerer() error { if err := t.setRemoteDescription(offer); err != nil { return err } + t.params.Handler.OnSetRemoteDescriptionOffer() return t.createAndSendAnswer() } @@ -2643,6 +2664,8 @@ func (t *PCTransport) handleRemoteOfferReceived(sd *webrtc.SessionDescription, o if err := t.setRemoteDescription(*sd); err != nil { return err } + t.params.Handler.OnSetRemoteDescriptionOffer() + rtxRepairs := nonSimulcastRTXRepairsFromSDP(parsed, t.params.Logger) if len(rtxRepairs) > 0 { t.params.Logger.Debugw("rtx pairs found from sdp", "ssrcs", rtxRepairs) @@ -2805,7 +2828,7 @@ func (t *PCTransport) outputAndClearICEStats() { // configure subscriber transceiver for audio stereo and nack // pion doesn't support per transciver codec configuration, so the nack of this session will be disabled // forever once it is first disabled by a transceiver. -func configureAudioTransceiver(tr *webrtc.RTPTransceiver, stereo bool, nack bool) { +func configureSenderAudio(tr *webrtc.RTPTransceiver, stereo bool, nack bool) { sender := tr.Sender() if sender == nil { return @@ -2834,13 +2857,14 @@ func configureAudioTransceiver(tr *webrtc.RTPTransceiver, stereo bool, nack bool tr.SetCodecPreferences(configCodecs) } -// In single peer connection mode, set up enebled codecs, -// the config provides config of direction, for publisher peer connection, it is publish enabled codecs -// and for subscriber peer connection, it is subscribe enabled codecs. +// In single peer connection mode, set up enebled codecs for sender. +// The config provides config of direction. +// For publisher peer connection those are publish enabled codecs +// and for subscriber peer connection those are subscribe enabled codecs. // // But, in single peer connection mode, if setting up a transceiver where the media is // flowing in the other direction, the other direction codec config needs to be set. -func configureTransceiverCodecs( +func configureSenderCodecs( tr *webrtc.RTPTransceiver, enabledCodecs []*livekit.Codec, rtcpFeedbackConfig RTCPFeedbackConfig, @@ -2864,6 +2888,54 @@ func configureTransceiverCodecs( tr.SetCodecPreferences(filteredCodecs) } +func configureReceiverCodecs( + tr *webrtc.RTPTransceiver, + preferredMimeType string, + compliesWithCodecOrderInSDPAnswer bool, +) { + receiver := tr.Receiver() + if receiver == nil { + return + } + + var preferredCodecs, leftCodecs []webrtc.RTPCodecParameters + for _, c := range receiver.GetParameters().Codecs { + if tr.Kind() == webrtc.RTPCodecTypeAudio { + nackFound := false + for _, fb := range c.RTCPFeedback { + if fb.Type == webrtc.TypeRTCPFBNACK { + nackFound = true + break + } + } + + if !nackFound { + c.RTCPFeedback = append(c.RTCPFeedback, webrtc.RTCPFeedback{Type: webrtc.TypeRTCPFBNACK}) + } + } + + if mime.GetMimeTypeCodec(preferredMimeType) == mime.GetMimeTypeCodec(c.RTPCodecCapability.MimeType) { + preferredCodecs = append(preferredCodecs, c) + } else { + leftCodecs = append(leftCodecs, c) + } + } + if len(preferredCodecs) == 0 { + return + } + + reorderedCodecs := append([]webrtc.RTPCodecParameters{}, preferredCodecs...) + if tr.Kind() == webrtc.RTPCodecTypeVideo { + // if the client don't comply with codec order in SDP answer, only keep preferred codecs to force client to use it + if compliesWithCodecOrderInSDPAnswer { + reorderedCodecs = append(reorderedCodecs, leftCodecs...) + } + } else { + reorderedCodecs = append(reorderedCodecs, leftCodecs...) + } + tr.SetCodecPreferences(reorderedCodecs) +} + func nonSimulcastRTXRepairsFromSDP(s *sdp.SessionDescription, logger logger.Logger) map[uint32]uint32 { rtxRepairFlows := map[uint32]uint32{} for _, media := range s.MediaDescriptions { diff --git a/pkg/rtc/transport/handler.go b/pkg/rtc/transport/handler.go index 72c4cc9b7..8abd0fbb5 100644 --- a/pkg/rtc/transport/handler.go +++ b/pkg/rtc/transport/handler.go @@ -43,6 +43,7 @@ type Handler interface { OnDataMessageUnlabeled(data []byte) OnDataSendError(err error) OnOffer(sd webrtc.SessionDescription, offerId uint32) error + OnSetRemoteDescriptionOffer() OnAnswer(sd webrtc.SessionDescription, answerId uint32) error OnNegotiationStateChanged(state NegotiationState) OnNegotiationFailed() @@ -65,6 +66,7 @@ func (h UnimplementedHandler) OnDataSendError(err error) func (h UnimplementedHandler) OnOffer(sd webrtc.SessionDescription, offerId uint32) error { return ErrNoOfferHandler } +func (h UnimplementedHandler) OnSetRemoteDescriptionOffer() {} func (h UnimplementedHandler) OnAnswer(sd webrtc.SessionDescription, answerId uint32) error { return ErrNoAnswerHandler } diff --git a/pkg/rtc/transport/transportfakes/fake_handler.go b/pkg/rtc/transport/transportfakes/fake_handler.go index 17151a70e..5ac5f381e 100644 --- a/pkg/rtc/transport/transportfakes/fake_handler.go +++ b/pkg/rtc/transport/transportfakes/fake_handler.go @@ -87,6 +87,10 @@ type FakeHandler struct { onOfferReturnsOnCall map[int]struct { result1 error } + OnSetRemoteDescriptionOfferStub func() + onSetRemoteDescriptionOfferMutex sync.RWMutex + onSetRemoteDescriptionOfferArgsForCall []struct { + } OnStreamStateChangeStub func(*streamallocator.StreamStateUpdate) error onStreamStateChangeMutex sync.RWMutex onStreamStateChangeArgsForCall []struct { @@ -550,6 +554,30 @@ func (fake *FakeHandler) OnOfferReturnsOnCall(i int, result1 error) { }{result1} } +func (fake *FakeHandler) OnSetRemoteDescriptionOffer() { + fake.onSetRemoteDescriptionOfferMutex.Lock() + fake.onSetRemoteDescriptionOfferArgsForCall = append(fake.onSetRemoteDescriptionOfferArgsForCall, struct { + }{}) + stub := fake.OnSetRemoteDescriptionOfferStub + fake.recordInvocation("OnSetRemoteDescriptionOffer", []interface{}{}) + fake.onSetRemoteDescriptionOfferMutex.Unlock() + if stub != nil { + fake.OnSetRemoteDescriptionOfferStub() + } +} + +func (fake *FakeHandler) OnSetRemoteDescriptionOfferCallCount() int { + fake.onSetRemoteDescriptionOfferMutex.RLock() + defer fake.onSetRemoteDescriptionOfferMutex.RUnlock() + return len(fake.onSetRemoteDescriptionOfferArgsForCall) +} + +func (fake *FakeHandler) OnSetRemoteDescriptionOfferCalls(stub func()) { + fake.onSetRemoteDescriptionOfferMutex.Lock() + defer fake.onSetRemoteDescriptionOfferMutex.Unlock() + fake.OnSetRemoteDescriptionOfferStub = stub +} + func (fake *FakeHandler) OnStreamStateChange(arg1 *streamallocator.StreamStateUpdate) error { fake.onStreamStateChangeMutex.Lock() ret, specificReturn := fake.onStreamStateChangeReturnsOnCall[len(fake.onStreamStateChangeArgsForCall)] diff --git a/pkg/rtc/transport_test.go b/pkg/rtc/transport_test.go index 0cc9ea56a..1deb43eab 100644 --- a/pkg/rtc/transport_test.go +++ b/pkg/rtc/transport_test.go @@ -617,7 +617,7 @@ func TestConfigureAudioTransceiver(t *testing.T) { tr, err := pc.AddTransceiverFromKind(webrtc.RTPCodecTypeAudio, webrtc.RTPTransceiverInit{Direction: webrtc.RTPTransceiverDirectionSendonly}) require.NoError(t, err) - configureAudioTransceiver(tr, testcase.stereo, testcase.nack) + configureSenderAudio(tr, testcase.stereo, testcase.nack) codecs := tr.Sender().GetParameters().Codecs for _, codec := range codecs { if mime.IsMimeTypeStringOpus(codec.MimeType) { diff --git a/pkg/rtc/transportmanager.go b/pkg/rtc/transportmanager.go index 68bcfb63f..367b949e0 100644 --- a/pkg/rtc/transportmanager.go +++ b/pkg/rtc/transportmanager.go @@ -224,6 +224,10 @@ func (t *TransportManager) GetPublisherMid(rtpReceiver *webrtc.RTPReceiver) stri return t.publisher.GetMid(rtpReceiver) } +func (t *TransportManager) GetPublisherRTPTransceiver(mid string) *webrtc.RTPTransceiver { + return t.publisher.GetRTPTransceiver(mid) +} + func (t *TransportManager) GetPublisherRTPReceiver(mid string) *webrtc.RTPReceiver { return t.publisher.GetRTPReceiver(mid) } @@ -451,6 +455,10 @@ func (t *TransportManager) LastPublisherOffer() *webrtc.SessionDescription { return t.publisher.CurrentRemoteDescription() } +func (t *TransportManager) LastPublisherOfferPending() *webrtc.SessionDescription { + return t.publisher.PendingRemoteDescription() +} + func (t *TransportManager) HandleOffer(offer webrtc.SessionDescription, offerId uint32, shouldPend bool) error { t.lock.Lock() if shouldPend { diff --git a/pkg/sfu/downtrack.go b/pkg/sfu/downtrack.go index 19a097907..96cef2b8e 100644 --- a/pkg/sfu/downtrack.go +++ b/pkg/sfu/downtrack.go @@ -542,8 +542,8 @@ func (d *DownTrack) Bind(t webrtc.TrackLocalContext) (webrtc.RTPCodecParameters, d.payloadTypeRTX.Store(uint32(utils.FindRTXPayloadType(codec.PayloadType, d.negotiatedCodecParameters))) logFields = append( logFields, - "payloadType", d.payloadType, - "payloadTypeRTX", d.payloadTypeRTX, + "payloadType", d.payloadType.Load(), + "payloadTypeRTX", d.payloadTypeRTX.Load(), "codecParameters", d.negotiatedCodecParameters, ) d.params.Logger.Debugw("DownTrack.Bind", logFields...)