Use total_decode_time_ms in VideoAnalyzer

Use the newly added total_decode_time_ms to get an accurate value
for the average decode time. The sparsely sampled decode_ms is
sensitive to the sampling instance.

Bug: chromium:980853
Change-Id: I9b63c8d1053fa95f74918807b83d1edb5cd726fb
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/147268
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Johannes Kron <kron@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28716}
diff --git a/video/video_analyzer.cc b/video/video_analyzer.cc
index fa18d00..b855753 100644
--- a/video/video_analyzer.cc
+++ b/video/video_analyzer.cc
@@ -82,6 +82,7 @@
       selected_stream_(selected_stream),
       selected_sl_(selected_sl),
       selected_tl_(selected_tl),
+      mean_decode_time_ms_(0.0),
       freeze_count_(0),
       total_freezes_duration_ms_(0),
       total_frames_duration_ms_(0),
@@ -509,6 +510,12 @@
 
   if (receive_stream_ != nullptr) {
     VideoReceiveStream::Stats receive_stats = receive_stream_->GetStats();
+    // |total_decode_time_ms| gives a good estimate of the mean decode time,
+    // |decode_ms| is used to keep track of the standard deviation.
+    if (receive_stats.frames_decoded > 0)
+      mean_decode_time_ms_ =
+          static_cast<double>(receive_stats.total_decode_time_ms) /
+          receive_stats.frames_decoded;
     if (receive_stats.decode_ms > 0)
       decode_time_ms_.AddSample(receive_stats.decode_ms);
     if (receive_stats.max_decode_ms > 0)
@@ -700,7 +707,8 @@
   }
 
   if (receive_stream_ != nullptr) {
-    PrintResult("decode_time", decode_time_ms_, " ms");
+    PrintResultWithExternalMean("decode_time", mean_decode_time_ms_,
+                                decode_time_ms_, " ms");
   }
   dropped_frames_ += dropped_frames_before_first_encode_ +
                      dropped_frames_before_rendering_ + frames_left;
@@ -821,6 +829,21 @@
       stats.GetStandardDeviation().value_or(0), unit, false);
 }
 
+void VideoAnalyzer::PrintResultWithExternalMean(const char* result_type,
+                                                double mean,
+                                                Statistics stats,
+                                                const char* unit) {
+  // If the true mean is different than the sample mean, the sample variance is
+  // too low. The sample variance given a known mean is obtained by adding the
+  // squared error between the true mean and the sample mean.
+  double compensated_variance =
+      stats.Size() > 0
+          ? *stats.GetVariance() + pow(mean - *stats.GetMean(), 2.0)
+          : 0.0;
+  test::PrintResultMeanAndError(result_type, "", test_label_.c_str(), mean,
+                                std::sqrt(compensated_variance), unit, false);
+}
+
 void VideoAnalyzer::PrintSamplesToFile() {
   FILE* out = graph_data_output_file_;
   rtc::CritScope crit(&comparison_lock_);
diff --git a/video/video_analyzer.h b/video/video_analyzer.h
index d14e9df..7cc3a86 100644
--- a/video/video_analyzer.h
+++ b/video/video_analyzer.h
@@ -193,6 +193,10 @@
   void PrintResults();
   void PerformFrameComparison(const FrameComparison& comparison);
   void PrintResult(const char* result_type, Statistics stats, const char* unit);
+  void PrintResultWithExternalMean(const char* result_type,
+                                   double mean,
+                                   Statistics stats,
+                                   const char* unit);
   void PrintSamplesToFile(void);
   double GetAverageMediaBitrateBps();
   void AddCapturedFrameForComparison(const VideoFrame& video_frame);
@@ -224,6 +228,7 @@
   Statistics encode_frame_rate_ RTC_GUARDED_BY(comparison_lock_);
   Statistics encode_time_ms_ RTC_GUARDED_BY(comparison_lock_);
   Statistics encode_usage_percent_ RTC_GUARDED_BY(comparison_lock_);
+  double mean_decode_time_ms_ RTC_GUARDED_BY(comparison_lock_);
   Statistics decode_time_ms_ RTC_GUARDED_BY(comparison_lock_);
   Statistics decode_time_max_ms_ RTC_GUARDED_BY(comparison_lock_);
   Statistics media_bitrate_bps_ RTC_GUARDED_BY(comparison_lock_);