Add totalDecodeTime to RTCInboundRTPStreamStats

Pull request to WebRTC stats specification:
https://github.com/w3c/webrtc-stats/pull/450

Bug: webrtc:10775
Change-Id: Id032cb324724329fee284ebc84595b9c39208ab8
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/144035
Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28440}
diff --git a/modules/video_coding/frame_buffer2.cc b/modules/video_coding/frame_buffer2.cc
index d5df3ba..d969946 100644
--- a/modules/video_coding/frame_buffer2.cc
+++ b/modules/video_coding/frame_buffer2.cc
@@ -699,19 +699,18 @@
   if (!stats_callback_)
     return;
 
-  int decode_ms;
   int max_decode_ms;
   int current_delay_ms;
   int target_delay_ms;
   int jitter_buffer_ms;
   int min_playout_delay_ms;
   int render_delay_ms;
-  if (timing_->GetTimings(&decode_ms, &max_decode_ms, &current_delay_ms,
-                          &target_delay_ms, &jitter_buffer_ms,
-                          &min_playout_delay_ms, &render_delay_ms)) {
+  if (timing_->GetTimings(&max_decode_ms, &current_delay_ms, &target_delay_ms,
+                          &jitter_buffer_ms, &min_playout_delay_ms,
+                          &render_delay_ms)) {
     stats_callback_->OnFrameBufferTimingsUpdated(
-        decode_ms, max_decode_ms, current_delay_ms, target_delay_ms,
-        jitter_buffer_ms, min_playout_delay_ms, render_delay_ms);
+        max_decode_ms, current_delay_ms, target_delay_ms, jitter_buffer_ms,
+        min_playout_delay_ms, render_delay_ms);
   }
 }
 
diff --git a/modules/video_coding/frame_buffer2_unittest.cc b/modules/video_coding/frame_buffer2_unittest.cc
index 083b89b..3182579 100644
--- a/modules/video_coding/frame_buffer2_unittest.cc
+++ b/modules/video_coding/frame_buffer2_unittest.cc
@@ -59,8 +59,7 @@
     return render_time_ms - now_ms - kDecodeTime;
   }
 
-  bool GetTimings(int* decode_ms,
-                  int* max_decode_ms,
+  bool GetTimings(int* max_decode_ms,
                   int* current_delay_ms,
                   int* target_delay_ms,
                   int* jitter_buffer_ms,
@@ -70,16 +69,15 @@
   }
 
   int GetCurrentJitter() {
-    int decode_ms;
     int max_decode_ms;
     int current_delay_ms;
     int target_delay_ms;
     int jitter_buffer_ms;
     int min_playout_delay_ms;
     int render_delay_ms;
-    VCMTiming::GetTimings(&decode_ms, &max_decode_ms, &current_delay_ms,
-                          &target_delay_ms, &jitter_buffer_ms,
-                          &min_playout_delay_ms, &render_delay_ms);
+    VCMTiming::GetTimings(&max_decode_ms, &current_delay_ms, &target_delay_ms,
+                          &jitter_buffer_ms, &min_playout_delay_ms,
+                          &render_delay_ms);
     return jitter_buffer_ms;
   }
 
@@ -115,9 +113,8 @@
                     VideoContentType content_type));
   MOCK_METHOD1(OnDiscardedPacketsUpdated, void(int discarded_packets));
   MOCK_METHOD1(OnFrameCountsUpdated, void(const FrameCounts& frame_counts));
