tor-browser

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

commit ad80a6364bb94a1382eff7f3eae6f06a30bcf0be
parent c54bcf8496a35deff5dccaaf0eeb6f7442979c3b
Author: Dan Baker <dbaker@mozilla.com>
Date:   Wed, 22 Oct 2025 14:59:44 -0600

Bug 1995393 - Vendor libwebrtc from b7bde5ab8a

Upstream commit: https://webrtc.googlesource.com/src/+/b7bde5ab8a9c44f0a31cf7be1d3d17d55e6dc433
    Implement L4S inbound-rtp stats

    described in
    https://w3c.github.io/webrtc-stats/#dom-rtcreceivedrtpstreamstats-packetsreceivedwithect1
    https://w3c.github.io/webrtc-stats/#dom-rtcreceivedrtpstreamstats-packetsreceivedwithce

    This largely mirrors the send side stats:
    https://webrtc-review.googlesource.com/c/src/+/390866

    The statistics on the remote-inbound-rtp that are sent to the sender via RFC 8888 feedback are not implemented yet.

    Bug: webrtc:42225697
    Change-Id: Id680c4361d4d7e563b069446c5365388322af55b
    Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/403188
    Reviewed-by: Harald Alvestrand <hta@webrtc.org>
    Reviewed-by: Per Kjellander <perkj@webrtc.org>
    Commit-Queue: Philipp Hancke <phancke@meta.com>
    Cr-Commit-Position: refs/heads/main@{#45311}

Diffstat:
Mthird_party/libwebrtc/README.mozilla.last-vendor | 4++--
Mthird_party/libwebrtc/api/stats/rtcstats_objects.h | 6+++++-
Mthird_party/libwebrtc/audio/audio_receive_stream.cc | 2++
Mthird_party/libwebrtc/audio/channel_receive.cc | 3+++
Mthird_party/libwebrtc/audio/channel_receive.h | 4++++
Mthird_party/libwebrtc/call/audio_receive_stream.h | 4++++
Mthird_party/libwebrtc/call/rtp_transport_controller_send.cc | 6+++---
Mthird_party/libwebrtc/media/base/media_channel.h | 6+++++-
Mthird_party/libwebrtc/media/engine/webrtc_video_engine.cc | 4++++
Mthird_party/libwebrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.cc | 25++++++++++++++++++++++++-
Mthird_party/libwebrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h | 10+++++++++-
Mthird_party/libwebrtc/moz-patch-stack/s0027.patch | 2+-
Mthird_party/libwebrtc/moz-patch-stack/s0035.patch | 18+++++++++---------
Mthird_party/libwebrtc/moz-patch-stack/s0039.patch | 4++--
Mthird_party/libwebrtc/pc/rtc_stats_collector.cc | 4++++
Mthird_party/libwebrtc/pc/rtc_stats_collector_unittest.cc | 8++++++++
Mthird_party/libwebrtc/pc/rtc_stats_integrationtest.cc | 14+++++++++++++-
Mthird_party/libwebrtc/stats/rtcstats_objects.cc | 4+++-
Mthird_party/libwebrtc/test/peer_scenario/tests/l4s_test.cc | 40++++++++++++++++++++++++++++++++++------
19 files changed, 139 insertions(+), 29 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-22T20:57:10.943830+00:00. +libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-10-22T20:59:28.116125+00:00. # base of lastest vendoring -897031c184 +b7bde5ab8a diff --git a/third_party/libwebrtc/api/stats/rtcstats_objects.h b/third_party/libwebrtc/api/stats/rtcstats_objects.h @@ -196,6 +196,10 @@ class RTC_EXPORT RTCReceivedRtpStreamStats : public RTCRtpStreamStats { std::optional<double> jitter; std::optional<int32_t> packets_lost; // Signed per RFC 3550 + // https://w3c.github.io/webrtc-stats/#dom-rtcreceivedrtpstreamstats-packetsreceivedwithect1 + std::optional<int64_t> packets_received_with_ect1; + // https://w3c.github.io/webrtc-stats/#dom-rtcreceivedrtpstreamstats-packetsreceivedwithce + std::optional<int64_t> packets_received_with_ce; protected: RTCReceivedRtpStreamStats(std::string id, Timestamp timestamp); @@ -371,7 +375,7 @@ class RTC_EXPORT RTCOutboundRtpStreamStats final std::optional<uint32_t> rtx_ssrc; // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-packetssentwithect1 - std::optional<uint64_t> packets_sent_with_ect1; + std::optional<int64_t> packets_sent_with_ect1; }; // https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict* diff --git a/third_party/libwebrtc/audio/audio_receive_stream.cc b/third_party/libwebrtc/audio/audio_receive_stream.cc @@ -282,6 +282,8 @@ AudioReceiveStreamInterface::Stats AudioReceiveStreamImpl::GetStats( stats.header_and_padding_bytes_received = call_stats.header_and_padding_bytes_received; stats.packets_received = call_stats.packets_received; + stats.packets_received_with_ect1 = call_stats.packets_received_with_ect1; + stats.packets_received_with_ce = call_stats.packets_received_with_ce; stats.packets_lost = call_stats.packets_lost; stats.jitter_ms = call_stats.jitter_ms; stats.nacks_sent = call_stats.nacks_sent; diff --git a/third_party/libwebrtc/audio/channel_receive.cc b/third_party/libwebrtc/audio/channel_receive.cc @@ -854,6 +854,9 @@ CallReceiveStatistics ChannelReceive::GetRTCPStatistics() const { rtp_stats.packet_counter.header_bytes + rtp_stats.packet_counter.padding_bytes; stats.packets_received = rtp_stats.packet_counter.packets; + stats.packets_received_with_ect1 = + rtp_stats.packet_counter.packets_with_ect1; + stats.packets_received_with_ce = rtp_stats.packet_counter.packets_with_ce; stats.last_packet_received = rtp_stats.last_packet_received; } diff --git a/third_party/libwebrtc/audio/channel_receive.h b/third_party/libwebrtc/audio/channel_receive.h @@ -56,6 +56,10 @@ struct CallReceiveStatistics { int64_t payload_bytes_received = 0; int64_t header_and_padding_bytes_received = 0; int packets_received = 0; + // https://w3c.github.io/webrtc-stats/#dom-rtcreceivedrtpstreamstats-packetsreceivedwithect1 + int64_t packets_received_with_ect1 = 0; + // https://w3c.github.io/webrtc-stats/#dom-rtcreceivedrtpstreamstats-packetsreceivedwithce + int64_t packets_received_with_ce = 0; uint32_t nacks_sent = 0; // The capture NTP time (in local timebase) of the first played out audio // frame. diff --git a/third_party/libwebrtc/call/audio_receive_stream.h b/third_party/libwebrtc/call/audio_receive_stream.h @@ -45,6 +45,10 @@ class AudioReceiveStreamInterface : public MediaReceiveStreamInterface { int64_t payload_bytes_received = 0; int64_t header_and_padding_bytes_received = 0; uint32_t packets_received = 0; + // https://w3c.github.io/webrtc-stats/#dom-rtcreceivedrtpstreamstats-packetsreceivedwithect1 + int64_t packets_received_with_ect1 = 0; + // https://w3c.github.io/webrtc-stats/#dom-rtcreceivedrtpstreamstats-packetsreceivedwithce + int64_t packets_received_with_ce = 0; uint64_t fec_packets_received = 0; uint64_t fec_packets_discarded = 0; int32_t packets_lost = 0; diff --git a/third_party/libwebrtc/call/rtp_transport_controller_send.cc b/third_party/libwebrtc/call/rtp_transport_controller_send.cc @@ -668,9 +668,9 @@ void RtpTransportControllerSend::HandleTransportPacketsFeedback( // TODO: bugs.webrtc.org/42225697 - adapt to ECN feedback and continue to // send packets as ECT(1) if transport is ECN capable. sending_packets_as_ect1_ = false; - RTC_LOG(LS_INFO) << " Transport is " - << (feedback.transport_supports_ecn ? "" : " not ") - << " ECN capable. Stop sending ECT(1)."; + RTC_LOG(LS_INFO) << "Transport is " + << (feedback.transport_supports_ecn ? "" : "not ") + << "ECN capable. Stop sending ECT(1)."; packet_router_.ConfigureForRfc8888Feedback(sending_packets_as_ect1_); } diff --git a/third_party/libwebrtc/media/base/media_channel.h b/third_party/libwebrtc/media/base/media_channel.h @@ -364,7 +364,7 @@ struct MediaSenderInfo { uint64_t retransmitted_bytes_sent = 0; int packets_sent = 0; // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-packetssentwithect1 - int packets_sent_with_ect1 = 0; + int64_t packets_sent_with_ect1 = 0; // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-retransmittedpacketssent uint64_t retransmitted_packets_sent = 0; // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-nackcount @@ -428,6 +428,10 @@ struct MediaReceiverInfo { // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-headerbytesreceived int64_t header_and_padding_bytes_received = 0; int packets_received = 0; + // https://w3c.github.io/webrtc-stats/#dom-rtcreceivedrtpstreamstats-packetsreceivedwithect1 + int64_t packets_received_with_ect1 = 0; + // https://w3c.github.io/webrtc-stats/#dom-rtcreceivedrtpstreamstats-packetsreceivedwithce + int64_t packets_received_with_ce = 0; int packets_lost = 0; std::optional<uint64_t> retransmitted_bytes_received; diff --git a/third_party/libwebrtc/media/engine/webrtc_video_engine.cc b/third_party/libwebrtc/media/engine/webrtc_video_engine.cc @@ -3787,6 +3787,10 @@ WebRtcVideoReceiveChannel::WebRtcVideoReceiveStream::GetVideoReceiverInfo( stats.rtp_stats.packet_counter.header_bytes + stats.rtp_stats.packet_counter.padding_bytes; info.packets_received = stats.rtp_stats.packet_counter.packets; + info.packets_received_with_ect1 = + stats.rtp_stats.packet_counter.packets_with_ect1; + info.packets_received_with_ce = + stats.rtp_stats.packet_counter.packets_with_ce; info.packets_lost = stats.rtp_stats.packets_lost; info.jitter_ms = stats.rtp_stats.jitter / (kVideoCodecClockrate / 1000); diff --git a/third_party/libwebrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.cc b/third_party/libwebrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.cc @@ -15,8 +15,10 @@ #include "absl/algorithm/container.h" #include "absl/strings/string_view.h" +#include "api/transport/ecn_marking.h" #include "api/units/time_delta.h" #include "modules/rtp_rtcp/source/rtp_packet.h" +#include "modules/rtp_rtcp/source/rtp_packet_received.h" #include "modules/rtp_rtcp/source/rtp_packet_to_send.h" namespace webrtc { @@ -52,7 +54,8 @@ RtpPacketCounter::RtpPacketCounter(const RtpPacket& packet) payload_bytes(packet.payload_size()), padding_bytes(packet.padding_size()), packets(1), - packets_with_ect1(0) {} + packets_with_ect1(0), + packets_with_ce(0) {} RtpPacketCounter::RtpPacketCounter(const RtpPacketToSend& packet_to_send) : RtpPacketCounter(static_cast<const RtpPacket&>(packet_to_send)) { @@ -63,6 +66,16 @@ RtpPacketCounter::RtpPacketCounter(const RtpPacketToSend& packet_to_send) } } +RtpPacketCounter::RtpPacketCounter(const RtpPacketReceived& packet_received) + : RtpPacketCounter(static_cast<const RtpPacket&>(packet_received)) { + EcnMarking ecn = packet_received.ecn(); + if (ecn == EcnMarking::kEct1) { + ++packets_with_ect1; + } else if (ecn == EcnMarking::kCe) { + ++packets_with_ce; + } +} + void RtpPacketCounter::AddPacket(const RtpPacket& packet) { ++packets; header_bytes += packet.headers_size(); @@ -79,4 +92,14 @@ void RtpPacketCounter::AddPacket(const RtpPacketToSend& packet_to_send) { } } +void RtpPacketCounter::AddPacket(const RtpPacketReceived& packet_received) { + AddPacket(static_cast<const RtpPacket&>(packet_received)); + EcnMarking ecn = packet_received.ecn(); + if (ecn == EcnMarking::kEct1) { + ++packets_with_ect1; + } else if (ecn == EcnMarking::kCe) { + ++packets_with_ce; + } +} + } // namespace webrtc diff --git a/third_party/libwebrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h b/third_party/libwebrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h @@ -38,6 +38,8 @@ namespace webrtc { class RtpPacket; class RtpPacketToSend; +class RtpPacketReceived; + namespace rtcp { class TransportFeedback; } // namespace rtcp @@ -280,10 +282,12 @@ struct RtpPacketCounter { payload_bytes(0), padding_bytes(0), packets(0), - packets_with_ect1(0) {} + packets_with_ect1(0), + packets_with_ce(0) {} explicit RtpPacketCounter(const RtpPacket& packet); explicit RtpPacketCounter(const RtpPacketToSend& packet_to_send); + explicit RtpPacketCounter(const RtpPacketReceived& packet_received); void Add(const RtpPacketCounter& other) { header_bytes += other.header_bytes; @@ -291,6 +295,7 @@ struct RtpPacketCounter { padding_bytes += other.padding_bytes; packets += other.packets; packets_with_ect1 += other.packets_with_ect1; + packets_with_ce += other.packets_with_ce; total_packet_delay += other.total_packet_delay; } @@ -299,12 +304,14 @@ struct RtpPacketCounter { payload_bytes == other.payload_bytes && padding_bytes == other.padding_bytes && packets == other.packets && packets_with_ect1 == other.packets_with_ect1 && + packets_with_ce == other.packets_with_ce && total_packet_delay == other.total_packet_delay; } // Not inlined, since use of RtpPacket would result in circular includes. void AddPacket(const RtpPacket& packet); void AddPacket(const RtpPacketToSend& packet_to_send); + void AddPacket(const RtpPacketReceived& packet_received); size_t TotalBytes() const { return header_bytes + payload_bytes + padding_bytes; @@ -315,6 +322,7 @@ struct RtpPacketCounter { size_t padding_bytes; // Number of padding bytes. size_t packets; // Number of packets. size_t packets_with_ect1; // Number of packets with ECT1 flag set to true. + size_t packets_with_ce; // Number of packets with CE flag set to true. // The total delay of all `packets`. For RtpPacketToSend packets, this is // `time_in_send_queue()`. For receive packets, this is zero. TimeDelta total_packet_delay = TimeDelta::Zero(); diff --git a/third_party/libwebrtc/moz-patch-stack/s0027.patch b/third_party/libwebrtc/moz-patch-stack/s0027.patch @@ -689,7 +689,7 @@ index 98a675a7c9..6cfbf1b9f3 100644 rtc_library("rtc_audio_video") { diff --git a/media/base/media_channel.h b/media/base/media_channel.h -index 17ad9ad5b6..c844dfd798 100644 +index 373f160c00..9aed74afa2 100644 --- a/media/base/media_channel.h +++ b/media/base/media_channel.h @@ -67,9 +67,6 @@ namespace webrtc { diff --git a/third_party/libwebrtc/moz-patch-stack/s0035.patch b/third_party/libwebrtc/moz-patch-stack/s0035.patch @@ -20,7 +20,7 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/d0b311007c033e838 11 files changed, 55 insertions(+), 10 deletions(-) diff --git a/audio/audio_receive_stream.cc b/audio/audio_receive_stream.cc -index ab2383ffe0..3df660ba85 100644 +index bbe84801e5..c61d4ba025 100644 --- a/audio/audio_receive_stream.cc +++ b/audio/audio_receive_stream.cc @@ -58,6 +58,8 @@ std::string AudioReceiveStreamInterface::Config::Rtp::ToString() const { @@ -42,7 +42,7 @@ index ab2383ffe0..3df660ba85 100644 } // namespace diff --git a/audio/channel_receive.cc b/audio/channel_receive.cc -index 724fb32ff3..ca1e41b63e 100644 +index 658266e41b..296551f60a 100644 --- a/audio/channel_receive.cc +++ b/audio/channel_receive.cc @@ -133,7 +133,8 @@ class ChannelReceive : public ChannelReceiveInterface, @@ -73,7 +73,7 @@ index 724fb32ff3..ca1e41b63e 100644 if (frame_transformer) InitFrameTransformerDelegate(std::move(frame_transformer)); -@@ -1188,13 +1191,14 @@ std::unique_ptr<ChannelReceiveInterface> CreateChannelReceive( +@@ -1191,13 +1194,14 @@ std::unique_ptr<ChannelReceiveInterface> CreateChannelReceive( std::optional<AudioCodecPairId> codec_pair_id, scoped_refptr<FrameDecryptorInterface> frame_decryptor, const CryptoOptions& crypto_options, @@ -91,7 +91,7 @@ index 724fb32ff3..ca1e41b63e 100644 } // namespace voe diff --git a/audio/channel_receive.h b/audio/channel_receive.h -index 6179c4f8f0..d2316adb12 100644 +index 0783363a7a..f99568ae78 100644 --- a/audio/channel_receive.h +++ b/audio/channel_receive.h @@ -39,6 +39,7 @@ @@ -102,7 +102,7 @@ index 6179c4f8f0..d2316adb12 100644 namespace webrtc { -@@ -179,7 +180,8 @@ std::unique_ptr<ChannelReceiveInterface> CreateChannelReceive( +@@ -183,7 +184,8 @@ std::unique_ptr<ChannelReceiveInterface> CreateChannelReceive( std::optional<AudioCodecPairId> codec_pair_id, scoped_refptr<FrameDecryptorInterface> frame_decryptor, const webrtc::CryptoOptions& crypto_options, @@ -113,7 +113,7 @@ index 6179c4f8f0..d2316adb12 100644 } // namespace voe } // namespace webrtc diff --git a/call/audio_receive_stream.h b/call/audio_receive_stream.h -index 4ae9ba04de..098307f135 100644 +index d7ab975231..85842bd112 100644 --- a/call/audio_receive_stream.h +++ b/call/audio_receive_stream.h @@ -22,6 +22,7 @@ @@ -124,7 +124,7 @@ index 4ae9ba04de..098307f135 100644 #include "api/crypto/crypto_options.h" #include "api/crypto/frame_decryptor_interface.h" #include "api/frame_transformer_interface.h" -@@ -130,6 +131,8 @@ class AudioReceiveStreamInterface : public MediaReceiveStreamInterface { +@@ -134,6 +135,8 @@ class AudioReceiveStreamInterface : public MediaReceiveStreamInterface { // See NackConfig for description. NackConfig nack; RtcpMode rtcp_mode = RtcpMode::kCompound; @@ -168,10 +168,10 @@ index c69ec1a674..b07f08eddf 100644 // Transport for outgoing packets (RTCP). diff --git a/modules/rtp_rtcp/include/rtp_rtcp_defines.h b/modules/rtp_rtcp/include/rtp_rtcp_defines.h -index 2552792e10..aa6a7a3005 100644 +index cb4decc834..664600fd76 100644 --- a/modules/rtp_rtcp/include/rtp_rtcp_defines.h +++ b/modules/rtp_rtcp/include/rtp_rtcp_defines.h -@@ -180,6 +180,14 @@ class NetworkLinkRtcpObserver { +@@ -182,6 +182,14 @@ class NetworkLinkRtcpObserver { virtual void OnRttUpdate(Timestamp /* receive_time */, TimeDelta /* rtt */) {} }; diff --git a/third_party/libwebrtc/moz-patch-stack/s0039.patch b/third_party/libwebrtc/moz-patch-stack/s0039.patch @@ -16,10 +16,10 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/c186df8a088e46285 1 file changed, 1 deletion(-) diff --git a/audio/audio_receive_stream.cc b/audio/audio_receive_stream.cc -index 3df660ba85..08936be46d 100644 +index c61d4ba025..9edf55fb0a 100644 --- a/audio/audio_receive_stream.cc +++ b/audio/audio_receive_stream.cc -@@ -380,7 +380,6 @@ int AudioReceiveStreamImpl::GetBaseMinimumPlayoutDelayMs() const { +@@ -382,7 +382,6 @@ int AudioReceiveStreamImpl::GetBaseMinimumPlayoutDelayMs() const { } std::vector<RtpSource> AudioReceiveStreamImpl::GetSources() const { diff --git a/third_party/libwebrtc/pc/rtc_stats_collector.cc b/third_party/libwebrtc/pc/rtc_stats_collector.cc @@ -397,6 +397,10 @@ void SetInboundRTPStreamStatsFromMediaReceiverInfo( inbound_stats->ssrc = media_receiver_info.ssrc(); inbound_stats->packets_received = static_cast<uint32_t>(media_receiver_info.packets_received); + inbound_stats->packets_received_with_ect1 = + media_receiver_info.packets_received_with_ect1; + inbound_stats->packets_received_with_ce = + media_receiver_info.packets_received_with_ce; inbound_stats->bytes_received = static_cast<uint64_t>(media_receiver_info.payload_bytes_received); inbound_stats->header_bytes_received = static_cast<uint64_t>( diff --git a/third_party/libwebrtc/pc/rtc_stats_collector_unittest.cc b/third_party/libwebrtc/pc/rtc_stats_collector_unittest.cc @@ -2147,6 +2147,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRtpStreamStats_Audio) { voice_media_info.receivers[0].packets_lost = -1; // Signed per RFC3550 voice_media_info.receivers[0].packets_discarded = 7788; voice_media_info.receivers[0].packets_received = 2; + voice_media_info.receivers[0].packets_received_with_ect1 = 7; + voice_media_info.receivers[0].packets_received_with_ce = 5; voice_media_info.receivers[0].nacks_sent = 5; voice_media_info.receivers[0].fec_packets_discarded = 5566; voice_media_info.receivers[0].fec_packets_received = 6677; @@ -2204,6 +2206,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRtpStreamStats_Audio) { expected_audio.transport_id = "TTransportName1"; expected_audio.codec_id = "CITTransportName1_42"; expected_audio.packets_received = 2; + expected_audio.packets_received_with_ect1 = 7; + expected_audio.packets_received_with_ce = 5; expected_audio.nack_count = 5; expected_audio.fec_packets_discarded = 5566; expected_audio.fec_packets_received = 6677; @@ -2300,6 +2304,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRtpStreamStats_Video) { video_media_info.receivers[0].local_stats.push_back(SsrcReceiverInfo()); video_media_info.receivers[0].local_stats[0].ssrc = 1; video_media_info.receivers[0].packets_received = 2; + video_media_info.receivers[0].packets_received_with_ect1 = 7; + video_media_info.receivers[0].packets_received_with_ce = 5; video_media_info.receivers[0].packets_lost = 42; video_media_info.receivers[0].payload_bytes_received = 3; video_media_info.receivers[0].header_and_padding_bytes_received = 12; @@ -2377,6 +2383,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRtpStreamStats_Video) { expected_video.pli_count = 6; expected_video.nack_count = 7; expected_video.packets_received = 2; + expected_video.packets_received_with_ect1 = 7; + expected_video.packets_received_with_ce = 5; expected_video.bytes_received = 3; expected_video.header_bytes_received = 12; expected_video.packets_lost = 42; diff --git a/third_party/libwebrtc/pc/rtc_stats_integrationtest.cc b/third_party/libwebrtc/pc/rtc_stats_integrationtest.cc @@ -556,6 +556,12 @@ class RTCStatsReportVerifier { inbound_stream.remote_id, RTCRemoteOutboundRtpStreamStats::kType); verifier.TestAttributeIsDefined(inbound_stream.mid); verifier.TestAttributeIsDefined(inbound_stream.track_identifier); + // TODO: bugs.webrtc.org/42225697 - move to RTCReceivedRtpStreamStats + // when wiring the RFC 8888 feedback to stats. + verifier.TestAttributeIsNonNegative<int64_t>( + inbound_stream.packets_received_with_ect1); + verifier.TestAttributeIsNonNegative<int64_t>( + inbound_stream.packets_received_with_ce); if (inbound_stream.kind.has_value() && *inbound_stream.kind == "video") { verifier.TestAttributeIsNonNegative<uint64_t>(inbound_stream.qp_sum); verifier.TestAttributeIsDefined(inbound_stream.decoder_implementation); @@ -799,7 +805,7 @@ class RTCStatsReportVerifier { verifier.TestAttributeIsNonNegative<uint64_t>( outbound_stream.retransmitted_bytes_sent); verifier.TestAttributeIsNonNegative<double>(outbound_stream.target_bitrate); - verifier.TestAttributeIsNonNegative<uint64_t>( + verifier.TestAttributeIsNonNegative<int64_t>( outbound_stream.packets_sent_with_ect1); if (outbound_stream.kind.has_value() && *outbound_stream.kind == "video") { verifier.TestAttributeIsDefined(outbound_stream.frames_encoded); @@ -896,6 +902,12 @@ class RTCStatsReportVerifier { remote_inbound_stream.total_round_trip_time); verifier.TestAttributeIsNonNegative<int32_t>( remote_inbound_stream.round_trip_time_measurements); + // TODO: bugs.webrtc.org/42225697 - move to RTCReceivedRtpStreamStats + // when wiring the RFC 8888 feedback to stats. + verifier.TestAttributeIsUndefined<int64_t>( + remote_inbound_stream.packets_received_with_ect1); + verifier.TestAttributeIsUndefined<int64_t>( + remote_inbound_stream.packets_received_with_ce); return verifier.ExpectAllAttributesSuccessfullyTested(); } diff --git a/third_party/libwebrtc/stats/rtcstats_objects.cc b/third_party/libwebrtc/stats/rtcstats_objects.cc @@ -186,7 +186,9 @@ RTCRtpStreamStats::~RTCRtpStreamStats() {} WEBRTC_RTCSTATS_IMPL( RTCReceivedRtpStreamStats, RTCRtpStreamStats, "received-rtp", AttributeInit("jitter", &jitter), - AttributeInit("packetsLost", &packets_lost)) + AttributeInit("packetsLost", &packets_lost), + AttributeInit("packetsReceivedWithEct1", &packets_received_with_ect1), + AttributeInit("packetsReceivedWithCn", &packets_received_with_ce)) // clang-format on RTCReceivedRtpStreamStats::RTCReceivedRtpStreamStats(std::string id, diff --git a/third_party/libwebrtc/test/peer_scenario/tests/l4s_test.cc b/third_party/libwebrtc/test/peer_scenario/tests/l4s_test.cc @@ -124,7 +124,7 @@ DataRate GetAvailableSendBitrate( return DataRate::BitsPerSec(*stats[0]->available_outgoing_bitrate); } -std::optional<uint64_t> GetPacketsSentWithEct1( +std::optional<int64_t> GetPacketsSentWithEct1( const scoped_refptr<const RTCStatsReport>& report) { auto stats = report->GetStatsOfType<RTCOutboundRtpStreamStats>(); if (stats.empty()) { @@ -133,6 +133,24 @@ std::optional<uint64_t> GetPacketsSentWithEct1( return stats[0]->packets_sent_with_ect1; } +std::optional<int64_t> GetPacketsReceivedWithEct1( + const scoped_refptr<const RTCStatsReport>& report) { + auto stats = report->GetStatsOfType<RTCInboundRtpStreamStats>(); + if (stats.empty()) { + return std::nullopt; + } + return stats[0]->packets_received_with_ect1; +} + +std::optional<int64_t> GetPacketsReceivedWithCe( + const scoped_refptr<const RTCStatsReport>& report) { + auto stats = report->GetStatsOfType<RTCInboundRtpStreamStats>(); + if (stats.empty()) { + return std::nullopt; + } + return stats[0]->packets_received_with_ce; +} + TEST(L4STest, NegotiateAndUseCcfbIfEnabled) { PeerScenario s(*test_info_); @@ -380,11 +398,11 @@ TEST(L4STest, SendsEct1UntilFirstFeedback) { feedback_counter.Count(packet); if (feedback_counter.ect1() > 0) { seen_ect1_feedback = true; - RTC_LOG(LS_INFO) << " ect 1: " << feedback_counter.ect1(); + RTC_LOG(LS_INFO) << "ect 1 feedback: " << feedback_counter.ect1(); } if (feedback_counter.not_ect() > 0) { seen_not_ect_feedback = true; - RTC_LOG(LS_INFO) << " not ect: " << feedback_counter.not_ect(); + RTC_LOG(LS_INFO) << "not ect feedback: " << feedback_counter.not_ect(); } }); @@ -447,12 +465,12 @@ TEST(L4STest, SendsEct1AfterRouteChange) { wifi_feedback_counter.Count(packet); if (wifi_feedback_counter.ect1() > 0) { seen_ect1_on_wifi_feedback = true; - RTC_LOG(LS_INFO) << " ect 1 feedback on wifi: " + RTC_LOG(LS_INFO) << "ect 1 feedback on wifi: " << wifi_feedback_counter.ect1(); } if (wifi_feedback_counter.not_ect() > 0) { seen_not_ect_on_wifi_feedback = true; - RTC_LOG(LS_INFO) << " not ect feedback on wifi: " + RTC_LOG(LS_INFO) << "not ect feedback on wifi: " << wifi_feedback_counter.not_ect(); } }); @@ -487,7 +505,7 @@ TEST(L4STest, SendsEct1AfterRouteChange) { cellular_feedback_counter.Count(packet); if (cellular_feedback_counter.ect1() > 0) { seen_ect1_on_cellular_feedback = true; - RTC_LOG(LS_INFO) << " ect 1 feedback on cellular: " + RTC_LOG(LS_INFO) << "ect 1 feedback on cellular: " << cellular_feedback_counter.ect1(); } }); @@ -496,10 +514,20 @@ TEST(L4STest, SendsEct1AfterRouteChange) { s.net()->DisableEndpoint(callee->endpoint(0)); EXPECT_TRUE( s.WaitAndProcess(&seen_ect1_on_cellular_feedback, TimeDelta::Seconds(5))); + + // Check statistics. auto packets_sent_with_ect1_stats = GetPacketsSentWithEct1(GetStatsAndProcess(s, caller)); EXPECT_EQ(packets_sent_with_ect1_stats, wifi_feedback_counter.ect1() + cellular_feedback_counter.ect1()); + + auto callee_stats = GetStatsAndProcess(s, callee); + auto packets_received_with_ect1_stats = + GetPacketsReceivedWithEct1(callee_stats); + auto packets_received_with_ce_stats = GetPacketsReceivedWithCe(callee_stats); + EXPECT_EQ(packets_received_with_ect1_stats, wifi_feedback_counter.ect1()); + // TODO: bugs.webrtc.org/42225697 - testing CE would be useful. + EXPECT_EQ(packets_received_with_ce_stats, 0); } } // namespace