[getStats] Reduce blocking thread-invokes from 2 to 1.

pc_->GetCallStats() does a blocking-invoke if not already on the worker
thread. By moving this call into one of the lambdas that is already
executing on the worker thread, we can "piggy-back" on it and reduce
the number of blocking-invokes by one.

No change in behavior is intended with this CL, other than performance
improvements.

Bug: webrtc:11767
Change-Id: I04eaf990be946720353adca82e87b739ec6614f2
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/193060
Reviewed-by: Philipp Hancke <philipp.hancke@googlemail.com>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32602}
diff --git a/pc/rtc_stats_collector.cc b/pc/rtc_stats_collector.cc
index 5b21d33..aaeb721 100644
--- a/pc/rtc_stats_collector.cc
+++ b/pc/rtc_stats_collector.cc
@@ -1074,24 +1074,14 @@
     num_pending_partial_reports_ = 2;
     partial_report_timestamp_us_ = cache_now_us;
 
-    // Prepare |transceiver_stats_infos_| for use in
+    // Prepare |transceiver_stats_infos_| and |call_stats_| for use in
     // |ProducePartialResultsOnNetworkThread| and
     // |ProducePartialResultsOnSignalingThread|.
-    transceiver_stats_infos_ = PrepareTransceiverStatsInfos_s_w();
+    PrepareTransceiverStatsInfosAndCallStats_s_w();
     // Prepare |transport_names_| for use in
     // |ProducePartialResultsOnNetworkThread|.
     transport_names_ = PrepareTransportNames_s();
 
-    // Prepare |call_stats_| here since GetCallStats() will hop to the worker
-    // thread.
-    // TODO(holmer): To avoid the hop we could move BWE and BWE stats to the
-    // network thread, where it more naturally belongs.
-    // TODO(https://crbug.com/webrtc/11767): In the meantime we can piggyback on
-    // the blocking-invoke that is already performed in
-    // PrepareTransceiverStatsInfos_s_w() so that we can call GetCallStats()
-    // without additional blocking-invokes.
-    call_stats_ = pc_->GetCallStats();
-
     // Don't touch |network_report_| on the signaling thread until
     // ProducePartialResultsOnNetworkThread() has signaled the
     // |network_report_event_|.
@@ -1898,11 +1888,10 @@
   return transport_cert_stats;
 }
 
-std::vector<RTCStatsCollector::RtpTransceiverStatsInfo>
-RTCStatsCollector::PrepareTransceiverStatsInfos_s_w() const {
+void RTCStatsCollector::PrepareTransceiverStatsInfosAndCallStats_s_w() {
   RTC_DCHECK(signaling_thread_->IsCurrent());
 
-  std::vector<RtpTransceiverStatsInfo> transceiver_stats_infos;
+  transceiver_stats_infos_.clear();
   // These are used to invoke GetStats for all the media channels together in
   // one worker thread hop.
   std::map<cricket::VoiceMediaChannel*,
@@ -1920,8 +1909,8 @@
 
       // Prepare stats entry. The TrackMediaInfoMap will be filled in after the
       // stats have been fetched on the worker thread.
-      transceiver_stats_infos.emplace_back();
-      RtpTransceiverStatsInfo& stats = transceiver_stats_infos.back();
+      transceiver_stats_infos_.emplace_back();
+      RtpTransceiverStatsInfo& stats = transceiver_stats_infos_.back();
       stats.transceiver = transceiver->internal();
       stats.media_type = media_type;
 
@@ -1952,9 +1941,10 @@
     }
   }
 
-  // We jump to the worker thread and call GetStats() on each media channel. At
-  // the same time we construct the TrackMediaInfoMaps, which also needs info
-  // from the worker thread. This minimizes the number of thread jumps.
+  // We jump to the worker thread and call GetStats() on each media channel as
+  // well as GetCallStats(). At the same time we construct the
+  // TrackMediaInfoMaps, which also needs info from the worker thread. This
+  // minimizes the number of thread jumps.
   worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
     rtc::Thread::ScopedDisallowBlockingCalls no_blocking_calls;
 
@@ -1971,7 +1961,7 @@
     }
 
     // Create the TrackMediaInfoMap for each transceiver stats object.
-    for (auto& stats : transceiver_stats_infos) {
+    for (auto& stats : transceiver_stats_infos_) {
       auto transceiver = stats.transceiver;
       std::unique_ptr<cricket::VoiceMediaInfo> voice_media_info;
       std::unique_ptr<cricket::VideoMediaInfo> video_media_info;
@@ -2003,9 +1993,9 @@
           std::move(voice_media_info), std::move(video_media_info), senders,
           receivers);
     }
-  });
 
-  return transceiver_stats_infos;
+    call_stats_ = pc_->GetCallStats();
+  });
 }
 
 std::set<std::string> RTCStatsCollector::PrepareTransportNames_s() const {