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_