From a957570d62481ba414602fcde900f191de63a686 Mon Sep 17 00:00:00 2001 From: "pbos@webrtc.org" Date: Fri, 30 Aug 2013 17:16:32 +0000 Subject: [PATCH] Overuse detection based on capture-input jitter. This is believed to be more reliable in real-world cases. The camera seems to fall behind sooner than the encoder starts taking too long time encoding, so this is believed to be an earlier trigger. BUG=2325 R=asapersson@webrtc.org, mflodman@webrtc.org Review URL: https://webrtc-codereview.appspot.com/2140004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4648 4adac7df-926f-26a2-2b94-8c16560cd09d --- webrtc/video_engine/overuse_frame_detector.cc | 252 ++++++++---------- webrtc/video_engine/overuse_frame_detector.h | 74 +++-- .../overuse_frame_detector_unittest.cc | 189 +++---------- webrtc/video_engine/vie_capturer.cc | 8 - 4 files changed, 184 insertions(+), 339 deletions(-) diff --git a/webrtc/video_engine/overuse_frame_detector.cc b/webrtc/video_engine/overuse_frame_detector.cc index 151a0a2c91..b8c1a0d5a7 100644 --- a/webrtc/video_engine/overuse_frame_detector.cc +++ b/webrtc/video_engine/overuse_frame_detector.cc @@ -11,48 +11,79 @@ #include "webrtc/video_engine/overuse_frame_detector.h" #include +#include #include "webrtc/system_wrappers/interface/clock.h" #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" +#include "webrtc/system_wrappers/interface/trace.h" #include "webrtc/video_engine/include/vie_base.h" namespace webrtc { +Statistics::Statistics() { Reset(); } + +void Statistics::Reset() { + sum_ = sum_squared_ = 0.0; + count_ = 0; +} + +void Statistics::AddSample(double sample) { + sum_ += sample; + sum_squared_ += sample * sample; + ++count_; +} + +double Statistics::Mean() const { + if (count_ == 0) + return 0.0; + return sum_ / count_; +} + +double Statistics::Variance() const { + if (count_ == 0) + return 0.0; + return sum_squared_ / count_ - Mean() * Mean(); +} + +double Statistics::StdDev() const { return sqrt(Variance()); } + +uint64_t Statistics::Samples() const { return count_; } + // TODO(mflodman) Test different values for all of these to trigger correctly, // avoid fluctuations etc. - namespace { -// Interval for 'Process' to be called. -const int64_t kProcessIntervalMs = 2000; +const int64_t kProcessIntervalMs = 5000; -// Duration capture and encode samples are valid. -const int kOveruseHistoryMs = 5000; +// Limits on standard deviation for under/overuse. +const double kOveruseStdDevMs = 15.0; +const double kNormalUseStdDevMs = 10.0; -// The minimum history to trigger an overuse or underuse. -const int64_t kMinValidHistoryMs = kOveruseHistoryMs / 2; +// Rampdown checks. +const int kConsecutiveChecksAboveThreshold = 2; -// Encode / capture ratio to decide an overuse. -const float kMinEncodeRatio = 29 / 30.0f; +// Delay between consecutive rampups. (Used for quick recovery.) +const int kQuickRampUpDelayMs = 10 * 1000; +// Delay between rampup attempts. Initially uses standard, scales up to max. +const int kStandardRampUpDelayMs = 30 * 1000; +const int kMaxRampUpDelayMs = 120 * 1000; +// Expontential back-off factor, to prevent annoying up-down behaviour. +const double kRampUpBackoffFactor = 2.0; -// Minimum time between two callbacks. -const int kMinCallbackDeltaMs = 30000; - -// Safety margin between encode time for different resolutions to decide if we -// can trigger an underuse callback. -// TODO(mflodman): This should be improved, e.g. test time per pixel? -const float kIncreaseThreshold = 1.5f; +// Minimum samples required to perform a check. +const size_t kMinFrameSampleCount = 30; } // namespace OveruseFrameDetector::OveruseFrameDetector(Clock* clock) : crit_(CriticalSectionWrapper::CreateCriticalSection()), observer_(NULL), clock_(clock), - last_process_time_(clock->TimeInMilliseconds()), - last_callback_time_(clock->TimeInMilliseconds()), - underuse_encode_timing_enabled_(false), - num_pixels_(0), - max_num_pixels_(0) { -} + next_process_time_(clock_->TimeInMilliseconds()), + last_capture_time_(0), + last_overuse_time_(0), + checks_above_threshold_(0), + last_rampup_time_(0), + in_quick_rampup_(false), + current_rampup_delay_ms_(kStandardRampUpDelayMs) {} OveruseFrameDetector::~OveruseFrameDetector() { } @@ -62,146 +93,99 @@ void OveruseFrameDetector::SetObserver(CpuOveruseObserver* observer) { observer_ = observer; } -void OveruseFrameDetector::set_underuse_encode_timing_enabled(bool enable) { - CriticalSectionScoped cs(crit_.get()); - underuse_encode_timing_enabled_ = enable; -} - void OveruseFrameDetector::FrameCaptured() { CriticalSectionScoped cs(crit_.get()); - capture_times_.push_back(clock_->TimeInMilliseconds()); -} - -void OveruseFrameDetector::FrameEncoded(int64_t encode_time, size_t width, - size_t height) { - assert(encode_time >= 0); - CriticalSectionScoped cs(crit_.get()); - // The frame is disregarded in case of a reset, to startup in a fresh state. - if (MaybeResetResolution(width, height)) - return; - - encode_times_.push_back(std::make_pair(clock_->TimeInMilliseconds(), - encode_time)); + int64_t time = clock_->TimeInMilliseconds(); + if (last_capture_time_ != 0) { + capture_deltas_.AddSample(time - last_capture_time_); + } + last_capture_time_ = time; } int32_t OveruseFrameDetector::TimeUntilNextProcess() { CriticalSectionScoped cs(crit_.get()); - return last_process_time_ + kProcessIntervalMs - clock_->TimeInMilliseconds(); + return next_process_time_ - clock_->TimeInMilliseconds(); } int32_t OveruseFrameDetector::Process() { CriticalSectionScoped cs(crit_.get()); + int64_t now = clock_->TimeInMilliseconds(); - if (now < last_process_time_ + kProcessIntervalMs) + + // Used to protect against Process() being called too often. + if (now < next_process_time_) return 0; - last_process_time_ = now; - RemoveOldSamples(); + next_process_time_ = now + kProcessIntervalMs; - // Don't trigger an overuse unless we've encoded at least one frame. - if (!observer_ || encode_times_.empty() || capture_times_.empty()) + // Don't trigger overuse unless we've seen any frames + if (capture_deltas_.Samples() < kMinFrameSampleCount) return 0; - // At least half the maximum history should be filled before we trigger an - // overuse. - // TODO(mflodman) Shall the time difference between the first and the last - // sample be checked instead? - if (encode_times_.front().first > now - kMinValidHistoryMs) { - return 0; - } - if (IsOverusing()) { - // Overuse detected. - // Remember the average encode time for this overuse, as a help to trigger - // normal usage. - encode_overuse_times_[num_pixels_] = CalculateAverageEncodeTime(); - RemoveAllSamples(); - observer_->OveruseDetected(); - last_callback_time_ = now; + // If the last thing we did was going up, and now have to back down, we need + // to check if this peak was short. If so we should back off to avoid going + // back and forth between this load, the system doesn't seem to handle it. + bool check_for_backoff = last_rampup_time_ > last_overuse_time_; + if (check_for_backoff) { + if (now - last_rampup_time_ < kStandardRampUpDelayMs) { + // Going up was not ok for very long, back off. + current_rampup_delay_ms_ *= kRampUpBackoffFactor; + if (current_rampup_delay_ms_ > kMaxRampUpDelayMs) + current_rampup_delay_ms_ = kMaxRampUpDelayMs; + } else { + // Not currently backing off, reset rampup delay. + current_rampup_delay_ms_ = kStandardRampUpDelayMs; + } + } + + last_overuse_time_ = now; + in_quick_rampup_ = false; + checks_above_threshold_ = 0; + + if (observer_ != NULL) + observer_->OveruseDetected(); } else if (IsUnderusing(now)) { - RemoveAllSamples(); - observer_->NormalUsage(); - last_callback_time_ = now; + last_rampup_time_ = now; + in_quick_rampup_ = true; + + if (observer_ != NULL) + observer_->NormalUsage(); } + + capture_deltas_.Reset(); + return 0; } -void OveruseFrameDetector::RemoveOldSamples() { - int64_t time_now = clock_->TimeInMilliseconds(); - while (!capture_times_.empty() && - capture_times_.front() < time_now - kOveruseHistoryMs) { - capture_times_.pop_front(); - } - while (!encode_times_.empty() && - encode_times_.front().first < time_now - kOveruseHistoryMs) { - encode_times_.pop_front(); - } -} - -void OveruseFrameDetector::RemoveAllSamples() { - capture_times_.clear(); - encode_times_.clear(); -} - -int64_t OveruseFrameDetector::CalculateAverageEncodeTime() const { - if (encode_times_.empty()) - return 0; - - int64_t total_encode_time = 0; - for (std::list::const_iterator it = encode_times_.begin(); - it != encode_times_.end(); ++it) { - total_encode_time += it->second; - } - return total_encode_time / encode_times_.size(); -} - -bool OveruseFrameDetector::MaybeResetResolution(size_t width, size_t height) { - int num_pixels = width * height; - if (num_pixels == num_pixels_) - return false; - - RemoveAllSamples(); - num_pixels_ = num_pixels; - if (num_pixels > max_num_pixels_) - max_num_pixels_ = num_pixels; - - return true; -} - bool OveruseFrameDetector::IsOverusing() { - if (encode_times_.empty()) - return false; + WEBRTC_TRACE( + webrtc::kTraceInfo, + webrtc::kTraceVideo, + -1, + "Capture input stats: avg: %.2fms, std_dev: %.2fms (rampup delay: " + "%dms, overuse: >=%.2fms, " + "underuse: <%.2fms)", + capture_deltas_.Mean(), + capture_deltas_.StdDev(), + in_quick_rampup_ ? kQuickRampUpDelayMs : current_rampup_delay_ms_, + kOveruseStdDevMs, + kNormalUseStdDevMs); - float encode_ratio = encode_times_.size() / - static_cast(capture_times_.size()); - return encode_ratio < kMinEncodeRatio; + if (capture_deltas_.StdDev() >= kOveruseStdDevMs) { + ++checks_above_threshold_; + } else { + checks_above_threshold_ = 0; + } + + return checks_above_threshold_ >= kConsecutiveChecksAboveThreshold; } bool OveruseFrameDetector::IsUnderusing(int64_t time_now) { - if (time_now < last_callback_time_ + kMinCallbackDeltaMs || - num_pixels_ >= max_num_pixels_) { + int delay = in_quick_rampup_ ? kQuickRampUpDelayMs : current_rampup_delay_ms_; + if (time_now < last_rampup_time_ + delay) return false; - } - bool underusing = true; - if (underuse_encode_timing_enabled_) { - int prev_overuse_encode_time = 0; - for (std::map::reverse_iterator rit = - encode_overuse_times_.rbegin(); - rit != encode_overuse_times_.rend() && rit->first > num_pixels_; - ++rit) { - prev_overuse_encode_time = rit->second; - } - // TODO(mflodman): This might happen now if the resolution is decreased - // by the user before an overuse has been triggered. - assert(prev_overuse_encode_time > 0); - // TODO(mflodman) Use some other way to guess if an increased resolution - // might work or not, e.g. encode time per pixel? - if (CalculateAverageEncodeTime() * kIncreaseThreshold > - prev_overuse_encode_time) { - underusing = false; - } - } - return underusing; + return capture_deltas_.StdDev() < kNormalUseStdDevMs; } } // namespace webrtc diff --git a/webrtc/video_engine/overuse_frame_detector.h b/webrtc/video_engine/overuse_frame_detector.h index 7772266902..00d3b19b8f 100644 --- a/webrtc/video_engine/overuse_frame_detector.h +++ b/webrtc/video_engine/overuse_frame_detector.h @@ -11,10 +11,6 @@ #ifndef WEBRTC_VIDEO_ENGINE_OVERUSE_FRAME_DETECTOR_H_ #define WEBRTC_VIDEO_ENGINE_OVERUSE_FRAME_DETECTOR_H_ -#include -#include -#include - #include "webrtc/modules/interface/module.h" #include "webrtc/system_wrappers/interface/constructor_magic.h" #include "webrtc/system_wrappers/interface/scoped_ptr.h" @@ -25,8 +21,26 @@ class Clock; class CriticalSectionWrapper; class CpuOveruseObserver; -// Use to detect system overuse based on the number of captured frames vs the -// number of encoded frames. +// TODO(pbos): Move this somewhere appropriate +class Statistics { + public: + Statistics(); + + void AddSample(double sample); + void Reset(); + + double Mean() const; + double Variance() const; + double StdDev() const; + uint64_t Samples() const; + + private: + double sum_; + double sum_squared_; + uint64_t count_; +}; + +// Use to detect system overuse based on jitter in incoming frames. class OveruseFrameDetector : public Module { public: explicit OveruseFrameDetector(Clock* clock); @@ -36,33 +50,14 @@ class OveruseFrameDetector : public Module { // 'observer' to NULL to disable callbacks. void SetObserver(CpuOveruseObserver* observer); - // TODO(mflodman): Move to another API? - // Enables usage of encode time to trigger normal usage after an overuse, - // default false. - void set_underuse_encode_timing_enabled(bool enable); - // Called for each captured frame. void FrameCaptured(); - // Called for every encoded frame. - void FrameEncoded(int64_t encode_time, size_t width, size_t height); - // Implements Module. - virtual int32_t TimeUntilNextProcess(); - virtual int32_t Process(); + virtual int32_t TimeUntilNextProcess() OVERRIDE; + virtual int32_t Process() OVERRIDE; private: - // All private functions are assumed to be critical section protected. - // Clear samples older than the overuse history. - void RemoveOldSamples(); - // Clears the entire history, including samples still affecting the - // calculations. - void RemoveAllSamples(); - int64_t CalculateAverageEncodeTime() const; - // Returns true and resets calculations and history if a new resolution is - // discovered, false otherwise. - bool MaybeResetResolution(size_t width, size_t height); - bool IsOverusing(); bool IsUnderusing(int64_t time_now); @@ -73,24 +68,17 @@ class OveruseFrameDetector : public Module { CpuOveruseObserver* observer_; Clock* clock_; - int64_t last_process_time_; - int64_t last_callback_time_; + int64_t next_process_time_; - // Sorted list of times captured frames were delivered, oldest frame first. - std::list capture_times_; - // . - typedef std::pair EncodeTime; - // Sorted list with oldest frame first. - std::list encode_times_; + Statistics capture_deltas_; + int64_t last_capture_time_; - // True if encode time should be considered to trigger an underuse. - bool underuse_encode_timing_enabled_; - // Number of pixels in the currently encoded resolution. - int num_pixels_; - // Maximum resolution encoded. - int max_num_pixels_; - // . - std::map encode_overuse_times_; + int64_t last_overuse_time_; + int checks_above_threshold_; + + int64_t last_rampup_time_; + bool in_quick_rampup_; + int current_rampup_delay_ms_; DISALLOW_COPY_AND_ASSIGN(OveruseFrameDetector); }; diff --git a/webrtc/video_engine/overuse_frame_detector_unittest.cc b/webrtc/video_engine/overuse_frame_detector_unittest.cc index c5398feec6..616b13dc64 100644 --- a/webrtc/video_engine/overuse_frame_detector_unittest.cc +++ b/webrtc/video_engine/overuse_frame_detector_unittest.cc @@ -16,17 +16,8 @@ #include "webrtc/video_engine/include/vie_base.h" #include "webrtc/video_engine/overuse_frame_detector.h" -using ::testing::_; -using ::testing::AnyNumber; -using ::testing::Return; - namespace webrtc { -const int kProcessIntervalMs = 2000; -const int kOveruseHistoryMs = 5000; -const int kMinCallbackDeltaMs = 30000; -const int64_t kMinValidHistoryMs = kOveruseHistoryMs / 2; - class MockCpuOveruseObserver : public CpuOveruseObserver { public: MockCpuOveruseObserver() {} @@ -45,29 +36,34 @@ class OveruseFrameDetectorTest : public ::testing::Test { overuse_detector_->SetObserver(observer_.get()); } - void CaptureAndEncodeFrames(int num_frames, int64_t frame_interval_ms, - int encode_time_ms, size_t width, size_t height) { - for (int frame = 0; frame < num_frames; ++frame) { + void InsertFramesWithInterval(size_t num_frames, int interval_ms) { + while (num_frames-- > 0) { + clock_->AdvanceTimeMilliseconds(interval_ms); overuse_detector_->FrameCaptured(); - overuse_detector_->FrameEncoded(encode_time_ms, width, height); - clock_->AdvanceTimeMilliseconds(frame_interval_ms); } } - void CaptureAndEncodeWithOveruse(int overuse_time_ms, - int64_t frame_interval_ms, - int64_t encode_time_ms, size_t width, - size_t height) { - // 'encodes_before_dropping' is derived from 'kMinEncodeRatio' in - // 'overuse_frame_detector.h'. - const int encodes_before_dropping = 14; - for (int time_ms = 0; time_ms < overuse_time_ms; - time_ms += frame_interval_ms * (1 + encodes_before_dropping)) { - CaptureAndEncodeFrames(encodes_before_dropping, frame_interval_ms, - encode_time_ms, width, height); - overuse_detector_->FrameCaptured(); - clock_->AdvanceTimeMilliseconds(frame_interval_ms); - } + void TriggerOveruse() { + int regular_frame_interval_ms = 33; + + EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1); + + InsertFramesWithInterval(30, regular_frame_interval_ms); + InsertFramesWithInterval(30, 1000); + overuse_detector_->Process(); + + InsertFramesWithInterval(30, regular_frame_interval_ms); + InsertFramesWithInterval(30, 1000); + overuse_detector_->Process(); + } + + void TriggerNormalUsage() { + int regular_frame_interval_ms = 33; + + EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(testing::AtLeast(1)); + + InsertFramesWithInterval(300, regular_frame_interval_ms); + overuse_detector_->Process(); } scoped_ptr clock_; @@ -76,140 +72,25 @@ class OveruseFrameDetectorTest : public ::testing::Test { }; TEST_F(OveruseFrameDetectorTest, TriggerOveruse) { - EXPECT_EQ(overuse_detector_->TimeUntilNextProcess(), kProcessIntervalMs); - - // Enough history to trigger an overuse, but life is good so far. - int frame_interval_ms = 33; - int num_frames = kMinValidHistoryMs / frame_interval_ms + 1; - CaptureAndEncodeFrames(num_frames, frame_interval_ms, 2, 2, 2); - EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0); - overuse_detector_->Process(); - - // Trigger an overuse. - CaptureAndEncodeWithOveruse(kOveruseHistoryMs, frame_interval_ms, 2, 2, 2); - EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1); - overuse_detector_->Process(); + TriggerOveruse(); } TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) { - overuse_detector_->set_underuse_encode_timing_enabled(true); - // Start with triggering an overuse. - // A new resolution will trigger a reset, so add one frame to get going. - int frame_interval_ms = 33; - CaptureAndEncodeWithOveruse(kMinValidHistoryMs, frame_interval_ms, 2, 2, 2); - EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1); - overuse_detector_->Process(); - - // Make everything good again, but don't advance time long enough to trigger - // an underuse. - int num_frames = kOveruseHistoryMs / frame_interval_ms; - CaptureAndEncodeFrames(num_frames, frame_interval_ms, 1, 1, 1); - EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0); - overuse_detector_->Process(); - - // Advance time long enough to trigger an increase callback. - num_frames = (kMinCallbackDeltaMs - kOveruseHistoryMs + 1) / - (frame_interval_ms - 0.5f); - CaptureAndEncodeFrames(num_frames, frame_interval_ms, 1, 1, 1); - EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(1); - overuse_detector_->Process(); + TriggerOveruse(); + TriggerNormalUsage(); } TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) { - overuse_detector_->set_underuse_encode_timing_enabled(true); - // Start with triggering an overuse. - int frame_interval_ms = 33; - CaptureAndEncodeWithOveruse(kMinValidHistoryMs, frame_interval_ms, 16, 4, 4); - EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1); - overuse_detector_->Process(); + TriggerOveruse(); + TriggerOveruse(); + TriggerNormalUsage(); +} - CaptureAndEncodeWithOveruse(kOveruseHistoryMs, frame_interval_ms, 4, 2, 2); - EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1); - overuse_detector_->Process(); - - // Let life be good again and wait for an underuse callback. - int num_frames = kMinCallbackDeltaMs / (frame_interval_ms - 0.5f); - CaptureAndEncodeFrames(num_frames, frame_interval_ms, 1, 1, 1); - EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(1); - overuse_detector_->Process(); - - // And one more. - CaptureAndEncodeFrames(num_frames, frame_interval_ms, 4, 2, 2); - EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(1); - overuse_detector_->Process(); - - // But no more since we're at the max resolution. - CaptureAndEncodeFrames(num_frames, frame_interval_ms, 4, 4, 4); +TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) { EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0); - overuse_detector_->Process(); + + for(size_t i = 0; i < 64; ++i) + TriggerOveruse(); } -TEST_F(OveruseFrameDetectorTest, OveruseAndNoRecovery) { - overuse_detector_->set_underuse_encode_timing_enabled(true); - // Start with triggering an overuse. - int frame_interval_ms = 33; - CaptureAndEncodeWithOveruse(kMinValidHistoryMs, frame_interval_ms, 4, 2, 2); - EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1); - overuse_detector_->Process(); - - // Everything is fine, but we haven't waited long enough to trigger an - // increase callback. - CaptureAndEncodeFrames(30, 33, 3, 1, 1); - EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0); - overuse_detector_->Process(); - - // Advance time enough to trigger an increase callback, but encode time - // shouldn't have decreased enough to try an increase. - int num_frames = kMinCallbackDeltaMs / (frame_interval_ms - 0.5f); - CaptureAndEncodeFrames(num_frames, frame_interval_ms, 3, 1, 1); - EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0); - overuse_detector_->Process(); -} - -TEST_F(OveruseFrameDetectorTest, NoEncodeTimeForUnderuse) { - overuse_detector_->set_underuse_encode_timing_enabled(false); - // Start with triggering an overuse. - int frame_interval_ms = 33; - CaptureAndEncodeWithOveruse(kMinValidHistoryMs, frame_interval_ms, 4, 2, 2); - EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1); - overuse_detector_->Process(); - - // Everything is fine, but we haven't waited long enough to trigger an - // increase callback. - int num_frames = 1000 / (frame_interval_ms - 0.5f); - CaptureAndEncodeFrames(num_frames, frame_interval_ms, 3, 1, 1); - EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0); - overuse_detector_->Process(); - - // Advance time enough to allow underuse, but keep encode time too high to - // trigger an underuse if accounted for, see 'OveruseAndNoRecovery' test case. - num_frames = kMinCallbackDeltaMs / (frame_interval_ms - 0.5f); - CaptureAndEncodeFrames(num_frames, frame_interval_ms, 3, 1, 1); - EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(1); - overuse_detector_->Process(); -} - -TEST_F(OveruseFrameDetectorTest, ResolutionChange) { - overuse_detector_->set_underuse_encode_timing_enabled(true); - int frame_interval_ms = 33; - CaptureAndEncodeWithOveruse(kMinValidHistoryMs / 2, frame_interval_ms, 3, 1, - 1); - - // Keep overusing, but with a new resolution. - CaptureAndEncodeWithOveruse(kMinValidHistoryMs - frame_interval_ms, - frame_interval_ms, 4, 2, 2); - - // Enough samples and time to trigger an overuse, but resolution reset should - // prevent this. - EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0); - overuse_detector_->Process(); - - // Fill the history. - CaptureAndEncodeFrames(2, kOveruseHistoryMs / 2, 3, 1, 1); - - // Capture a frame without finish encoding to trigger an overuse. - overuse_detector_->FrameCaptured(); - EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1); - overuse_detector_->Process(); -} } // namespace webrtc diff --git a/webrtc/video_engine/vie_capturer.cc b/webrtc/video_engine/vie_capturer.cc index 66f3eec4b2..cc08ffaae1 100644 --- a/webrtc/video_engine/vie_capturer.cc +++ b/webrtc/video_engine/vie_capturer.cc @@ -518,15 +518,7 @@ bool ViECapturer::ViECaptureProcess() { captured_frame_.ResetSize(); capture_cs_->Leave(); - int64_t encode_start_time = - Clock::GetRealTimeClock()->TimeInMilliseconds(); DeliverI420Frame(&deliver_frame_); - - // The frame has been encoded, update the overuse detector with the - // duration. - overuse_detector_->FrameEncoded( - Clock::GetRealTimeClock()->TimeInMilliseconds() - encode_start_time, - deliver_frame_.width(), deliver_frame_.height()); } deliver_cs_->Leave(); if (current_brightness_level_ != reported_brightness_level_) {