From f26c042eee7c0438077d474e8b894c6136a532b5 Mon Sep 17 00:00:00 2001 From: Michael Froman Date: Wed, 21 Sep 2022 11:40:10 -0500 Subject: [PATCH] Bug 1790097 - Vendor libwebrtc from 2f3168ff38 Upstream commit: https://webrtc.googlesource.com/src/+/2f3168ff383c393c1af635b872570aabf3f6d7c8 peerconnection: reject content if there are no common media codecs for video dealing with both the case where there is no common media codec as well as only a red/ulpfec/flexfec codec in common for video and only RED/CN in common for audio BUG=webrtc:4957,webrtc:14069 Change-Id: I1c888b4f77199aade8122051c31b690dc2fd5925 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/262642 Commit-Queue: Harald Alvestrand Reviewed-by: Harald Alvestrand Cr-Commit-Position: refs/heads/main@{#36920} --- third_party/libwebrtc/README.moz-ff-commit | 3 + third_party/libwebrtc/README.mozilla | 2 + third_party/libwebrtc/pc/media_session.cc | 33 ++++++++-- .../libwebrtc/pc/media_session_unittest.cc | 66 +++++++++++++++++++ 4 files changed, 99 insertions(+), 5 deletions(-) diff --git a/third_party/libwebrtc/README.moz-ff-commit b/third_party/libwebrtc/README.moz-ff-commit index 3e2b8ff97977..e3f6fecf385c 100644 --- a/third_party/libwebrtc/README.moz-ff-commit +++ b/third_party/libwebrtc/README.moz-ff-commit @@ -14298,3 +14298,6 @@ f92a0846c3 # MOZ_LIBWEBRTC_SRC=/home/mfroman/git-checkouts/moz-libwebrtc MOZ_LIBWEBRTC_COMMIT=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh # base of lastest vendoring cde992ddad +# MOZ_LIBWEBRTC_SRC=/home/mfroman/git-checkouts/moz-libwebrtc MOZ_LIBWEBRTC_COMMIT=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh +# base of lastest vendoring +2f3168ff38 diff --git a/third_party/libwebrtc/README.mozilla b/third_party/libwebrtc/README.mozilla index 590078d9cb8c..51a225762c66 100644 --- a/third_party/libwebrtc/README.mozilla +++ b/third_party/libwebrtc/README.mozilla @@ -9552,3 +9552,5 @@ libwebrtc updated from /home/mfroman/git-checkouts/moz-libwebrtc commit mozpatch libwebrtc updated from /home/mfroman/git-checkouts/moz-libwebrtc commit mozpatches on 2022-09-21T16:20:52.540207. # python3 vendor-libwebrtc.py --from-local /home/mfroman/git-checkouts/moz-libwebrtc --commit mozpatches libwebrtc libwebrtc updated from /home/mfroman/git-checkouts/moz-libwebrtc commit mozpatches on 2022-09-21T16:36:11.195361. +# python3 vendor-libwebrtc.py --from-local /home/mfroman/git-checkouts/moz-libwebrtc --commit mozpatches libwebrtc +libwebrtc updated from /home/mfroman/git-checkouts/moz-libwebrtc commit mozpatches on 2022-09-21T16:40:05.479553. diff --git a/third_party/libwebrtc/pc/media_session.cc b/third_party/libwebrtc/pc/media_session.cc index 71a6d0a19c75..5d87a4f7216a 100644 --- a/third_party/libwebrtc/pc/media_session.cc +++ b/third_party/libwebrtc/pc/media_session.cc @@ -645,6 +645,16 @@ static bool IsFlexfecCodec(const C& codec) { return absl::EqualsIgnoreCase(codec.name, kFlexfecCodecName); } +template +static bool IsUlpfecCodec(const C& codec) { + return absl::EqualsIgnoreCase(codec.name, kUlpfecCodecName); +} + +template +static bool IsComfortNoiseCodec(const C& codec) { + return absl::EqualsIgnoreCase(codec.name, kComfortNoiseCodecName); +} + // Create a media content to be offered for the given `sender_options`, // according to the given options.rtcp_mux, session_options.is_muc, codecs, // secure_transport, crypto, and current_streams. If we don't currently have @@ -1347,8 +1357,7 @@ static void NegotiateRtpHeaderExtensions( static void StripCNCodecs(AudioCodecs* audio_codecs) { audio_codecs->erase(std::remove_if(audio_codecs->begin(), audio_codecs->end(), [](const AudioCodec& codec) { - return absl::EqualsIgnoreCase( - codec.name, kComfortNoiseCodecName); + return IsComfortNoiseCodec(codec); }), audio_codecs->end()); } @@ -2646,6 +2655,13 @@ bool MediaSessionDescriptionFactory::AddAudioContentForAnswer( StripCNCodecs(&filtered_codecs); } + // Determine if we have media codecs in common. + bool has_common_media_codecs = + std::find_if(filtered_codecs.begin(), filtered_codecs.end(), + [](const AudioCodec& c) { + return !(IsRedCodec(c) || IsComfortNoiseCodec(c)); + }) != filtered_codecs.end(); + bool bundle_enabled = offer_description->HasGroup(GROUP_TYPE_BUNDLE) && session_options.bundle_enabled; auto audio_answer = std::make_unique(); @@ -2670,7 +2686,7 @@ bool MediaSessionDescriptionFactory::AddAudioContentForAnswer( bool secure = bundle_transport ? bundle_transport->description.secure() : audio_transport->secure(); bool rejected = media_description_options.stopped || - offer_content->rejected || + offer_content->rejected || !has_common_media_codecs || !IsMediaProtocolSupported(MEDIA_TYPE_AUDIO, audio_answer->protocol(), secure); if (!AddTransportAnswer(media_description_options.mid, @@ -2766,6 +2782,13 @@ bool MediaSessionDescriptionFactory::AddVideoContentForAnswer( filtered_codecs = ComputeCodecsUnion( filtered_codecs, other_video_codecs, field_trials); } + // Determine if we have media codecs in common. + bool has_common_media_codecs = + std::find_if( + filtered_codecs.begin(), filtered_codecs.end(), + [](const VideoCodec& c) { + return !(IsRedCodec(c) || IsUlpfecCodec(c) || IsFlexfecCodec(c)); + }) != filtered_codecs.end(); if (session_options.raw_packetization_for_video) { for (VideoCodec& codec : filtered_codecs) { @@ -2793,12 +2816,12 @@ bool MediaSessionDescriptionFactory::AddVideoContentForAnswer( filtered_rtp_header_extensions(default_video_rtp_header_extensions), ssrc_generator_, enable_encrypted_rtp_header_extensions_, current_streams, bundle_enabled, video_answer.get())) { - return false; // Failed the sessin setup. + return false; // Failed the session setup. } bool secure = bundle_transport ? bundle_transport->description.secure() : video_transport->secure(); bool rejected = media_description_options.stopped || - offer_content->rejected || + offer_content->rejected || !has_common_media_codecs || !IsMediaProtocolSupported(MEDIA_TYPE_VIDEO, video_answer->protocol(), secure); if (!AddTransportAnswer(media_description_options.mid, diff --git a/third_party/libwebrtc/pc/media_session_unittest.cc b/third_party/libwebrtc/pc/media_session_unittest.cc index 3ca6c8580f22..8f38f6a1b491 100644 --- a/third_party/libwebrtc/pc/media_session_unittest.cc +++ b/third_party/libwebrtc/pc/media_session_unittest.cc @@ -1305,6 +1305,27 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswerGcm) { EXPECT_EQ(cricket::kMediaProtocolSavpf, acd->protocol()); } +// Create an audio answer with no common codecs, and ensure it is rejected. +TEST_F(MediaSessionDescriptionFactoryTest, + TestCreateAudioAnswerWithNoCommonCodecs) { + MediaSessionOptions opts; + AddMediaDescriptionOptions(MEDIA_TYPE_AUDIO, "audio", + RtpTransceiverDirection::kSendRecv, kActive, + &opts); + std::vector f1_codecs = {AudioCodec(96, "opus", 48000, -1, 1)}; + f1_.set_audio_codecs(f1_codecs, f1_codecs); + + std::vector f2_codecs = {AudioCodec(0, "PCMU", 8000, -1, 1)}; + f2_.set_audio_codecs(f2_codecs, f2_codecs); + + std::unique_ptr offer = f1_.CreateOffer(opts, nullptr); + std::unique_ptr answer = + f2_.CreateAnswer(offer.get(), opts, NULL); + const ContentInfo* ac = answer->GetContentByName("audio"); + ASSERT_TRUE(ac != NULL); + EXPECT_TRUE(ac->rejected); +} + // Create a typical video answer, and ensure it matches what we expect. TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswer) { MediaSessionOptions opts; @@ -1355,6 +1376,51 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswerGcmAnswer) { TestVideoGcmCipher(false, true); } +// Create a video answer with no common codecs, and ensure it is rejected. +TEST_F(MediaSessionDescriptionFactoryTest, + TestCreateVideoAnswerWithNoCommonCodecs) { + MediaSessionOptions opts; + AddMediaDescriptionOptions(MEDIA_TYPE_VIDEO, "video", + RtpTransceiverDirection::kSendRecv, kActive, + &opts); + std::vector f1_codecs = {VideoCodec(96, "H264")}; + f1_.set_video_codecs(f1_codecs, f1_codecs); + + std::vector f2_codecs = {VideoCodec(97, "VP8")}; + f2_.set_video_codecs(f2_codecs, f2_codecs); + + std::unique_ptr offer = f1_.CreateOffer(opts, nullptr); + std::unique_ptr answer = + f2_.CreateAnswer(offer.get(), opts, NULL); + const ContentInfo* vc = answer->GetContentByName("video"); + ASSERT_TRUE(vc != NULL); + EXPECT_TRUE(vc->rejected); +} + +// Create a video answer with no common codecs (but a common FEC codec), and +// ensure it is rejected. +TEST_F(MediaSessionDescriptionFactoryTest, + TestCreateVideoAnswerWithOnlyFecCodecsCommon) { + MediaSessionOptions opts; + AddMediaDescriptionOptions(MEDIA_TYPE_VIDEO, "video", + RtpTransceiverDirection::kSendRecv, kActive, + &opts); + std::vector f1_codecs = {VideoCodec(96, "H264"), + VideoCodec(118, "flexfec-03")}; + f1_.set_video_codecs(f1_codecs, f1_codecs); + + std::vector f2_codecs = {VideoCodec(97, "VP8"), + VideoCodec(118, "flexfec-03")}; + f2_.set_video_codecs(f2_codecs, f2_codecs); + + std::unique_ptr offer = f1_.CreateOffer(opts, nullptr); + std::unique_ptr answer = + f2_.CreateAnswer(offer.get(), opts, NULL); + const ContentInfo* vc = answer->GetContentByName("video"); + ASSERT_TRUE(vc != NULL); + EXPECT_TRUE(vc->rejected); +} + // The use_sctpmap flag should be set in an Sctp DataContentDescription by // default. The answer's use_sctpmap flag should match the offer's. TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswerUsesSctpmap) {