commit f8f1dfd993b37c5e6eebd3521c72aa62700949e8 parent ad80a6364bb94a1382eff7f3eae6f06a30bcf0be Author: Dan Baker <dbaker@mozilla.com> Date: Wed, 22 Oct 2025 15:02:43 -0600 Bug 1995393 - Vendor libwebrtc from 8e8480de52 Upstream commit: https://webrtc.googlesource.com/src/+/8e8480de52505e4a086010b4732ce1197bc17139 Calculate video encode PSNR (in supported codecs) the Y, U and V components, applications can do a weighted average. https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-psnrsum Depends on https://github.com/cisco/openh264/pull/3824 (for OpenH264) https://chromium-review.googlesource.com/c/webm/libvpx/+/6167966 (libvpx) https://aomedia-review.googlesource.com/c/aom/+/196501 (libaom) This CL implements the codec changes, https://webrtc-review.googlesource.com/c/src/+/375021 is a follow-up to wire up getStats. BUG=webrtc:388070060 Change-Id: I7046158a7b6e4183a9ec939fcac94eee9d65530d Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/368960 Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Philipp Hancke <phancke@meta.com> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Cr-Commit-Position: refs/heads/main@{#45312} Diffstat:
29 files changed, 334 insertions(+), 59 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:59:28.116125+00:00. +libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-10-22T21:02:26.587370+00:00. # base of lastest vendoring -b7bde5ab8a +8e8480de52 diff --git a/third_party/libwebrtc/api/video/encoded_image.h b/third_party/libwebrtc/api/video/encoded_image.h @@ -78,6 +78,13 @@ class RTC_EXPORT EncodedImageBuffer : public EncodedImageBufferInterface { // cleaned up. Direct use of its members is strongly discouraged. class RTC_EXPORT EncodedImage { public: + // Peak signal to noise ratio, Y/U/V components. + struct Psnr { + double y = 0.0; + double u = 0.0; + double v = 0.0; + }; + EncodedImage(); EncodedImage(EncodedImage&&); EncodedImage(const EncodedImage&); @@ -260,6 +267,9 @@ class RTC_EXPORT EncodedImage { EncodedImage::Timing video_timing() const { return timing_; } EncodedImage::Timing* video_timing_mutable() { return &timing_; } + std::optional<Psnr> psnr() const { return psnr_; } + void set_psnr(std::optional<Psnr> psnr) { psnr_ = psnr; } + private: size_t capacity() const { return encoded_data_ ? encoded_data_->size() : 0; } @@ -296,6 +306,9 @@ class RTC_EXPORT EncodedImage { // used. std::optional<CorruptionDetectionFilterSettings> corruption_detection_filter_settings_; + + // Encoders may compute PSNR for a frame. + std::optional<Psnr> psnr_; }; } // namespace webrtc diff --git a/third_party/libwebrtc/call/BUILD.gn b/third_party/libwebrtc/call/BUILD.gn @@ -409,6 +409,7 @@ rtc_library("video_send_stream_api") { "../api/adaptation:resource_adaptation_api", "../api/crypto:options", "../api/units:data_rate", + "../api/video:encoded_image", "../api/video:video_frame", "../api/video:video_rtp_headers", "../api/video:video_stream_encoder", diff --git a/third_party/libwebrtc/call/video_send_stream.h b/third_party/libwebrtc/call/video_send_stream.h @@ -27,6 +27,7 @@ #include "api/rtp_sender_setparameters_callback.h" #include "api/scoped_refptr.h" #include "api/units/data_rate.h" +#include "api/video/encoded_image.h" #include "api/video/video_content_type.h" #include "api/video/video_frame.h" #include "api/video/video_source_interface.h" @@ -94,6 +95,8 @@ class VideoSendStream { double encode_frame_rate = 0.0; int frames_encoded = 0; std::optional<uint64_t> qp_sum; + EncodedImage::Psnr psnr_sum; + uint64_t psnr_measurements = 0; uint64_t total_encode_time_ms = 0; uint64_t total_encoded_bytes_target = 0; uint32_t huge_frames_sent = 0; diff --git a/third_party/libwebrtc/experiments/field_trials.py b/third_party/libwebrtc/experiments/field_trials.py @@ -197,6 +197,9 @@ ACTIVE_FIELD_TRIALS: FrozenSet[FieldTrial] = frozenset([ FieldTrial('WebRTC-VP9-SvcForSimulcast', 347737882, date(2024, 10, 1)), + FieldTrial('WebRTC-Video-CalculatePsnr', + 388070060, + date(2026, 1, 1)), FieldTrial('WebRTC-Video-EnableRetransmitAllLayers', 42225262, date(2024, 4, 1)), diff --git a/third_party/libwebrtc/media/BUILD.gn b/third_party/libwebrtc/media/BUILD.gn @@ -352,6 +352,7 @@ rtc_source_set("media_channel") { "../api/units:data_rate", "../api/units:time_delta", "../api/units:timestamp", + "../api/video:encoded_image", "../api/video:recordable_encoded_frame", "../api/video:video_frame", "../api/video:video_rtp_headers", diff --git a/third_party/libwebrtc/media/base/media_channel.h b/third_party/libwebrtc/media/base/media_channel.h @@ -43,6 +43,7 @@ #include "api/units/data_rate.h" #include "api/units/time_delta.h" #include "api/units/timestamp.h" +#include "api/video/encoded_image.h" #include "api/video/recordable_encoded_frame.h" #include "api/video/video_content_type.h" #include "api/video/video_sink_interface.h" @@ -593,8 +594,12 @@ struct VideoSenderInfo : public MediaSenderInfo { // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-totalencodedbytestarget uint64_t total_encoded_bytes_target = 0; bool has_entered_low_resolution = false; + // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-qpsum std::optional<uint64_t> qp_sum; VideoContentType content_type = VideoContentType::UNSPECIFIED; + // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-psnrsum + webrtc::EncodedImage::Psnr psnr_sum; + uint32_t psnr_measurements = 0; uint32_t frames_sent = 0; // https://w3c.github.io/webrtc-stats/#dom-rtcvideosenderstats-hugeframessent uint32_t huge_frames_sent = 0; diff --git a/third_party/libwebrtc/media/engine/webrtc_video_engine.cc b/third_party/libwebrtc/media/engine/webrtc_video_engine.cc @@ -2537,6 +2537,8 @@ WebRtcVideoSendChannel::WebRtcVideoSendStream::GetPerLayerVideoSenderInfos( info.report_block_datas.push_back(*stream_stats.report_block_data); } info.qp_sum = stream_stats.qp_sum; + info.psnr_sum = stream_stats.psnr_sum; + info.psnr_measurements = stream_stats.psnr_measurements; info.total_encode_time_ms = stream_stats.total_encode_time_ms; info.total_encoded_bytes_target = stream_stats.total_encoded_bytes_target; info.huge_frames_sent = stream_stats.huge_frames_sent; @@ -2589,6 +2591,12 @@ WebRtcVideoSendChannel::WebRtcVideoSendStream::GetAggregatedVideoSenderInfo( } info.qp_sum = *info.qp_sum + *infos[i].qp_sum; } + if (infos[i].psnr_measurements > 0) { + info.psnr_measurements += infos[i].psnr_measurements; + info.psnr_sum.y += infos[i].psnr_sum.y; + info.psnr_sum.u += infos[i].psnr_sum.u; + info.psnr_sum.v += infos[i].psnr_sum.v; + } info.frames_encoded += infos[i].frames_encoded; info.frames_sent += infos[i].frames_sent; info.total_encode_time_ms += infos[i].total_encode_time_ms; diff --git a/third_party/libwebrtc/modules/video_coding/BUILD.gn b/third_party/libwebrtc/modules/video_coding/BUILD.gn @@ -388,6 +388,18 @@ if (rtc_use_h264 && rtc_system_openh264) { } } +rtc_library("frame_sampler") { + visibility = [ "*" ] + sources = [ + "utility/frame_sampler.cc", + "utility/frame_sampler.h", + ] + deps = [ + "..:module_api_public", + "../../api/video:video_frame", + ] +} + rtc_library("video_coding_utility") { visibility = [ "*" ] sources = [ @@ -488,6 +500,7 @@ rtc_library("webrtc_h264") { defines = [] deps = [ ":codec_globals_headers", + ":frame_sampler", ":video_codec_interface", ":video_coding_utility", "../../api:scoped_refptr", @@ -514,6 +527,7 @@ rtc_library("webrtc_h264") { "../../rtc_base:timeutils", "../../rtc_base/system:rtc_export", "../../system_wrappers:metrics", + "../rtp_rtcp:rtp_rtcp_format", "svc:scalability_structures", "svc:scalable_video_controller", "//third_party/abseil-cpp/absl/base:nullability", @@ -575,6 +589,7 @@ rtc_library("webrtc_vp8") { deps = [ ":codec_globals_headers", + ":frame_sampler", ":video_codec_interface", ":video_coding_utility", ":webrtc_libvpx_interface", @@ -608,6 +623,7 @@ rtc_library("webrtc_vp8") { "../../rtc_base/experiments:field_trial_parser", "../../rtc_base/experiments:rate_control_settings", "../../system_wrappers:metrics", + "../rtp_rtcp:rtp_rtcp_format", "svc:scalability_mode_util", "//third_party/abseil-cpp/absl/algorithm:container", "//third_party/abseil-cpp/absl/base:nullability", @@ -701,6 +717,7 @@ rtc_library("webrtc_vp9") { deps = [ ":codec_globals_headers", + ":frame_sampler", ":video_codec_interface", ":video_coding_utility", ":webrtc_libvpx_interface", @@ -1209,6 +1226,7 @@ if (rtc_include_tests) { "utility/corruption_detection_settings_generator_unittest.cc", "utility/decoded_frames_history_unittest.cc", "utility/frame_dropper_unittest.cc", + "utility/frame_sampler_unittest.cc", "utility/framerate_controller_deprecated_unittest.cc", "utility/ivf_file_reader_unittest.cc", "utility/ivf_file_writer_unittest.cc", @@ -1233,6 +1251,7 @@ if (rtc_include_tests) { ":encoded_frame", ":frame_dependencies_calculator", ":frame_helpers", + ":frame_sampler", ":h264_sprop_parameter_sets", ":h26x_packet_buffer", ":nack_requester", diff --git a/third_party/libwebrtc/modules/video_coding/codecs/av1/BUILD.gn b/third_party/libwebrtc/modules/video_coding/codecs/av1/BUILD.gn @@ -60,6 +60,8 @@ rtc_library("libaom_av1_encoder") { ] deps = [ "../..:video_codec_interface", + "../..:video_coding_utility", + "../../:frame_sampler", "../../../../api:field_trials_view", "../../../../api:scoped_refptr", "../../../../api/environment", diff --git a/third_party/libwebrtc/modules/video_coding/codecs/av1/libaom_av1_encoder.cc b/third_party/libwebrtc/modules/video_coding/codecs/av1/libaom_av1_encoder.cc @@ -41,6 +41,7 @@ #include "modules/video_coding/include/video_error_codes.h" #include "modules/video_coding/svc/create_scalability_structure.h" #include "modules/video_coding/svc/scalable_video_controller.h" +#include "modules/video_coding/utility/frame_sampler.h" #include "rtc_base/checks.h" #include "rtc_base/experiments/encoder_info_settings.h" #include "rtc_base/logging.h" @@ -154,6 +155,11 @@ class LibaomAv1Encoder final : public VideoEncoder { // TODO(webrtc:351644568): Remove this kill-switch after the feature is fully // deployed. const bool post_encode_frame_drop_; + + // Determine whether the frame should be sampled for PSNR. + FrameSampler psnr_frame_sampler_; + // TODO(webrtc:388070060): Remove after rollout. + const bool calculate_psnr_; }; int32_t VerifyCodecSettings(const VideoCodec& codec_settings) { @@ -195,7 +201,9 @@ LibaomAv1Encoder::LibaomAv1Encoder(const Environment& env, timestamp_(0), encoder_info_override_(env.field_trials()), post_encode_frame_drop_(!env.field_trials().IsDisabled( - "WebRTC-LibaomAv1Encoder-PostEncodeFrameDrop")) {} + "WebRTC-LibaomAv1Encoder-PostEncodeFrameDrop")), + calculate_psnr_( + env.field_trials().IsEnabled("WebRTC-Video-CalculatePsnr")) {} LibaomAv1Encoder::~LibaomAv1Encoder() { Release(); @@ -747,6 +755,11 @@ int32_t LibaomAv1Encoder::Encode( aom_enc_frame_flags_t flags = layer_frame->IsKeyframe() ? AOM_EFLAG_FORCE_KF : 0; +#ifdef AOM_EFLAG_CALCULATE_PSNR + if (calculate_psnr_ && psnr_frame_sampler_.ShouldBeSampled(frame)) { + flags |= AOM_EFLAG_CALCULATE_PSNR; + } +#endif if (SvcEnabled()) { SetSvcLayerId(*layer_frame); @@ -770,10 +783,10 @@ int32_t LibaomAv1Encoder::Encode( // Get encoded image data. EncodedImage encoded_image; + const aom_codec_cx_pkt_t* pkt; aom_codec_iter_t iter = nullptr; int data_pkt_count = 0; - while (const aom_codec_cx_pkt_t* pkt = - aom_codec_get_cx_data(&ctx_, &iter)) { + while ((pkt = aom_codec_get_cx_data(&ctx_, &iter)) != nullptr) { if (pkt->kind == AOM_CODEC_CX_FRAME_PKT && pkt->data.frame.sz > 0) { if (data_pkt_count > 0) { RTC_LOG(LS_WARNING) << "LibaomAv1Encoder::Encoder returned more than " @@ -817,6 +830,12 @@ int32_t LibaomAv1Encoder::Encode( encoded_image.SetColorSpace(frame.color_space()); ++data_pkt_count; + } else if (pkt->kind == AOM_CODEC_PSNR_PKT) { + // PSNR index: 0: total, 1: Y, 2: U, 3: V + encoded_image.set_psnr( + EncodedImage::Psnr({.y = pkt->data.psnr.psnr[1], + .u = pkt->data.psnr.psnr[2], + .v = pkt->data.psnr.psnr[3]})); } } diff --git a/third_party/libwebrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc b/third_party/libwebrtc/modules/video_coding/codecs/h264/h264_encoder_impl.cc @@ -198,7 +198,9 @@ H264EncoderImpl::H264EncoderImpl(const Environment& env, number_of_cores_(0), encoded_image_callback_(nullptr), has_reported_init_(false), - has_reported_error_(false) { + has_reported_error_(false), + calculate_psnr_( + env.field_trials().IsEnabled("WebRTC-Video-CalculatePsnr")) { downscaled_buffers_.reserve(kMaxSimulcastStreams - 1); encoded_images_.reserve(kMaxSimulcastStreams); encoders_.reserve(kMaxSimulcastStreams); @@ -464,6 +466,8 @@ int32_t H264EncoderImpl::Encode( RTC_DCHECK_EQ(configurations_[0].width, frame_buffer->width()); RTC_DCHECK_EQ(configurations_[0].height, frame_buffer->height()); + bool calculate_psnr = + calculate_psnr_ && psnr_frame_sampler_.ShouldBeSampled(input_frame); // Encode image for each layer. for (size_t i = 0; i < encoders_.size(); ++i) { // EncodeFrame input. @@ -472,6 +476,9 @@ int32_t H264EncoderImpl::Encode( pictures_[i].iPicHeight = configurations_[i].height; pictures_[i].iColorFormat = EVideoFormatType::videoFormatI420; pictures_[i].uiTimeStamp = input_frame.ntp_time_ms(); + pictures_[i].bPsnrY = calculate_psnr; + pictures_[i].bPsnrU = calculate_psnr; + pictures_[i].bPsnrV = calculate_psnr; // Downscale images on second and ongoing layers. if (i == 0) { pictures_[i].iStride[0] = frame_buffer->StrideY(); @@ -564,6 +571,15 @@ int32_t H264EncoderImpl::Encode( h264_bitstream_parser_.ParseBitstream(encoded_images_[i]); encoded_images_[i].qp_ = h264_bitstream_parser_.GetLastSliceQp().value_or(-1); + if (calculate_psnr) { + encoded_images_[i].set_psnr(EncodedImage::Psnr({ + .y = info.sLayerInfo[info.iLayerNum - 1].rPsnr[0], + .u = info.sLayerInfo[info.iLayerNum - 1].rPsnr[1], + .v = info.sLayerInfo[info.iLayerNum - 1].rPsnr[2], + })); + } else { + encoded_images_[i].set_psnr(std::nullopt); + } // Deliver encoded image. CodecSpecificInfo codec_specific; diff --git a/third_party/libwebrtc/modules/video_coding/codecs/h264/h264_encoder_impl.h b/third_party/libwebrtc/modules/video_coding/codecs/h264/h264_encoder_impl.h @@ -38,6 +38,7 @@ #include "modules/video_coding/codecs/h264/include/h264.h" #include "modules/video_coding/codecs/h264/include/h264_globals.h" #include "modules/video_coding/svc/scalable_video_controller.h" +#include "modules/video_coding/utility/frame_sampler.h" #include "third_party/openh264/src/codec/api/wels/codec_app_def.h" #if defined(WEBRTC_WIN) && !defined(__clang__) @@ -126,6 +127,11 @@ class H264EncoderImpl : public VideoEncoder { bool has_reported_error_; std::vector<uint8_t> tl0sync_limit_; + + // Determine whether the frame should be sampled for PSNR. + FrameSampler psnr_frame_sampler_; + // TODO(webrtc:388070060): Remove after rollout. + const bool calculate_psnr_; }; } // namespace webrtc diff --git a/third_party/libwebrtc/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc b/third_party/libwebrtc/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc @@ -44,6 +44,7 @@ #include "api/video_codecs/vp8_frame_buffer_controller.h" #include "api/video_codecs/vp8_frame_config.h" #include "api/video_codecs/vp8_temporal_layers_factory.h" +#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/video_coding/codecs/interface/common_constants.h" #include "modules/video_coding/codecs/interface/libvpx_interface.h" #include "modules/video_coding/codecs/vp8/include/vp8.h" @@ -94,8 +95,7 @@ constexpr int kScreenshareMinQp = 15; constexpr int kTokenPartitions = VP8_ONE_TOKENPARTITION; constexpr uint32_t kVp832ByteAlign = 32u; -constexpr int kRtpTicksPerSecond = 90000; -constexpr int kRtpTicksPerMs = kRtpTicksPerSecond / 1000; +constexpr int kRtpTicksPerMs = kVideoPayloadTypeFrequency / 1000; // If internal frame dropping is enabled, force the encoder to output a frame // on an encode request after this timeout even if this causes some @@ -340,7 +340,9 @@ LibvpxVp8Encoder::LibvpxVp8Encoder(const Environment& env, encoder_info_override_(env_.field_trials()), max_frame_drop_interval_(ParseFrameDropInterval(env_.field_trials())), android_specific_threading_settings_(env_.field_trials().IsEnabled( - "WebRTC-LibvpxVp8Encoder-AndroidSpecificThreadingSettings")) { + "WebRTC-LibvpxVp8Encoder-AndroidSpecificThreadingSettings")), + calculate_psnr_( + env.field_trials().IsEnabled("WebRTC-Video-CalculatePsnr")) { // TODO(eladalon/ilnik): These reservations might be wasting memory. // InitEncode() is resizing to the actual size, which might be smaller. raw_images_.reserve(kMaxSimulcastStreams); @@ -602,7 +604,7 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst, } // setting the time base of the codec vpx_configs_[0].g_timebase.num = 1; - vpx_configs_[0].g_timebase.den = kRtpTicksPerSecond; + vpx_configs_[0].g_timebase.den = kVideoPayloadTypeFrequency; vpx_configs_[0].g_lag_in_frames = 0; // 0- no frame lagging // Set the error resilience mode for temporal layers (but not simulcast). @@ -1095,6 +1097,14 @@ int LibvpxVp8Encoder::Encode(const VideoFrame& frame, flags[i] = send_key_frame ? VPX_EFLAG_FORCE_KF : EncodeFlags(tl_configs[i]); } +#ifdef VPX_EFLAG_CALCULATE_PSNR + if (calculate_psnr_ && psnr_frame_sampler_.ShouldBeSampled(frame)) { + for (size_t i = 0; i < encoders_.size(); ++i) { + flags[i] |= VPX_EFLAG_CALCULATE_PSNR; + } + } +#endif + // Scale and map buffers and set `raw_images_` to hold pointers to the result. // Because `raw_images_` are set to hold pointers to the prepared buffers, we // need to keep these buffers alive through reference counting until after @@ -1156,7 +1166,7 @@ int LibvpxVp8Encoder::Encode(const VideoFrame& frame, // rate control seems to be off with that setup. Using the average input // frame rate to calculate an average duration for now. RTC_DCHECK_GT(codec_.maxFramerate, 0); - uint32_t duration = kRtpTicksPerSecond / codec_.maxFramerate; + uint32_t duration = kVideoPayloadTypeFrequency / codec_.maxFramerate; int error = WEBRTC_VIDEO_CODEC_OK; int num_tries = 0; @@ -1241,6 +1251,7 @@ int LibvpxVp8Encoder::GetEncodedPartitions(const VideoFrame& input_image, ++encoder_idx, --stream_idx) { vpx_codec_iter_t iter = nullptr; encoded_images_[encoder_idx].set_size(0); + encoded_images_[encoder_idx].set_psnr(std::nullopt); encoded_images_[encoder_idx]._frameType = VideoFrameType::kVideoFrameDelta; CodecSpecificInfo codec_specific; const vpx_codec_cx_pkt_t* pkt = nullptr; @@ -1267,11 +1278,19 @@ int LibvpxVp8Encoder::GetEncodedPartitions(const VideoFrame& input_image, encoded_pos += pkt->data.frame.sz; break; } + case VPX_CODEC_PSNR_PKT: + // PSNR index: 0: total, 1: Y, 2: U, 3: V + encoded_images_[encoder_idx].set_psnr( + EncodedImage::Psnr({.y = pkt->data.psnr.psnr[1], + .u = pkt->data.psnr.psnr[2], + .v = pkt->data.psnr.psnr[3]})); + break; default: break; } // End of frame - if ((pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT) == 0) { + if (pkt->kind == VPX_CODEC_CX_FRAME_PKT && + (pkt->data.frame.flags & VPX_FRAME_IS_FRAGMENT) == 0) { // check if encoded frame is a key frame if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) { encoded_images_[encoder_idx]._frameType = diff --git a/third_party/libwebrtc/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h b/third_party/libwebrtc/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h @@ -34,6 +34,7 @@ #include "modules/video_coding/codecs/vp8/include/vp8.h" #include "modules/video_coding/include/video_codec_interface.h" #include "modules/video_coding/utility/corruption_detection_settings_generator.h" +#include "modules/video_coding/utility/frame_sampler.h" #include "modules/video_coding/utility/framerate_controller_deprecated.h" #include "rtc_base/experiments/encoder_info_settings.h" #include "rtc_base/experiments/rate_control_settings.h" @@ -155,6 +156,11 @@ class LibvpxVp8Encoder : public VideoEncoder { std::unique_ptr<CorruptionDetectionSettingsGenerator> corruption_detection_settings_generator_; + + // Determine whether the frame should be sampled for PSNR. + FrameSampler psnr_frame_sampler_; + // TODO(webrtc:388070060): Remove after rollout. + const bool calculate_psnr_; }; } // namespace webrtc diff --git a/third_party/libwebrtc/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc b/third_party/libwebrtc/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc @@ -291,7 +291,9 @@ LibvpxVp9Encoder::LibvpxVp9Encoder(const Environment& env, performance_flags_(ParsePerformanceFlagsFromTrials(env.field_trials())), num_steady_state_frames_(0), config_changed_(true), - encoder_info_override_(env.field_trials()) { + encoder_info_override_(env.field_trials()), + calculate_psnr_( + env.field_trials().IsEnabled("WebRTC-Video-CalculatePsnr")) { codec_ = {}; memset(&svc_params_, 0, sizeof(vpx_svc_extra_cfg_t)); } @@ -669,7 +671,7 @@ int LibvpxVp9Encoder::InitEncode(const VideoCodec* inst, config_->g_error_resilient = is_svc_ ? VPX_ERROR_RESILIENT_DEFAULT : 0; // Setting the time base of the codec. config_->g_timebase.num = 1; - config_->g_timebase.den = 90000; + config_->g_timebase.den = kVideoPayloadTypeFrequency; config_->g_lag_in_frames = 0; // 0- no frame lagging config_->g_threads = 1; // Rate control settings. @@ -843,9 +845,11 @@ int LibvpxVp9Encoder::InitAndSetControlSettings() { return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; } - const vpx_codec_err_t rv = libvpx_->codec_enc_init( - encoder_, vpx_codec_vp9_cx(), config_, - config_->g_bit_depth == VPX_BITS_8 ? 0 : VPX_CODEC_USE_HIGHBITDEPTH); + vpx_codec_flags_t flags = + config_->g_bit_depth == VPX_BITS_8 ? 0 : VPX_CODEC_USE_HIGHBITDEPTH; + + const vpx_codec_err_t rv = + libvpx_->codec_enc_init(encoder_, vpx_codec_vp9_cx(), config_, flags); if (rv != VPX_CODEC_OK) { RTC_LOG(LS_ERROR) << "Init error: " << libvpx_->codec_err_to_string(rv); return WEBRTC_VIDEO_CODEC_UNINITIALIZED; @@ -1243,6 +1247,11 @@ int LibvpxVp9Encoder::Encode(const VideoFrame& input_image, if (force_key_frame_) { flags = VPX_EFLAG_FORCE_KF; } +#ifdef VPX_EFLAG_CALCULATE_PSNR + if (calculate_psnr_ && psnr_frame_sampler_.ShouldBeSampled(input_image)) { + flags |= VPX_EFLAG_CALCULATE_PSNR; + } +#endif if (svc_controller_) { vpx_svc_ref_frame_config_t ref_config = Vp9References(layer_frames_); @@ -1255,8 +1264,9 @@ int LibvpxVp9Encoder::Encode(const VideoFrame& input_image, if (VideoCodecMode::kScreensharing == codec_.mode) { for (uint8_t sl_idx = 0; sl_idx < num_active_spatial_layers_; ++sl_idx) { ref_config.duration[sl_idx] = static_cast<int64_t>( - 90000 / (std::min(static_cast<float>(codec_.maxFramerate), - framerate_controller_[sl_idx].GetTargetRate()))); + kVideoPayloadTypeFrequency / + (std::min(static_cast<float>(codec_.maxFramerate), + framerate_controller_[sl_idx].GetTargetRate()))); } } @@ -1280,7 +1290,8 @@ int LibvpxVp9Encoder::Encode(const VideoFrame& input_image, framerate_controller_[num_active_spatial_layers_ - 1] .GetTargetRate()) : codec_.maxFramerate; - uint32_t duration = static_cast<uint32_t>(90000 / target_framerate_fps); + uint32_t duration = + static_cast<uint32_t>(kVideoPayloadTypeFrequency / target_framerate_fps); const vpx_codec_err_t rv = libvpx_->codec_encode( encoder_, raw_, timestamp_, duration, flags, VPX_DL_REALTIME); if (rv != VPX_CODEC_OK) { @@ -1824,6 +1835,22 @@ void LibvpxVp9Encoder::GetEncodedLayerFrame(const vpx_codec_cx_pkt* pkt) { int qp = -1; libvpx_->codec_control(encoder_, VP8E_GET_LAST_QUANTIZER, &qp); encoded_image_.qp_ = qp; + // Pull PSNR which is not pushed for VP9. + // TODO: bugs.webrtc.org/388070060 - check SVC behavior. + // TODO: bugs.webrtc.org/388070060 - this is broken for simulcast which seems + // to be using kSVC. + vpx_codec_iter_t iter = nullptr; + const vpx_codec_cx_pkt_t* cx_data = nullptr; + encoded_image_.set_psnr(std::nullopt); + while ((cx_data = vpx_codec_get_cx_data(encoder_, &iter)) != nullptr) { + if (cx_data->kind == VPX_CODEC_PSNR_PKT) { + // PSNR index: 0: total, 1: Y, 2: U, 3: V + encoded_image_.set_psnr( + EncodedImage::Psnr({.y = cx_data->data.psnr.psnr[1], + .u = cx_data->data.psnr.psnr[2], + .v = cx_data->data.psnr.psnr[3]})); + } + } const bool end_of_picture = encoded_image_.SpatialIndex().value_or(0) + 1 == num_active_spatial_layers_; diff --git a/third_party/libwebrtc/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h b/third_party/libwebrtc/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h @@ -40,6 +40,7 @@ #include "modules/video_coding/include/video_codec_interface.h" #include "modules/video_coding/svc/scalable_video_controller.h" #include "modules/video_coding/svc/simulcast_to_svc_converter.h" +#include "modules/video_coding/utility/frame_sampler.h" #include "modules/video_coding/utility/framerate_controller_deprecated.h" #include "rtc_base/containers/flat_map.h" #include "rtc_base/experiments/encoder_info_settings.h" @@ -252,6 +253,11 @@ class LibvpxVp9Encoder : public VideoEncoder { bool config_changed_; const LibvpxVp9EncoderInfoSettings encoder_info_override_; + + // Determine whether the frame should be sampled for PSNR. + FrameSampler psnr_frame_sampler_; + // TODO(webrtc:388070060): Remove after rollout. + const bool calculate_psnr_; }; } // namespace webrtc diff --git a/third_party/libwebrtc/modules/video_coding/utility/frame_sampler.cc b/third_party/libwebrtc/modules/video_coding/utility/frame_sampler.cc @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "modules/video_coding/utility/frame_sampler.h" + +#include "api/video/video_frame.h" +#include "modules/include/module_common_types_public.h" + +namespace webrtc { + +constexpr int kTimestampDifference = + 90'000 - 1; // Sample every 90khz or once per second. + +bool FrameSampler::ShouldBeSampled(const VideoFrame& frame) { + if (!last_rtp_timestamp_sampled_.has_value() || + (IsNewerTimestamp(frame.rtp_timestamp(), + *last_rtp_timestamp_sampled_ + kTimestampDifference))) { + last_rtp_timestamp_sampled_ = frame.rtp_timestamp(); + return true; + } + return false; +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/modules/video_coding/utility/frame_sampler.h b/third_party/libwebrtc/modules/video_coding/utility/frame_sampler.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef MODULES_VIDEO_CODING_UTILITY_FRAME_SAMPLER_H_ +#define MODULES_VIDEO_CODING_UTILITY_FRAME_SAMPLER_H_ + +#include <cstdint> +#include <optional> + +#include "api/video/video_frame.h" + +namespace webrtc { + +// Determine whether the frame should be sampled for operations +// not done for every frame but only some of them. An example strategy +// would be to require a minimum time elapsed between two frames based +// on the RTP timestamp difference. +class FrameSampler { + public: + FrameSampler() = default; + FrameSampler(const FrameSampler&) = delete; + FrameSampler& operator=(const FrameSampler&) = delete; + + bool ShouldBeSampled(const VideoFrame& frame); + + private: + std::optional<uint32_t> last_rtp_timestamp_sampled_; +}; + +} // namespace webrtc + +#endif // MODULES_VIDEO_CODING_UTILITY_FRAME_SAMPLER_H_ diff --git a/third_party/libwebrtc/modules/video_coding/utility/frame_sampler_unittest.cc b/third_party/libwebrtc/modules/video_coding/utility/frame_sampler_unittest.cc @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "modules/video_coding/utility/frame_sampler.h" + +#include "api/make_ref_counted.h" +#include "api/video/i420_buffer.h" +#include "api/video/video_frame.h" +#include "test/gtest.h" + +namespace webrtc { + +TEST(FrameSampler, SamplesBasedOnRtpTimestamp) { + FrameSampler sampler; + + auto buffer = make_ref_counted<I420Buffer>(320, 240); + VideoFrame frame = + VideoFrame::Builder().set_video_frame_buffer(buffer).build(); + + frame.set_rtp_timestamp(0); + EXPECT_TRUE(sampler.ShouldBeSampled(frame)); + frame.set_rtp_timestamp(45'000); + EXPECT_FALSE(sampler.ShouldBeSampled(frame)); + frame.set_rtp_timestamp(90'000); + EXPECT_TRUE(sampler.ShouldBeSampled(frame)); +} + +TEST(FrameSampler, RtpTimestampWraparound) { + FrameSampler sampler; + + auto buffer = make_ref_counted<I420Buffer>(320, 240); + VideoFrame frame = + VideoFrame::Builder().set_video_frame_buffer(buffer).build(); + + // RTP timestamp wraps at 2**32. + frame.set_rtp_timestamp(0xffff'ffff - 4000); + EXPECT_TRUE(sampler.ShouldBeSampled(frame)); + frame.set_rtp_timestamp(41'000); + EXPECT_FALSE(sampler.ShouldBeSampled(frame)); + frame.set_rtp_timestamp(86'000); + EXPECT_TRUE(sampler.ShouldBeSampled(frame)); +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/moz-patch-stack/s0001.patch b/third_party/libwebrtc/moz-patch-stack/s0001.patch @@ -413,7 +413,7 @@ index 7bd443f711..a433aa21e7 100644 bool RtpExtension::IsSupportedForVideo(absl::string_view uri) { diff --git a/call/BUILD.gn b/call/BUILD.gn -index 2b796266c2..01b4bcf984 100644 +index 3f5c615fac..d9ef5920dc 100644 --- a/call/BUILD.gn +++ b/call/BUILD.gn @@ -20,6 +20,7 @@ rtc_library("call_interfaces") { @@ -1277,7 +1277,7 @@ index 8c0f592e94..502a152902 100644 int64_t _lastProcessFrameTimeNanos RTC_GUARDED_BY(capture_checker_); diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc -index d941cd6f00..2dfdaac098 100644 +index b07e5235cc..f0f2e3b853 100644 --- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc +++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc @@ -284,6 +284,7 @@ LibvpxVp9Encoder::LibvpxVp9Encoder(const Environment& env, @@ -1288,7 +1288,7 @@ index d941cd6f00..2dfdaac098 100644 is_flexible_mode_(false), variable_framerate_controller_(variable_framerate_screenshare::kMinFps), quality_scaler_experiment_(ParseQualityScalerConfig(env.field_trials())), -@@ -602,6 +603,7 @@ int LibvpxVp9Encoder::InitEncode(const VideoCodec* inst, +@@ -604,6 +605,7 @@ int LibvpxVp9Encoder::InitEncode(const VideoCodec* inst, force_key_frame_ = true; pics_since_key_ = 0; @@ -1296,7 +1296,7 @@ index d941cd6f00..2dfdaac098 100644 scalability_mode_ = codec_.GetScalabilityMode(); if (scalability_mode_.has_value()) { -@@ -1154,6 +1156,14 @@ int LibvpxVp9Encoder::Encode(const VideoFrame& input_image, +@@ -1158,6 +1160,14 @@ int LibvpxVp9Encoder::Encode(const VideoFrame& input_image, config_changed_ = false; } @@ -1311,7 +1311,7 @@ index d941cd6f00..2dfdaac098 100644 // Set input image for use in the callback. // This was necessary since you need some information from input_image. // You can save only the necessary information (such as timestamp) instead of -@@ -1286,6 +1296,48 @@ int LibvpxVp9Encoder::Encode(const VideoFrame& input_image, +@@ -1297,6 +1307,48 @@ int LibvpxVp9Encoder::Encode(const VideoFrame& input_image, return WEBRTC_VIDEO_CODEC_OK; } @@ -1361,10 +1361,10 @@ index d941cd6f00..2dfdaac098 100644 std::optional<int>* spatial_idx, std::optional<int>* temporal_idx, diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h -index d5ce6105a3..8bfd24de2b 100644 +index 5ccc3d7d38..cd957416bc 100644 --- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h +++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h -@@ -82,6 +82,9 @@ class LibvpxVp9Encoder : public VideoEncoder { +@@ -83,6 +83,9 @@ class LibvpxVp9Encoder : public VideoEncoder { // Call encoder initialize function and set control settings. int InitAndSetControlSettings(); @@ -1374,7 +1374,7 @@ index d5ce6105a3..8bfd24de2b 100644 bool PopulateCodecSpecific(CodecSpecificInfo* codec_specific, std::optional<int>* spatial_idx, std::optional<int>* temporal_idx, -@@ -170,6 +173,7 @@ class LibvpxVp9Encoder : public VideoEncoder { +@@ -171,6 +174,7 @@ class LibvpxVp9Encoder : public VideoEncoder { VideoBitrateAllocation current_bitrate_allocation_; bool ss_info_needed_; bool force_all_active_layers_; diff --git a/third_party/libwebrtc/moz-patch-stack/s0018.patch b/third_party/libwebrtc/moz-patch-stack/s0018.patch @@ -23,10 +23,10 @@ index 13e7b3229b..85b85e06a2 100644 #else constexpr bool kIsArm = false; diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc -index 5446d837ec..7b54ebe884 100644 +index 7ff38e2d5b..5c734e5eaa 100644 --- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc +++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc -@@ -792,7 +792,7 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst, +@@ -794,7 +794,7 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst, } int LibvpxVp8Encoder::GetCpuSpeed(int width, int height) { @@ -35,7 +35,7 @@ index 5446d837ec..7b54ebe884 100644 // On mobile platform, use a lower speed setting for lower resolutions for // CPUs with 4 or more cores. RTC_DCHECK_GT(number_of_cores_, 0); -@@ -820,6 +820,8 @@ int LibvpxVp8Encoder::GetCpuSpeed(int width, int height) { +@@ -822,6 +822,8 @@ int LibvpxVp8Encoder::GetCpuSpeed(int width, int height) { int LibvpxVp8Encoder::NumberOfThreads(int width, int height, int cpus) { #if defined(WEBRTC_ANDROID) if (android_specific_threading_settings_) { @@ -44,7 +44,7 @@ index 5446d837ec..7b54ebe884 100644 if (width * height >= 320 * 180) { if (cpus >= 4) { // 3 threads for CPUs with 4 and more cores since most of times only 4 -@@ -832,7 +834,9 @@ int LibvpxVp8Encoder::NumberOfThreads(int width, int height, int cpus) { +@@ -834,7 +836,9 @@ int LibvpxVp8Encoder::NumberOfThreads(int width, int height, int cpus) { } } return 1; @@ -54,7 +54,7 @@ index 5446d837ec..7b54ebe884 100644 #elif defined(WEBRTC_IOS) std::string trial_string = env_.field_trials().Lookup(kVP8IosMaxNumberOfThreadFieldTrial); -@@ -890,7 +894,7 @@ int LibvpxVp8Encoder::InitAndSetControlSettings() { +@@ -892,7 +896,7 @@ int LibvpxVp8Encoder::InitAndSetControlSettings() { // for getting the denoised frame from the encoder and using that // when encoding lower resolution streams. Would it work with the // multi-res encoding feature? diff --git a/third_party/libwebrtc/moz-patch-stack/s0027.patch b/third_party/libwebrtc/moz-patch-stack/s0027.patch @@ -478,7 +478,7 @@ index 67a2dbf7ec..9c5e881a70 100644 if (rtc_include_tests) { rtc_source_set("test_feedback_generator_interface") { diff --git a/call/BUILD.gn b/call/BUILD.gn -index 01b4bcf984..ff746af7d4 100644 +index d9ef5920dc..808f55d243 100644 --- a/call/BUILD.gn +++ b/call/BUILD.gn @@ -48,7 +48,7 @@ rtc_library("call_interfaces") { @@ -504,7 +504,7 @@ index 851c7aed30..2ae1020161 100644 #include "api/units/time_delta.h" #include "call/audio_sender.h" diff --git a/call/video_send_stream.h b/call/video_send_stream.h -index bfcc15cc88..58d3033431 100644 +index c5a24d2c48..6ae8932ca9 100644 --- a/call/video_send_stream.h +++ b/call/video_send_stream.h @@ -24,7 +24,7 @@ @@ -515,7 +515,7 @@ index bfcc15cc88..58d3033431 100644 +#include "api/rtp_sender_setparameters_callback.h" #include "api/scoped_refptr.h" #include "api/units/data_rate.h" - #include "api/video/video_content_type.h" + #include "api/video/encoded_image.h" diff --git a/common_audio/BUILD.gn b/common_audio/BUILD.gn index 6ddf551658..7eb2aca444 100644 --- a/common_audio/BUILD.gn @@ -549,7 +549,7 @@ index 88890be798..c9aefc297b 100644 #include "rtc_base/memory/aligned_malloc.h" diff --git a/media/BUILD.gn b/media/BUILD.gn -index 98a675a7c9..6cfbf1b9f3 100644 +index 4bfd8b4be8..da1a893214 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -77,7 +77,7 @@ rtc_library("rtc_media_base") { @@ -609,7 +609,7 @@ index 98a675a7c9..6cfbf1b9f3 100644 rtc_source_set("media_channel") { sources = [ "base/media_channel.h" ] -@@ -410,6 +427,7 @@ rtc_library("codec_list") { +@@ -411,6 +428,7 @@ rtc_library("codec_list") { } rtc_library("rtp_utils") { @@ -617,7 +617,7 @@ index 98a675a7c9..6cfbf1b9f3 100644 sources = [ "base/rtp_utils.cc", "base/rtp_utils.h", -@@ -426,8 +444,10 @@ rtc_library("rtp_utils") { +@@ -427,8 +445,10 @@ rtc_library("rtp_utils") { "//third_party/abseil-cpp/absl/strings:string_view", ] } @@ -628,7 +628,7 @@ index 98a675a7c9..6cfbf1b9f3 100644 sources = [ "base/stream_params.cc", "base/stream_params.h", -@@ -441,6 +461,7 @@ rtc_library("stream_params") { +@@ -442,6 +462,7 @@ rtc_library("stream_params") { "//third_party/abseil-cpp/absl/algorithm:container", ] } @@ -636,7 +636,7 @@ index 98a675a7c9..6cfbf1b9f3 100644 rtc_library("media_constants") { sources = [ -@@ -451,6 +472,7 @@ rtc_library("media_constants") { +@@ -452,6 +473,7 @@ rtc_library("media_constants") { } rtc_library("turn_utils") { @@ -644,7 +644,7 @@ index 98a675a7c9..6cfbf1b9f3 100644 sources = [ "base/turn_utils.cc", "base/turn_utils.h", -@@ -461,14 +483,17 @@ rtc_library("turn_utils") { +@@ -462,14 +484,17 @@ rtc_library("turn_utils") { "../rtc_base/system:rtc_export", ] } @@ -662,7 +662,7 @@ index 98a675a7c9..6cfbf1b9f3 100644 rtc_library("rtc_simulcast_encoder_adapter") { visibility = [ "*" ] -@@ -549,6 +574,11 @@ rtc_library("rtc_internal_video_codecs") { +@@ -550,6 +575,11 @@ rtc_library("rtc_internal_video_codecs") { "//third_party/abseil-cpp/absl/container:inlined_vector", "//third_party/abseil-cpp/absl/strings", ] @@ -674,7 +674,7 @@ index 98a675a7c9..6cfbf1b9f3 100644 if (enable_libaom) { defines += [ "RTC_USE_LIBAOM_AV1_ENCODER" ] -@@ -568,6 +598,13 @@ rtc_library("rtc_internal_video_codecs") { +@@ -569,6 +599,13 @@ rtc_library("rtc_internal_video_codecs") { "engine/internal_encoder_factory.cc", "engine/internal_encoder_factory.h", ] @@ -689,10 +689,10 @@ index 98a675a7c9..6cfbf1b9f3 100644 rtc_library("rtc_audio_video") { diff --git a/media/base/media_channel.h b/media/base/media_channel.h -index 373f160c00..9aed74afa2 100644 +index d569c19390..9030e8e590 100644 --- a/media/base/media_channel.h +++ b/media/base/media_channel.h -@@ -67,9 +67,6 @@ namespace webrtc { +@@ -68,9 +68,6 @@ namespace webrtc { class VideoFrame; struct VideoFormat; diff --git a/third_party/libwebrtc/moz-patch-stack/s0087.patch b/third_party/libwebrtc/moz-patch-stack/s0087.patch @@ -9,7 +9,7 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/60304c5d8a86fdecf 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/media/BUILD.gn b/media/BUILD.gn -index 6cfbf1b9f3..00a0d00e49 100644 +index da1a893214..0f2341a462 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -56,6 +56,11 @@ rtc_library("rtc_media_base") { diff --git a/third_party/libwebrtc/moz-patch-stack/s0101.patch b/third_party/libwebrtc/moz-patch-stack/s0101.patch @@ -26,7 +26,7 @@ index 851c745732..cdbd705ec2 100644 # These are the targets to skip header checking by default. The files in targets # matching these patterns (see "gn help label_pattern" for format) will not have diff --git a/media/BUILD.gn b/media/BUILD.gn -index 00a0d00e49..e7f7f53743 100644 +index 0f2341a462..51d055bcf0 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -7,7 +7,7 @@ @@ -39,7 +39,7 @@ index 00a0d00e49..e7f7f53743 100644 group("media") { diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn -index b100541101..88655146af 100644 +index b0dd69877b..959bea0ab4 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -7,7 +7,7 @@ diff --git a/third_party/libwebrtc/moz-patch-stack/s0103.patch b/third_party/libwebrtc/moz-patch-stack/s0103.patch @@ -427,7 +427,7 @@ index 187019693e..e1edf6befb 100644 group("logging") { diff --git a/media/BUILD.gn b/media/BUILD.gn -index e7f7f53743..04552ba728 100644 +index 51d055bcf0..e50b924806 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -6,7 +6,7 @@ @@ -588,7 +588,7 @@ index a693604389..72972d18e1 100644 import("../../webrtc.gni") diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn -index 88655146af..70782e51b6 100644 +index 959bea0ab4..2f8b9c0df1 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -6,7 +6,7 @@ diff --git a/third_party/libwebrtc/moz-patch-stack/s0105.patch b/third_party/libwebrtc/moz-patch-stack/s0105.patch @@ -9,10 +9,10 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/fadad7695efe0d9cc 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc -index 2dfdaac098..94b96d4cdf 100644 +index f0f2e3b853..34f50ee61a 100644 --- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc +++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc -@@ -1327,7 +1327,7 @@ int LibvpxVp9Encoder::UpdateCodecFrameSize( +@@ -1338,7 +1338,7 @@ int LibvpxVp9Encoder::UpdateCodecFrameSize( // bugs in trying to do it the "right" way, we basically re-do // the initialization. vpx_codec_destroy(encoder_); // clean up old state diff --git a/third_party/libwebrtc/moz-patch-stack/s0108.patch b/third_party/libwebrtc/moz-patch-stack/s0108.patch @@ -38,7 +38,7 @@ index 2e315c79c4..174ce0d2f4 100644 ] # Added when we removed deps in other places to avoid building diff --git a/media/BUILD.gn b/media/BUILD.gn -index 04552ba728..b9792deabc 100644 +index e50b924806..ac722ddda3 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -12,12 +12,10 @@ import("../webrtc.gni") @@ -68,7 +68,7 @@ index 04552ba728..b9792deabc 100644 } } -@@ -431,6 +432,7 @@ rtc_library("codec_list") { +@@ -432,6 +433,7 @@ rtc_library("codec_list") { ] } @@ -76,7 +76,7 @@ index 04552ba728..b9792deabc 100644 rtc_library("rtp_utils") { if (!build_with_mozilla) { sources = [ -@@ -477,7 +479,6 @@ rtc_library("media_constants") { +@@ -478,7 +480,6 @@ rtc_library("media_constants") { } rtc_library("turn_utils") { @@ -84,7 +84,7 @@ index 04552ba728..b9792deabc 100644 sources = [ "base/turn_utils.cc", "base/turn_utils.h", -@@ -488,17 +489,14 @@ if (!build_with_mozilla) { +@@ -489,17 +490,14 @@ if (!build_with_mozilla) { "../rtc_base/system:rtc_export", ] } @@ -102,7 +102,7 @@ index 04552ba728..b9792deabc 100644 rtc_library("rtc_simulcast_encoder_adapter") { visibility = [ "*" ] -@@ -716,6 +714,12 @@ rtc_library("rtc_audio_video") { +@@ -717,6 +715,12 @@ rtc_library("rtc_audio_video") { "engine/webrtc_voice_engine.cc", "engine/webrtc_voice_engine.h", ] diff --git a/third_party/libwebrtc/moz-patch-stack/s0110.patch b/third_party/libwebrtc/moz-patch-stack/s0110.patch @@ -10,7 +10,7 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/b6dd815fc9d2df718 1 file changed, 11 deletions(-) diff --git a/media/BUILD.gn b/media/BUILD.gn -index b9792deabc..e79c00b05d 100644 +index ac722ddda3..31df4610c7 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -54,11 +54,6 @@ rtc_library("rtc_media_base") {