Report timing frames info in GetStats.

Some frames are already marked as 'timing frames' via video-timing RTP header extension. Timestamps along full WebRTC pipeline are gathered for these frames. This CL implements reporting of these timestamps for a single
timing frame since the last GetStats(). The frame with the longest end-to-end delay between two consecutive GetStats calls is reported.

The purpose of this timing information is not to provide a realtime statistics but to provide debugging information as it will help identify problematic places in video pipeline for outliers (frames which took longest to process).

BUG=webrtc:7594

Review-Url: https://codereview.webrtc.org/2946413002
Cr-Commit-Position: refs/heads/master@{#18909}
diff --git a/webrtc/api/BUILD.gn b/webrtc/api/BUILD.gn
index 40741bc..249411b 100644
--- a/webrtc/api/BUILD.gn
+++ b/webrtc/api/BUILD.gn
@@ -173,6 +173,7 @@
     "video/video_frame_buffer.cc",
     "video/video_frame_buffer.h",
     "video/video_rotation.h",
+    "video/video_timing.cc",
     "video/video_timing.h",
   ]
 
diff --git a/webrtc/api/statstypes.cc b/webrtc/api/statstypes.cc
index b7459fa..f6f2689 100644
--- a/webrtc/api/statstypes.cc
+++ b/webrtc/api/statstypes.cc
@@ -598,6 +598,8 @@
       return "googTransportType";
     case kStatsValueNameTrackId:
       return "googTrackId";
+    case kStatsValueNameTimingFrameInfo:
+      return "googTimingFrameInfo";
     case kStatsValueNameTypingNoiseState:
       return "googTypingNoiseState";
     case kStatsValueNameWritable:
diff --git a/webrtc/api/statstypes.h b/webrtc/api/statstypes.h
index 8ef79d9..6fe6f37 100644
--- a/webrtc/api/statstypes.h
+++ b/webrtc/api/statstypes.h
@@ -210,6 +210,7 @@
     kStatsValueNameSrtpCipher,
     kStatsValueNameTargetDelayMs,
     kStatsValueNameTargetEncBitrate,
+    kStatsValueNameTimingFrameInfo,  // Result of |TimingFrameInfo::ToString|
     kStatsValueNameTrackId,
     kStatsValueNameTransmitBitrate,
     kStatsValueNameTransportType,
diff --git a/webrtc/api/video/video_timing.cc b/webrtc/api/video/video_timing.cc
new file mode 100644
index 0000000..a0a3f4d
--- /dev/null
+++ b/webrtc/api/video/video_timing.cc
@@ -0,0 +1,52 @@
+/*
+ *  Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/api/video/video_timing.h"
+
+#include <sstream>
+
+namespace webrtc {
+
+TimingFrameInfo::TimingFrameInfo()
+    : rtp_timestamp(0),
+      capture_time_ms(-1),
+      encode_start_ms(-1),
+      encode_finish_ms(-1),
+      packetization_finish_ms(-1),
+      pacer_exit_ms(-1),
+      network_timestamp_ms(-1),
+      network2_timestamp_ms(-1),
+      receive_start_ms(-1),
+      receive_finish_ms(-1),
+      decode_start_ms(-1),
+      decode_finish_ms(-1),
+      render_time_ms(-1) {}
+
+int64_t TimingFrameInfo::EndToEndDelay() const {
+  return capture_time_ms >= 0 ? decode_finish_ms - capture_time_ms : -1;
+}
+
+bool TimingFrameInfo::IsLongerThan(const TimingFrameInfo& other) const {
+  int64_t other_delay = other.EndToEndDelay();
+  return other_delay == -1 || EndToEndDelay() > other_delay;
+}
+
+std::string TimingFrameInfo::ToString() const {
+  std::stringstream out;
+  out << rtp_timestamp << ',' << capture_time_ms << ',' << encode_start_ms
+      << ',' << encode_finish_ms << ',' << packetization_finish_ms << ','
+      << pacer_exit_ms << ',' << network_timestamp_ms << ','
+      << network2_timestamp_ms << ',' << receive_start_ms << ','
+      << receive_finish_ms << ',' << decode_start_ms << ',' << decode_finish_ms
+      << ',' << render_time_ms;
+  return out.str();
+}
+
+}  // namespace webrtc
diff --git a/webrtc/api/video/video_timing.h b/webrtc/api/video/video_timing.h
index a44a8ef..05414de 100644
--- a/webrtc/api/video/video_timing.h
+++ b/webrtc/api/video/video_timing.h
@@ -12,14 +12,17 @@
 #define WEBRTC_API_VIDEO_VIDEO_TIMING_H_
 
 #include <stdint.h>
-#include <limits>
+
+#include <string>
+
 #include "webrtc/base/checks.h"
 #include "webrtc/base/safe_conversions.h"
 
 namespace webrtc {
 
-// Video timing timstamps in ms counted from capture_time_ms of a frame.
-struct VideoTiming {
+// Video timing timestamps in ms counted from capture_time_ms of a frame.
+// This structure represents data sent in video-timing RTP header extension.
+struct VideoSendTiming {
   static const uint8_t kEncodeStartDeltaIdx = 0;
   static const uint8_t kEncodeFinishDeltaIdx = 1;
   static const uint8_t kPacketizationFinishDeltaIdx = 2;
@@ -45,6 +48,44 @@
   bool is_timing_frame;
 };
 
+// Used to report precise timings of a 'timing frames'. Contains all important
+// timestamps for a lifetime of that specific frame. Reported as a string via
+// GetStats(). Only frame which took the longest between two GetStats calls is
+// reported.
+struct TimingFrameInfo {
+  TimingFrameInfo();
+
+  // Returns end-to-end delay of a frame, if sender and receiver timestamps are
+  // synchronized, -1 otherwise.
+  int64_t EndToEndDelay() const;
+
+  // Returns true if current frame took longer to process than |other| frame.
+  // If other frame's clocks are not synchronized, current frame is always
+  // preferred.
+  bool IsLongerThan(const TimingFrameInfo& other) const;
+
+  std::string ToString() const;
+
+  uint32_t rtp_timestamp;  // Identifier of a frame.
+  // All timestamps below are in local monotonous clock of a receiver.
+  // If sender clock is not yet estimated, sender timestamps
+  // (capture_time_ms ... pacer_exit_ms) are negative values, still
+  // relatively correct.
+  int64_t capture_time_ms;          // Captrue time of a frame.
+  int64_t encode_start_ms;          // Encode start time.
+  int64_t encode_finish_ms;         // Encode completion time.
+  int64_t packetization_finish_ms;  // Time when frame was passed to pacer.
+  int64_t pacer_exit_ms;  // Time when last packet was pushed out of pacer.
+  // Two in-network RTP processor timestamps: meaning is application specific.
+  int64_t network_timestamp_ms;
+  int64_t network2_timestamp_ms;
+  int64_t receive_start_ms;   // First received packet time.
+  int64_t receive_finish_ms;  // Last received packet time.
+  int64_t decode_start_ms;    // Decode start time.
+  int64_t decode_finish_ms;   // Decode completion time.
+  int64_t render_time_ms;     // Proposed render time to insure smooth playback.
+};
+
 }  // namespace webrtc
 
 #endif  // WEBRTC_API_VIDEO_VIDEO_TIMING_H_