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}
This commit is contained in:
ilnik
2017-07-06 03:06:50 -07:00
committed by Commit Bot
parent 5b7fc8ce42
commit 2edc6845ac
34 changed files with 376 additions and 67 deletions

View File

@ -266,40 +266,41 @@ constexpr uint8_t VideoTimingExtension::kValueSizeBytes;
constexpr const char* VideoTimingExtension::kUri;
bool VideoTimingExtension::Parse(rtc::ArrayView<const uint8_t> data,
VideoTiming* timing) {
VideoSendTiming* timing) {
RTC_DCHECK(timing);
if (data.size() != kValueSizeBytes)
return false;
timing->encode_start_delta_ms =
ByteReader<uint16_t>::ReadBigEndian(data.data());
timing->encode_finish_delta_ms = ByteReader<uint16_t>::ReadBigEndian(
data.data() + 2 * VideoTiming::kEncodeFinishDeltaIdx);
data.data() + 2 * VideoSendTiming::kEncodeFinishDeltaIdx);
timing->packetization_finish_delta_ms = ByteReader<uint16_t>::ReadBigEndian(
data.data() + 2 * VideoTiming::kPacketizationFinishDeltaIdx);
data.data() + 2 * VideoSendTiming::kPacketizationFinishDeltaIdx);
timing->pacer_exit_delta_ms = ByteReader<uint16_t>::ReadBigEndian(
data.data() + 2 * VideoTiming::kPacerExitDeltaIdx);
data.data() + 2 * VideoSendTiming::kPacerExitDeltaIdx);
timing->network_timstamp_delta_ms = ByteReader<uint16_t>::ReadBigEndian(
data.data() + 2 * VideoTiming::kNetworkTimestampDeltaIdx);
data.data() + 2 * VideoSendTiming::kNetworkTimestampDeltaIdx);
timing->network2_timstamp_delta_ms = ByteReader<uint16_t>::ReadBigEndian(
data.data() + 2 * VideoTiming::kNetwork2TimestampDeltaIdx);
data.data() + 2 * VideoSendTiming::kNetwork2TimestampDeltaIdx);
timing->is_timing_frame = true;
return true;
}
bool VideoTimingExtension::Write(uint8_t* data, const VideoTiming& timing) {
bool VideoTimingExtension::Write(uint8_t* data, const VideoSendTiming& timing) {
ByteWriter<uint16_t>::WriteBigEndian(data, timing.encode_start_delta_ms);
ByteWriter<uint16_t>::WriteBigEndian(
data + 2 * VideoTiming::kEncodeFinishDeltaIdx,
data + 2 * VideoSendTiming::kEncodeFinishDeltaIdx,
timing.encode_finish_delta_ms);
ByteWriter<uint16_t>::WriteBigEndian(
data + 2 * VideoTiming::kPacketizationFinishDeltaIdx,
data + 2 * VideoSendTiming::kPacketizationFinishDeltaIdx,
timing.packetization_finish_delta_ms);
ByteWriter<uint16_t>::WriteBigEndian(
data + 2 * VideoTiming::kPacerExitDeltaIdx, timing.pacer_exit_delta_ms);
data + 2 * VideoSendTiming::kPacerExitDeltaIdx,
timing.pacer_exit_delta_ms);
ByteWriter<uint16_t>::WriteBigEndian(
data + 2 * VideoTiming::kNetworkTimestampDeltaIdx, 0); // reserved
data + 2 * VideoSendTiming::kNetworkTimestampDeltaIdx, 0); // reserved
ByteWriter<uint16_t>::WriteBigEndian(
data + 2 * VideoTiming::kNetwork2TimestampDeltaIdx, 0); // reserved
data + 2 * VideoSendTiming::kNetwork2TimestampDeltaIdx, 0); // reserved
return true;
}

View File

@ -134,9 +134,10 @@ class VideoTimingExtension {
static constexpr const char* kUri =
"http://www.webrtc.org/experiments/rtp-hdrext/video-timing";
static bool Parse(rtc::ArrayView<const uint8_t> data, VideoTiming* timing);
static size_t ValueSize(const VideoTiming&) { return kValueSizeBytes; }
static bool Write(uint8_t* data, const VideoTiming& timing);
static bool Parse(rtc::ArrayView<const uint8_t> data,
VideoSendTiming* timing);
static size_t ValueSize(const VideoSendTiming&) { return kValueSizeBytes; }
static bool Write(uint8_t* data, const VideoSendTiming& timing);
static size_t ValueSize(uint16_t time_delta_ms, uint8_t idx) {
return kValueSizeBytes;

View File

@ -32,26 +32,26 @@ class RtpPacketToSend : public rtp::Packet {
void set_packetization_finish_time_ms(int64_t time) {
SetExtension<VideoTimingExtension>(
VideoTiming::GetDeltaCappedMs(capture_time_ms_, time),
VideoTiming::kPacketizationFinishDeltaIdx);
VideoSendTiming::GetDeltaCappedMs(capture_time_ms_, time),
VideoSendTiming::kPacketizationFinishDeltaIdx);
}
void set_pacer_exit_time_ms(int64_t time) {
SetExtension<VideoTimingExtension>(
VideoTiming::GetDeltaCappedMs(capture_time_ms_, time),
VideoTiming::kPacerExitDeltaIdx);
VideoSendTiming::GetDeltaCappedMs(capture_time_ms_, time),
VideoSendTiming::kPacerExitDeltaIdx);
}
void set_network_time_ms(int64_t time) {
SetExtension<VideoTimingExtension>(
VideoTiming::GetDeltaCappedMs(capture_time_ms_, time),
VideoTiming::kNetworkTimestampDeltaIdx);
VideoSendTiming::GetDeltaCappedMs(capture_time_ms_, time),
VideoSendTiming::kNetworkTimestampDeltaIdx);
}
void set_network2_time_ms(int64_t time) {
SetExtension<VideoTimingExtension>(
VideoTiming::GetDeltaCappedMs(capture_time_ms_, time),
VideoTiming::kNetwork2TimestampDeltaIdx);
VideoSendTiming::GetDeltaCappedMs(capture_time_ms_, time),
VideoSendTiming::kNetwork2TimestampDeltaIdx);
}
private:

View File

@ -473,7 +473,7 @@ TEST_P(RtpSenderTestWithoutPacer, WritesTimestampToTimingExtension) {
packet->SetMarker(true);
packet->SetTimestamp(kTimestamp);
packet->set_capture_time_ms(capture_time_ms);
const VideoTiming kVideoTiming = {0u, 0u, 0u, 0u, 0u, 0u, true};
const VideoSendTiming kVideoTiming = {0u, 0u, 0u, 0u, 0u, 0u, true};
packet->SetExtension<VideoTimingExtension>(kVideoTiming);
EXPECT_TRUE(rtp_sender_->AssignSequenceNumber(packet.get()));
size_t packet_size = packet->size();
@ -1578,7 +1578,7 @@ TEST_P(RtpSenderVideoTest, TimingFrameHasPacketizationTimstampSet) {
rtp_sender_video_->SendVideo(kRtpVideoGeneric, kVideoFrameKey, kPayload,
kTimestamp, kCaptureTimestamp, kFrame,
sizeof(kFrame), nullptr, &hdr);
VideoTiming timing;
VideoSendTiming timing;
EXPECT_TRUE(transport_.last_sent_packet().GetExtension<VideoTimingExtension>(
&timing));
EXPECT_EQ(kPacketizationTimeMs, timing.packetization_finish_delta_ms);