commit ddc0cfabdb9a7b17a63babec72dd2c77f3cea243 parent ef754d45f2126e87e2aec3192e137011532be660 Author: Dan Baker <dbaker@mozilla.com> Date: Tue, 2 Dec 2025 00:47:28 -0700 Bug 2000941 - Vendor libwebrtc from ad5e5d4876 Upstream commit: https://webrtc.googlesource.com/src/+/ad5e5d48761344c010305b6bb8dc2b4b2e3ed179 Add WindowedMinFilter to rtc_base/numerics The filter returns the min value within a fixed size window. Bug: webrtc:447037083 Change-Id: If42ff0e19af8b4a6aaf8f4addc11e326b4244e43 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/411760 Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Commit-Queue: Per Kjellander <perkj@webrtc.org> Cr-Commit-Position: refs/heads/main@{#45741} Diffstat:
13 files changed, 271 insertions(+), 34 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-12-02T07:42:44.400041+00:00. +libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-12-02T07:47:14.506975+00:00. # base of lastest vendoring -5477ae9ac4 +ad5e5d4876 diff --git a/third_party/libwebrtc/moz-patch-stack/s0001.patch b/third_party/libwebrtc/moz-patch-stack/s0001.patch @@ -1392,7 +1392,7 @@ index 5ccc3d7d38..cd957416bc 100644 const bool enable_svc_for_simulcast_; std::optional<SimulcastToSvcConverter> simulcast_to_svc_converter_; diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn -index ce7896bbed..668b55b766 100644 +index 49245ac8a3..6fe678371b 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn @@ -449,6 +449,12 @@ rtc_library("logging") { diff --git a/third_party/libwebrtc/moz-patch-stack/s0027.patch b/third_party/libwebrtc/moz-patch-stack/s0027.patch @@ -1008,7 +1008,7 @@ index 39aa39a41c..b26e30e8bb 100644 "/config/external/nspr", "/nsprpub/lib/ds", diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn -index 668b55b766..fa927c25d9 100644 +index 6fe678371b..0bc3bb4dd6 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn @@ -326,6 +326,7 @@ rtc_library("sample_counter") { @@ -1027,7 +1027,7 @@ index 668b55b766..fa927c25d9 100644 rtc_library("zero_memory") { visibility = [ "*" ] -@@ -805,7 +807,9 @@ rtc_library("rtc_json") { +@@ -810,7 +812,9 @@ rtc_library("rtc_json") { "//third_party/abseil-cpp/absl/strings", "//third_party/abseil-cpp/absl/strings:string_view", ] @@ -1037,7 +1037,7 @@ index 668b55b766..fa927c25d9 100644 if (rtc_build_json) { deps += [ "//third_party/jsoncpp" ] } else { -@@ -1183,6 +1187,7 @@ if (!build_with_chromium) { +@@ -1188,6 +1192,7 @@ if (!build_with_chromium) { } rtc_library("network") { @@ -1045,7 +1045,7 @@ index 668b55b766..fa927c25d9 100644 visibility = [ "*" ] sources = [ "network.cc", -@@ -1227,6 +1232,7 @@ rtc_library("network") { +@@ -1232,6 +1237,7 @@ rtc_library("network") { deps += [ ":win32" ] } } @@ -1053,7 +1053,7 @@ index 668b55b766..fa927c25d9 100644 rtc_source_set("sigslot_trampoline") { sources = [ "sigslot_trampoline.h" ] -@@ -1249,14 +1255,17 @@ rtc_library("sigslot_trampoline_unittest") { +@@ -1254,14 +1260,17 @@ rtc_library("sigslot_trampoline_unittest") { } rtc_library("socket_address_pair") { @@ -1071,7 +1071,7 @@ index 668b55b766..fa927c25d9 100644 visibility = [ "*" ] sources = [ "net_helper.cc", -@@ -1267,8 +1276,10 @@ rtc_library("net_helper") { +@@ -1272,8 +1281,10 @@ rtc_library("net_helper") { "//third_party/abseil-cpp/absl/strings:string_view", ] } @@ -1082,7 +1082,7 @@ index 668b55b766..fa927c25d9 100644 visibility = [ "*" ] sources = [ "socket_adapters.cc", -@@ -1289,6 +1300,7 @@ rtc_library("socket_adapters") { +@@ -1294,6 +1305,7 @@ rtc_library("socket_adapters") { "//third_party/abseil-cpp/absl/strings:string_view", ] } @@ -1090,7 +1090,7 @@ index 668b55b766..fa927c25d9 100644 rtc_library("network_route") { sources = [ -@@ -1303,6 +1315,7 @@ rtc_library("network_route") { +@@ -1308,6 +1320,7 @@ rtc_library("network_route") { } rtc_library("async_tcp_socket") { @@ -1098,7 +1098,7 @@ index 668b55b766..fa927c25d9 100644 sources = [ "async_tcp_socket.cc", "async_tcp_socket.h", -@@ -1325,8 +1338,10 @@ rtc_library("async_tcp_socket") { +@@ -1330,8 +1343,10 @@ rtc_library("async_tcp_socket") { "//third_party/abseil-cpp/absl/memory", ] } @@ -1109,7 +1109,7 @@ index 668b55b766..fa927c25d9 100644 visibility = [ "*" ] sources = [ "async_udp_socket.cc", -@@ -1352,8 +1367,10 @@ rtc_library("async_udp_socket") { +@@ -1357,8 +1372,10 @@ rtc_library("async_udp_socket") { "//third_party/abseil-cpp/absl/base:nullability", ] } @@ -1120,7 +1120,7 @@ index 668b55b766..fa927c25d9 100644 visibility = [ "*" ] sources = [ "async_packet_socket.cc", -@@ -1377,6 +1394,7 @@ rtc_library("async_packet_socket") { +@@ -1382,6 +1399,7 @@ rtc_library("async_packet_socket") { "//third_party/abseil-cpp/absl/functional:any_invocable", ] } @@ -1128,7 +1128,7 @@ index 668b55b766..fa927c25d9 100644 if (rtc_include_tests) { rtc_library("async_packet_socket_unittest") { -@@ -1464,6 +1482,7 @@ rtc_library("data_rate_limiter") { +@@ -1469,6 +1487,7 @@ rtc_library("data_rate_limiter") { } rtc_library("unique_id_generator") { @@ -1136,7 +1136,7 @@ index 668b55b766..fa927c25d9 100644 sources = [ "unique_id_generator.cc", "unique_id_generator.h", -@@ -1481,6 +1500,7 @@ rtc_library("unique_id_generator") { +@@ -1486,6 +1505,7 @@ rtc_library("unique_id_generator") { "//third_party/abseil-cpp/absl/strings:string_view", ] } @@ -1144,7 +1144,7 @@ index 668b55b766..fa927c25d9 100644 rtc_library("crc32") { sources = [ -@@ -1512,6 +1532,7 @@ rtc_library("stream") { +@@ -1517,6 +1537,7 @@ rtc_library("stream") { } rtc_library("rtc_certificate_generator") { @@ -1152,7 +1152,7 @@ index 668b55b766..fa927c25d9 100644 visibility = [ "*" ] sources = [ "rtc_certificate_generator.cc", -@@ -1526,6 +1547,7 @@ rtc_library("rtc_certificate_generator") { +@@ -1531,6 +1552,7 @@ rtc_library("rtc_certificate_generator") { "//third_party/abseil-cpp/absl/functional:any_invocable", ] } @@ -1160,7 +1160,7 @@ index 668b55b766..fa927c25d9 100644 rtc_source_set("ssl_header") { visibility = [ "*" ] -@@ -1582,6 +1604,7 @@ rtc_library("crypto_random") { +@@ -1587,6 +1609,7 @@ rtc_library("crypto_random") { } rtc_library("ssl") { @@ -1168,7 +1168,7 @@ index 668b55b766..fa927c25d9 100644 visibility = [ "*" ] sources = [ "openssl_key_pair.cc", -@@ -1654,6 +1677,7 @@ rtc_library("ssl") { +@@ -1659,6 +1682,7 @@ rtc_library("ssl") { deps += [ ":win32" ] } } @@ -1176,7 +1176,7 @@ index 668b55b766..fa927c25d9 100644 rtc_library("ssl_adapter") { visibility = [ "*" ] -@@ -2386,7 +2410,7 @@ if (rtc_include_tests) { +@@ -2395,7 +2419,7 @@ if (rtc_include_tests) { } } diff --git a/third_party/libwebrtc/moz-patch-stack/s0053.patch b/third_party/libwebrtc/moz-patch-stack/s0053.patch @@ -29,7 +29,7 @@ index 7db75d5fd3..d0feb5007c 100644 rtc_library("task_queue_test") { visibility = [ "*" ] diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn -index fa927c25d9..7bca814660 100644 +index 0bc3bb4dd6..cf78dcea10 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn @@ -664,10 +664,14 @@ if (is_mac || is_ios) { diff --git a/third_party/libwebrtc/moz-patch-stack/s0091.patch b/third_party/libwebrtc/moz-patch-stack/s0091.patch @@ -13,10 +13,10 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/4e7b3c485e549e7e3 1 file changed, 6 insertions(+) diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn -index 7bca814660..d640c9ddc3 100644 +index cf78dcea10..4e8d2cab04 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn -@@ -992,6 +992,12 @@ rtc_library("threading") { +@@ -997,6 +997,12 @@ rtc_library("threading") { "thread.cc", "thread.h", ] diff --git a/third_party/libwebrtc/moz-patch-stack/s0094.patch b/third_party/libwebrtc/moz-patch-stack/s0094.patch @@ -9,10 +9,10 @@ Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/ee2f06666bcc6d22c 1 file changed, 2 insertions(+) diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn -index d640c9ddc3..f7a8428d3f 100644 +index 4e8d2cab04..d65503677a 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn -@@ -1690,6 +1690,7 @@ if (!build_with_mozilla) { +@@ -1695,6 +1695,7 @@ if (!build_with_mozilla) { } rtc_library("ssl_adapter") { @@ -20,7 +20,7 @@ index d640c9ddc3..f7a8428d3f 100644 visibility = [ "*" ] sources = [ "openssl_adapter.cc", -@@ -1738,6 +1739,7 @@ rtc_library("ssl_adapter") { +@@ -1743,6 +1744,7 @@ rtc_library("ssl_adapter") { configs += [ "..:external_ssl_library" ] } } diff --git a/third_party/libwebrtc/moz-patch-stack/s0102.patch b/third_party/libwebrtc/moz-patch-stack/s0102.patch @@ -616,7 +616,7 @@ index 61f874c816..6cde29a50d 100644 if (rtc_build_libsrtp) { diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn -index f7a8428d3f..408573e6a7 100644 +index d65503677a..59a2f60b5d 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn @@ -9,8 +9,8 @@ @@ -630,7 +630,7 @@ index f7a8428d3f..408573e6a7 100644 } rtc_source_set("protobuf_utils") { -@@ -1934,8 +1934,8 @@ if (!rtc_rusty_base64) { +@@ -1939,8 +1939,8 @@ if (!rtc_rusty_base64) { ] } } else { @@ -782,7 +782,7 @@ index b24e6d2957..329313d232 100644 deps = [ ":google_test_runner_delegate" ] } diff --git a/test/fuzzers/BUILD.gn b/test/fuzzers/BUILD.gn -index e7a254c85d..eb2cb6c937 100644 +index 5611c78d40..7591f0189c 100644 --- a/test/fuzzers/BUILD.gn +++ b/test/fuzzers/BUILD.gn @@ -6,7 +6,7 @@ diff --git a/third_party/libwebrtc/moz-patch-stack/s0107.patch b/third_party/libwebrtc/moz-patch-stack/s0107.patch @@ -116,10 +116,10 @@ index 35a2d46444..0990000a73 100644 public_configs = [] if (!build_with_chromium) { diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn -index 408573e6a7..2f064aaf3a 100644 +index 59a2f60b5d..81c4a6711c 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn -@@ -1569,6 +1569,7 @@ rtc_source_set("ssl_header") { +@@ -1574,6 +1574,7 @@ rtc_source_set("ssl_header") { } rtc_library("digest") { @@ -127,7 +127,7 @@ index 408573e6a7..2f064aaf3a 100644 visibility = [ "*" ] sources = [ "message_digest.cc", -@@ -1590,8 +1591,10 @@ rtc_library("digest") { +@@ -1595,8 +1596,10 @@ rtc_library("digest") { configs += [ "..:external_ssl_library" ] } } @@ -138,7 +138,7 @@ index 408573e6a7..2f064aaf3a 100644 visibility = [ "*" ] sources = [ "crypto_random.cc", -@@ -1612,6 +1615,7 @@ rtc_library("crypto_random") { +@@ -1617,6 +1620,7 @@ rtc_library("crypto_random") { configs += [ "..:external_ssl_library" ] } } diff --git a/third_party/libwebrtc/rtc_base/BUILD.gn b/third_party/libwebrtc/rtc_base/BUILD.gn @@ -749,6 +749,11 @@ rtc_library("weak_ptr") { ] } +rtc_library("windowed_min_filter") { + sources = [ "numerics/windowed_min_filter.h" ] + deps = [ ":checks" ] +} + rtc_library("rtc_numerics") { sources = [ "numerics/event_based_exponential_moving_average.cc", @@ -2266,13 +2271,17 @@ if (rtc_include_tests) { "numerics/running_statistics_unittest.cc", "numerics/sequence_number_unwrapper_unittest.cc", "numerics/sequence_number_util_unittest.cc", + "numerics/windowed_min_filter_unittest.cc", ] deps = [ ":mod_ops", ":rtc_numerics", ":timeutils", + ":windowed_min_filter", + "../api/units:time_delta", "../test:test_main", "../test:test_support", + "//testing/gtest", "//third_party/abseil-cpp/absl/algorithm:container", ] } diff --git a/third_party/libwebrtc/rtc_base/numerics/windowed_min_filter.h b/third_party/libwebrtc/rtc_base/numerics/windowed_min_filter.h @@ -0,0 +1,78 @@ +/* + * 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 RTC_BASE_NUMERICS_WINDOWED_MIN_FILTER_H_ +#define RTC_BASE_NUMERICS_WINDOWED_MIN_FILTER_H_ + +#include <deque> + +#include "rtc_base/checks.h" + +namespace webrtc { + +template <typename V> +class WindowedMinFilter { + public: + explicit WindowedMinFilter(int window_length) : max_size_(window_length) { + RTC_DCHECK_GT(window_length, 1); + } + + void Insert(V value) { + if (!min_values_.empty()) { + if (min_values_.front().index == index_) { + // Min value is too old. + min_values_.pop_front(); + } + + // If value <= min_values_.front().value, value is the minimum value and + // we can forget all other. The alternative had been to always + // check the back value, but then we would also have to check for + // empty. + if (min_values_.front().value >= value) { + min_values_.clear(); + } else { + while (min_values_.back().value >= value) { + min_values_.pop_back(); + } + } + } + RTC_DCHECK_LT(min_values_.size(), max_size_); + min_values_.push_back({.value = value, .index = index_}); + index_ = (index_ + 1) % max_size_; + } + + // Returns the min value within the window. If no value has been inserted, + // returns the default value of V. + V GetMin() const { + if (min_values_.empty()) { + return V(); + } + return min_values_.front().value; + } + + void Reset() { + min_values_.clear(); + index_ = 0; + } + + private: + const int max_size_; + struct ValueAndIndex { + V value; + int index; + }; + + int index_ = 0; + std::deque<ValueAndIndex> min_values_; +}; + +} // namespace webrtc + +#endif // RTC_BASE_NUMERICS_WINDOWED_MIN_FILTER_H_ diff --git a/third_party/libwebrtc/rtc_base/numerics/windowed_min_filter_unittest.cc b/third_party/libwebrtc/rtc_base/numerics/windowed_min_filter_unittest.cc @@ -0,0 +1,93 @@ +/* + * 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 "rtc_base/numerics/windowed_min_filter.h" + +#include <string> + +#include "api/units/time_delta.h" +#include "test/gtest.h" + +namespace webrtc { +namespace { + +TEST(WindowedMinFilterTest, EmptyFilterReturnZero) { + WindowedMinFilter<TimeDelta> filter(/*window_length=*/3); + EXPECT_EQ(filter.GetMin(), TimeDelta::Zero()); +} + +TEST(WindowedMinFilterTest, EmptyFilterReturnEmptyString) { + WindowedMinFilter<std::string> filter(/*window_length=*/3); + EXPECT_EQ(filter.GetMin(), ""); +} + +TEST(WindowedMinFilterTest, GetMinReturnsMin) { + WindowedMinFilter<int> filter(/*window_length=*/3); + + filter.Insert(30); + EXPECT_EQ(filter.GetMin(), 30); + filter.Insert(20); + EXPECT_EQ(filter.GetMin(), 20); + filter.Insert(10); + EXPECT_EQ(filter.GetMin(), 10); +} + +TEST(WindowedMinFilterTest, GetMinReturnsMinNotSortedInput) { + WindowedMinFilter<int> filter(/*window_length=*/4); + + filter.Insert(0); + filter.Insert(30); + EXPECT_EQ(filter.GetMin(), 0); + filter.Insert(10); + EXPECT_EQ(filter.GetMin(), 0); + filter.Insert(40); + EXPECT_EQ(filter.GetMin(), 0); + filter.Insert(40); + EXPECT_EQ(filter.GetMin(), 10); +} + +TEST(WindowedMinFilterTest, GetMinReturnsMinWithStringsNotSorted) { + WindowedMinFilter<std::string> filter(/*window_length=*/3); + + filter.Insert("bbb"); + EXPECT_EQ(filter.GetMin(), "bbb"); + filter.Insert("ccc"); + EXPECT_EQ(filter.GetMin(), "bbb"); + filter.Insert("aaa"); + EXPECT_EQ(filter.GetMin(), "aaa"); +} + +TEST(WindowedMinFilterTest, GetMinReturnsMinInWindow) { + WindowedMinFilter<int> filter(/*window_length=*/3); + + filter.Insert(10); + filter.Insert(20); + filter.Insert(30); + EXPECT_EQ(filter.GetMin(), 10); + filter.Insert(40); + EXPECT_EQ(filter.GetMin(), 20); + filter.Insert(50); + EXPECT_EQ(filter.GetMin(), 30); +} + +TEST(WindowedMinFilterTest, RestartAfterReset) { + WindowedMinFilter<int> filter(/*window_length=*/3); + + filter.Insert(10); + filter.Insert(20); + ASSERT_EQ(filter.GetMin(), 10); + filter.Reset(); + EXPECT_EQ(filter.GetMin(), 0); + filter.Insert(30); + EXPECT_EQ(filter.GetMin(), 30); +} + +} // namespace +} // namespace webrtc diff --git a/third_party/libwebrtc/test/fuzzers/BUILD.gn b/third_party/libwebrtc/test/fuzzers/BUILD.gn @@ -829,6 +829,15 @@ webrtc_fuzzer_test("webrtc_base64_encode_fuzzer") { ] } +webrtc_fuzzer_test("windowed_min_filter_fuzzer") { + sources = [ "windowed_min_filter_fuzzer.cc" ] + deps = [ + "../../rtc_base:checks", + "../../rtc_base:windowed_min_filter", + "//third_party/abseil-cpp/absl/algorithm:container", + ] +} + group("fuzzers") { testonly = true deps = [ @@ -889,6 +898,7 @@ group("fuzzers") { ":vp9_replay_fuzzer", ":webrtc_base64_decode_fuzzer", ":webrtc_base64_encode_fuzzer", + ":windowed_min_filter_fuzzer", ] if (rtc_use_h265) { deps += [ diff --git a/third_party/libwebrtc/test/fuzzers/windowed_min_filter_fuzzer.cc b/third_party/libwebrtc/test/fuzzers/windowed_min_filter_fuzzer.cc @@ -0,0 +1,47 @@ +/* + * 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 <deque> +#include "absl/algorithm/container.h" +#include "rtc_base/numerics/windowed_min_filter.h" +#include "rtc_base/checks.h" +#include "test/fuzzers/fuzz_data_helper.h" + +namespace webrtc { + +void FuzzOneInput(const uint8_t* data, size_t size) { + class ReferenceFilter { + public: + explicit ReferenceFilter(int window_length) : max_size_(window_length) {} + void Insert(int value) { + buffer_.push_back(value); + if (buffer_.size() > max_size_) { + buffer_.pop_front(); + } + } + int GetMin() const { return *absl::c_min_element(buffer_); } + + private: + const size_t max_size_; + std::deque<int> buffer_; + }; + + ReferenceFilter reference_filter(/*window_length=*/10); + WindowedMinFilter<int> filter(/*window_length=*/10); + test::FuzzDataHelper fuzz_data(MakeArrayView(data, size)); + + while (fuzz_data.CanReadBytes(sizeof(int))) { + int value = fuzz_data.Read<int>(); + reference_filter.Insert(value); + filter.Insert(value); + RTC_CHECK_EQ(filter.GetMin(), reference_filter.GetMin()); + } +} +} // namespace webrtc