From 20a90295fcea910dc774df0bbd0e65e13606c2e8 Mon Sep 17 00:00:00 2001 From: Philipp Hancke Date: Thu, 8 Feb 2024 14:11:39 +0100 Subject: [PATCH] sdp: set content to rejected if the list of common codecs is empty which avoids throwing an error when using setCodecPreferences to set a recvonly codec on a sendonly transceiver. See https://github.com/w3c/webrtc-pc/issues/2936 BUG=webrtc:15396 Change-Id: I435a98c944ed2eeef87d9b8a7f791d095ec25502 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338642 Reviewed-by: Harald Alvestrand Reviewed-by: Florent Castelli Commit-Queue: Philipp Hancke Cr-Commit-Position: refs/heads/main@{#41843} --- pc/media_session.cc | 4 +++- pc/peer_connection_media_unittest.cc | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/pc/media_session.cc b/pc/media_session.cc index 3928088c7f..a7352cce08 100644 --- a/pc/media_session.cc +++ b/pc/media_session.cc @@ -2069,10 +2069,12 @@ RTCError MediaSessionDescriptionFactory::AddRtpContentForOffer( SetMediaProtocol(secure_transport, content_description.get()); content_description->set_direction(media_description_options.direction); + bool has_codecs = !content_description->codecs().empty(); session_description->AddContent( media_description_options.mid, MediaProtocolType::kRtp, - media_description_options.stopped, std::move(content_description)); + media_description_options.stopped || !has_codecs, + std::move(content_description)); return AddTransportOffer(media_description_options.mid, media_description_options.transport_options, current_description, session_description, diff --git a/pc/peer_connection_media_unittest.cc b/pc/peer_connection_media_unittest.cc index 04fb9c9e26..acefd9ebec 100644 --- a/pc/peer_connection_media_unittest.cc +++ b/pc/peer_connection_media_unittest.cc @@ -2094,6 +2094,31 @@ TEST_F(PeerConnectionMediaTestUnifiedPlan, .size()); } +TEST_F(PeerConnectionMediaTestUnifiedPlan, + SetCodecPreferencesReceiveOnlyWithSendOnlyTransceiverStops) { + auto fake_engine = std::make_unique(); + + std::vector audio_codecs; + audio_codecs.emplace_back(cricket::CreateAudioCodec(100, "foo", 0, 1)); + fake_engine->SetAudioRecvCodecs(audio_codecs); + + auto caller = CreatePeerConnectionWithAudio(std::move(fake_engine)); + + auto transceivers = caller->pc()->GetTransceivers(); + ASSERT_EQ(1u, transceivers.size()); + + auto audio_transceiver = caller->pc()->GetTransceivers()[0]; + auto error = audio_transceiver->SetDirectionWithError( + RtpTransceiverDirection::kSendOnly); + ASSERT_TRUE(error.ok()); + auto capabilities = caller->pc_factory()->GetRtpReceiverCapabilities( + cricket::MediaType::MEDIA_TYPE_AUDIO); + EXPECT_TRUE(audio_transceiver->SetCodecPreferences(capabilities.codecs).ok()); + RTCOfferAnswerOptions options; + EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer(options))); + EXPECT_EQ(audio_transceiver->direction(), RtpTransceiverDirection::kStopped); +} + INSTANTIATE_TEST_SUITE_P(PeerConnectionMediaTest, PeerConnectionMediaTest, Values(SdpSemantics::kPlanB_DEPRECATED,