From 1aa420b6aa70bd97cbe33e396e5dc0346aeb6415 Mon Sep 17 00:00:00 2001 From: asapersson Date: Mon, 7 Dec 2015 03:12:22 -0800 Subject: [PATCH] Remove avg encode time from CpuOveruseMetric struct and use value from OnEncodedFrame instead. BUG= Review URL: https://codereview.webrtc.org/1278383002 Cr-Commit-Position: refs/heads/master@{#10911} --- webrtc/video/send_statistics_proxy.cc | 8 +-- webrtc/video/send_statistics_proxy.h | 2 + .../video/send_statistics_proxy_unittest.cc | 8 +++ webrtc/video_engine/overuse_frame_detector.cc | 53 +++---------------- webrtc/video_engine/overuse_frame_detector.h | 8 +-- .../overuse_frame_detector_unittest.cc | 12 ----- 6 files changed, 24 insertions(+), 67 deletions(-) diff --git a/webrtc/video/send_statistics_proxy.cc b/webrtc/video/send_statistics_proxy.cc index 8dd91d90f4..57d38a523b 100644 --- a/webrtc/video/send_statistics_proxy.cc +++ b/webrtc/video/send_statistics_proxy.cc @@ -15,13 +15,14 @@ #include #include "webrtc/base/checks.h" - #include "webrtc/base/logging.h" #include "webrtc/system_wrappers/include/critical_section_wrapper.h" #include "webrtc/system_wrappers/include/metrics.h" namespace webrtc { namespace { +const float kEncodeTimeWeigthFactor = 0.5f; + // Used by histograms. Values of entries should not be changed. enum HistogramCodecType { kVideoUnknown = 0, @@ -72,6 +73,7 @@ SendStatisticsProxy::SendStatisticsProxy( config_(config), content_type_(content_type), last_sent_frame_timestamp_(0), + encode_time_(kEncodeTimeWeigthFactor), uma_container_(new UmaSamplesContainer(GetUmaPrefix(content_type_))) { UpdateCodecTypeHistogram(config_.encoder_settings.payload_name); } @@ -168,8 +170,6 @@ void SendStatisticsProxy::OnOutgoingRate(uint32_t framerate, uint32_t bitrate) { 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; } @@ -308,6 +308,8 @@ void SendStatisticsProxy::OnIncomingFrame(int width, int height) { void SendStatisticsProxy::OnEncodedFrame(int encode_time_ms) { rtc::CritScope lock(&crit_); uma_container_->encode_time_counter_.Add(encode_time_ms); + encode_time_.Apply(1.0f, encode_time_ms); + stats_.avg_encode_time_ms = round(encode_time_.filtered()); } void SendStatisticsProxy::RtcpPacketTypesCounterUpdated( diff --git a/webrtc/video/send_statistics_proxy.h b/webrtc/video/send_statistics_proxy.h index a2b840eff6..4098e33f62 100644 --- a/webrtc/video/send_statistics_proxy.h +++ b/webrtc/video/send_statistics_proxy.h @@ -14,6 +14,7 @@ #include #include "webrtc/base/criticalsection.h" +#include "webrtc/base/exp_filter.h" #include "webrtc/base/ratetracker.h" #include "webrtc/base/scoped_ptr.h" #include "webrtc/base/thread_annotations.h" @@ -133,6 +134,7 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver, VideoSendStream::Stats stats_ GUARDED_BY(crit_); uint32_t last_sent_frame_timestamp_ GUARDED_BY(crit_); std::map update_times_ GUARDED_BY(crit_); + rtc::ExpFilter encode_time_ GUARDED_BY(crit_); // Contains stats used for UMA histograms. These stats will be reset if // content type changes between real-time video and screenshare, since these diff --git a/webrtc/video/send_statistics_proxy_unittest.cc b/webrtc/video/send_statistics_proxy_unittest.cc index 1bf9814412..f098ce2d23 100644 --- a/webrtc/video/send_statistics_proxy_unittest.cc +++ b/webrtc/video/send_statistics_proxy_unittest.cc @@ -288,6 +288,14 @@ TEST_F(SendStatisticsProxyTest, SendSideDelay) { ExpectEqual(expected_, stats); } +TEST_F(SendStatisticsProxyTest, OnEncodedFrame) { + const int kEncodeTimeMs = 11; + statistics_proxy_->OnEncodedFrame(kEncodeTimeMs); + + VideoSendStream::Stats stats = statistics_proxy_->GetStats(); + EXPECT_EQ(kEncodeTimeMs, stats.avg_encode_time_ms); +} + TEST_F(SendStatisticsProxyTest, NoSubstreams) { uint32_t excluded_ssrc = std::max( diff --git a/webrtc/video_engine/overuse_frame_detector.cc b/webrtc/video_engine/overuse_frame_detector.cc index 47a6e496b9..264bedd9b3 100644 --- a/webrtc/video_engine/overuse_frame_detector.cc +++ b/webrtc/video_engine/overuse_frame_detector.cc @@ -44,33 +44,6 @@ const float kMaxExp = 7.0f; } // namespace -// Class for calculating the average encode time. -class OveruseFrameDetector::EncodeTimeAvg { - public: - EncodeTimeAvg() - : kWeightFactor(0.5f), - kInitialAvgEncodeTimeMs(5.0f), - filtered_encode_time_ms_(new rtc::ExpFilter(kWeightFactor)) { - filtered_encode_time_ms_->Apply(1.0f, kInitialAvgEncodeTimeMs); - } - ~EncodeTimeAvg() {} - - void AddSample(float encode_time_ms, int64_t diff_last_sample_ms) { - float exp = diff_last_sample_ms / kSampleDiffMs; - exp = std::min(exp, kMaxExp); - filtered_encode_time_ms_->Apply(exp, encode_time_ms); - } - - int Value() const { - return static_cast(filtered_encode_time_ms_->filtered() + 0.5); - } - - private: - const float kWeightFactor; - const float kInitialAvgEncodeTimeMs; - rtc::scoped_ptr filtered_encode_time_ms_; -}; - // Class for calculating the processing usage on the send-side (the average // processing time of a frame divided by the average time difference between // captured frames). @@ -209,9 +182,7 @@ OveruseFrameDetector::OveruseFrameDetector( last_rampup_time_(0), in_quick_rampup_(false), current_rampup_delay_ms_(kStandardRampUpDelayMs), - last_encode_sample_ms_(0), last_sample_time_ms_(0), - encode_time_(new EncodeTimeAvg()), usage_(new SendProcessingUsage(options)), frame_queue_(new FrameQueue()) { RTC_DCHECK(metrics_observer != nullptr); @@ -236,7 +207,6 @@ int OveruseFrameDetector::FramesInQueue() const { } void OveruseFrameDetector::UpdateCpuOveruseMetrics() { - metrics_.avg_encode_time_ms = encode_time_->Value(); metrics_.encode_usage_percent = usage_->Value(); metrics_observer_->CpuOveruseMetricsUpdated(metrics_); @@ -291,31 +261,23 @@ void OveruseFrameDetector::FrameCaptured(int width, } void OveruseFrameDetector::FrameEncoded(int encode_time_ms) { - rtc::CritScope cs(&crit_); - int64_t now = clock_->TimeInMilliseconds(); - if (last_encode_sample_ms_ != 0) { - int64_t diff_ms = now - last_encode_sample_ms_; - encode_time_->AddSample(encode_time_ms, diff_ms); - } - last_encode_sample_ms_ = now; + if (options_.enable_extended_processing_usage) + return; - if (!options_.enable_extended_processing_usage) { - AddProcessingTime(encode_time_ms); - } - UpdateCpuOveruseMetrics(); + rtc::CritScope cs(&crit_); + AddProcessingTime(encode_time_ms); } void OveruseFrameDetector::FrameSent(int64_t capture_time_ms) { - rtc::CritScope cs(&crit_); - if (!options_.enable_extended_processing_usage) { + if (!options_.enable_extended_processing_usage) return; - } + + rtc::CritScope cs(&crit_); int delay_ms = frame_queue_->End(capture_time_ms, clock_->TimeInMilliseconds()); if (delay_ms > 0) { AddProcessingTime(delay_ms); } - UpdateCpuOveruseMetrics(); } void OveruseFrameDetector::AddProcessingTime(int elapsed_ms) { @@ -325,6 +287,7 @@ void OveruseFrameDetector::AddProcessingTime(int elapsed_ms) { usage_->AddSample(elapsed_ms, diff_ms); } last_sample_time_ms_ = now; + UpdateCpuOveruseMetrics(); } int32_t OveruseFrameDetector::Process() { diff --git a/webrtc/video_engine/overuse_frame_detector.h b/webrtc/video_engine/overuse_frame_detector.h index 050b14fd00..63281d2373 100644 --- a/webrtc/video_engine/overuse_frame_detector.h +++ b/webrtc/video_engine/overuse_frame_detector.h @@ -67,11 +67,8 @@ struct CpuOveruseOptions { }; struct CpuOveruseMetrics { - CpuOveruseMetrics() - : avg_encode_time_ms(-1), - encode_usage_percent(-1) {} + CpuOveruseMetrics() : encode_usage_percent(-1) {} - int avg_encode_time_ms; // Average encode time in ms. int encode_usage_percent; // Average encode time divided by the average time // difference between incoming captured frames. }; @@ -111,7 +108,6 @@ class OveruseFrameDetector : public Module { int32_t Process() override; private: - class EncodeTimeAvg; class SendProcessingUsage; class FrameQueue; @@ -162,12 +158,10 @@ class OveruseFrameDetector : public Module { bool in_quick_rampup_; int current_rampup_delay_ms_; - int64_t last_encode_sample_ms_; // Only accessed by one thread. int64_t last_sample_time_ms_; // Only accessed by one thread. // TODO(asapersson): Can these be regular members (avoid separate heap // allocs)? - const rtc::scoped_ptr encode_time_ GUARDED_BY(crit_); const rtc::scoped_ptr usage_ GUARDED_BY(crit_); const rtc::scoped_ptr frame_queue_ GUARDED_BY(crit_); diff --git a/webrtc/video_engine/overuse_frame_detector_unittest.cc b/webrtc/video_engine/overuse_frame_detector_unittest.cc index 5524ba5a0f..f6f6bf5600 100644 --- a/webrtc/video_engine/overuse_frame_detector_unittest.cc +++ b/webrtc/video_engine/overuse_frame_detector_unittest.cc @@ -103,8 +103,6 @@ class OveruseFrameDetectorTest : public ::testing::Test, overuse_detector_->Process(); } - int AvgEncodeTimeMs() { return metrics_.avg_encode_time_ms; } - int UsagePercent() { return metrics_.encode_usage_percent; } CpuOveruseOptions options_; @@ -356,16 +354,6 @@ TEST_F(OveruseFrameDetectorTest, FrameDelay_NonMatchingSendFrameIgnored) { EXPECT_EQ(kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs()); } -TEST_F(OveruseFrameDetectorTest, EncodedFrame) { - const int kInitialAvgEncodeTimeInMs = 5; - EXPECT_EQ(kInitialAvgEncodeTimeInMs, AvgEncodeTimeMs()); - for (int i = 0; i < 30; i++) { - clock_->AdvanceTimeMilliseconds(33); - overuse_detector_->FrameEncoded(2); - } - EXPECT_EQ(2, AvgEncodeTimeMs()); -} - // enable_encode_usage_method = true; // enable_extended_processing_usage = true; // UsagePercent() > high_encode_usage_threshold_percent => overuse.