-  MOCK_METHOD7(OnFrameBufferTimingsUpdated,
-               void(int decode_ms,
-                    int max_decode_ms,
+  MOCK_METHOD6(OnFrameBufferTimingsUpdated,
+               void(int max_decode_ms,
                     int current_delay_ms,
                     int target_delay_ms,
                     int jitter_buffer_ms,
@@ -548,8 +545,7 @@
 
   EXPECT_CALL(stats_callback_,
               OnCompleteFrame(true, kFrameSize, VideoContentType::UNSPECIFIED));
-  EXPECT_CALL(stats_callback_,
-              OnFrameBufferTimingsUpdated(_, _, _, _, _, _, _));
+  EXPECT_CALL(stats_callback_, OnFrameBufferTimingsUpdated(_, _, _, _, _, _));
 
   {
     std::unique_ptr<FrameObjectFake> frame(new FrameObjectFake());
diff --git a/modules/video_coding/generic_decoder.cc b/modules/video_coding/generic_decoder.cc
index ab83119..0f928d2 100644
--- a/modules/video_coding/generic_decoder.cc
+++ b/modules/video_coding/generic_decoder.cc
@@ -91,8 +91,7 @@
   if (!decode_time_ms) {
     decode_time_ms = now_ms - frameInfo->decodeStartTimeMs;
   }
-  _timing->StopDecodeTimer(decodedImage.timestamp(), *decode_time_ms, now_ms,
-                           frameInfo->renderTimeMs);
+  _timing->StopDecodeTimer(*decode_time_ms, now_ms);
 
   // Report timing information.
   TimingFrameInfo timing_frame_info;
@@ -147,7 +146,8 @@
 
   decodedImage.set_timestamp_us(frameInfo->renderTimeMs *
                                 rtc::kNumMicrosecsPerMillisec);
-  _receiveCallback->FrameToRender(decodedImage, qp, frameInfo->content_type);
+  _receiveCallback->FrameToRender(decodedImage, qp, *decode_time_ms,
+                                  frameInfo->content_type);
 }
 
 void VCMDecodedFrameCallback::OnDecoderImplementationName(
diff --git a/modules/video_coding/generic_decoder_unittest.cc b/modules/video_coding/generic_decoder_unittest.cc
index 691561d..93d55a6 100644
--- a/modules/video_coding/generic_decoder_unittest.cc
+++ b/modules/video_coding/generic_decoder_unittest.cc
@@ -30,6 +30,7 @@
  public:
   int32_t FrameToRender(VideoFrame& videoFrame,  // NOLINT
                         absl::optional<uint8_t> qp,
+                        int32_t decode_time_ms,
                         VideoContentType content_type) override {
     {
       rtc::CritScope cs(&lock_);
diff --git a/modules/video_coding/include/mock/mock_vcm_callbacks.h b/modules/video_coding/include/mock/mock_vcm_callbacks.h
index d2d0378..76fc561 100644
--- a/modules/video_coding/include/mock/mock_vcm_callbacks.h
+++ b/modules/video_coding/include/mock/mock_vcm_callbacks.h
@@ -27,8 +27,9 @@
   MockVCMReceiveCallback() {}
   virtual ~MockVCMReceiveCallback() {}
 
-  MOCK_METHOD3(FrameToRender,
-               int32_t(VideoFrame&, absl::optional<uint8_t>, VideoContentType));
+  MOCK_METHOD4(
+      FrameToRender,
+      int32_t(VideoFrame&, absl::optional<uint8_t>, int32_t, VideoContentType));
   MOCK_METHOD1(OnIncomingPayloadType, void(int));
   MOCK_METHOD1(OnDecoderImplementationName, void(const char*));
 };
diff --git a/modules/video_coding/include/video_coding_defines.h b/modules/video_coding/include/video_coding_defines.h
index b785734..043d8c6 100644
--- a/modules/video_coding/include/video_coding_defines.h
+++ b/modules/video_coding/include/video_coding_defines.h
@@ -51,9 +51,21 @@
 // rendered.
 class VCMReceiveCallback {
  public:
+  // TODO(kron): Remove once downstream projects are updated.
   virtual int32_t FrameToRender(VideoFrame& videoFrame,  // NOLINT
                                 absl::optional<uint8_t> qp,
-                                VideoContentType content_type) = 0;
+                                VideoContentType content_type) {
+    // Cannot be pure virtual since this should be removed from derived
+    // classes.
+    return FrameToRender(videoFrame, qp, 0, content_type);
+  }
+
+  virtual int32_t FrameToRender(VideoFrame& videoFrame,  // NOLINT
+                                absl::optional<uint8_t> qp,
+                                int32_t decode_time_ms,
+                                VideoContentType content_type) {
+    return FrameToRender(videoFrame, qp, content_type);
+  }
 
   // Called when the current receive codec changes.
   virtual void OnIncomingPayloadType(int payload_type);
@@ -71,8 +83,7 @@
                                size_t size_bytes,
                                VideoContentType content_type) = 0;
 
-  virtual void OnFrameBufferTimingsUpdated(int decode_ms,
-                                           int max_decode_ms,
+  virtual void OnFrameBufferTimingsUpdated(int max_decode_ms,
                                            int current_delay_ms,
                                            int target_delay_ms,
                                            int jitter_buffer_ms,
diff --git a/modules/video_coding/receiver_unittest.cc b/modules/video_coding/receiver_unittest.cc
index 5631166..ade26ca 100644
--- a/modules/video_coding/receiver_unittest.cc
+++ b/modules/video_coding/receiver_unittest.cc
@@ -454,7 +454,7 @@
   int render_delay_ms;
   int max_decode_ms;
   int dummy;
-  timing_.GetTimings(&dummy, &max_decode_ms, &dummy, &dummy, &dummy, &dummy,
+  timing_.GetTimings(&max_decode_ms, &dummy, &dummy, &dummy, &dummy,
                      &render_delay_ms);
 
   // Construct test samples.
diff --git a/modules/video_coding/timing.cc b/modules/video_coding/timing.cc
index a2a4e47..8da2b85 100644
--- a/modules/video_coding/timing.cc
+++ b/modules/video_coding/timing.cc
@@ -28,7 +28,6 @@
       max_playout_delay_ms_(10000),
       jitter_delay_ms_(0),
       current_delay_ms_(0),
-      last_decode_ms_(0),
       prev_frame_timestamp_(0),
       timing_frame_info_(),
       num_decoded_frames_(0) {
@@ -150,14 +149,17 @@
   }
 }
 
-void VCMTiming::StopDecodeTimer(uint32_t time_stamp,
+void VCMTiming::StopDecodeTimer(uint32_t /*time_stamp*/,
                                 int32_t decode_time_ms,
                                 int64_t now_ms,
-                                int64_t render_time_ms) {
+                                int64_t /*render_time_ms*/) {
+  StopDecodeTimer(decode_time_ms, now_ms);
+}
+
+void VCMTiming::StopDecodeTimer(int32_t decode_time_ms, int64_t now_ms) {
   rtc::CritScope cs(&crit_sect_);
   codec_timer_->AddTiming(decode_time_ms, now_ms);
   assert(decode_time_ms >= 0);
-  last_decode_ms_ = decode_time_ms;
   ++num_decoded_frames_;
 }
 
@@ -217,15 +219,13 @@
                   jitter_delay_ms_ + RequiredDecodeTimeMs() + render_delay_ms_);
 }
 
-bool VCMTiming::GetTimings(int* decode_ms,
-                           int* max_decode_ms,
+bool VCMTiming::GetTimings(int* max_decode_ms,
                            int* current_delay_ms,
                            int* target_delay_ms,
                            int* jitter_buffer_ms,
                            int* min_playout_delay_ms,
                            int* render_delay_ms) const {
   rtc::CritScope cs(&crit_sect_);
-  *decode_ms = last_decode_ms_;
   *max_decode_ms = RequiredDecodeTimeMs();
   *current_delay_ms = current_delay_ms_;
   *target_delay_ms = TargetDelayInternal();
diff --git a/modules/video_coding/timing.h b/modules/video_coding/timing.h
index c70410e..764f0be 100644
--- a/modules/video_coding/timing.h
+++ b/modules/video_coding/timing.h
@@ -61,6 +61,9 @@
 
   // Stops the decoder timer, should be called when the decoder returns a frame
   // or when the decoded frame callback is called.
+  void StopDecodeTimer(int32_t decode_time_ms, int64_t now_ms);
+  // TODO(kron): Remove once downstream projects has been changed to use the
+  // above function.
   void StopDecodeTimer(uint32_t time_stamp,
                        int32_t decode_time_ms,
                        int64_t now_ms,
@@ -85,8 +88,7 @@
 
   // Return current timing information. Returns true if the first frame has been
   // decoded, false otherwise.
-  virtual bool GetTimings(int* decode_ms,
-                          int* max_decode_ms,
+  virtual bool GetTimings(int* max_decode_ms,
                           int* current_delay_ms,
                           int* target_delay_ms,
                           int* jitter_buffer_ms,
@@ -121,7 +123,6 @@
   int max_playout_delay_ms_ RTC_GUARDED_BY(crit_sect_);
   int jitter_delay_ms_ RTC_GUARDED_BY(crit_sect_);
   int current_delay_ms_ RTC_GUARDED_BY(crit_sect_);
-  int last_decode_ms_ RTC_GUARDED_BY(crit_sect_);
   uint32_t prev_frame_timestamp_ RTC_GUARDED_BY(crit_sect_);
   absl::optional<TimingFrameInfo> timing_frame_info_ RTC_GUARDED_BY(crit_sect_);
   size_t num_decoded_frames_ RTC_GUARDED_BY(crit_sect_);
diff --git a/modules/video_coding/timing_unittest.cc b/modules/video_coding/timing_unittest.cc
index b9397ea..40e8c97 100644
--- a/modules/video_coding/timing_unittest.cc
+++ b/modules/video_coding/timing_unittest.cc
@@ -75,9 +75,7 @@
   const uint32_t kDecodeTimeMs = 10;
   for (int i = 0; i < kFps; i++) {
     clock.AdvanceTimeMilliseconds(kDecodeTimeMs);
-    timing.StopDecodeTimer(
-        timestamp, kDecodeTimeMs, clock.TimeInMilliseconds(),
-        timing.RenderTimeMs(timestamp, clock.TimeInMilliseconds()));
+    timing.StopDecodeTimer(kDecodeTimeMs, clock.TimeInMilliseconds());
     timestamp += 90000 / kFps;
     clock.AdvanceTimeMilliseconds(1000 / kFps - kDecodeTimeMs);
     timing.IncomingTimestamp(timestamp, clock.TimeInMilliseconds());