tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit eb2edc3322f7dec38c1df10889ac6de42601024c
parent dc36d28a38c56237928e3fc852a3a0ddafb7b849
Author: Dan Baker <dbaker@mozilla.com>
Date:   Mon, 27 Oct 2025 13:02:49 -0600

Bug 1995393 - Vendor libwebrtc from d142f35c7e

Upstream commit: https://webrtc.googlesource.com/src/+/d142f35c7ed5d909357dce845e2b56b6f7a963a0
    Add std::optional<RtcpFeedbackType> MediaContentDescription::preferred_rtcp_cc_ack_type()

    This method returns the preferred feedback format to use for a certain media type. This is used to decide if CCFB should be enabled or not.
    Also, if a feedback type is decided, this is propagated to Audio Send stream in order for the stream to be aware of if it should be part of BW allocation.

    Bug: webrtc:440151993, webrtc:383078466
    Change-Id: Id3475d5cf547d7f875e0664e46a81e3c6c8c4f44
    Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/406160
    Reviewed-by: Harald Alvestrand <hta@webrtc.org>
    Commit-Queue: Per Kjellander <perkj@webrtc.org>
    Reviewed-by: Jakob Ivarsson‎ <jakobi@webrtc.org>
    Cr-Commit-Position: refs/heads/main@{#45443}

Diffstat:
Mthird_party/libwebrtc/README.mozilla.last-vendor | 4++--
Mthird_party/libwebrtc/api/rtp_parameters.h | 34++++++++++++++++++++++++++++++++++
Mthird_party/libwebrtc/audio/audio_send_stream.cc | 6++++--
Mthird_party/libwebrtc/audio/audio_send_stream_unittest.cc | 31++++++++++++++++---------------
Mthird_party/libwebrtc/call/audio_send_stream.h | 3+++
Mthird_party/libwebrtc/call/call.cc | 13+++++++++----
Mthird_party/libwebrtc/call/call.h | 6+++++-
Mthird_party/libwebrtc/media/base/media_channel.h | 4++++
Mthird_party/libwebrtc/media/engine/fake_webrtc_call.h | 3++-
Mthird_party/libwebrtc/media/engine/webrtc_voice_engine.cc | 26+++++++++++++++++++++++++-
Mthird_party/libwebrtc/media/engine/webrtc_voice_engine.h | 1+
Mthird_party/libwebrtc/moz-patch-stack/s0027.patch | 4++--
Mthird_party/libwebrtc/moz-patch-stack/s0029.patch | 6+++---
Mthird_party/libwebrtc/moz-patch-stack/s0119.patch | 10+++++-----
Mthird_party/libwebrtc/pc/channel.cc | 1+
Mthird_party/libwebrtc/pc/sdp_offer_answer.cc | 57++++++++++++++++++++++++++++++++++++++-------------------
Mthird_party/libwebrtc/pc/session_description.h | 15+++++++++++++++
Mthird_party/libwebrtc/test/call_test.cc | 1+
Mthird_party/libwebrtc/test/peer_scenario/tests/l4s_test.cc | 32++++++++++++++++++++++++--------
Mthird_party/libwebrtc/test/scenario/audio_stream.cc | 2++
20 files changed, 196 insertions(+), 63 deletions(-)

diff --git a/third_party/libwebrtc/README.mozilla.last-vendor b/third_party/libwebrtc/README.mozilla.last-vendor @@ -1,4 +1,4 @@ # ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc -libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-10-27T19:00:30.556337+00:00. +libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-10-27T19:02:31.587770+00:00. # base of lastest vendoring -9e448578ea +d142f35c7e diff --git a/third_party/libwebrtc/api/rtp_parameters.h b/third_party/libwebrtc/api/rtp_parameters.h @@ -64,8 +64,42 @@ enum class RtcpFeedbackType { NACK, REMB, // "goog-remb" TRANSPORT_CC, + CCFB, // RFC8888 }; +template <typename Sink> +void AbslStringify(Sink& sink, RtcpFeedbackType type) { + switch (type) { + case RtcpFeedbackType::CCM: + sink.Append("CCM"); + break; + case RtcpFeedbackType::LNTF: + sink.Append("LNTF"); + break; + case RtcpFeedbackType::NACK: + sink.Append("NACK"); + break; + case RtcpFeedbackType::REMB: + sink.Append("REMB"); + break; + case RtcpFeedbackType::TRANSPORT_CC: + sink.Append("TRANSPORT_CC"); + break; + case RtcpFeedbackType::CCFB: + sink.Append("CCFB"); + break; + } +} + +template <typename Sink> +void AbslStringify(Sink& sink, std::optional<RtcpFeedbackType> type) { + if (!type.has_value()) { + sink.Append("nullopt"); + return; + } + AbslStringify(sink, *type); +} + // Used in RtcpFeedback struct when type is NACK or CCM. enum class RtcpFeedbackMessageType { // Equivalent to {type: "nack", parameter: undefined} in ORTC. diff --git a/third_party/libwebrtc/audio/audio_send_stream.cc b/third_party/libwebrtc/audio/audio_send_stream.cc @@ -361,7 +361,8 @@ void AudioSendStream::Start() { RTC_LOG(LS_INFO) << "AudioSendStream::Start: " << config_.rtp.ssrc; if (!config_.has_dscp && config_.min_bitrate_bps != -1 && config_.max_bitrate_bps != -1 && - (allocate_audio_without_feedback_ || TransportSeqNumId(config_) != 0)) { + (allocate_audio_without_feedback_ || + config_.include_in_congestion_control_allocation)) { rtp_transport_->AccountForAudioPacketsInPacedSender(true); rtp_transport_->IncludeOverheadInPacedSender(); rtp_rtcp_module_->SetAsPartOfAllocation(true); @@ -794,7 +795,8 @@ void AudioSendStream::ReconfigureBitrateObserver( } if (!new_config.has_dscp && new_config.min_bitrate_bps != -1 && - new_config.max_bitrate_bps != -1 && TransportSeqNumId(new_config) != 0) { + new_config.max_bitrate_bps != -1 && + new_config.include_in_congestion_control_allocation) { rtp_transport_->AccountForAudioPacketsInPacedSender(true); rtp_transport_->IncludeOverheadInPacedSender(); // We may get a callback immediately as the observer is registered, so diff --git a/third_party/libwebrtc/audio/audio_send_stream_unittest.cc b/third_party/libwebrtc/audio/audio_send_stream_unittest.cc @@ -196,9 +196,8 @@ class ConfigHelper { stream_config_.rtp.c_name = kCName; stream_config_.rtp.extensions.push_back( RtpExtension(RtpExtension::kAudioLevelUri, kAudioLevelId)); - if (audio_bwe_enabled) { - AddBweToConfig(&stream_config_); - } + stream_config_.include_in_congestion_control_allocation = audio_bwe_enabled; + stream_config_.encoder_factory = SetupEncoderFactoryMock(); stream_config_.min_bitrate_bps = 10000; stream_config_.max_bitrate_bps = 65000; @@ -223,11 +222,6 @@ class ConfigHelper { RtpTransportControllerSendInterface* transport() { return &rtp_transport_; } MockBitrateAllocator* bitrate_allocator() { return &bitrate_allocator_; } - static void AddBweToConfig(AudioSendStream::Config* config) { - config->rtp.extensions.push_back(RtpExtension( - RtpExtension::kTransportSequenceNumberUri, kTransportSequenceNumberId)); - } - void SetupDefaultChannelSend(bool audio_bwe_enabled) { EXPECT_TRUE(channel_send_ == nullptr); channel_send_ = new ::testing::StrictMock<MockChannelSend>(); @@ -246,12 +240,6 @@ class ConfigHelper { .Times(1); EXPECT_CALL(rtp_transport_, GetRtcpObserver) .WillRepeatedly(Return(&rtcp_observer_)); - if (audio_bwe_enabled) { - EXPECT_CALL(rtp_rtcp_, - RegisterRtpHeaderExtension(TransportSequenceNumber::Uri(), - kTransportSequenceNumberId)) - .Times(1); - } EXPECT_CALL(*channel_send_, RegisterSenderCongestionControlObjects(&rtp_transport_)) .Times(1); @@ -804,12 +792,25 @@ TEST(AudioSendStreamTest, DontRecreateEncoder) { } } +TEST(AudioSendStreamTest, ConfiguresTransportCcIfExtensionNegotiated) { + ConfigHelper helper(true, true, false); + helper.config().rtp.extensions.push_back(RtpExtension( + RtpExtension::kTransportSequenceNumberUri, kTransportSequenceNumberId)); + + EXPECT_CALL(*helper.rtp_rtcp(), + RegisterRtpHeaderExtension(TransportSequenceNumber::Uri(), + kTransportSequenceNumberId)) + .Times(1); + auto send_stream = helper.CreateAudioSendStream(); +} + TEST(AudioSendStreamTest, ReconfigureTransportCcResetsFirst) { for (bool use_null_audio_processing : {false, true}) { ConfigHelper helper(false, true, use_null_audio_processing); auto send_stream = helper.CreateAudioSendStream(); auto new_config = helper.config(); - ConfigHelper::AddBweToConfig(&new_config); + new_config.rtp.extensions.push_back(RtpExtension( + RtpExtension::kTransportSequenceNumberUri, kTransportSequenceNumberId)); EXPECT_CALL(*helper.rtp_rtcp(), RegisterRtpHeaderExtension(TransportSequenceNumber::Uri(), diff --git a/third_party/libwebrtc/call/audio_send_stream.h b/third_party/libwebrtc/call/audio_send_stream.h @@ -134,6 +134,9 @@ class AudioSendStream : public AudioSender { double bitrate_priority = 1.0; bool has_dscp = false; + // If true, the stream will allocate bandwidth from the bandwidth estimate + // created by the congestion controller. + bool include_in_congestion_control_allocation = false; // Defines whether to turn on audio network adaptor, and defines its config // string. diff --git a/third_party/libwebrtc/call/call.cc b/third_party/libwebrtc/call/call.cc @@ -33,6 +33,7 @@ #include "api/rtc_error.h" #include "api/rtc_event_log/rtc_event_log.h" #include "api/rtp_headers.h" +#include "api/rtp_parameters.h" #include "api/scoped_refptr.h" #include "api/sequence_checker.h" #include "api/task_queue/pending_task_safety_flag.h" @@ -278,7 +279,8 @@ class Call final : public webrtc::Call, Stats GetStats() const override; - void EnableSendCongestionControlFeedbackAccordingToRfc8888() override; + void SetPreferredRtcpCcAckType( + RtcpFeedbackType preferred_rtcp_cc_ack_type) override; int FeedbackAccordingToRfc8888Count() override; int FeedbackAccordingToTransportCcCount() override; @@ -1159,9 +1161,12 @@ Call::Stats Call::GetStats() const { return stats; } -void Call::EnableSendCongestionControlFeedbackAccordingToRfc8888() { - receive_side_cc_.EnableSendCongestionControlFeedbackAccordingToRfc8888(); - transport_send_->EnableCongestionControlFeedbackAccordingToRfc8888(); +void Call::SetPreferredRtcpCcAckType( + RtcpFeedbackType preferred_rtcp_cc_ack_type) { + if (preferred_rtcp_cc_ack_type == RtcpFeedbackType::CCFB) { + receive_side_cc_.EnableSendCongestionControlFeedbackAccordingToRfc8888(); + transport_send_->EnableCongestionControlFeedbackAccordingToRfc8888(); + } // else default to transport CC if correct header extension is negotiated } int Call::FeedbackAccordingToRfc8888Count() { diff --git a/third_party/libwebrtc/call/call.h b/third_party/libwebrtc/call/call.h @@ -21,6 +21,7 @@ #include "api/field_trials_view.h" #include "api/media_types.h" #include "api/rtp_headers.h" +#include "api/rtp_parameters.h" #include "api/scoped_refptr.h" #include "api/task_queue/task_queue_base.h" #include "api/transport/bitrate_settings.h" @@ -147,7 +148,10 @@ class Call { virtual void SetClientBitratePreferences( const BitrateSettings& preferences) = 0; - virtual void EnableSendCongestionControlFeedbackAccordingToRfc8888() = 0; + // Decides which RTCP feedback type to use for congestion control. + virtual void SetPreferredRtcpCcAckType( + RtcpFeedbackType preferred_rtcp_cc_ack_type) = 0; + virtual int FeedbackAccordingToRfc8888Count() = 0; virtual int FeedbackAccordingToTransportCcCount() = 0; diff --git a/third_party/libwebrtc/media/base/media_channel.h b/third_party/libwebrtc/media/base/media_channel.h @@ -828,6 +828,10 @@ struct MediaChannelParameters { std::vector<Codec> codecs; std::vector<RtpExtension> extensions; + // RTCP feedback type used for congestion control for this media channel. + // If transport sequence numbers are used, 'extensions' will include + // kTransportSequenceNumberUri. + std::optional<RtcpFeedbackType> rtcp_cc_ack_type; // For a send stream this is true if we've negotiated a send direction, // for a receive stream this is true if we've negotiated a receive direction. bool is_stream_active = true; diff --git a/third_party/libwebrtc/media/engine/fake_webrtc_call.h b/third_party/libwebrtc/media/engine/fake_webrtc_call.h @@ -434,7 +434,8 @@ class FakeCall final : public Call, public PacketReceiver { const BitrateSettings& /* preferences */) override {} const FieldTrialsView& trials() const override { return env_.field_trials(); } const Environment& env() const override { return env_; } - void EnableSendCongestionControlFeedbackAccordingToRfc8888() override {} + void SetPreferredRtcpCcAckType( + RtcpFeedbackType preferred_rtcp_cc_ack_type) override {} int FeedbackAccordingToRfc8888Count() { return 0; } int FeedbackAccordingToTransportCcCount() { return 0; } diff --git a/third_party/libwebrtc/media/engine/webrtc_voice_engine.cc b/third_party/libwebrtc/media/engine/webrtc_voice_engine.cc @@ -841,6 +841,7 @@ class WebRtcVoiceSendChannel::WebRtcAudioSendStream : public AudioSource::Sink { send_codec_spec, bool extmap_allow_mixed, const std::vector<RtpExtension>& extensions, + std::optional<RtcpFeedbackType> rtcp_cc_ack_type, int max_send_bitrate_bps, int rtcp_report_interval_ms, const std::optional<std::string>& audio_network_adaptor_config, @@ -862,6 +863,8 @@ class WebRtcVoiceSendChannel::WebRtcAudioSendStream : public AudioSource::Sink { config_.rtp.c_name = c_name; config_.rtp.extmap_allow_mixed = extmap_allow_mixed; config_.rtp.extensions = extensions; + config_.include_in_congestion_control_allocation = + rtcp_cc_ack_type.has_value(); config_.has_dscp = rtp_parameters_.encodings[0].network_priority != Priority::kLow; config_.encoder_factory = encoder_factory; @@ -907,6 +910,12 @@ class WebRtcVoiceSendChannel::WebRtcAudioSendStream : public AudioSource::Sink { ReconfigureAudioSendStream(nullptr); } + void SetIncludeInCongestionControlAllocation() { + RTC_DCHECK_RUN_ON(&worker_thread_checker_); + config_.include_in_congestion_control_allocation = true; + ReconfigureAudioSendStream(nullptr); + } + void SetExtmapAllowMixed(bool extmap_allow_mixed) { config_.rtp.extmap_allow_mixed = extmap_allow_mixed; ReconfigureAudioSendStream(nullptr); @@ -1371,6 +1380,21 @@ bool WebRtcVoiceSendChannel::SetSenderParameters( it.second->SetRtpExtensions(send_rtp_extensions_); } } + if (rtcp_cc_ack_type_.has_value() && + rtcp_cc_ack_type_ != params.rtcp_cc_ack_type) { + RTC_LOG(LS_WARNING) << "RTCP cc ack type change is not supported! Current: " + << *rtcp_cc_ack_type_; + } else { + rtcp_cc_ack_type_ = params.rtcp_cc_ack_type; + if (rtcp_cc_ack_type_.has_value()) { + // It does not matter what type of RTCP feedback we use for congestion + // control. Only that audio is included in the BWE allocation. + for (auto& it : send_streams_) { + it.second->SetIncludeInCongestionControlAllocation(); + } + } + } + if (!params.mid.empty()) { mid_ = params.mid; for (auto& it : send_streams_) { @@ -1602,7 +1626,7 @@ bool WebRtcVoiceSendChannel::AddSendStream(const StreamParams& sp) { GetAudioNetworkAdaptorConfig(options_); WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( ssrc, mid_, sp.cname, sp.id, send_codec_spec_, ExtmapAllowMixed(), - send_rtp_extensions_, max_send_bitrate_bps_, + send_rtp_extensions_, rtcp_cc_ack_type_, max_send_bitrate_bps_, audio_config_.rtcp_report_interval_ms, audio_network_adaptor_config, call_, transport(), engine()->encoder_factory_, codec_pair_id_, nullptr, crypto_options_); diff --git a/third_party/libwebrtc/media/engine/webrtc_voice_engine.h b/third_party/libwebrtc/media/engine/webrtc_voice_engine.h @@ -306,6 +306,7 @@ class WebRtcVoiceSendChannel final : public MediaChannelUtil, std::map<uint32_t, WebRtcAudioSendStream*> send_streams_; std::vector<RtpExtension> send_rtp_extensions_; + std::optional<RtcpFeedbackType> rtcp_cc_ack_type_; std::string mid_; RtcpMode rtcp_mode_; diff --git a/third_party/libwebrtc/moz-patch-stack/s0027.patch b/third_party/libwebrtc/moz-patch-stack/s0027.patch @@ -491,7 +491,7 @@ index a9c0de8016..f8b2a9b7b5 100644 "../api:transport_api", "../api/adaptation:resource_adaptation_api", diff --git a/call/audio_send_stream.h b/call/audio_send_stream.h -index 851c7aed30..2ae1020161 100644 +index 84341b5cb1..2ae1742f91 100644 --- a/call/audio_send_stream.h +++ b/call/audio_send_stream.h @@ -27,7 +27,7 @@ @@ -689,7 +689,7 @@ index 0221c2b573..0f58959926 100644 rtc_library("rtc_audio_video") { diff --git a/media/base/media_channel.h b/media/base/media_channel.h -index d569c19390..9030e8e590 100644 +index cbec6fcfd7..15f4f39141 100644 --- a/media/base/media_channel.h +++ b/media/base/media_channel.h @@ -68,9 +68,6 @@ namespace webrtc { diff --git a/third_party/libwebrtc/moz-patch-stack/s0029.patch b/third_party/libwebrtc/moz-patch-stack/s0029.patch @@ -15,10 +15,10 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/d380a43d59f4f7cbc 4 files changed, 36 insertions(+) diff --git a/audio/audio_send_stream.cc b/audio/audio_send_stream.cc -index fc923a8733..11b6ac6e08 100644 +index a414cc15bb..34ad23d1a7 100644 --- a/audio/audio_send_stream.cc +++ b/audio/audio_send_stream.cc -@@ -436,6 +436,7 @@ webrtc::AudioSendStream::Stats AudioSendStream::GetStats( +@@ -437,6 +437,7 @@ webrtc::AudioSendStream::Stats AudioSendStream::GetStats( webrtc::ChannelSendStatistics channel_stats = channel_send_->GetRTCPStatistics(); @@ -110,7 +110,7 @@ index 185f3e9975..5a2c547673 100644 // Within this list, the sender-source SSRC pair is unique and per-pair the // ReportBlockData represents the latest Report Block that was received for diff --git a/call/audio_send_stream.h b/call/audio_send_stream.h -index 2ae1020161..88e8a7f18b 100644 +index 2ae1742f91..21ae21b66f 100644 --- a/call/audio_send_stream.h +++ b/call/audio_send_stream.h @@ -32,6 +32,7 @@ diff --git a/third_party/libwebrtc/moz-patch-stack/s0119.patch b/third_party/libwebrtc/moz-patch-stack/s0119.patch @@ -12,10 +12,10 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/19164e58323d59c1f 3 files changed, 7 insertions(+), 22 deletions(-) diff --git a/call/call.cc b/call/call.cc -index 9a78aa6fb1..8423297fac 100644 +index 01c6cc7be6..7b9ef6b5a9 100644 --- a/call/call.cc +++ b/call/call.cc -@@ -515,19 +515,6 @@ class Call final : public webrtc::Call, +@@ -517,19 +517,6 @@ class Call final : public webrtc::Call, }; } // namespace internal @@ -36,10 +36,10 @@ index 9a78aa6fb1..8423297fac 100644 std::unique_ptr<RtpTransportControllerSendInterface> transport_send; if (config.rtp_transport_controller_send_factory != nullptr) { diff --git a/call/call.h b/call/call.h -index 08e883da06..c3119cc18c 100644 +index f100da4d15..4361577be4 100644 --- a/call/call.h +++ b/call/call.h -@@ -26,6 +26,7 @@ +@@ -27,6 +27,7 @@ #include "api/transport/bitrate_settings.h" #include "call/audio_receive_stream.h" #include "call/audio_send_stream.h" @@ -47,7 +47,7 @@ index 08e883da06..c3119cc18c 100644 #include "call/call_config.h" #include "call/flexfec_receive_stream.h" #include "call/packet_receiver.h" -@@ -51,15 +52,7 @@ namespace webrtc { +@@ -52,15 +53,7 @@ namespace webrtc { class Call { public: diff --git a/third_party/libwebrtc/pc/channel.cc b/third_party/libwebrtc/pc/channel.cc @@ -101,6 +101,7 @@ void MediaChannelParametersFromMediaDescription( params->extensions = extensions; params->rtcp.reduced_size = desc->rtcp_reduced_size(); params->rtcp.remote_estimate = desc->remote_estimate(); + params->rtcp_cc_ack_type = desc->preferred_rtcp_cc_ack_type(); } void RtpSendParametersFromMediaDescription( diff --git a/third_party/libwebrtc/pc/sdp_offer_answer.cc b/third_party/libwebrtc/pc/sdp_offer_answer.cc @@ -5063,8 +5063,7 @@ RTCError SdpOfferAnswerHandler::PushdownMediaDescription( auto rtp_transceivers = transceivers()->ListInternal(); std::vector<std::pair<ChannelInterface*, const MediaContentDescription*>> channels; - bool use_ccfb = false; - bool seen_ccfb = false; + std::optional<RtcpFeedbackType> preferred_rtcp_cc_ack_type; for (const auto& transceiver : rtp_transceivers) { const ContentInfo* content_info = FindMediaSectionForTransceiver(transceiver, sdesc); @@ -5077,16 +5076,20 @@ RTCError SdpOfferAnswerHandler::PushdownMediaDescription( if (!content_desc) { continue; } - // RFC 8888 says that the ccfb must be consistent across the description. - if (seen_ccfb) { - if (use_ccfb != content_desc->rtcp_fb_ack_ccfb()) { + if (preferred_rtcp_cc_ack_type.has_value()) { + // RFC 8888 says that the ccfb must be consistent across the + // description. + if (preferred_rtcp_cc_ack_type == RtcpFeedbackType::CCFB && + preferred_rtcp_cc_ack_type != + content_desc->preferred_rtcp_cc_ack_type()) { RTC_LOG(LS_ERROR) - << "Warning: Inconsistent CCFB flag - CCFB turned off"; - use_ccfb = false; + << "Warning: Inconsistent CCFB flag - ack type changed to " + << content_desc->preferred_rtcp_cc_ack_type(); + preferred_rtcp_cc_ack_type = + content_desc->preferred_rtcp_cc_ack_type(); } } else { - use_ccfb = content_desc->rtcp_fb_ack_ccfb(); - seen_ccfb = true; + preferred_rtcp_cc_ack_type = content_desc->preferred_rtcp_cc_ack_type(); } transceiver->OnNegotiationUpdate(type, content_desc); @@ -5117,28 +5120,44 @@ RTCError SdpOfferAnswerHandler::PushdownMediaDescription( // If local and remote are both set, we assume that it's safe to trigger // CCFB. if (pc_->trials().IsEnabled("WebRTC-RFC8888CongestionControlFeedback")) { - if (type == SdpType::kAnswer && use_ccfb && local_description() && + if (type == SdpType::kAnswer && local_description() && remote_description()) { - bool remote_supports_ccfb = true; - // Verify that the remote supports CCFB before enabling. + std::optional<RtcpFeedbackType> remote_preferred_rtcp_cc_ack_type; + // Verify that the remote agrees on congestion control feedback format. for (const auto& content : remote_description()->description()->contents()) { if (content.type != MediaProtocolType::kRtp || content.rejected || content.media_description() == nullptr) { continue; } - if (!content.media_description()->rtcp_fb_ack_ccfb()) { - remote_supports_ccfb = false; + if (!remote_preferred_rtcp_cc_ack_type.has_value()) { + remote_preferred_rtcp_cc_ack_type = + content.media_description()->preferred_rtcp_cc_ack_type(); + } + if (content.media_description() + ->preferred_rtcp_cc_ack_type() + .has_value() && + remote_preferred_rtcp_cc_ack_type != + content.media_description()->preferred_rtcp_cc_ack_type()) { + RTC_LOG(LS_ERROR) << "Warning: Inconsistent remote congestion " + "control feedback types. "; + remote_preferred_rtcp_cc_ack_type = std::nullopt; break; } } - if (remote_supports_ccfb) { + if (preferred_rtcp_cc_ack_type.has_value() && + preferred_rtcp_cc_ack_type == remote_preferred_rtcp_cc_ack_type) { // The call and the congestion controller live on the worker thread. - context_->worker_thread()->PostTask([call = pc_->call_ptr()] { - call->EnableSendCongestionControlFeedbackAccordingToRfc8888(); - }); + context_->worker_thread()->PostTask( + [call = pc_->call_ptr(), + preferred_rtcp_cc_ack_type = *preferred_rtcp_cc_ack_type] { + call->SetPreferredRtcpCcAckType(preferred_rtcp_cc_ack_type); + }); } else { - RTC_LOG(LS_WARNING) << "Local but not Remote supports CCFB."; + RTC_LOG(LS_WARNING) + << "Inconsistent Congestion Control feedback types: " + << preferred_rtcp_cc_ack_type << " vs " + << remote_preferred_rtcp_cc_ack_type << " Using default."; } } } diff --git a/third_party/libwebrtc/pc/session_description.h b/third_party/libwebrtc/pc/session_description.h @@ -15,6 +15,7 @@ #include <stdint.h> #include <memory> +#include <optional> #include <string> #include <utility> #include <vector> @@ -118,6 +119,20 @@ class MediaContentDescription { bool rtcp_fb_ack_ccfb() const { return rtcp_fb_ack_ccfb_; } void set_rtcp_fb_ack_ccfb(bool enable) { rtcp_fb_ack_ccfb_ = enable; } + // Returns the preferred RTCP ack type used for congestion control for this + // media content or `std::nullopt` if no supported type exists. + std::optional<RtcpFeedbackType> preferred_rtcp_cc_ack_type() const { + if (rtcp_fb_ack_ccfb_) { + return RtcpFeedbackType::CCFB; + } + for (const auto& codec : codecs_) { + if (codec.feedback_params.Has(FeedbackParam(kRtcpFbParamTransportCc))) { + return RtcpFeedbackType::TRANSPORT_CC; + } + } + return std::nullopt; + } + int bandwidth() const { return bandwidth_; } void set_bandwidth(int bandwidth) { bandwidth_ = bandwidth; } std::string bandwidth_type() const { return bandwidth_type_; } diff --git a/third_party/libwebrtc/test/call_test.cc b/third_party/libwebrtc/test/call_test.cc @@ -347,6 +347,7 @@ void CallTest::CreateAudioAndFecSendConfigs(size_t num_audio_streams, audio_send_config.rtp.ssrc = VideoTestConstants::kAudioSendSsrc; AddRtpExtensionByUri(RtpExtension::kTransportSequenceNumberUri, &audio_send_config.rtp.extensions); + audio_send_config.include_in_congestion_control_allocation = true; audio_send_config.send_codec_spec = AudioSendStream::Config::SendCodecSpec( VideoTestConstants::kAudioSendPayloadType, diff --git a/third_party/libwebrtc/test/peer_scenario/tests/l4s_test.cc b/third_party/libwebrtc/test/peer_scenario/tests/l4s_test.cc @@ -126,6 +126,17 @@ DataRate GetAvailableSendBitrate( return DataRate::BitsPerSec(*stats[0]->available_outgoing_bitrate); } +TimeDelta GetAverageRoundTripTime( + const scoped_refptr<const RTCStatsReport>& report) { + auto stats = report->GetStatsOfType<RTCIceCandidatePairStats>(); + if (stats.empty() || (stats[0]->responses_received.value_or(0) == 0)) { + return TimeDelta::Zero(); + } + + return TimeDelta::Seconds(*stats[0]->total_round_trip_time / + *stats[0]->responses_received); +} + std::optional<int64_t> GetPacketsSentWithEct1( const scoped_refptr<const RTCStatsReport>& report) { auto stats = report->GetStatsOfType<RTCOutboundRtpStreamStats>(); @@ -254,12 +265,12 @@ TEST_P(FeedbackFormatTest, AdaptToLinkCapacityWithoutEcn) { auto caller_to_callee = s.net() ->NodeBuilder() - .capacity(DataRate::KilobitsPerSec(600)) + .capacity(DataRate::KilobitsPerSec(250)) .Build() .node; auto callee_to_caller = s.net() ->NodeBuilder() - .capacity(DataRate::KilobitsPerSec(600)) + .capacity(DataRate::KilobitsPerSec(250)) .Build() .node; RtcpFeedbackCounter callee_feedback_counter; @@ -280,10 +291,12 @@ TEST_P(FeedbackFormatTest, AdaptToLinkCapacityWithoutEcn) { {callee_to_caller}); PeerScenarioClient::VideoSendTrackConfig video_conf; video_conf.generator.squares_video->framerate = 30; - video_conf.generator.squares_video->width = 640; - video_conf.generator.squares_video->height = 360; + video_conf.generator.squares_video->width = 320; + video_conf.generator.squares_video->height = 240; caller->CreateVideo("FROM_CALLER", video_conf); callee->CreateVideo("FROM_CALLEE", video_conf); + caller->CreateAudio("FROM_CALLER", AudioOptions()); + callee->CreateAudio("FROM_CALLEE", AudioOptions()); signaling.StartIceSignaling(); std::atomic<bool> offer_exchange_done(false); @@ -295,13 +308,16 @@ TEST_P(FeedbackFormatTest, AdaptToLinkCapacityWithoutEcn) { DataRate caller_available_bwe = GetAvailableSendBitrate(GetStatsAndProcess(s, caller)); - EXPECT_GT(caller_available_bwe.kbps(), 450); - EXPECT_LT(caller_available_bwe.kbps(), 610); + EXPECT_GT(caller_available_bwe.kbps(), 150); + EXPECT_LT(caller_available_bwe.kbps(), 260); DataRate callee_available_bwe = GetAvailableSendBitrate(GetStatsAndProcess(s, callee)); - EXPECT_GT(callee_available_bwe.kbps(), 450); - EXPECT_LT(callee_available_bwe.kbps(), 610); + EXPECT_GT(callee_available_bwe.kbps(), 150); + EXPECT_LT(callee_available_bwe.kbps(), 260); + + EXPECT_LT(GetAverageRoundTripTime(GetStatsAndProcess(s, caller)), + TimeDelta::Millis(200)); if (params.caller_supports_rfc8888 && params.callee_supports_rfc8888) { EXPECT_GT(caller_feedback_counter.FeedbackAccordingToRfc8888(), 0); diff --git a/third_party/libwebrtc/test/scenario/audio_stream.cc b/third_party/libwebrtc/test/scenario/audio_stream.cc @@ -152,6 +152,8 @@ SendAudioStream::SendAudioStream( } send_config.rtp.extensions = GetAudioRtpExtensions(config); + send_config.include_in_congestion_control_allocation = + config.stream.in_bandwidth_estimation; sender_->SendTask([&] { send_stream_ = sender_->call_->CreateAudioSendStream(send_config);