Skip to content

Commit

Permalink
Bug 1867099 - Vendor libwebrtc from 52bc9f7c12
Browse files Browse the repository at this point in the history
Upstream commit: https://webrtc.googlesource.com/src/+/52bc9f7c1205f4b731ea0289b059f7d240c1e228
    [Merge M119] Return error when requested codec is preferred but not negotiated

    Because of our asymmetrical codec situation, it's possible to have
    send only codecs that we cannot negotiate even with ourselves.
    This means that we should not have a DCHECK, but just a plain error.

    (cherry picked from commit 1adea9806d7aec9b5f91181231ccc31fef3b115f)

    Bug: chromium:1442194, webrtc:15064
    Change-Id: I0c170e5c7f356197bcb04bcecb8259c344423ccb
    Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/323183
    Reviewed-by: Harald Alvestrand <hta@webrtc.org>
    Commit-Queue: Florent Castelli <orphis@webrtc.org>
    Cr-Original-Commit-Position: refs/heads/main@{#40939}
    No-Try: True
    Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/324044
    Reviewed-by: Guido Urdaneta <guidou@webrtc.org>
    Cr-Commit-Position: refs/branch-heads/6045@{#2}
    Cr-Branched-From: bce7ce7ba054ac0e79fed49b84ef52fb24c31778-refs/heads/main@{#40854}
  • Loading branch information
mfromanmoz committed Nov 30, 2023
1 parent dcdce64 commit 3bfb001
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 4 deletions.
3 changes: 3 additions & 0 deletions third_party/libwebrtc/README.moz-ff-commit
Original file line number Diff line number Diff line change
Expand Up @@ -26283,3 +26283,6 @@ bce7ce7ba0
# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh
# base of lastest vendoring
71e3fbf5d7
# MOZ_LIBWEBRTC_SRC=/home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh
# base of lastest vendoring
52bc9f7c12
2 changes: 2 additions & 0 deletions third_party/libwebrtc/README.mozilla
Original file line number Diff line number Diff line change
Expand Up @@ -17546,3 +17546,5 @@ libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc
libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-11-30T00:08:15.535670.
# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc
libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-11-30T00:09:13.684510.
# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc
libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2023-11-30T00:10:54.605726.
15 changes: 12 additions & 3 deletions third_party/libwebrtc/media/engine/webrtc_video_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "api/media_stream_interface.h"
#include "api/media_types.h"
#include "api/priority.h"
#include "api/rtc_error.h"
#include "api/rtp_transceiver_direction.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
Expand All @@ -47,6 +48,7 @@
#include "common_video/frame_counts.h"
#include "common_video/include/quality_limitation_reason.h"
#include "media/base/codec.h"
#include "media/base/media_channel.h"
#include "media/base/media_constants.h"
#include "media/base/rid_description.h"
#include "media/base/rtp_utils.h"
Expand Down Expand Up @@ -1333,17 +1335,24 @@ webrtc::RTCError WebRtcVideoSendChannel::SetRtpSendParameters(
break;
}

// Since we validate that all layers have the same value, we can just check
// the first layer.
// TODO(orphis): Support mixed-codec simulcast
if (parameters.encodings[0].codec && send_codec_ &&
!send_codec_->codec.MatchesRtpCodec(*parameters.encodings[0].codec)) {
RTC_LOG(LS_ERROR) << "Trying to change codec to "
<< parameters.encodings[0].codec->name;
RTC_LOG(LS_VERBOSE) << "Trying to change codec to "
<< parameters.encodings[0].codec->name;
auto matched_codec =
absl::c_find_if(negotiated_codecs_, [&](auto negotiated_codec) {
return negotiated_codec.codec.MatchesRtpCodec(
*parameters.encodings[0].codec);
});
RTC_CHECK(matched_codec != negotiated_codecs_.end());
if (matched_codec == negotiated_codecs_.end()) {
return webrtc::InvokeSetParametersCallback(
callback, webrtc::RTCError(
webrtc::RTCErrorType::INVALID_MODIFICATION,
"Attempted to use an unsupported codec for layer 0"));
}

ChangedSenderParameters params;
params.send_codec = *matched_codec;
Expand Down
10 changes: 9 additions & 1 deletion third_party/libwebrtc/media/engine/webrtc_voice_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1870,6 +1870,8 @@ webrtc::RTCError WebRtcVoiceSendChannel::SetRtpSendParameters(
SetPreferredDscp(new_dscp);

absl::optional<cricket::Codec> send_codec = GetSendCodec();
// Since we validate that all layers have the same value, we can just check
// the first layer.
// TODO(orphis): Support mixed-codec simulcast
if (parameters.encodings[0].codec && send_codec &&
!send_codec->MatchesRtpCodec(*parameters.encodings[0].codec)) {
Expand All @@ -1880,7 +1882,13 @@ webrtc::RTCError WebRtcVoiceSendChannel::SetRtpSendParameters(
return negotiated_codec.MatchesRtpCodec(
*parameters.encodings[0].codec);
});
RTC_DCHECK(matched_codec != send_codecs_.end());

if (matched_codec == send_codecs_.end()) {
return webrtc::InvokeSetParametersCallback(
callback, webrtc::RTCError(
webrtc::RTCErrorType::INVALID_MODIFICATION,
"Attempted to use an unsupported codec for layer 0"));
}

SetSendCodecs(send_codecs_, *matched_codec);
}
Expand Down
126 changes: 126 additions & 0 deletions third_party/libwebrtc/pc/peer_connection_encodings_integrationtest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1422,6 +1422,69 @@ TEST_F(PeerConnectionEncodingsIntegrationTest,
EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION);
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
SetParametersRejectsNonRemotelyNegotiatedCodecParameterAudio) {
rtc::scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
rtc::scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

absl::optional<webrtc::RtpCodecCapability> opus =
local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_AUDIO,
"opus");
ASSERT_TRUE(opus);

std::vector<webrtc::RtpCodecCapability> not_opus_codecs =
local_pc_wrapper->pc_factory()
->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_AUDIO)
.codecs;
not_opus_codecs.erase(
std::remove_if(not_opus_codecs.begin(), not_opus_codecs.end(),
[&](const auto& codec) {
return absl::EqualsIgnoreCase(codec.name, opus->name);
}),
not_opus_codecs.end());

auto transceiver_or_error =
local_pc_wrapper->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO);
ASSERT_TRUE(transceiver_or_error.ok());
rtc::scoped_refptr<RtpTransceiverInterface> audio_transceiver =
transceiver_or_error.MoveValue();

// Negotiation, create offer and apply it
std::unique_ptr<SessionDescriptionInterface> offer =
CreateOffer(local_pc_wrapper);
rtc::scoped_refptr<MockSetSessionDescriptionObserver> p1 =
SetLocalDescription(local_pc_wrapper, offer.get());
rtc::scoped_refptr<MockSetSessionDescriptionObserver> p2 =
SetRemoteDescription(remote_pc_wrapper, offer.get());
EXPECT_TRUE(Await({p1, p2}));

// Update the remote transceiver to reject Opus
std::vector<rtc::scoped_refptr<RtpTransceiverInterface>> remote_transceivers =
remote_pc_wrapper->pc()->GetTransceivers();
ASSERT_TRUE(!remote_transceivers.empty());
rtc::scoped_refptr<RtpTransceiverInterface> remote_audio_transceiver =
remote_transceivers[0];
ASSERT_TRUE(
remote_audio_transceiver->SetCodecPreferences(not_opus_codecs).ok());

// Create answer and apply it
std::unique_ptr<SessionDescriptionInterface> answer =
CreateAnswer(remote_pc_wrapper);
p1 = SetLocalDescription(remote_pc_wrapper, answer.get());
p2 = SetRemoteDescription(local_pc_wrapper, answer.get());
EXPECT_TRUE(Await({p1, p2}));

local_pc_wrapper->WaitForConnection();
remote_pc_wrapper->WaitForConnection();

webrtc::RtpParameters parameters =
audio_transceiver->sender()->GetParameters();
parameters.encodings[0].codec = opus;
RTCError error = audio_transceiver->sender()->SetParameters(parameters);
EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION);
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
SetParametersRejectsNonNegotiatedCodecParameterVideo) {
rtc::scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
Expand Down Expand Up @@ -1462,6 +1525,69 @@ TEST_F(PeerConnectionEncodingsIntegrationTest,
EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION);
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
SetParametersRejectsNonRemotelyNegotiatedCodecParameterVideo) {
rtc::scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
rtc::scoped_refptr<PeerConnectionTestWrapper> remote_pc_wrapper = CreatePc();
ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper);

