Home | History | Annotate | Download | only in video_engine
      1 /*
      2  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include "testing/gmock/include/gmock/gmock.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 
     14 #include "webrtc/system_wrappers/interface/clock.h"
     15 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
     16 #include "webrtc/video_engine/include/vie_base.h"
     17 #include "webrtc/video_engine/overuse_frame_detector.h"
     18 
     19 namespace webrtc {
     20 namespace {
     21   const int kWidth = 640;
     22   const int kHeight = 480;
     23   const int kFrameInterval33ms = 33;
     24   const int kProcessIntervalMs = 5000;
     25 }  // namespace
     26 
     27 class MockCpuOveruseObserver : public CpuOveruseObserver {
     28  public:
     29   MockCpuOveruseObserver() {}
     30   virtual ~MockCpuOveruseObserver() {}
     31 
     32   MOCK_METHOD0(OveruseDetected, void());
     33   MOCK_METHOD0(NormalUsage, void());
     34 };
     35 
     36 class CpuOveruseObserverImpl : public CpuOveruseObserver {
     37  public:
     38   CpuOveruseObserverImpl() :
     39     overuse_(0),
     40     normaluse_(0) {}
     41   virtual ~CpuOveruseObserverImpl() {}
     42 
     43   void OveruseDetected() { ++overuse_; }
     44   void NormalUsage() { ++normaluse_; }
     45 
     46   int overuse_;
     47   int normaluse_;
     48 };
     49 
     50 class OveruseFrameDetectorTest : public ::testing::Test {
     51  protected:
     52   virtual void SetUp() {
     53     clock_.reset(new SimulatedClock(1234));
     54     observer_.reset(new MockCpuOveruseObserver());
     55     overuse_detector_.reset(new OveruseFrameDetector(clock_.get()));
     56 
     57     options_.low_capture_jitter_threshold_ms = 10.0f;
     58     options_.high_capture_jitter_threshold_ms = 15.0f;
     59     options_.min_process_count = 0;
     60     overuse_detector_->SetOptions(options_);
     61     overuse_detector_->SetObserver(observer_.get());
     62   }
     63 
     64   int InitialJitter() {
     65     return ((options_.low_capture_jitter_threshold_ms +
     66              options_.high_capture_jitter_threshold_ms) / 2.0f) + 0.5;
     67   }
     68 
     69   int InitialEncodeUsage() {
     70     return ((options_.low_encode_usage_threshold_percent +
     71              options_.high_encode_usage_threshold_percent) / 2.0f) + 0.5;
     72   }
     73 
     74   int InitialEncodeRsd() {
     75     return std::max(
     76         ((options_.low_encode_time_rsd_threshold +
     77           options_.high_encode_time_rsd_threshold) / 2.0f) + 0.5f, 0.0f);
     78   }
     79 
     80   void InsertFramesWithInterval(
     81       size_t num_frames, int interval_ms, int width, int height) {
     82     while (num_frames-- > 0) {
     83       clock_->AdvanceTimeMilliseconds(interval_ms);
     84       overuse_detector_->FrameCaptured(width, height);
     85     }
     86   }
     87 
     88   void InsertAndEncodeFramesWithInterval(
     89       int num_frames, int interval_ms, int width, int height, int encode_ms) {
     90     while (num_frames-- > 0) {
     91       overuse_detector_->FrameCaptured(width, height);
     92       clock_->AdvanceTimeMilliseconds(encode_ms);
     93       overuse_detector_->FrameEncoded(encode_ms);
     94       clock_->AdvanceTimeMilliseconds(interval_ms - encode_ms);
     95     }
     96   }
     97 
     98   void TriggerOveruse(int num_times) {
     99     for (int i = 0; i < num_times; ++i) {
    100       InsertFramesWithInterval(200, kFrameInterval33ms, kWidth, kHeight);
    101       InsertFramesWithInterval(50, 110, kWidth, kHeight);
    102       overuse_detector_->Process();
    103     }
    104   }
    105 
    106   void TriggerNormalUsage() {
    107     InsertFramesWithInterval(900, kFrameInterval33ms, kWidth, kHeight);
    108     overuse_detector_->Process();
    109   }
    110 
    111   void TriggerOveruseWithEncodeUsage(int num_times) {
    112     const int kEncodeTimeMs = 32;
    113     for (int i = 0; i < num_times; ++i) {
    114       InsertAndEncodeFramesWithInterval(
    115           1000, kFrameInterval33ms, kWidth, kHeight, kEncodeTimeMs);
    116       overuse_detector_->Process();
    117     }
    118   }
    119 
    120   void TriggerOveruseWithEncodeRsd(int num_times) {
    121     const int kEncodeTimeMs1 = 10;
    122     const int kEncodeTimeMs2 = 25;
    123     for (int i = 0; i < num_times; ++i) {
    124       InsertAndEncodeFramesWithInterval(
    125           200, kFrameInterval33ms, kWidth, kHeight, kEncodeTimeMs1);
    126       InsertAndEncodeFramesWithInterval(
    127           10, kFrameInterval33ms, kWidth, kHeight, kEncodeTimeMs2);
    128       overuse_detector_->Process();
    129     }
    130   }
    131 
    132   void TriggerNormalUsageWithEncodeTime() {
    133     const int kEncodeTimeMs = 5;
    134     InsertAndEncodeFramesWithInterval(
    135         1000, kFrameInterval33ms, kWidth, kHeight, kEncodeTimeMs);
    136     overuse_detector_->Process();
    137   }
    138 
    139   int CaptureJitterMs() {
    140     CpuOveruseMetrics metrics;
    141     overuse_detector_->GetCpuOveruseMetrics(&metrics);
    142     return metrics.capture_jitter_ms;
    143   }
    144 
    145   int AvgEncodeTimeMs() {
    146     CpuOveruseMetrics metrics;
    147     overuse_detector_->GetCpuOveruseMetrics(&metrics);
    148     return metrics.avg_encode_time_ms;
    149   }
    150 
    151   int EncodeUsagePercent() {
    152     CpuOveruseMetrics metrics;
    153     overuse_detector_->GetCpuOveruseMetrics(&metrics);
    154     return metrics.encode_usage_percent;
    155   }
    156 
    157   int EncodeRsd() {
    158     CpuOveruseMetrics metrics;
    159     overuse_detector_->GetCpuOveruseMetrics(&metrics);
    160     return metrics.encode_rsd;
    161   }
    162 
    163   CpuOveruseOptions options_;
    164   scoped_ptr<SimulatedClock> clock_;
    165   scoped_ptr<MockCpuOveruseObserver> observer_;
    166   scoped_ptr<OveruseFrameDetector> overuse_detector_;
    167 };
    168 
    169 // enable_capture_jitter_method = true;
    170 // CaptureJitterMs() > high_capture_jitter_threshold_ms => overuse.
    171 // CaptureJitterMs() < low_capture_jitter_threshold_ms => underuse.
    172 TEST_F(OveruseFrameDetectorTest, TriggerOveruse) {
    173   // capture_jitter > high => overuse
    174   EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
    175   TriggerOveruse(options_.high_threshold_consecutive_count);
    176 }
    177 
    178 TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) {
    179   // capture_jitter > high => overuse
    180   EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
    181   TriggerOveruse(options_.high_threshold_consecutive_count);
    182   // capture_jitter < low => underuse
    183   EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(testing::AtLeast(1));
    184   TriggerNormalUsage();
    185 }
    186 
    187 TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithNoObserver) {
    188   overuse_detector_->SetObserver(NULL);
    189   EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0);
    190   TriggerOveruse(options_.high_threshold_consecutive_count);
    191   EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
    192   TriggerNormalUsage();
    193 }
    194 
    195 TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithMethodDisabled) {
    196   options_.enable_capture_jitter_method = false;
    197   options_.enable_encode_usage_method = false;
    198   overuse_detector_->SetOptions(options_);
    199   EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0);
    200   TriggerOveruse(options_.high_threshold_consecutive_count);
    201   EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
    202   TriggerNormalUsage();
    203 }
    204 
    205 TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) {
    206   EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(2);
    207   TriggerOveruse(options_.high_threshold_consecutive_count);
    208   TriggerOveruse(options_.high_threshold_consecutive_count);
    209   EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(testing::AtLeast(1));
    210   TriggerNormalUsage();
    211 }
    212 
    213 TEST_F(OveruseFrameDetectorTest, TriggerNormalUsageWithMinProcessCount) {
    214   CpuOveruseObserverImpl overuse_observer_;
    215   overuse_detector_->SetObserver(&overuse_observer_);
    216   options_.min_process_count = 1;
    217   overuse_detector_->SetOptions(options_);
    218   InsertFramesWithInterval(900, kFrameInterval33ms, kWidth, kHeight);
    219   overuse_detector_->Process();
    220   EXPECT_EQ(0, overuse_observer_.normaluse_);
    221   clock_->AdvanceTimeMilliseconds(kProcessIntervalMs);
    222   overuse_detector_->Process();
    223   EXPECT_EQ(1, overuse_observer_.normaluse_);
    224 }
    225 
    226 TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) {
    227   EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
    228   EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(64);
    229   for(size_t i = 0; i < 64; ++i) {
    230     TriggerOveruse(options_.high_threshold_consecutive_count);
    231   }
    232 }
    233 
    234 TEST_F(OveruseFrameDetectorTest, ConsecutiveCountTriggersOveruse) {
    235   EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
    236   options_.high_threshold_consecutive_count = 2;
    237   overuse_detector_->SetOptions(options_);
    238   TriggerOveruse(2);
    239 }
    240 
    241 TEST_F(OveruseFrameDetectorTest, IncorrectConsecutiveCountTriggersNoOveruse) {
    242   EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0);
    243   options_.high_threshold_consecutive_count = 2;
    244   overuse_detector_->SetOptions(options_);
    245   TriggerOveruse(1);
    246 }
    247 
    248 TEST_F(OveruseFrameDetectorTest, GetCpuOveruseMetrics) {
    249   CpuOveruseMetrics metrics;
    250   overuse_detector_->GetCpuOveruseMetrics(&metrics);
    251   EXPECT_GT(metrics.capture_jitter_ms, 0);
    252   EXPECT_GT(metrics.avg_encode_time_ms, 0);
    253   EXPECT_GT(metrics.encode_usage_percent, 0);
    254   EXPECT_GE(metrics.capture_queue_delay_ms_per_s, 0);
    255   EXPECT_GE(metrics.encode_rsd, 0);
    256 }
    257 
    258 TEST_F(OveruseFrameDetectorTest, CaptureJitter) {
    259   EXPECT_EQ(InitialJitter(), CaptureJitterMs());
    260   InsertFramesWithInterval(1000, kFrameInterval33ms, kWidth, kHeight);
    261   EXPECT_NE(InitialJitter(), CaptureJitterMs());
    262 }
    263 
    264 TEST_F(OveruseFrameDetectorTest, CaptureJitterResetAfterResolutionChange) {
    265   EXPECT_EQ(InitialJitter(), CaptureJitterMs());
    266   InsertFramesWithInterval(1000, kFrameInterval33ms, kWidth, kHeight);
    267   EXPECT_NE(InitialJitter(), CaptureJitterMs());
    268   // Verify reset.
    269   InsertFramesWithInterval(1, kFrameInterval33ms, kWidth, kHeight + 1);
    270   EXPECT_EQ(InitialJitter(), CaptureJitterMs());
    271 }
    272 
    273 TEST_F(OveruseFrameDetectorTest, CaptureJitterResetAfterFrameTimeout) {
    274   EXPECT_EQ(InitialJitter(), CaptureJitterMs());
    275   InsertFramesWithInterval(1000, kFrameInterval33ms, kWidth, kHeight);
    276   EXPECT_NE(InitialJitter(), CaptureJitterMs());
    277   InsertFramesWithInterval(
    278       1, options_.frame_timeout_interval_ms, kWidth, kHeight);
    279   EXPECT_NE(InitialJitter(), CaptureJitterMs());
    280   // Verify reset.
    281   InsertFramesWithInterval(
    282       1, options_.frame_timeout_interval_ms + 1, kWidth, kHeight);
    283   EXPECT_EQ(InitialJitter(), CaptureJitterMs());
    284 }
    285 
    286 TEST_F(OveruseFrameDetectorTest, CaptureJitterResetAfterChangingThreshold) {
    287   EXPECT_EQ(InitialJitter(), CaptureJitterMs());
    288   options_.high_capture_jitter_threshold_ms = 90.0f;
    289   overuse_detector_->SetOptions(options_);
    290   EXPECT_EQ(InitialJitter(), CaptureJitterMs());
    291   options_.low_capture_jitter_threshold_ms = 30.0f;
    292   overuse_detector_->SetOptions(options_);
    293   EXPECT_EQ(InitialJitter(), CaptureJitterMs());
    294 }
    295 
    296 TEST_F(OveruseFrameDetectorTest, MinFrameSamplesBeforeUpdatingCaptureJitter) {
    297   options_.min_frame_samples = 40;
    298   overuse_detector_->SetOptions(options_);
    299   InsertFramesWithInterval(40, kFrameInterval33ms, kWidth, kHeight);
    300   EXPECT_EQ(InitialJitter(), CaptureJitterMs());
    301 }
    302 
    303 TEST_F(OveruseFrameDetectorTest, NoCaptureQueueDelay) {
    304   EXPECT_EQ(overuse_detector_->CaptureQueueDelayMsPerS(), 0);
    305   overuse_detector_->FrameCaptured(kWidth, kHeight);
    306   overuse_detector_->FrameProcessingStarted();
    307   EXPECT_EQ(overuse_detector_->CaptureQueueDelayMsPerS(), 0);
    308 }
    309 
    310 TEST_F(OveruseFrameDetectorTest, CaptureQueueDelay) {
    311   overuse_detector_->FrameCaptured(kWidth, kHeight);
    312   clock_->AdvanceTimeMilliseconds(100);
    313   overuse_detector_->FrameProcessingStarted();
    314   EXPECT_EQ(overuse_detector_->CaptureQueueDelayMsPerS(), 100);
    315 }
    316 
    317 TEST_F(OveruseFrameDetectorTest, CaptureQueueDelayMultipleFrames) {
    318   overuse_detector_->FrameCaptured(kWidth, kHeight);
    319   clock_->AdvanceTimeMilliseconds(10);
    320   overuse_detector_->FrameCaptured(kWidth, kHeight);
    321   clock_->AdvanceTimeMilliseconds(20);
    322 
    323   overuse_detector_->FrameProcessingStarted();
    324   EXPECT_EQ(overuse_detector_->CaptureQueueDelayMsPerS(), 30);
    325   overuse_detector_->FrameProcessingStarted();
    326   EXPECT_EQ(overuse_detector_->CaptureQueueDelayMsPerS(), 20);
    327 }
    328 
    329 TEST_F(OveruseFrameDetectorTest, CaptureQueueDelayResetAtResolutionSwitch) {
    330   overuse_detector_->FrameCaptured(kWidth, kHeight);
    331   clock_->AdvanceTimeMilliseconds(10);
    332   overuse_detector_->FrameCaptured(kWidth, kHeight + 1);
    333   clock_->AdvanceTimeMilliseconds(20);
    334 
    335   overuse_detector_->FrameProcessingStarted();
    336   EXPECT_EQ(overuse_detector_->CaptureQueueDelayMsPerS(), 20);
    337 }
    338 
    339 TEST_F(OveruseFrameDetectorTest, CaptureQueueDelayNoMatchingCapturedFrame) {
    340   overuse_detector_->FrameCaptured(kWidth, kHeight);
    341   clock_->AdvanceTimeMilliseconds(100);
    342   overuse_detector_->FrameProcessingStarted();
    343   EXPECT_EQ(overuse_detector_->CaptureQueueDelayMsPerS(), 100);
    344   // No new captured frame. The last delay should be reported.
    345   overuse_detector_->FrameProcessingStarted();
    346   EXPECT_EQ(overuse_detector_->CaptureQueueDelayMsPerS(), 100);
    347 }
    348 
    349 TEST_F(OveruseFrameDetectorTest, EncodedFrame) {
    350   const int kInitialAvgEncodeTimeInMs = 5;
    351   EXPECT_EQ(kInitialAvgEncodeTimeInMs, AvgEncodeTimeMs());
    352   for (int i = 0; i < 30; i++) {
    353     clock_->AdvanceTimeMilliseconds(33);
    354     overuse_detector_->FrameEncoded(2);
    355   }
    356   EXPECT_EQ(2, AvgEncodeTimeMs());
    357 }
    358 
    359 TEST_F(OveruseFrameDetectorTest, InitialEncodeUsage) {
    360   EXPECT_EQ(InitialEncodeUsage(), EncodeUsagePercent());
    361 }
    362 
    363 TEST_F(OveruseFrameDetectorTest, EncodedUsage) {
    364   const int kEncodeTimeMs = 5;
    365   InsertAndEncodeFramesWithInterval(
    366       1000, kFrameInterval33ms, kWidth, kHeight, kEncodeTimeMs);
    367   EXPECT_EQ(kEncodeTimeMs * 100 / kFrameInterval33ms, EncodeUsagePercent());
    368 }
    369 
    370 TEST_F(OveruseFrameDetectorTest, EncodeUsageResetAfterChangingThreshold) {
    371   EXPECT_EQ(InitialEncodeUsage(), EncodeUsagePercent());
    372   options_.high_encode_usage_threshold_percent = 100;
    373   overuse_detector_->SetOptions(options_);
    374   EXPECT_EQ(InitialEncodeUsage(), EncodeUsagePercent());
    375   options_.low_encode_usage_threshold_percent = 20;
    376   overuse_detector_->SetOptions(options_);
    377   EXPECT_EQ(InitialEncodeUsage(), EncodeUsagePercent());
    378 }
    379 
    380 // enable_encode_usage_method = true;
    381 // EncodeUsagePercent() > high_encode_usage_threshold_percent => overuse.
    382 // EncodeUsagePercent() < low_encode_usage_threshold_percent => underuse.
    383 TEST_F(OveruseFrameDetectorTest, TriggerOveruseWithEncodeUsage) {
    384   options_.enable_capture_jitter_method = false;
    385   options_.enable_encode_usage_method = true;
    386   overuse_detector_->SetOptions(options_);
    387   // usage > high => overuse
    388   EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
    389   TriggerOveruseWithEncodeUsage(options_.high_threshold_consecutive_count);
    390 }
    391 
    392 TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithEncodeUsage) {
    393   options_.enable_capture_jitter_method = false;
    394   options_.enable_encode_usage_method = true;
    395   overuse_detector_->SetOptions(options_);
    396   // usage > high => overuse
    397   EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
    398   TriggerOveruseWithEncodeUsage(options_.high_threshold_consecutive_count);
    399   // usage < low => underuse
    400   EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(testing::AtLeast(1));
    401   TriggerNormalUsageWithEncodeTime();
    402 }
    403 
    404 TEST_F(OveruseFrameDetectorTest,
    405        OveruseAndRecoverWithEncodeUsageMethodDisabled) {
    406   options_.enable_capture_jitter_method = false;
    407   options_.enable_encode_usage_method = false;
    408   overuse_detector_->SetOptions(options_);
    409   // usage > high => overuse
    410   EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0);
    411   TriggerOveruseWithEncodeUsage(options_.high_threshold_consecutive_count);
    412   // usage < low => underuse
    413   EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
    414   TriggerNormalUsageWithEncodeTime();
    415 }
    416 
    417 TEST_F(OveruseFrameDetectorTest, EncodeRsdResetAfterChangingThreshold) {
    418   EXPECT_EQ(InitialEncodeRsd(), EncodeRsd());
    419   options_.high_encode_time_rsd_threshold = 100;
    420   overuse_detector_->SetOptions(options_);
    421   EXPECT_EQ(InitialEncodeRsd(), EncodeRsd());
    422   options_.low_encode_time_rsd_threshold = 20;
    423   overuse_detector_->SetOptions(options_);
    424   EXPECT_EQ(InitialEncodeRsd(), EncodeRsd());
    425 }
    426 
    427 // enable_encode_usage_method = true;
    428 // low/high_encode_time_rsd_threshold >= 0
    429 // EncodeUsagePercent() > high_encode_usage_threshold_percent ||
    430 // EncodeRsd() > high_encode_time_rsd_threshold => overuse.
    431 // EncodeUsagePercent() < low_encode_usage_threshold_percent &&
    432 // EncodeRsd() < low_encode_time_rsd_threshold => underuse.
    433 TEST_F(OveruseFrameDetectorTest, TriggerOveruseWithEncodeRsd) {
    434   options_.enable_capture_jitter_method = false;
    435   options_.enable_encode_usage_method = true;
    436   options_.high_encode_time_rsd_threshold = 80;
    437   overuse_detector_->SetOptions(options_);
    438   // rsd > high, usage < high => overuse
    439   EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
    440   TriggerOveruseWithEncodeRsd(options_.high_threshold_consecutive_count);
    441   EXPECT_LT(EncodeUsagePercent(), options_.high_encode_usage_threshold_percent);
    442 }
    443 
    444 TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithEncodeRsd) {
    445   options_.enable_capture_jitter_method = false;
    446   options_.enable_encode_usage_method = true;
    447   options_.low_encode_time_rsd_threshold = 20;
    448   options_.high_encode_time_rsd_threshold = 80;
    449   overuse_detector_->SetOptions(options_);
    450   // rsd > high, usage < high => overuse
    451   EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
    452   TriggerOveruseWithEncodeRsd(options_.high_threshold_consecutive_count);
    453   EXPECT_LT(EncodeUsagePercent(), options_.high_encode_usage_threshold_percent);
    454   // rsd < low, usage < low => underuse
    455   EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(testing::AtLeast(1));
    456   TriggerNormalUsageWithEncodeTime();
    457 }
    458 
    459 TEST_F(OveruseFrameDetectorTest, NoUnderuseWithEncodeRsd_UsageGtLowThreshold) {
    460   options_.enable_capture_jitter_method = false;
    461   options_.enable_encode_usage_method = true;
    462   options_.low_encode_usage_threshold_percent = 1;
    463   options_.low_encode_time_rsd_threshold = 20;
    464   options_.high_encode_time_rsd_threshold = 90;
    465   overuse_detector_->SetOptions(options_);
    466   // rsd < low, usage > low => no underuse
    467   EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
    468   TriggerNormalUsageWithEncodeTime();
    469   EXPECT_LT(EncodeRsd(), options_.low_encode_time_rsd_threshold);
    470   EXPECT_GT(EncodeUsagePercent(), options_.low_encode_usage_threshold_percent);
    471 }
    472 
    473 TEST_F(OveruseFrameDetectorTest, NoUnderuseWithEncodeRsd_RsdGtLowThreshold) {
    474   options_.enable_capture_jitter_method = false;
    475   options_.enable_encode_usage_method = true;
    476   options_.low_encode_usage_threshold_percent = 20;
    477   options_.low_encode_time_rsd_threshold = 1;
    478   options_.high_encode_time_rsd_threshold = 90;
    479   overuse_detector_->SetOptions(options_);
    480   // rsd > low, usage < low => no underuse
    481   EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
    482   TriggerNormalUsageWithEncodeTime();
    483   EXPECT_GT(EncodeRsd(), options_.low_encode_time_rsd_threshold);
    484   EXPECT_LT(EncodeUsagePercent(), options_.low_encode_usage_threshold_percent);
    485 }
    486 }  // namespace webrtc
    487