Refactor PeerConnection transceiver teardown to use batching

Replaced blocking StopInternal calls with batched tasks on worker
thread. This reduces blocking calls in Close by approx 50% when running
the RenegotiateManyVideoTransceiversAndWatchAudioDelay test.

Bug: webrtc:42222804
Change-Id: I931ab727826a3f8ac9f95b23c949e0684b76cb1e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/461700
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#47346}
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
index cbc6b6d..b634e67 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -1924,10 +1924,14 @@
 
   NoteUsageEvent(UsageEvent::CLOSE_CALLED);
 
+  ScopedOperationsBatcher worker_tasks(worker_thread());
+
   if (ConfiguredForMedia()) {
-    for (const auto& transceiver : rtp_manager()->transceivers()->List()) {
-      if (!transceiver->stopped())
-        transceiver->StopInternal();
+    for (RtpTransceiver* transceiver :
+         rtp_manager()->transceivers()->ListInternal()) {
+      if (!transceiver->stopped()) {
+        worker_tasks.Add(transceiver->GetStopTransceiverProcedure());
+      }
     }
   }
 
@@ -1938,7 +1942,6 @@
   // worker thread (see `PushNewMediaChannelAndDeleteChannel`) and then
   // eventually freed on the signaling thread.
   // It would be good to combine those steps with the teardown steps here.
-  ScopedOperationsBatcher worker_tasks(worker_thread());
   {
     ScopedOperationsBatcher network_tasks(network_thread());
     sdp_handler_->GetMediaChannelTeardownTasks(network_tasks, worker_tasks);