diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc index 33fc75e20d..416c8dd5d8 100644 --- a/webrtc/video/end_to_end_tests.cc +++ b/webrtc/video/end_to_end_tests.cc @@ -1661,6 +1661,9 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx, bool use_red) { "WebRTC.Video.DecodedFramesPerSecond")); EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.RenderFramesPerSecond")); + EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.EncodeTimeInMs")); + EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.DecodeTimeInMs")); + EXPECT_EQ(1, test::NumHistogramSamples( "WebRTC.Video.BitrateSentInKbps")); EXPECT_EQ(1, test::NumHistogramSamples( diff --git a/webrtc/video/receive_statistics_proxy.cc b/webrtc/video/receive_statistics_proxy.cc index e028dab2e8..6604d3de6f 100644 --- a/webrtc/video/receive_statistics_proxy.cc +++ b/webrtc/video/receive_statistics_proxy.cc @@ -39,13 +39,19 @@ void ReceiveStatisticsProxy::UpdateHistograms() { if (render_fps > 0) RTC_HISTOGRAM_COUNTS_100("WebRTC.Video.RenderFramesPerSecond", render_fps); - const int kMinRequiredSamples = 100; + const int kMinRequiredSamples = 200; int width = render_width_counter_.Avg(kMinRequiredSamples); int height = render_height_counter_.Avg(kMinRequiredSamples); if (width != -1) { RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.ReceivedWidthInPixels", width); RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.ReceivedHeightInPixels", height); } + // TODO(asapersson): DecoderTiming() is call periodically (each 1000ms) and + // not per frame. Change decode time to include every frame. + const int kMinRequiredDecodeSamples = 5; + int decode_ms = decode_time_counter_.Avg(kMinRequiredDecodeSamples); + if (decode_ms != -1) + RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.DecodeTimeInMs", decode_ms); } VideoReceiveStream::Stats ReceiveStatisticsProxy::GetStats() const { @@ -76,6 +82,7 @@ void ReceiveStatisticsProxy::DecoderTiming(int decode_ms, stats_.jitter_buffer_ms = jitter_buffer_ms; stats_.min_playout_delay_ms = min_playout_delay_ms; stats_.render_delay_ms = render_delay_ms; + decode_time_counter_.Add(decode_ms); } void ReceiveStatisticsProxy::RtcpPacketTypesCounterUpdated( diff --git a/webrtc/video/receive_statistics_proxy.h b/webrtc/video/receive_statistics_proxy.h index 0d229487b9..50422109aa 100644 --- a/webrtc/video/receive_statistics_proxy.h +++ b/webrtc/video/receive_statistics_proxy.h @@ -99,6 +99,7 @@ class ReceiveStatisticsProxy : public ViEDecoderObserver, rtc::RateTracker render_fps_tracker_total_ GUARDED_BY(crit_); SampleCounter render_width_counter_ GUARDED_BY(crit_); SampleCounter render_height_counter_ GUARDED_BY(crit_); + SampleCounter decode_time_counter_ GUARDED_BY(crit_); ReportBlockStats report_block_stats_ GUARDED_BY(crit_); }; diff --git a/webrtc/video/send_statistics_proxy.cc b/webrtc/video/send_statistics_proxy.cc index fe60f1eaa5..551b4b562a 100644 --- a/webrtc/video/send_statistics_proxy.cc +++ b/webrtc/video/send_statistics_proxy.cc @@ -46,7 +46,7 @@ void SendStatisticsProxy::UpdateHistograms() { if (sent_fps > 0) RTC_HISTOGRAM_COUNTS_100("WebRTC.Video.SentFramesPerSecond", sent_fps); - const int kMinRequiredSamples = 100; + const int kMinRequiredSamples = 200; int in_width = input_width_counter_.Avg(kMinRequiredSamples); int in_height = input_height_counter_.Avg(kMinRequiredSamples); if (in_width != -1) { @@ -59,6 +59,9 @@ void SendStatisticsProxy::UpdateHistograms() { RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.SentWidthInPixels", sent_width); RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.SentHeightInPixels", sent_height); } + int encode_ms = encode_time_counter_.Avg(kMinRequiredSamples); + if (encode_ms != -1) + RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.EncodeTimeInMs", encode_ms); } void SendStatisticsProxy::OutgoingRate(const int video_channel, @@ -72,6 +75,7 @@ void SendStatisticsProxy::OutgoingRate(const int video_channel, void SendStatisticsProxy::CpuOveruseMetricsUpdated( const CpuOveruseMetrics& metrics) { rtc::CritScope lock(&crit_); + // TODO(asapersson): Change to use OnEncodedFrame() for avg_encode_time_ms. stats_.avg_encode_time_ms = metrics.avg_encode_time_ms; stats_.encode_usage_percent = metrics.encode_usage_percent; } @@ -186,6 +190,11 @@ void SendStatisticsProxy::OnIncomingFrame(int width, int height) { input_height_counter_.Add(height); } +void SendStatisticsProxy::OnEncodedFrame(int encode_time_ms) { + rtc::CritScope lock(&crit_); + encode_time_counter_.Add(encode_time_ms); +} + void SendStatisticsProxy::RtcpPacketTypesCounterUpdated( uint32_t ssrc, const RtcpPacketTypeCounter& packet_counter) { diff --git a/webrtc/video/send_statistics_proxy.h b/webrtc/video/send_statistics_proxy.h index 1d37f18b84..60d962f93b 100644 --- a/webrtc/video/send_statistics_proxy.h +++ b/webrtc/video/send_statistics_proxy.h @@ -49,6 +49,9 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver, // Used to update incoming frame rate. void OnIncomingFrame(int width, int height); + // Used to update encode time of frames. + void OnEncodedFrame(int encode_time_ms); + // From VideoEncoderRateObserver. void OnSetRates(uint32_t bitrate_bps, int framerate) override; @@ -125,6 +128,7 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver, SampleCounter input_height_counter_ GUARDED_BY(crit_); SampleCounter sent_width_counter_ GUARDED_BY(crit_); SampleCounter sent_height_counter_ GUARDED_BY(crit_); + SampleCounter encode_time_counter_ GUARDED_BY(crit_); }; } // namespace webrtc diff --git a/webrtc/video/video_capture_input.cc b/webrtc/video/video_capture_input.cc index 1fbadff14e..456e99c526 100644 --- a/webrtc/video/video_capture_input.cc +++ b/webrtc/video/video_capture_input.cc @@ -147,8 +147,10 @@ bool VideoCaptureInput::CaptureProcess() { } // Update the overuse detector with the duration. if (encode_start_time != -1) { - overuse_detector_->FrameEncoded( + int encode_time_ms = static_cast( Clock::GetRealTimeClock()->TimeInMilliseconds() - encode_start_time); + overuse_detector_->FrameEncoded(encode_time_ms); + stats_proxy_->OnEncodedFrame(encode_time_ms); } } // We're done!