From 58e06579af1b63d2270c6d59d751d24db104a5f1 Mon Sep 17 00:00:00 2001 From: Elad Alon Date: Wed, 8 May 2019 15:34:24 +0200 Subject: [PATCH] Add decode/render frame rate metrics These metrics were previously collected by WebRTC, but not printed. Bug: None Change-Id: I79cf4b70da7608d88f13f21c92170d45d00ccaa5 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/135567 Commit-Queue: Elad Alon Reviewed-by: Ilya Nikolaevskiy Reviewed-by: Sergey Silkin Cr-Commit-Position: refs/heads/master@{#27880} --- video/video_analyzer.cc | 21 +++++++++++++++++++++ video/video_analyzer.h | 3 +++ video/video_quality_observer.cc | 12 ++++++------ video/video_quality_observer.h | 12 ++++++------ 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/video/video_analyzer.cc b/video/video_analyzer.cc index 9b5189d307..7efbaf3b60 100644 --- a/video/video_analyzer.cc +++ b/video/video_analyzer.cc @@ -85,6 +85,8 @@ VideoAnalyzer::VideoAnalyzer( total_freezes_duration_ms_(0), total_frames_duration_ms_(0), sum_squared_frame_durations_(0), + decode_frame_rate_(0), + render_frame_rate_(0), last_fec_bytes_(0), frames_to_process_(duration_frames), frames_recorded_(0), @@ -513,6 +515,20 @@ void VideoAnalyzer::PollStats() { if (receive_stats.width > 0 && receive_stats.height > 0) { pixels_.AddSample(receive_stats.width * receive_stats.height); } + + // |frames_decoded| and |frames_rendered| are used because they are more + // accurate than |decode_frame_rate| and |render_frame_rate|. + // The latter two are calculated on a momentary basis. + const double total_frames_duration_sec_double = + static_cast(receive_stats.total_frames_duration_ms) / 1000.0; + if (total_frames_duration_sec_double > 0) { + decode_frame_rate_ = static_cast(receive_stats.frames_decoded) / + total_frames_duration_sec_double; + render_frame_rate_ = static_cast(receive_stats.frames_rendered) / + total_frames_duration_sec_double; + } + + // Freeze metrics. freeze_count_ = receive_stats.freeze_count; total_freezes_duration_ms_ = receive_stats.total_freezes_duration_ms; total_frames_duration_ms_ = receive_stats.total_frames_duration_ms; @@ -627,6 +643,11 @@ void VideoAnalyzer::PrintResults() { PrintResult("send_bandwidth", send_bandwidth_bps_, " bps"); PrintResult("pixels_per_frame", pixels_, " px"); + test::PrintResult("decode_frame_rate", "", test_label_.c_str(), + decode_frame_rate_, "fps", false); + test::PrintResult("render_frame_rate", "", test_label_.c_str(), + render_frame_rate_, "fps", false); + // Record the time from the last freeze until the last rendered frame to // ensure we cover the full timespan of the session. Otherwise the metric // would penalize an early freeze followed by no freezes until the end. diff --git a/video/video_analyzer.h b/video/video_analyzer.h index 33fa08f16f..d14e9dfb49 100644 --- a/video/video_analyzer.h +++ b/video/video_analyzer.h @@ -243,6 +243,9 @@ class VideoAnalyzer : public PacketReceiver, uint32_t total_frames_duration_ms_ RTC_GUARDED_BY(comparison_lock_); double sum_squared_frame_durations_ RTC_GUARDED_BY(comparison_lock_); + double decode_frame_rate_ RTC_GUARDED_BY(comparison_lock_); + double render_frame_rate_ RTC_GUARDED_BY(comparison_lock_); + size_t last_fec_bytes_; const int frames_to_process_; diff --git a/video/video_quality_observer.cc b/video/video_quality_observer.cc index df7d52fae0..86f8c3ada9 100644 --- a/video/video_quality_observer.cc +++ b/video/video_quality_observer.cc @@ -263,27 +263,27 @@ void VideoQualityObserver::OnStreamInactive() { is_paused_ = true; } -uint32_t VideoQualityObserver::NumFreezes() { +uint32_t VideoQualityObserver::NumFreezes() const { return freezes_durations_.NumSamples(); } -uint32_t VideoQualityObserver::NumPauses() { +uint32_t VideoQualityObserver::NumPauses() const { return pauses_durations_.NumSamples(); } -uint32_t VideoQualityObserver::TotalFreezesDurationMs() { +uint32_t VideoQualityObserver::TotalFreezesDurationMs() const { return freezes_durations_.Sum(kMinRequiredSamples).value_or(0); } -uint32_t VideoQualityObserver::TotalPausesDurationMs() { +uint32_t VideoQualityObserver::TotalPausesDurationMs() const { return pauses_durations_.Sum(kMinRequiredSamples).value_or(0); } -uint32_t VideoQualityObserver::TotalFramesDurationMs() { +uint32_t VideoQualityObserver::TotalFramesDurationMs() const { return last_frame_rendered_ms_ - first_frame_rendered_ms_; } -double VideoQualityObserver::SumSquaredFrameDurationsSec() { +double VideoQualityObserver::SumSquaredFrameDurationsSec() const { return sum_squared_interframe_delays_secs_; } diff --git a/video/video_quality_observer.h b/video/video_quality_observer.h index afa0156dfb..ecd06f8311 100644 --- a/video/video_quality_observer.h +++ b/video/video_quality_observer.h @@ -41,12 +41,12 @@ class VideoQualityObserver { void OnStreamInactive(); - uint32_t NumFreezes(); - uint32_t NumPauses(); - uint32_t TotalFreezesDurationMs(); - uint32_t TotalPausesDurationMs(); - uint32_t TotalFramesDurationMs(); - double SumSquaredFrameDurationsSec(); + uint32_t NumFreezes() const; + uint32_t NumPauses() const; + uint32_t TotalFreezesDurationMs() const; + uint32_t TotalPausesDurationMs() const; + uint32_t TotalFramesDurationMs() const; + double SumSquaredFrameDurationsSec() const; static const uint32_t kMinFrameSamplesToDetectFreeze; static const uint32_t kMinIncreaseForFreezeMs;