commit d2f9bb9b3166edf4eac7b84c991ca77f27b83250
parent eb34cb05f7430ca0c930a4e7d2c9cc88933803fa
Author: Dan Baker <dbaker@mozilla.com>
Date: Wed, 19 Nov 2025 16:36:02 -0700
Bug 2000941 - updated libwebrtc patch stack
Diffstat:
7 files changed, 819 insertions(+), 0 deletions(-)
diff --git a/third_party/libwebrtc/moz-patch-stack/6908505ae0.no-op-cherry-pick-msg b/third_party/libwebrtc/moz-patch-stack/6908505ae0.no-op-cherry-pick-msg
@@ -0,0 +1 @@
+We already cherry-picked this when we vendored d2eaa5570f.
diff --git a/third_party/libwebrtc/moz-patch-stack/924e561d63.no-op-cherry-pick-msg b/third_party/libwebrtc/moz-patch-stack/924e561d63.no-op-cherry-pick-msg
@@ -0,0 +1 @@
+We already cherry-picked this when we vendored 71dfd3bde9.
diff --git a/third_party/libwebrtc/moz-patch-stack/a734a240f3.no-op-cherry-pick-msg b/third_party/libwebrtc/moz-patch-stack/a734a240f3.no-op-cherry-pick-msg
@@ -0,0 +1 @@
+We already cherry-picked this when we vendored d2eaa5570f.
diff --git a/third_party/libwebrtc/moz-patch-stack/c15949eda5.no-op-cherry-pick-msg b/third_party/libwebrtc/moz-patch-stack/c15949eda5.no-op-cherry-pick-msg
@@ -0,0 +1 @@
+We already cherry-picked this when we vendored bc7452c444.
diff --git a/third_party/libwebrtc/moz-patch-stack/p0001.patch b/third_party/libwebrtc/moz-patch-stack/p0001.patch
@@ -0,0 +1,423 @@
+From: Peter Hanspers <peterhanspers@webrtc.org>
+Date: Mon, 1 Sep 2025 16:21:55 +0200
+Subject: (cherry-pick-branch-heads/7390) [M141] Revert "Propagate content name
+ to ports at construction time, add sanity checks"
+
+Original change's description:
+> Revert "Propagate content name to ports at construction time, add sanity checks"
+>
+> I get a SIG_SEGV in basic_port_allocator.cc:AllocationSequence::OnReadPacket() on iOS. Reinstating the subscription to the OnPortDestroyedSignal for TURN ports fixes it but I'll leave it to the original author to determine what the correct approach is.
+>
+> This reverts commit 5dded01501f2e29e9f13de67dcf59d00dc2606de.
+>
+> Change-Id: I9c5497a1dbe1fc338aede54dd5e112e51cf40d5d
+> Bug: none
+> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/407048
+> Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org>
+> Commit-Queue: Peter Hanspers <peterhanspers@webrtc.org>
+> Cr-Commit-Position: refs/heads/main@{#45522}
+
+(cherry picked from commit 924e561d6370dbc7bc4e8ef9bffc984dd401b196)
+
+Bug: chromium:442851756,none
+Change-Id: I9c5497a1dbe1fc338aede54dd5e112e51cf40d5d
+Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/407740
+Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
+Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
+Auto-Submit: Chrome Cherry Picker <chrome-cherry-picker@chops-service-accounts.iam.gserviceaccount.com>
+Cr-Commit-Position: refs/branch-heads/7390@{#1}
+Cr-Branched-From: 2f553bf8d573c90176d51559b76dfc836996c8f5-refs/heads/main@{#45520}
+---
+ p2p/base/connection.cc | 4 ---
+ p2p/base/connection.h | 22 ++++----------
+ p2p/base/p2p_transport_channel.cc | 15 +++++-----
+ p2p/base/p2p_transport_channel.h | 4 +--
+ p2p/base/port.cc | 1 -
+ p2p/base/port.h | 1 -
+ p2p/base/port_allocator.cc | 4 +--
+ p2p/base/port_allocator.h | 10 +------
+ p2p/base/port_allocator_unittest.cc | 1 -
+ p2p/base/turn_port.h | 2 --
+ p2p/client/basic_port_allocator.cc | 35 ++++++++++++-----------
+ p2p/client/basic_port_allocator.h | 5 +---
+ p2p/client/relay_port_factory_interface.h | 1 -
+ 13 files changed, 38 insertions(+), 67 deletions(-)
+
+diff --git a/p2p/base/connection.cc b/p2p/base/connection.cc
+index 577e4b0d3f..1afd41bfaa 100644
+--- a/p2p/base/connection.cc
++++ b/p2p/base/connection.cc
+@@ -287,19 +287,16 @@ const Candidate& Connection::remote_candidate() const {
+ }
+
+ const Network* Connection::network() const {
+- RTC_DCHECK_RUN_ON(network_thread_);
+ RTC_DCHECK(port_) << ToDebugId() << ": port_ null in network()";
+ return port()->Network();
+ }
+
+ int Connection::generation() const {
+- RTC_DCHECK_RUN_ON(network_thread_);
+ RTC_DCHECK(port_) << ToDebugId() << ": port_ null in generation()";
+ return port()->generation();
+ }
+
+ uint64_t Connection::priority() const {
+- RTC_DCHECK_RUN_ON(network_thread_);
+ RTC_DCHECK(port_) << ToDebugId() << ": port_ null in priority()";
+ if (!port_)
+ return 0;
+@@ -1394,7 +1391,6 @@ std::string Connection::ToDebugId() const {
+ }
+
+ uint32_t Connection::ComputeNetworkCost() const {
+- RTC_DCHECK_RUN_ON(network_thread_);
+ // TODO(honghaiz): Will add rtt as part of the network cost.
+ RTC_DCHECK(port_) << ToDebugId() << ": port_ null in ComputeNetworkCost()";
+ return port()->network_cost() + remote_candidate_.network_cost();
+diff --git a/p2p/base/connection.h b/p2p/base/connection.h
+index 1cb0c20424..55de3f9bc9 100644
+--- a/p2p/base/connection.h
++++ b/p2p/base/connection.h
+@@ -117,10 +117,7 @@ class RTC_EXPORT Connection : public CandidatePairInterface {
+ bool connected() const;
+ bool weak() const;
+ bool active() const;
+- bool pending_delete() const {
+- RTC_DCHECK_RUN_ON(network_thread_);
+- return !port_;
+- }
++ bool pending_delete() const { return !port_; }
+
+ // A connection is dead if it can be safely deleted.
+ bool dead(Timestamp now) const;
+@@ -394,14 +391,8 @@ class RTC_EXPORT Connection : public CandidatePairInterface {
+ void SendResponseMessage(const StunMessage& response);
+
+ // An accessor for unit tests.
+- PortInterface* PortForTest() {
+- RTC_DCHECK_RUN_ON(network_thread_);
+- return port_.get();
+- }
+- const PortInterface* PortForTest() const {
+- RTC_DCHECK_RUN_ON(network_thread_);
+- return port_.get();
+- }
++ PortInterface* PortForTest() { return port_.get(); }
++ const PortInterface* PortForTest() const { return port_.get(); }
+
+ std::unique_ptr<IceMessage> BuildPingRequestForTest() {
+ RTC_DCHECK_RUN_ON(network_thread_);
+@@ -487,10 +478,7 @@ class RTC_EXPORT Connection : public CandidatePairInterface {
+ void set_connected(bool value);
+
+ // The local port where this connection sends and receives packets.
+- PortInterface* port() {
+- RTC_DCHECK_RUN_ON(network_thread_);
+- return port_.get();
+- }
++ PortInterface* port() { return port_.get(); }
+
+ const Environment& env() { return env_; }
+ ConnectionInfo& mutable_stats() { return stats_; }
+@@ -523,7 +511,7 @@ class RTC_EXPORT Connection : public CandidatePairInterface {
+ // TODO(tommi): This ^^^ should be fixed.
+ TaskQueueBase* const network_thread_;
+ const uint32_t id_;
+- WeakPtr<PortInterface> port_ RTC_GUARDED_BY(network_thread_);
++ WeakPtr<PortInterface> port_;
+ Candidate local_candidate_ RTC_GUARDED_BY(network_thread_);
+ Candidate remote_candidate_;
+
+diff --git a/p2p/base/p2p_transport_channel.cc b/p2p/base/p2p_transport_channel.cc
+index 9b99b90bee..eee1092080 100644
+--- a/p2p/base/p2p_transport_channel.cc
++++ b/p2p/base/p2p_transport_channel.cc
+@@ -865,16 +865,17 @@ void P2PTransportChannel::MaybeStartGathering() {
+ ice_parameters_.ufrag,
+ ice_parameters_.pwd);
+ if (pooled_session) {
+- PortAllocatorSession* raw_session = pooled_session.get();
+ AddAllocatorSession(std::move(pooled_session));
+- RTC_DCHECK_EQ(raw_session, allocator_sessions_.back().get());
++ PortAllocatorSession* raw_pooled_session =
++ allocator_sessions_.back().get();
+ // Process the pooled session's existing candidates/ports, if they exist.
+- OnCandidatesReady(raw_session, raw_session->ReadyCandidates());
+- for (PortInterface* port : raw_session->ReadyPorts()) {
+- OnPortReady(raw_session, port);
++ OnCandidatesReady(raw_pooled_session,
++ raw_pooled_session->ReadyCandidates());
++ for (PortInterface* port : allocator_sessions_.back()->ReadyPorts()) {
++ OnPortReady(raw_pooled_session, port);
+ }
+- if (raw_session->CandidatesAllocationDone()) {
+- OnCandidatesAllocationDone(raw_session);
++ if (allocator_sessions_.back()->CandidatesAllocationDone()) {
++ OnCandidatesAllocationDone(raw_pooled_session);
+ }
+ } else {
+ AddAllocatorSession(allocator_->CreateSession(
+diff --git a/p2p/base/p2p_transport_channel.h b/p2p/base/p2p_transport_channel.h
+index 8ce03f60f4..7f087ba22d 100644
+--- a/p2p/base/p2p_transport_channel.h
++++ b/p2p/base/p2p_transport_channel.h
+@@ -443,9 +443,9 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal,
+ void GoogDeltaAckReceived(RTCErrorOr<const StunUInt64Attribute*>);
+
+ const Environment env_;
+- const std::string transport_name_ RTC_GUARDED_BY(network_thread_);
++ std::string transport_name_ RTC_GUARDED_BY(network_thread_);
+ int component_ RTC_GUARDED_BY(network_thread_);
+- PortAllocator* const allocator_ RTC_GUARDED_BY(network_thread_);
++ PortAllocator* allocator_ RTC_GUARDED_BY(network_thread_);
+ AsyncDnsResolverFactoryInterface* const async_dns_resolver_factory_
+ RTC_GUARDED_BY(network_thread_);
+ const std::unique_ptr<AsyncDnsResolverFactoryInterface>
+diff --git a/p2p/base/port.cc b/p2p/base/port.cc
+index ea6b045a11..c7c1de2ef5 100644
+--- a/p2p/base/port.cc
++++ b/p2p/base/port.cc
+@@ -121,7 +121,6 @@ Port::Port(const PortParametersRef& args,
+ network_(args.network),
+ min_port_(min_port),
+ max_port_(max_port),
+- content_name_(args.content_name),
+ component_(ICE_CANDIDATE_COMPONENT_DEFAULT),
+ generation_(0),
+ ice_username_fragment_(args.ice_username_fragment),
+diff --git a/p2p/base/port.h b/p2p/base/port.h
+index 134d9eb854..1a237be898 100644
+--- a/p2p/base/port.h
++++ b/p2p/base/port.h
+@@ -169,7 +169,6 @@ class RTC_EXPORT Port : public PortInterface, public sigslot::has_slots<> {
+ const ::webrtc::Network* network;
+ absl::string_view ice_username_fragment;
+ absl::string_view ice_password;
+- absl::string_view content_name;
+ LocalNetworkAccessPermissionFactoryInterface* lna_permission_factory =
+ nullptr;
+ };
+diff --git a/p2p/base/port_allocator.cc b/p2p/base/port_allocator.cc
+index cd7bd076ce..ba95687415 100644
+--- a/p2p/base/port_allocator.cc
++++ b/p2p/base/port_allocator.cc
+@@ -241,7 +241,6 @@ std::unique_ptr<PortAllocatorSession> PortAllocator::TakePooledSession(
+ auto it =
+ pooled_sessions_.begin() + std::distance(pooled_sessions_.cbegin(), cit);
+ std::unique_ptr<PortAllocatorSession> ret = std::move(*it);
+- RTC_DCHECK(ret->pooled());
+ ret->SetIceParameters(content_name, component, ice_ufrag, ice_pwd);
+ ret->set_pooled(false);
+ // According to JSEP, a pooled session should filter candidates only
+@@ -257,8 +256,9 @@ const PortAllocatorSession* PortAllocator::GetPooledSession(
+ auto it = FindPooledSession(ice_credentials);
+ if (it == pooled_sessions_.end()) {
+ return nullptr;
++ } else {
++ return it->get();
+ }
+- return it->get();
+ }
+
+ std::vector<std::unique_ptr<PortAllocatorSession>>::const_iterator
+diff --git a/p2p/base/port_allocator.h b/p2p/base/port_allocator.h
+index 643fb7b656..87490f2652 100644
+--- a/p2p/base/port_allocator.h
++++ b/p2p/base/port_allocator.h
+@@ -303,9 +303,6 @@ class RTC_EXPORT PortAllocatorSession : public sigslot::has_slots<> {
+ int component,
+ absl::string_view ice_ufrag,
+ absl::string_view ice_pwd) {
+- RTC_DCHECK(pooled_);
+- RTC_DCHECK(!content_name.empty());
+- RTC_DCHECK(content_name_.empty());
+ content_name_ = std::string(content_name);
+ component_ = component;
+ ice_ufrag_ = std::string(ice_ufrag);
+@@ -313,12 +310,7 @@ class RTC_EXPORT PortAllocatorSession : public sigslot::has_slots<> {
+ UpdateIceParametersInternal();
+ }
+
+- void set_pooled(bool value) {
+- pooled_ = value;
+- if (pooled_) {
+- content_name_.clear();
+- }
+- }
++ void set_pooled(bool value) { pooled_ = value; }
+
+ uint32_t flags_;
+ uint32_t generation_;
+diff --git a/p2p/base/port_allocator_unittest.cc b/p2p/base/port_allocator_unittest.cc
+index d7272baa0e..8bc61dadd8 100644
+--- a/p2p/base/port_allocator_unittest.cc
++++ b/p2p/base/port_allocator_unittest.cc
+@@ -239,7 +239,6 @@ TEST_F(PortAllocatorTest, TakePooledSessionUpdatesIceParameters) {
+ static_cast<webrtc::FakePortAllocatorSession*>(
+ allocator_->TakePooledSession(kContentName, 1, kIceUfrag, kIcePwd)
+ .release()));
+- EXPECT_FALSE(session->pooled());
+ EXPECT_EQ(1, session->transport_info_update_count());
+ EXPECT_EQ(kContentName, session->content_name());
+ EXPECT_EQ(1, session->component());
+diff --git a/p2p/base/turn_port.h b/p2p/base/turn_port.h
+index 0674a5a320..c74feae432 100644
+--- a/p2p/base/turn_port.h
++++ b/p2p/base/turn_port.h
+@@ -93,7 +93,6 @@ class TurnPort : public Port {
+ .network = args.network,
+ .ice_username_fragment = args.username,
+ .ice_password = args.password,
+- .content_name = args.content_name,
+ .lna_permission_factory = args.lna_permission_factory},
+ socket, *args.server_address, args.config->credentials,
+ args.relative_priority, args.config->tls_alpn_protocols,
+@@ -117,7 +116,6 @@ class TurnPort : public Port {
+ .network = args.network,
+ .ice_username_fragment = args.username,
+ .ice_password = args.password,
+- .content_name = args.content_name,
+ .lna_permission_factory = args.lna_permission_factory},
+ min_port, max_port, *args.server_address, args.config->credentials,
+ args.relative_priority, args.config->tls_alpn_protocols,
+diff --git a/p2p/client/basic_port_allocator.cc b/p2p/client/basic_port_allocator.cc
+index e288c7122d..ee4762815e 100644
+--- a/p2p/client/basic_port_allocator.cc
++++ b/p2p/client/basic_port_allocator.cc
+@@ -567,7 +567,6 @@ bool BasicPortAllocatorSession::CandidatesAllocationDone() const {
+
+ void BasicPortAllocatorSession::UpdateIceParametersInternal() {
+ RTC_DCHECK_RUN_ON(network_thread_);
+- RTC_DCHECK(pooled());
+ for (PortData& port : ports_) {
+ port.port()->set_content_name(content_name());
+ port.port()->SetIceParameters(component(), ice_ufrag(), ice_pwd());
+@@ -908,15 +907,18 @@ void BasicPortAllocatorSession::DisableEquivalentPhases(
+ void BasicPortAllocatorSession::AddAllocatedPort(Port* port,
+ AllocationSequence* seq) {
+ RTC_DCHECK_RUN_ON(network_thread_);
+- RTC_DCHECK_EQ(port->content_name(), content_name());
++ if (!port)
++ return;
+
+ RTC_LOG(LS_INFO) << "Adding allocated port for " << content_name();
++ port->set_content_name(content_name());
+ port->set_component(component());
+ port->set_generation(generation());
+ port->set_send_retransmit_count_attribute(
+ (flags() & PORTALLOCATOR_ENABLE_STUN_RETRANSMIT_ATTRIBUTE) != 0);
+
+- ports_.emplace_back(port, seq);
++ PortData data(port, seq);
++ ports_.push_back(data);
+
+ port->SubscribeCandidateReadyCallback(
+ [this](Port* port, const Candidate& c) { OnCandidateReady(port, c); });
+@@ -1451,7 +1453,6 @@ void AllocationSequence::CreateUDPPorts() {
+ .network = network_,
+ .ice_username_fragment = session_->username(),
+ .ice_password = session_->password(),
+- .content_name = session_->content_name(),
+ .lna_permission_factory =
+ session_->allocator()->lna_permission_factory()},
+ udp_socket_.get(), emit_local_candidate_for_anyaddress,
+@@ -1464,7 +1465,6 @@ void AllocationSequence::CreateUDPPorts() {
+ .network = network_,
+ .ice_username_fragment = session_->username(),
+ .ice_password = session_->password(),
+- .content_name = session_->content_name(),
+ .lna_permission_factory =
+ session_->allocator()->lna_permission_factory()},
+ session_->allocator()->min_port(), session_->allocator()->max_port(),
+@@ -1478,6 +1478,9 @@ void AllocationSequence::CreateUDPPorts() {
+ // UDPPort.
+ if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET)) {
+ udp_port_ = port.get();
++ port->SubscribePortDestroyed(
++ [this](PortInterface* port) { OnPortDestroyed(port); });
++
+ // If STUN is not disabled, setting stun server address to port.
+ if (!IsFlagSet(PORTALLOCATOR_DISABLE_STUN)) {
+ if (config_ && !config_->StunServers().empty()) {
+@@ -1500,15 +1503,12 @@ void AllocationSequence::CreateTCPPorts() {
+ }
+
+ std::unique_ptr<Port> port = TCPPort::Create(
+- {
+- .env = session_->allocator()->env(),
+- .network_thread = session_->network_thread(),
+- .socket_factory = session_->socket_factory(),
+- .network = network_,
+- .ice_username_fragment = session_->username(),
+- .ice_password = session_->password(),
+- .content_name = session_->content_name(),
+- },
++ {.env = session_->allocator()->env(),
++ .network_thread = session_->network_thread(),
++ .socket_factory = session_->socket_factory(),
++ .network = network_,
++ .ice_username_fragment = session_->username(),
++ .ice_password = session_->password()},
+ session_->allocator()->min_port(), session_->allocator()->max_port(),
+ session_->allocator()->allow_tcp_listen());
+ if (port) {
+@@ -1542,7 +1542,6 @@ void AllocationSequence::CreateStunPorts() {
+ .network = network_,
+ .ice_username_fragment = session_->username(),
+ .ice_password = session_->password(),
+- .content_name = session_->content_name(),
+ .lna_permission_factory =
+ session_->allocator()->lna_permission_factory()},
+ session_->allocator()->min_port(), session_->allocator()->max_port(),
+@@ -1612,7 +1611,6 @@ void AllocationSequence::CreateTurnPort(const RelayServerConfig& config,
+ args.network = network_;
+ args.username = session_->username();
+ args.password = session_->password();
+- args.content_name = session_->content_name();
+ args.server_address = &(*relay_port);
+ args.config = &config;
+ args.turn_customizer = session_->allocator()->turn_customizer();
+@@ -1637,6 +1635,11 @@ void AllocationSequence::CreateTurnPort(const RelayServerConfig& config,
+ }
+
+ relay_ports_.push_back(port.get());
++ // Listen to the port destroyed signal, to allow AllocationSequence to
++ // remove the entry from it's map.
++ port->SubscribePortDestroyed(
++ [this](PortInterface* port) { OnPortDestroyed(port); });
++
+ } else {
+ port = session_->allocator()->relay_port_factory()->Create(
+ args, session_->allocator()->min_port(),
+diff --git a/p2p/client/basic_port_allocator.h b/p2p/client/basic_port_allocator.h
+index f2242a7236..ced785f66a 100644
+--- a/p2p/client/basic_port_allocator.h
++++ b/p2p/client/basic_port_allocator.h
+@@ -201,13 +201,10 @@ class RTC_EXPORT BasicPortAllocatorSession : public PortAllocatorSession {
+ // interface. Only TURN ports may be pruned.
+ };
+
+- PortData() = delete;
+- PortData(PortData&&) = default;
++ PortData() {}
+ PortData(Port* port, AllocationSequence* seq)
+ : port_(port), sequence_(seq) {}
+
+- PortData& operator=(PortData&&) = default;
+-
+ Port* port() const { return port_; }
+ AllocationSequence* sequence() const { return sequence_; }
+ bool has_pairable_candidate() const { return has_pairable_candidate_; }
+diff --git a/p2p/client/relay_port_factory_interface.h b/p2p/client/relay_port_factory_interface.h
+index 2bcb2e0f55..63b7c8bd77 100644
+--- a/p2p/client/relay_port_factory_interface.h
++++ b/p2p/client/relay_port_factory_interface.h
+@@ -40,7 +40,6 @@ struct CreateRelayPortArgs {
+ const RelayServerConfig* config;
+ std::string username;
+ std::string password;
+- std::string content_name;
+ TurnCustomizer* turn_customizer = nullptr;
+ // Relative priority of candidates from this TURN server in relation
+ // to the candidates from other servers. Required because ICE priorities
diff --git a/third_party/libwebrtc/moz-patch-stack/p0002.patch b/third_party/libwebrtc/moz-patch-stack/p0002.patch
@@ -0,0 +1,61 @@
+From: =?UTF-8?q?Henrik=20Bostr=C3=B6m?= <hbos@webrtc.org>
+Date: Wed, 10 Sep 2025 12:47:04 +0200
+Subject: (cherry-pick-branch-heads/7390) [M141] Do not hide inbound-rtp if
+ media is received.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This condition neglected the fact that if Insertable Streams API is used
+we can have frames or samples despite packets never being received.
+
+This CL fixes this unintended regression.
+
+# Ignore unrelated compile issues on ios webrtc bots
+NOTRY=True
+
+(cherry picked from commit c15949eda5a00122e2f3b5a643e15781049b9927)
+
+Bug: chromium:444048024, chromium:444384230
+Change-Id: Ie6e17a3bc96701476787f5898446f3f706715d15
+Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/408884
+Commit-Queue: Guido Urdaneta <guidou@webrtc.org>
+Reviewed-by: Guido Urdaneta <guidou@webrtc.org>
+Auto-Submit: Henrik Boström <hbos@webrtc.org>
+Commit-Queue: Henrik Boström <hbos@webrtc.org>
+Cr-Original-Commit-Position: refs/heads/main@{#45616}
+Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/409020
+Cr-Commit-Position: refs/branch-heads/7390@{#2}
+Cr-Branched-From: 2f553bf8d573c90176d51559b76dfc836996c8f5-refs/heads/main@{#45520}
+---
+ pc/rtc_stats_collector.cc | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/pc/rtc_stats_collector.cc b/pc/rtc_stats_collector.cc
+index 8686143e68..8d6cc22426 100644
+--- a/pc/rtc_stats_collector.cc
++++ b/pc/rtc_stats_collector.cc
+@@ -1754,7 +1754,10 @@ void RTCStatsCollector::ProduceAudioRTPStreamStats_n(
+ if (!voice_receiver_info.connected()) {
+ continue; // The SSRC is not known yet.
+ }
+- if (spec_lifetime && voice_receiver_info.packets_received == 0) {
++ // Check both packets received and samples received to handle the Insertable
++ // Streams use case of receiving media without receiving packets.
++ if (spec_lifetime && voice_receiver_info.packets_received == 0 &&
++ voice_receiver_info.total_samples_received == 0) {
+ // The SSRC is known despite not receiving any packets. This happens if
+ // SSRC is signalled in the SDP which we should not rely on for getStats.
+ continue;
+@@ -1868,7 +1871,10 @@ void RTCStatsCollector::ProduceVideoRTPStreamStats_n(
+ if (!video_receiver_info.connected()) {
+ continue; // The SSRC is not known yet.
+ }
+- if (spec_lifetime && video_receiver_info.packets_received == 0) {
++ // Check both packets received and frames received to handle the Insertable
++ // Streams use case of receiving media without receiving packets.
++ if (spec_lifetime && video_receiver_info.packets_received == 0 &&
++ video_receiver_info.frames_received == 0) {
+ // The SSRC is known despite not receiving any packets. This happens if
+ // SSRC is signalled in the SDP which we should not rely on for getStats.
+ continue;
diff --git a/third_party/libwebrtc/moz-patch-stack/p0003.patch b/third_party/libwebrtc/moz-patch-stack/p0003.patch
@@ -0,0 +1,331 @@
+From: Palak Agarwal <agpalak@google.com>
+Date: Tue, 7 Oct 2025 13:45:52 +0200
+Subject: (cherry-pick-branch-heads/7390) [M141] Add logging while creating
+ {Window|Screen}Capturer
+
+(cherry picked from commit 6908505ae0eba5d530ad0bb4b37d4654a4f36c95)
+
+Fixed: chromium:450184498
+Bug: chromium:448881311
+Change-Id: I0f043f58bf831e6822451cac99a8972a054ffdf7
+Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/414800
+Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
+Reviewed-by: Harald Alvestrand <hta@webrtc.org>
+Commit-Queue: Palak Agarwal <agpalak@google.com>
+Cr-Original-Commit-Position: refs/heads/main@{#45856}
+Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/415420
+Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
+Cr-Commit-Position: refs/branch-heads/7390@{#3}
+Cr-Branched-From: 2f553bf8d573c90176d51559b76dfc836996c8f5-refs/heads/main@{#45520}
+---
+ modules/desktop_capture/desktop_capturer.cc | 15 +++++++++++++++
+ .../linux/x11/screen_capturer_x11.cc | 6 ++++++
+ .../linux/x11/window_capturer_x11.cc | 4 ++++
+ modules/desktop_capture/screen_capturer_darwin.mm | 7 +++++++
+ .../desktop_capture/screen_capturer_fuchsia.cc | 3 +++
+ modules/desktop_capture/screen_capturer_linux.cc | 4 ++++
+ modules/desktop_capture/screen_capturer_null.cc | 4 ++++
+ modules/desktop_capture/screen_capturer_win.cc | 6 ++++++
+ modules/desktop_capture/window_capturer_linux.cc | 4 ++++
+ modules/desktop_capture/window_capturer_mac.mm | 2 ++
+ modules/desktop_capture/window_capturer_null.cc | 3 +++
+ modules/desktop_capture/window_capturer_win.cc | 7 +++++++
+ 12 files changed, 65 insertions(+)
+
+diff --git a/modules/desktop_capture/desktop_capturer.cc b/modules/desktop_capture/desktop_capturer.cc
+index ae9aba26ee..bf63f73178 100644
+--- a/modules/desktop_capture/desktop_capturer.cc
++++ b/modules/desktop_capture/desktop_capturer.cc
+@@ -21,6 +21,7 @@
+ #include "modules/desktop_capture/desktop_capturer_differ_wrapper.h"
+ #include "modules/desktop_capture/desktop_geometry.h"
+ #include "modules/desktop_capture/shared_memory.h"
++#include "rtc_base/logging.h"
+ #include "system_wrappers/include/metrics.h"
+
+ #if defined(WEBRTC_WIN)
+@@ -81,18 +82,26 @@ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateWindowCapturer(
+ #if defined(RTC_ENABLE_WIN_WGC)
+ if (options.allow_wgc_window_capturer() &&
+ IsWgcSupported(CaptureType::kWindow)) {
++ RTC_LOG(LS_INFO) << "video capture: DesktopCapturer::CreateWindowCapturer "
++ "creates DesktopCapturer of type WgcCapturerWin";
+ return WgcCapturerWin::CreateRawWindowCapturer(options);
+ }
+ #endif // defined(RTC_ENABLE_WIN_WGC)
+
+ #if defined(WEBRTC_WIN)
+ if (options.allow_cropping_window_capturer()) {
++ RTC_LOG(LS_INFO)
++ << "video capture: DesktopCapturer::CreateWindowCapturer "
++ "creates DesktopCapturer of type CroppingWindowCapturerWin";
+ return CroppingWindowCapturer::CreateCapturer(options);
+ }
+ #endif // defined(WEBRTC_WIN)
+
+ std::unique_ptr<DesktopCapturer> capturer = CreateRawWindowCapturer(options);
+ if (capturer && options.detect_updated_region()) {
++ RTC_LOG(LS_INFO) << "video capture: DesktopCapturer::CreateWindowCapturer "
++ "creates DesktopCapturer of type "
++ "DesktopCapturerDifferWrapper over a base capturer";
+ capturer.reset(new DesktopCapturerDifferWrapper(std::move(capturer)));
+ }
+
+@@ -105,12 +114,18 @@ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateScreenCapturer(
+ #if defined(RTC_ENABLE_WIN_WGC)
+ if (options.allow_wgc_screen_capturer() &&
+ IsWgcSupported(CaptureType::kScreen)) {
++ RTC_LOG(LS_INFO) << "video capture: DesktopCapturer::CreateScreenCapturer "
++ "creates DesktopCapturer of type WgcCapturerWin";
+ return WgcCapturerWin::CreateRawScreenCapturer(options);
+ }
+ #endif // defined(RTC_ENABLE_WIN_WGC)
+
+ std::unique_ptr<DesktopCapturer> capturer = CreateRawScreenCapturer(options);
+ if (capturer && options.detect_updated_region()) {
++ RTC_LOG(LS_INFO)
++ << "video capture: DesktopCapturer::CreateScreenCapturer creates "
++ "DesktopCapturer of type DesktopCapturerDifferWrapper over a base "
++ "capturer";
+ capturer.reset(new DesktopCapturerDifferWrapper(std::move(capturer)));
+ }
+
+diff --git a/modules/desktop_capture/linux/x11/screen_capturer_x11.cc b/modules/desktop_capture/linux/x11/screen_capturer_x11.cc
+index 90dd797cb3..f10dcabc7e 100644
+--- a/modules/desktop_capture/linux/x11/screen_capturer_x11.cc
++++ b/modules/desktop_capture/linux/x11/screen_capturer_x11.cc
+@@ -511,8 +511,14 @@ std::unique_ptr<DesktopCapturer> ScreenCapturerX11::CreateRawScreenCapturer(
+ if (!options.x_display())
+ return nullptr;
+
++ RTC_LOG(LS_INFO)
++ << "video capture: ScreenCapturerX11::CreateRawScreenCapturer creates "
++ "DesktopCapturer of type ScreenCapturerX11";
+ std::unique_ptr<ScreenCapturerX11> capturer(new ScreenCapturerX11());
+ if (!capturer->Init(options)) {
++ RTC_LOG(LS_INFO)
++ << "video capture: ScreenCapturerX11::CreateRawScreenCapturer "
++ "DesktopCapturer is null because it can not be initiated";
+ return nullptr;
+ }
+
+diff --git a/modules/desktop_capture/linux/x11/window_capturer_x11.cc b/modules/desktop_capture/linux/x11/window_capturer_x11.cc
+index 8e592ff2d9..9505205b76 100644
+--- a/modules/desktop_capture/linux/x11/window_capturer_x11.cc
++++ b/modules/desktop_capture/linux/x11/window_capturer_x11.cc
+@@ -247,6 +247,10 @@ std::unique_ptr<DesktopCapturer> WindowCapturerX11::CreateRawWindowCapturer(
+ const DesktopCaptureOptions& options) {
+ if (!options.x_display())
+ return nullptr;
++
++ RTC_LOG(LS_INFO)
++ << "video capture: WindowCapturerX11::CreateRawWindowCapturer creates "
++ "DesktopCapturer of type WindowCapturerX11";
+ return std::unique_ptr<DesktopCapturer>(new WindowCapturerX11(options));
+ }
+
+diff --git a/modules/desktop_capture/screen_capturer_darwin.mm b/modules/desktop_capture/screen_capturer_darwin.mm
+index 95a877c45d..3f14ddfe58 100644
+--- a/modules/desktop_capture/screen_capturer_darwin.mm
++++ b/modules/desktop_capture/screen_capturer_darwin.mm
+@@ -12,6 +12,7 @@
+
+ #include "modules/desktop_capture/mac/screen_capturer_mac.h"
+ #include "modules/desktop_capture/mac/screen_capturer_sck.h"
++#include "rtc_base/logging.h"
+
+ namespace webrtc {
+
+@@ -27,10 +28,16 @@ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawScreenCapturer(
+ std::unique_ptr<DesktopCapturer> sck_capturer =
+ CreateScreenCapturerSck(options);
+ if (sck_capturer) {
++ RTC_LOG(LS_INFO)
++ << "video capture: DesktopCapturer::CreateRawScreenCapturer creates "
++ "DesktopCapturer of type ScreenCapturerSck";
+ return sck_capturer;
+ }
+ }
+
++ RTC_LOG(LS_INFO)
++ << "video capture: DesktopCapturer::CreateRawScreenCapturer creates "
++ "DesktopCapturer of type ScreenCapturerMac";
+ auto capturer =
+ std::make_unique<ScreenCapturerMac>(options.configuration_monitor(),
+ options.detect_updated_region(),
+diff --git a/modules/desktop_capture/screen_capturer_fuchsia.cc b/modules/desktop_capture/screen_capturer_fuchsia.cc
+index c3f51ef0fc..2a6c5e753d 100644
+--- a/modules/desktop_capture/screen_capturer_fuchsia.cc
++++ b/modules/desktop_capture/screen_capturer_fuchsia.cc
+@@ -56,6 +56,9 @@ size_t RoundUpToMultiple(size_t value, size_t multiple) {
+
+ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawScreenCapturer(
+ const DesktopCaptureOptions& options) {
++ RTC_LOG(LS_INFO)
++ << "video capture: DesktopCapturer::CreateRawScreenCapturer creates "
++ "DesktopCapturer of type ScreenCapturerFuchsia";
+ std::unique_ptr<ScreenCapturerFuchsia> capturer(new ScreenCapturerFuchsia());
+ return capturer;
+ }
+diff --git a/modules/desktop_capture/screen_capturer_linux.cc b/modules/desktop_capture/screen_capturer_linux.cc
+index 94726750c5..f25e08fb59 100644
+--- a/modules/desktop_capture/screen_capturer_linux.cc
++++ b/modules/desktop_capture/screen_capturer_linux.cc
+@@ -13,6 +13,7 @@
+ #include "modules/desktop_capture/desktop_capture_options.h"
+ #include "modules/desktop_capture/desktop_capture_types.h"
+ #include "modules/desktop_capture/desktop_capturer.h"
++#include "rtc_base/logging.h"
+
+ #if defined(WEBRTC_USE_PIPEWIRE)
+ #include "modules/desktop_capture/linux/wayland/base_capturer_pipewire.h"
+@@ -29,6 +30,9 @@ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawScreenCapturer(
+ const DesktopCaptureOptions& options) {
+ #if defined(WEBRTC_USE_PIPEWIRE)
+ if (options.allow_pipewire() && BaseCapturerPipeWire::IsSupported()) {
++ RTC_LOG(LS_INFO)
++ << "video capture: DesktopCapturer::CreateRawScreenCapturer creates "
++ "DesktopCapturer of type BaseCapturerPipeWire";
+ return std::make_unique<BaseCapturerPipeWire>(options,
+ CaptureType::kScreen);
+ }
+diff --git a/modules/desktop_capture/screen_capturer_null.cc b/modules/desktop_capture/screen_capturer_null.cc
+index aa6d4991a0..21b2f46c4d 100644
+--- a/modules/desktop_capture/screen_capturer_null.cc
++++ b/modules/desktop_capture/screen_capturer_null.cc
+@@ -11,12 +11,16 @@
+ #include <memory>
+
+ #include "modules/desktop_capture/desktop_capturer.h"
++#include "rtc_base/logging.h"
+
+ namespace webrtc {
+
+ // static
+ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawScreenCapturer(
+ const DesktopCaptureOptions& options) {
++ RTC_LOG(LS_INFO)
++ << "video capture: DesktopCapturer::CreateRawScreenCapturer creates null "
++ "DesktopCapturer";
+ return nullptr;
+ }
+
+diff --git a/modules/desktop_capture/screen_capturer_win.cc b/modules/desktop_capture/screen_capturer_win.cc
+index a5f2052979..6620888f18 100644
+--- a/modules/desktop_capture/screen_capturer_win.cc
++++ b/modules/desktop_capture/screen_capturer_win.cc
+@@ -19,6 +19,7 @@
+ #include "modules/desktop_capture/win/dxgi_duplicator_controller.h"
+ #include "modules/desktop_capture/win/screen_capturer_win_directx.h"
+ #include "modules/desktop_capture/win/screen_capturer_win_gdi.h"
++#include "rtc_base/logging.h"
+
+ namespace webrtc {
+
+@@ -26,6 +27,9 @@ namespace {
+
+ std::unique_ptr<DesktopCapturer> CreateScreenCapturerWinDirectx(
+ const DesktopCaptureOptions& options) {
++ RTC_LOG(LS_INFO)
++ << "video capture: DesktopCapturer::CreateRawScreenCapturer creates "
++ "DesktopCapturer of type ScreenCapturerWinDirectx";
+ std::unique_ptr<DesktopCapturer> capturer(
+ new ScreenCapturerWinDirectx(options));
+ capturer.reset(new BlankDetectorDesktopCapturerWrapper(
+@@ -39,6 +43,8 @@ std::unique_ptr<DesktopCapturer> CreateScreenCapturerWinDirectx(
+ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawScreenCapturer(
+ const DesktopCaptureOptions& options) {
+ // Default capturer if no options are enabled is GDI.
++ RTC_LOG(LS_INFO) << "video capture: DesktopCapturer::CreateRawScreenCapturer "
++ "creates DesktopCapturer of type ScreenCapturerWinGdi";
+ std::unique_ptr<DesktopCapturer> capturer(new ScreenCapturerWinGdi(options));
+
+ // If DirectX is enabled use it as main capturer with GDI as fallback.
+diff --git a/modules/desktop_capture/window_capturer_linux.cc b/modules/desktop_capture/window_capturer_linux.cc
+index f621a63e72..87ea3d5721 100644
+--- a/modules/desktop_capture/window_capturer_linux.cc
++++ b/modules/desktop_capture/window_capturer_linux.cc
+@@ -13,6 +13,7 @@
+ #include "modules/desktop_capture/desktop_capture_options.h"
+ #include "modules/desktop_capture/desktop_capture_types.h"
+ #include "modules/desktop_capture/desktop_capturer.h"
++#include "rtc_base/logging.h"
+
+ #if defined(WEBRTC_USE_PIPEWIRE)
+ #include "modules/desktop_capture/linux/wayland/base_capturer_pipewire.h"
+@@ -29,6 +30,9 @@ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawWindowCapturer(
+ const DesktopCaptureOptions& options) {
+ #if defined(WEBRTC_USE_PIPEWIRE)
+ if (options.allow_pipewire() && BaseCapturerPipeWire::IsSupported()) {
++ RTC_LOG(LS_INFO)
++ << "video capture: DesktopCapturer::CreateRawWindowCapturer creates "
++ "DesktopCapturer of type BaseCapturerPipeWire";
+ return std::make_unique<BaseCapturerPipeWire>(options,
+ CaptureType::kWindow);
+ }
+diff --git a/modules/desktop_capture/window_capturer_mac.mm b/modules/desktop_capture/window_capturer_mac.mm
+index a1e6157b87..731090d3fb 100644
+--- a/modules/desktop_capture/window_capturer_mac.mm
++++ b/modules/desktop_capture/window_capturer_mac.mm
+@@ -217,6 +217,8 @@ void WindowCapturerMac::CaptureFrame() {
+ // static
+ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawWindowCapturer(
+ const DesktopCaptureOptions& options) {
++ RTC_LOG(LS_INFO) << "video capture: DesktopCapturer::CreateRawWindowCapturer "
++ "creates DesktopCapturer of type WindowCapturerMac";
+ return std::unique_ptr<DesktopCapturer>(new WindowCapturerMac(
+ options.full_screen_window_detector(), options.configuration_monitor()));
+ }
+diff --git a/modules/desktop_capture/window_capturer_null.cc b/modules/desktop_capture/window_capturer_null.cc
+index 2061dc5248..384e186d20 100644
+--- a/modules/desktop_capture/window_capturer_null.cc
++++ b/modules/desktop_capture/window_capturer_null.cc
+@@ -12,6 +12,7 @@
+
+ #include "modules/desktop_capture/desktop_capturer.h"
+ #include "rtc_base/checks.h"
++#include "rtc_base/logging.h"
+
+ namespace webrtc {
+
+@@ -65,6 +66,8 @@ void WindowCapturerNull::CaptureFrame() {
+ // static
+ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawWindowCapturer(
+ const DesktopCaptureOptions& options) {
++ RTC_LOG(LS_INFO) << "video capture: DesktopCapturer::CreateRawWindowCapturer "
++ "creates DesktopCapturer of type WindowCapturerNull";
+ return std::unique_ptr<DesktopCapturer>(new WindowCapturerNull());
+ }
+
+diff --git a/modules/desktop_capture/window_capturer_win.cc b/modules/desktop_capture/window_capturer_win.cc
+index 115bc7d9b0..15ed7f5121 100644
+--- a/modules/desktop_capture/window_capturer_win.cc
++++ b/modules/desktop_capture/window_capturer_win.cc
+@@ -15,6 +15,7 @@
+ #include "modules/desktop_capture/desktop_capturer.h"
+ #include "modules/desktop_capture/rgba_color.h"
+ #include "modules/desktop_capture/win/window_capturer_win_gdi.h"
++#include "rtc_base/logging.h"
+
+ #if defined(RTC_ENABLE_WIN_WGC)
+ #include "modules/desktop_capture/blank_detector_desktop_capturer_wrapper.h"
+@@ -28,6 +29,8 @@ namespace webrtc {
+ // static
+ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawWindowCapturer(
+ const DesktopCaptureOptions& options) {
++ RTC_LOG(LS_INFO) << "video capture: DesktopCapturer::CreateRawWindowCapturer "
++ "creates DesktopCapturer of type WindowCapturerWinGdi";
+ std::unique_ptr<DesktopCapturer> capturer(
+ WindowCapturerWinGdi::CreateRawWindowCapturer(options));
+ #if defined(RTC_ENABLE_WIN_WGC)
+@@ -36,6 +39,10 @@ std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawWindowCapturer(
+ // BlankDectector capturer will send an error when it detects a failed
+ // GDI rendering, then Fallback capturer will try to capture it again with
+ // WGC.
++ RTC_LOG(LS_INFO)
++ << "video capture: DesktopCapturer::CreateRawWindowCapturer creates "
++ "DesktopCapturer of type FallbackDesktopCapturerWrapper which has a "
++ "fallback capturer of type WgcCapturerWin";
+ capturer = std::make_unique<BlankDetectorDesktopCapturerWrapper>(
+ std::move(capturer), RgbaColor(0, 0, 0, 0),
+ /*check_per_capture*/ true);