diff --git a/webrtc/video/receive_statistics_proxy.cc b/webrtc/video/receive_statistics_proxy.cc index 9485a54a04..308424054b 100644 --- a/webrtc/video/receive_statistics_proxy.cc +++ b/webrtc/video/receive_statistics_proxy.cc @@ -104,12 +104,14 @@ void ReceiveStatisticsProxy::UpdateHistograms() { if (fraction_lost != -1) { RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.ReceivedPacketsLostInPercent", fraction_lost); + LOG(LS_INFO) << "WebRTC.Video.ReceivedPacketsLostInPercent " + << fraction_lost; } } const int kMinRequiredSamples = 200; int samples = static_cast(render_fps_tracker_.TotalSampleCount()); - if (samples > kMinRequiredSamples) { + if (samples >= kMinRequiredSamples) { RTC_HISTOGRAM_COUNTS_100("WebRTC.Video.RenderFramesPerSecond", round(render_fps_tracker_.ComputeTotalRate())); RTC_HISTOGRAM_COUNTS_100000( @@ -121,10 +123,13 @@ void ReceiveStatisticsProxy::UpdateHistograms() { if (width != -1) { RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.ReceivedWidthInPixels", width); RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.ReceivedHeightInPixels", height); + LOG(LS_INFO) << "WebRTC.Video.ReceivedWidthInPixels " << width; + LOG(LS_INFO) << "WebRTC.Video.ReceivedHeightInPixels " << height; } int sync_offset_ms = sync_offset_counter_.Avg(kMinRequiredSamples); if (sync_offset_ms != -1) { RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.AVSyncOffsetInMs", sync_offset_ms); + LOG(LS_INFO) << "WebRTC.Video.AVSyncOffsetInMs " << sync_offset_ms; } AggregatedStats freq_offset_stats = freq_offset_counter_.GetStats(); if (freq_offset_stats.num_samples > 0) { @@ -142,30 +147,37 @@ void ReceiveStatisticsProxy::UpdateHistograms() { (num_key_frames * 1000 + num_total_frames / 2) / num_total_frames; RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.KeyFramesReceivedInPermille", key_frames_permille); + LOG(LS_INFO) << "WebRTC.Video.KeyFramesReceivedInPermille " + << key_frames_permille; } int qp = qp_counters_.vp8.Avg(kMinRequiredSamples); - if (qp != -1) + if (qp != -1) { RTC_HISTOGRAM_COUNTS_200("WebRTC.Video.Decoded.Vp8.Qp", qp); - + LOG(LS_INFO) << "WebRTC.Video.Decoded.Vp8.Qp " << qp; + } int decode_ms = decode_time_counter_.Avg(kMinRequiredSamples); - if (decode_ms != -1) + if (decode_ms != -1) { RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.DecodeTimeInMs", decode_ms); - + LOG(LS_INFO) << "WebRTC.Video.DecodeTimeInMs " << decode_ms; + } int jb_delay_ms = jitter_buffer_delay_counter_.Avg(kMinRequiredSamples); if (jb_delay_ms != -1) { RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.JitterBufferDelayInMs", jb_delay_ms); + LOG(LS_INFO) << "WebRTC.Video.JitterBufferDelayInMs " << jb_delay_ms; } int target_delay_ms = target_delay_counter_.Avg(kMinRequiredSamples); if (target_delay_ms != -1) { RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.TargetDelayInMs", target_delay_ms); + LOG(LS_INFO) << "WebRTC.Video.TargetDelayInMs " << target_delay_ms; } int current_delay_ms = current_delay_counter_.Avg(kMinRequiredSamples); if (current_delay_ms != -1) { RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.CurrentDelayInMs", current_delay_ms); + LOG(LS_INFO) << "WebRTC.Video.CurrentDelayInMs " << current_delay_ms; } int delay_ms = delay_counter_.Avg(kMinRequiredSamples); if (delay_ms != -1) @@ -175,6 +187,7 @@ void ReceiveStatisticsProxy::UpdateHistograms() { if (e2e_delay_ms_video != -1) { RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.EndToEndDelayInMs", e2e_delay_ms_video); + LOG(LS_INFO) << "WebRTC.Video.EndToEndDelayInMs " << e2e_delay_ms_video; } int e2e_delay_ms_screenshare = @@ -204,7 +217,7 @@ void ReceiveStatisticsProxy::UpdateHistograms() { rtp_rtx.Add(rtx); int64_t elapsed_sec = rtp_rtx.TimeSinceFirstPacketInMs(clock_->TimeInMilliseconds()) / 1000; - if (elapsed_sec > metrics::kMinRunTimeInSeconds) { + if (elapsed_sec >= metrics::kMinRunTimeInSeconds) { RTC_HISTOGRAM_COUNTS_10000( "WebRTC.Video.BitrateReceivedInKbps", static_cast(rtp_rtx.transmitted.TotalBytes() * 8 / elapsed_sec / diff --git a/webrtc/video/receive_statistics_proxy_unittest.cc b/webrtc/video/receive_statistics_proxy_unittest.cc index 427f3856a0..e219542768 100644 --- a/webrtc/video/receive_statistics_proxy_unittest.cc +++ b/webrtc/video/receive_statistics_proxy_unittest.cc @@ -10,6 +10,7 @@ #include "webrtc/video/receive_statistics_proxy.h" +#include #include #include "webrtc/api/video/i420_buffer.h" @@ -47,6 +48,18 @@ class ReceiveStatisticsProxyTest : public ::testing::Test { return config; } + void InsertFirstRtpPacket(uint32_t ssrc) { + StreamDataCounters counters; + counters.first_packet_time_ms = fake_clock_.TimeInMilliseconds(); + statistics_proxy_->DataCountersUpdated(counters, ssrc); + } + + VideoFrame CreateFrame(int width, int height) { + VideoFrame frame(I420Buffer::Create(width, height), 0, 0, kVideoRotation_0); + frame.set_ntp_time_ms(fake_clock_.CurrentNtpInMilliseconds()); + return frame; + } + SimulatedClock fake_clock_; const VideoReceiveStream::Config config_; std::unique_ptr statistics_proxy_; @@ -332,6 +345,15 @@ TEST_F(ReceiveStatisticsProxyTest, metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent")); } +TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsAvSyncOffset) { + const int64_t kSyncOffsetMs = 22; + const double kFreqKhz = 90.0; + EXPECT_EQ(std::numeric_limits::max(), + statistics_proxy_->GetStats().sync_offset_ms); + statistics_proxy_->OnSyncOffsetUpdated(kSyncOffsetMs, kFreqKhz); + EXPECT_EQ(kSyncOffsetMs, statistics_proxy_->GetStats().sync_offset_ms); +} + TEST_F(ReceiveStatisticsProxyTest, AvSyncOffsetHistogramIsUpdated) { const int64_t kSyncOffsetMs = 22; const double kFreqKhz = 90.0; @@ -541,4 +563,95 @@ TEST_F(ReceiveStatisticsProxyTest, DoesNotReportStaleFramerates) { EXPECT_EQ(0, statistics_proxy_->GetStats().render_frame_rate); } +TEST_F(ReceiveStatisticsProxyTest, GetStatsReportsReceivedFrameStats) { + const int kWidth = 160; + const int kHeight = 120; + EXPECT_EQ(0, statistics_proxy_->GetStats().width); + EXPECT_EQ(0, statistics_proxy_->GetStats().height); + EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_rendered); + + statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight)); + + EXPECT_EQ(kWidth, statistics_proxy_->GetStats().width); + EXPECT_EQ(kHeight, statistics_proxy_->GetStats().height); + EXPECT_EQ(1u, statistics_proxy_->GetStats().frames_rendered); +} + +TEST_F(ReceiveStatisticsProxyTest, + ReceivedFrameHistogramsAreNotUpdatedForTooFewSamples) { + const int kWidth = 160; + const int kHeight = 120; + + for (int i = 0; i < kMinRequiredSamples - 1; ++i) + statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight)); + + statistics_proxy_.reset(); + EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels")); + EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels")); + EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond")); + EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond")); +} + +TEST_F(ReceiveStatisticsProxyTest, ReceivedFrameHistogramsAreUpdated) { + const int kWidth = 160; + const int kHeight = 120; + + for (int i = 0; i < kMinRequiredSamples; ++i) + statistics_proxy_->OnRenderedFrame(CreateFrame(kWidth, kHeight)); + + statistics_proxy_.reset(); + EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels")); + EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels")); + EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond")); + EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond")); + EXPECT_EQ(1, + metrics::NumEvents("WebRTC.Video.ReceivedWidthInPixels", kWidth)); + EXPECT_EQ(1, + metrics::NumEvents("WebRTC.Video.ReceivedHeightInPixels", kHeight)); +} + +TEST_F(ReceiveStatisticsProxyTest, + RtcpHistogramsNotUpdatedIfMinRuntimeHasNotPassed) { + InsertFirstRtpPacket(kRemoteSsrc); + fake_clock_.AdvanceTimeMilliseconds((metrics::kMinRunTimeInSeconds * 1000) - + 1); + + RtcpPacketTypeCounter counter; + statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter); + + statistics_proxy_.reset(); + EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute")); + EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute")); + EXPECT_EQ(0, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute")); +} + +TEST_F(ReceiveStatisticsProxyTest, RtcpHistogramsAreUpdated) { + InsertFirstRtpPacket(kRemoteSsrc); + fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000); + + const uint32_t kFirPackets = 100; + const uint32_t kPliPackets = 200; + const uint32_t kNackPackets = 300; + + RtcpPacketTypeCounter counter; + counter.fir_packets = kFirPackets; + counter.pli_packets = kPliPackets; + counter.nack_packets = kNackPackets; + statistics_proxy_->RtcpPacketTypesCounterUpdated(kRemoteSsrc, counter); + + statistics_proxy_.reset(); + EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute")); + EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute")); + EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute")); + EXPECT_EQ( + 1, metrics::NumEvents("WebRTC.Video.FirPacketsSentPerMinute", + kFirPackets * 60 / metrics::kMinRunTimeInSeconds)); + EXPECT_EQ( + 1, metrics::NumEvents("WebRTC.Video.PliPacketsSentPerMinute", + kPliPackets * 60 / metrics::kMinRunTimeInSeconds)); + EXPECT_EQ( + 1, metrics::NumEvents("WebRTC.Video.NackPacketsSentPerMinute", + kNackPackets * 60 / metrics::kMinRunTimeInSeconds)); +} + } // namespace webrtc diff --git a/webrtc/video/send_statistics_proxy.cc b/webrtc/video/send_statistics_proxy.cc index 4fcf84261d..71d980addc 100644 --- a/webrtc/video/send_statistics_proxy.cc +++ b/webrtc/video/send_statistics_proxy.cc @@ -166,6 +166,8 @@ void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms( in_width); RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "InputHeightInPixels", in_height); + LOG(LS_INFO) << uma_prefix_ << "InputWidthInPixels " << in_width; + LOG(LS_INFO) << uma_prefix_ << "InputHeightInPixels " << in_height; } AggregatedStats in_fps = input_fps_counter_.GetStats(); if (in_fps.num_samples >= kMinRequiredPeriodicSamples) { @@ -181,6 +183,8 @@ void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms( sent_width); RTC_HISTOGRAMS_COUNTS_10000(kIndex, uma_prefix_ + "SentHeightInPixels", sent_height); + LOG(LS_INFO) << uma_prefix_ << "SentWidthInPixels " << sent_width; + LOG(LS_INFO) << uma_prefix_ << "SentHeightInPixels " << sent_height; } AggregatedStats sent_fps = sent_fps_counter_.GetStats(); if (sent_fps.num_samples >= kMinRequiredPeriodicSamples) { @@ -194,12 +198,15 @@ void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms( if (encode_ms != -1) { RTC_HISTOGRAMS_COUNTS_1000(kIndex, uma_prefix_ + "EncodeTimeInMs", encode_ms); + LOG(LS_INFO) << uma_prefix_ << "EncodeTimeInMs " << encode_ms; } int key_frames_permille = key_frame_counter_.Permille(kMinRequiredMetricsSamples); if (key_frames_permille != -1) { RTC_HISTOGRAMS_COUNTS_1000(kIndex, uma_prefix_ + "KeyFramesSentInPermille", key_frames_permille); + LOG(LS_INFO) << uma_prefix_ << "KeyFramesSentInPermille " + << key_frames_permille; } int quality_limited = quality_limited_frame_counter_.Percent(kMinRequiredMetricsSamples); @@ -207,6 +214,8 @@ void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms( RTC_HISTOGRAMS_PERCENTAGE(kIndex, uma_prefix_ + "QualityLimitedResolutionInPercent", quality_limited); + LOG(LS_INFO) << uma_prefix_ << "QualityLimitedResolutionInPercent " + << quality_limited; } int downscales = quality_downscales_counter_.Avg(kMinRequiredMetricsSamples); if (downscales != -1) { @@ -324,6 +333,8 @@ void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms( if (fraction_lost != -1) { RTC_HISTOGRAMS_PERCENTAGE( kIndex, uma_prefix_ + "SentPacketsLostInPercent", fraction_lost); + LOG(LS_INFO) << uma_prefix_ << "SentPacketsLostInPercent " + << fraction_lost; } // The RTCP packet type counters, delivered via the @@ -370,12 +381,16 @@ void SendStatisticsProxy::UmaSamplesContainer::UpdateHistograms( if (elapsed_sec >= metrics::kMinRunTimeInSeconds) { RTC_HISTOGRAMS_COUNTS_100(kIndex, uma_prefix_ + "NumberOfPauseEvents", target_rate_updates_.pause_resume_events); + LOG(LS_INFO) << uma_prefix_ << "NumberOfPauseEvents " + << target_rate_updates_.pause_resume_events; int paused_time_percent = paused_time_counter_.Percent(metrics::kMinRunTimeInSeconds * 1000); if (paused_time_percent != -1) { RTC_HISTOGRAMS_PERCENTAGE(kIndex, uma_prefix_ + "PausedTimeInPercent", paused_time_percent); + LOG(LS_INFO) << uma_prefix_ << "PausedTimeInPercent " + << paused_time_percent; } } }