diff --git a/webrtc/api/statstypes.cc b/webrtc/api/statstypes.cc index 3a4e7e7b97..b5481ecbef 100644 --- a/webrtc/api/statstypes.cc +++ b/webrtc/api/statstypes.cc @@ -538,6 +538,8 @@ const char* StatsReport::Value::display_name() const { return "googFrameWidthSent"; case kStatsValueNameInitiator: return "googInitiator"; + case kStatsValueNameInterframeDelaySumMs: + return "googInterframeDelaySum"; case kStatsValueNameIssuerId: return "googIssuerId"; case kStatsValueNameJitterReceived: diff --git a/webrtc/api/statstypes.h b/webrtc/api/statstypes.h index 30102676c4..b4a805b250 100644 --- a/webrtc/api/statstypes.h +++ b/webrtc/api/statstypes.h @@ -107,6 +107,7 @@ class StatsReport { kStatsValueNameDataChannelId, kStatsValueNameFramesDecoded, kStatsValueNameFramesEncoded, + kStatsValueNameInterframeDelaySumMs, kStatsValueNameMediaType, kStatsValueNamePacketsLost, kStatsValueNamePacketsReceived, diff --git a/webrtc/media/base/mediachannel.h b/webrtc/media/base/mediachannel.h index de2a7cdd4e..1109f56205 100644 --- a/webrtc/media/base/mediachannel.h +++ b/webrtc/media/base/mediachannel.h @@ -741,6 +741,7 @@ struct VideoReceiverInfo : public MediaReceiverInfo { frames_received(0), frames_decoded(0), frames_rendered(0), + interframe_delay_sum_ms(0), decode_ms(0), max_decode_ms(0), jitter_buffer_ms(0), @@ -770,6 +771,7 @@ struct VideoReceiverInfo : public MediaReceiverInfo { uint32_t frames_decoded; uint32_t frames_rendered; rtc::Optional qp_sum; + uint64_t interframe_delay_sum_ms; // All stats below are gathered per-VideoReceiver, but some will be correlated // across MediaStreamTracks. NOTE(hta): when sinking stats into per-SSRC diff --git a/webrtc/media/engine/webrtcvideoengine.cc b/webrtc/media/engine/webrtcvideoengine.cc index 428353d793..55de5ae335 100644 --- a/webrtc/media/engine/webrtcvideoengine.cc +++ b/webrtc/media/engine/webrtcvideoengine.cc @@ -2477,6 +2477,8 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::GetVideoReceiverInfo( info.frames_rendered = stats.frames_rendered; info.qp_sum = stats.qp_sum; + info.interframe_delay_sum_ms = stats.interframe_delay_sum_ms; + info.codec_name = GetCodecNameFromPayloadType(stats.current_payload_type); info.firs_sent = stats.rtcp_packet_type_counts.fir_packets; diff --git a/webrtc/pc/statscollector.cc b/webrtc/pc/statscollector.cc index 8da5b88589..f74a683a85 100644 --- a/webrtc/pc/statscollector.cc +++ b/webrtc/pc/statscollector.cc @@ -249,10 +249,14 @@ void ExtractStats(const cricket::VideoReceiverInfo& info, StatsReport* report) { for (const auto& i : ints) report->AddInt(i.name, i.value); report->AddString(StatsReport::kStatsValueNameMediaType, "video"); + if (info.timing_frame_info) { report->AddString(StatsReport::kStatsValueNameTimingFrameInfo, info.timing_frame_info->ToString()); } + + report->AddInt64(StatsReport::kStatsValueNameInterframeDelaySumMs, + info.interframe_delay_sum_ms); } void ExtractStats(const cricket::VideoSenderInfo& info, StatsReport* report) { diff --git a/webrtc/video/receive_statistics_proxy.cc b/webrtc/video/receive_statistics_proxy.cc index cf65a75b4a..38e91d7a8e 100644 --- a/webrtc/video/receive_statistics_proxy.cc +++ b/webrtc/video/receive_statistics_proxy.cc @@ -573,6 +573,7 @@ void ReceiveStatisticsProxy::OnDecodedFrame(rtc::Optional qp, if (last_decoded_frame_time_ms_) { int64_t interframe_delay_ms = now - *last_decoded_frame_time_ms_; RTC_DCHECK_GE(interframe_delay_ms, 0); + stats_.interframe_delay_sum_ms += interframe_delay_ms; if (last_content_type_ == VideoContentType::SCREENSHARE) { interframe_delay_counter_screenshare_.Add(interframe_delay_ms); if (interframe_delay_max_ms_screenshare_ < interframe_delay_ms) { diff --git a/webrtc/video/receive_statistics_proxy_unittest.cc b/webrtc/video/receive_statistics_proxy_unittest.cc index 2c4d330195..822fc453f4 100644 --- a/webrtc/video/receive_statistics_proxy_unittest.cc +++ b/webrtc/video/receive_statistics_proxy_unittest.cc @@ -97,6 +97,28 @@ TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameIncreasesQpSum) { statistics_proxy_->GetStats().qp_sum); } +TEST_F(ReceiveStatisticsProxyTest, + OnDecodedFrameIncreasesInterframeDelayMsSum) { + const uint64_t kInterframeDelayMs1 = 100; + const uint64_t kInterframeDelayMs2 = 200; + EXPECT_EQ(0u, statistics_proxy_->GetStats().interframe_delay_sum_ms); + statistics_proxy_->OnDecodedFrame(rtc::Optional(3u), + VideoContentType::UNSPECIFIED); + EXPECT_EQ(0u, statistics_proxy_->GetStats().interframe_delay_sum_ms); + + fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs1); + statistics_proxy_->OnDecodedFrame(rtc::Optional(127u), + VideoContentType::UNSPECIFIED); + EXPECT_EQ(kInterframeDelayMs1, + statistics_proxy_->GetStats().interframe_delay_sum_ms); + + fake_clock_.AdvanceTimeMilliseconds(kInterframeDelayMs2); + statistics_proxy_->OnDecodedFrame(rtc::Optional(127u), + VideoContentType::UNSPECIFIED); + EXPECT_EQ(kInterframeDelayMs1 + kInterframeDelayMs2, + statistics_proxy_->GetStats().interframe_delay_sum_ms); +} + TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameWithoutQpQpSumWontExist) { EXPECT_EQ(rtc::Optional(), statistics_proxy_->GetStats().qp_sum); statistics_proxy_->OnDecodedFrame(rtc::Optional(), diff --git a/webrtc/video_receive_stream.h b/webrtc/video_receive_stream.h index a2de503f29..863cb2e088 100644 --- a/webrtc/video_receive_stream.h +++ b/webrtc/video_receive_stream.h @@ -69,6 +69,7 @@ class VideoReceiveStream { int jitter_buffer_ms = 0; int min_playout_delay_ms = 0; int render_delay_ms = 10; + uint64_t interframe_delay_sum_ms = 0; uint32_t frames_decoded = 0; rtc::Optional qp_sum;