tor-browser

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

commit 2d2804e92a8f4e374438c81448de9718999f5626
parent a28cad6403de2b85d603b709660c9c5a68c81670
Author: Dan Baker <dbaker@mozilla.com>
Date:   Mon, 27 Oct 2025 11:41:46 -0600

Bug 1995393 - Vendor libwebrtc from b62361bfe9

Upstream commit: https://webrtc.googlesource.com/src/+/b62361bfe989884f4137039d1e75d67b260bd1b2
    Expose video encode PSNR (in supported codecs) in stats

    the Y, U and V components, applications can do a weighted average.

    https://webrtc-review.googlesource.com/c/src/+/368960 implements the
    codec changes, this change wires those up to getStats.

    spec PR:
    https://github.com/w3c/webrtc-stats/pull/794

    BUG=webrtc:388070060

    Change-Id: Idba317422e8cfe40f3c2c7b16e4072d2c6042b3f
    Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/375021
    Commit-Queue: Philipp Hancke <phancke@meta.com>
    Reviewed-by: Henrik Boström <hbos@webrtc.org>
    Reviewed-by: Harald Alvestrand <hta@webrtc.org>
    Cr-Commit-Position: refs/heads/main@{#45414}

Diffstat:
Mthird_party/libwebrtc/README.mozilla.last-vendor | 4++--
Mthird_party/libwebrtc/api/stats/rtcstats_objects.h | 3+++
Mthird_party/libwebrtc/pc/rtc_stats_collector.cc | 15++++++++++++++-
Mthird_party/libwebrtc/pc/rtc_stats_collector_unittest.cc | 7+++++++
Mthird_party/libwebrtc/pc/rtc_stats_integrationtest.cc | 46++++++++++++++++++++++++++++++++++++++++------
Mthird_party/libwebrtc/stats/rtcstats_objects.cc | 2++
Mthird_party/libwebrtc/video/send_statistics_proxy.cc | 8++++++++
7 files changed, 76 insertions(+), 9 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-27T17:38:23.244502+00:00. +libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-10-27T17:41:31.035918+00:00. # base of lastest vendoring -dedf36cfdc +b62361bfe9 diff --git a/third_party/libwebrtc/api/stats/rtcstats_objects.h b/third_party/libwebrtc/api/stats/rtcstats_objects.h @@ -365,7 +365,10 @@ class RTC_EXPORT RTCOutboundRtpStreamStats final std::optional<uint32_t> fir_count; std::optional<uint32_t> pli_count; std::optional<uint32_t> nack_count; + // QP and PSNR are only defined for video. std::optional<uint64_t> qp_sum; + std::optional<std::map<std::string, double>> psnr_sum; // y, u, v. + std::optional<uint32_t> psnr_measurements; std::optional<bool> active; // In JavaScript, this is only exposed if HW exposure is allowed. std::optional<bool> power_efficient_encoder; diff --git a/third_party/libwebrtc/pc/rtc_stats_collector.cc b/third_party/libwebrtc/pc/rtc_stats_collector.cc @@ -804,8 +804,21 @@ CreateOutboundRTPStreamStatsFromVideoSenderInfo( static_cast<uint32_t>(video_sender_info.firs_received); outbound_video->pli_count = static_cast<uint32_t>(video_sender_info.plis_received); - if (video_sender_info.qp_sum.has_value()) + if (video_sender_info.qp_sum.has_value()) { outbound_video->qp_sum = *video_sender_info.qp_sum; + } + // psnrSum is gated on psnrMeasurements > 0. + if (video_sender_info.psnr_measurements > 0) { + outbound_video->psnr_measurements = video_sender_info.psnr_measurements; + outbound_video->psnr_sum = { + {"y", video_sender_info.psnr_sum.y}, + {"u", video_sender_info.psnr_sum.u}, + {"v", video_sender_info.psnr_sum.v}, + }; + } + if (video_sender_info.psnr_measurements > 0) { + outbound_video->psnr_measurements = video_sender_info.psnr_measurements; + } if (video_sender_info.target_bitrate.has_value()) { outbound_video->target_bitrate = video_sender_info.target_bitrate->bps(); } diff --git a/third_party/libwebrtc/pc/rtc_stats_collector_unittest.cc b/third_party/libwebrtc/pc/rtc_stats_collector_unittest.cc @@ -2620,6 +2620,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRtpStreamStats_Video) { 300; video_media_info.senders[0].quality_limitation_resolution_changes = 56u; video_media_info.senders[0].qp_sum = std::nullopt; + video_media_info.senders[0].psnr_measurements = 0; video_media_info.senders[0].content_type = VideoContentType::UNSPECIFIED; video_media_info.senders[0].encoder_implementation_name = std::nullopt; video_media_info.senders[0].power_efficient_encoder = false; @@ -2706,6 +2707,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRtpStreamStats_Video) { expected_video.rtx_ssrc = 4404; // `expected_video.content_type` should be undefined. // `expected_video.qp_sum` should be undefined. + // `expected_video.psnr_sum` should be undefined. + // `expected_video.psnr_measurements` should be undefined. // `expected_video.encoder_implementation` should be undefined. ASSERT_TRUE(report->Get(expected_video.id())); @@ -2716,6 +2719,10 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRtpStreamStats_Video) { // Set previously undefined values and "GetStats" again. video_media_info.senders[0].qp_sum = 9; expected_video.qp_sum = 9; + video_media_info.senders[0].psnr_sum = {.y = 29, .u = 30, .v = 31}; + video_media_info.senders[0].psnr_measurements = 1; + expected_video.psnr_sum = {{"y", 29}, {"u", 30}, {"v", 31}}; + expected_video.psnr_measurements = 1; video_media_info.senders[0].content_type = VideoContentType::SCREENSHARE; expected_video.content_type = "screenshare"; video_media_info.senders[0].encoder_implementation_name = "libfooencoder"; diff --git a/third_party/libwebrtc/pc/rtc_stats_integrationtest.cc b/third_party/libwebrtc/pc/rtc_stats_integrationtest.cc @@ -39,6 +39,7 @@ #include "rtc_base/thread.h" #include "rtc_base/trace_event.h" #include "rtc_base/virtual_socket_server.h" +#include "test/create_test_field_trials.h" #include "test/gmock.h" #include "test/gtest.h" #include "test/wait_until.h" @@ -49,7 +50,7 @@ namespace webrtc { namespace { -const int64_t kGetStatsTimeoutMs = 10000; +constexpr int64_t kGetStatsTimeoutMs = 10000; class RTCStatsIntegrationTest : public ::testing::Test { public: @@ -67,17 +68,22 @@ class RTCStatsIntegrationTest : public ::testing::Test { worker_thread_.get()); } - void StartCall() { + void StartCall() { StartCall(""); } + void StartCall(const char* field_trial_string) { // Create PeerConnections and "connect" sigslots PeerConnectionInterface::RTCConfiguration config; config.sdp_semantics = SdpSemantics::kUnifiedPlan; PeerConnectionInterface::IceServer ice_server; ice_server.uri = "stun:1.1.1.1:3478"; config.servers.push_back(ice_server); - EXPECT_TRUE(caller_->CreatePc(config, CreateBuiltinAudioEncoderFactory(), - CreateBuiltinAudioDecoderFactory())); - EXPECT_TRUE(callee_->CreatePc(config, CreateBuiltinAudioEncoderFactory(), - CreateBuiltinAudioDecoderFactory())); + EXPECT_TRUE( + caller_->CreatePc(config, CreateBuiltinAudioEncoderFactory(), + CreateBuiltinAudioDecoderFactory(), + CreateTestFieldTrialsPtr(field_trial_string))); + EXPECT_TRUE( + callee_->CreatePc(config, CreateBuiltinAudioEncoderFactory(), + CreateBuiltinAudioDecoderFactory(), + CreateTestFieldTrialsPtr(field_trial_string))); PeerConnectionTestWrapper::Connect(caller_.get(), callee_.get()); // Get user media for audio and video @@ -571,6 +577,7 @@ class RTCStatsReportVerifier { verifier.TestAttributeIsUndefined(inbound_stream.decoder_implementation); verifier.TestAttributeIsUndefined(inbound_stream.power_efficient_decoder); } + // As long as the corruption detection RTP header extension is not activated // it should not aggregate any corruption score. The tests where this header // extension is enabled are located in pc/peer_connection_integrationtest.cc @@ -793,6 +800,10 @@ class RTCStatsReportVerifier { RTCAudioSourceStats::kType); verifier.TestAttributeIsUndefined(outbound_stream.qp_sum); } + // TODO: bugs.webrtc.org/388070060 - PSNR stats are disabled by default. + verifier.TestAttributeIsUndefined(outbound_stream.psnr_sum); + verifier.TestAttributeIsUndefined(outbound_stream.psnr_measurements); + verifier.TestAttributeIsNonNegative<uint32_t>(outbound_stream.nack_count); verifier.TestAttributeIsOptionalIDReference( outbound_stream.remote_id, RTCRemoteInboundRtpStreamStats::kType); @@ -1198,6 +1209,29 @@ TEST_F(RTCStatsIntegrationTest, GetStatsContainsNoDuplicateAttributes) { } } } + +TEST_F(RTCStatsIntegrationTest, ExperimentalPsnrStats) { + StartCall("WebRTC-Video-CalculatePsnr/Enabled/"); + + // This assumes all other stats are ok and tests the stats which should be + // different under the field trial. + scoped_refptr<const RTCStatsReport> report = GetStatsFromCaller(); + for (const RTCStats& stats : *report) { + if (stats.type() == RTCOutboundRtpStreamStats::kType) { + const RTCOutboundRtpStreamStats& outbound_stream( + stats.cast_to<RTCOutboundRtpStreamStats>()); + RTCStatsVerifier verifier(report.get(), &outbound_stream); + if (outbound_stream.kind.has_value() && + *outbound_stream.kind == "video") { + verifier.TestAttributeIsDefined(outbound_stream.psnr_sum); + verifier.TestAttributeIsNonNegative(outbound_stream.psnr_measurements); + } else { + verifier.TestAttributeIsUndefined(outbound_stream.psnr_sum); + verifier.TestAttributeIsUndefined(outbound_stream.psnr_measurements); + } + } + } +} #endif // WEBRTC_HAVE_SCTP } // namespace diff --git a/third_party/libwebrtc/stats/rtcstats_objects.cc b/third_party/libwebrtc/stats/rtcstats_objects.cc @@ -323,6 +323,8 @@ WEBRTC_RTCSTATS_IMPL( AttributeInit("pliCount", &pli_count), AttributeInit("nackCount", &nack_count), AttributeInit("qpSum", &qp_sum), + AttributeInit("psnrSum", &psnr_sum), + AttributeInit("psnrMeasurements", &psnr_measurements), AttributeInit("active", &active), AttributeInit("powerEfficientEncoder", &power_efficient_encoder), AttributeInit("scalabilityMode", &scalability_mode), diff --git a/third_party/libwebrtc/video/send_statistics_proxy.cc b/third_party/libwebrtc/video/send_statistics_proxy.cc @@ -1053,6 +1053,14 @@ void SendStatisticsProxy::OnSendEncodedImage( } } + std::optional<EncodedImage::Psnr> psnr = encoded_image.psnr(); + if (psnr.has_value()) { + stats->psnr_sum.y += psnr->y; + stats->psnr_sum.u += psnr->u; + stats->psnr_sum.v += psnr->v; + stats->psnr_measurements += 1; + } + // If any of the simulcast streams have a huge frame, it should be counted // as a single difficult input frame. // https://w3c.github.io/webrtc-stats/#dom-rtcvideosenderstats-hugeframessent