absl::optional<webrtc::RtpCodecCapability> vp8 =
local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_VIDEO,
"vp8");
ASSERT_TRUE(vp8);

std::vector<webrtc::RtpCodecCapability> not_vp8_codecs =
local_pc_wrapper->pc_factory()
->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO)
.codecs;
not_vp8_codecs.erase(
std::remove_if(not_vp8_codecs.begin(), not_vp8_codecs.end(),
[&](const auto& codec) {
return absl::EqualsIgnoreCase(codec.name, vp8->name);
}),
not_vp8_codecs.end());

auto transceiver_or_error =
local_pc_wrapper->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO);
ASSERT_TRUE(transceiver_or_error.ok());
rtc::scoped_refptr<RtpTransceiverInterface> video_transceiver =
transceiver_or_error.MoveValue();

// Negotiation, create offer and apply it
std::unique_ptr<SessionDescriptionInterface> offer =
CreateOffer(local_pc_wrapper);
rtc::scoped_refptr<MockSetSessionDescriptionObserver> p1 =
SetLocalDescription(local_pc_wrapper, offer.get());
rtc::scoped_refptr<MockSetSessionDescriptionObserver> p2 =
SetRemoteDescription(remote_pc_wrapper, offer.get());
EXPECT_TRUE(Await({p1, p2}));

// Update the remote transceiver to reject VP8
std::vector<rtc::scoped_refptr<RtpTransceiverInterface>> remote_transceivers =
remote_pc_wrapper->pc()->GetTransceivers();
ASSERT_TRUE(!remote_transceivers.empty());
rtc::scoped_refptr<RtpTransceiverInterface> remote_video_transceiver =
remote_transceivers[0];
ASSERT_TRUE(
remote_video_transceiver->SetCodecPreferences(not_vp8_codecs).ok());

// Create answer and apply it
std::unique_ptr<SessionDescriptionInterface> answer =
CreateAnswer(remote_pc_wrapper);
p1 = SetLocalDescription(remote_pc_wrapper, answer.get());
p2 = SetRemoteDescription(local_pc_wrapper, answer.get());
EXPECT_TRUE(Await({p1, p2}));

local_pc_wrapper->WaitForConnection();
remote_pc_wrapper->WaitForConnection();

webrtc::RtpParameters parameters =
video_transceiver->sender()->GetParameters();
parameters.encodings[0].codec = vp8;
RTCError error = video_transceiver->sender()->SetParameters(parameters);
EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION);
}

TEST_F(PeerConnectionEncodingsIntegrationTest,
EncodingParametersCodecRemovedAfterNegotiationAudio) {
rtc::scoped_refptr<PeerConnectionTestWrapper> local_pc_wrapper = CreatePc();
Expand Down

0 comments on commit 3bfb001

Please sign in to comment.