1 /*
2  *  Copyright (c) 2020 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 "video/adaptation/overuse_frame_detector.h"
12 
13 #include <memory>
14 
15 #include "api/video/encoded_image.h"
16 #include "api/video/i420_buffer.h"
17 #include "api/video/video_adaptation_reason.h"
18 #include "modules/video_coding/utility/quality_scaler.h"
19 #include "rtc_base/event.h"
20 #include "rtc_base/fake_clock.h"
21 #include "rtc_base/random.h"
22 #include "rtc_base/task_queue_for_test.h"
23 #include "test/gmock.h"
24 #include "test/gtest.h"
25 
26 namespace webrtc {
27 
28 using ::testing::_;
29 using ::testing::InvokeWithoutArgs;
30 
31 namespace {
32 const int kWidth = 640;
33 const int kHeight = 480;
34 // Corresponds to load of 15%
35 const int kFrameIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
36 const int kProcessTimeUs = 5 * rtc::kNumMicrosecsPerMillisec;
37 }  // namespace
38 
39 class MockCpuOveruseObserver : public OveruseFrameDetectorObserverInterface {
40  public:
MockCpuOveruseObserver()41   MockCpuOveruseObserver() {}
~MockCpuOveruseObserver()42   virtual ~MockCpuOveruseObserver() {}
43 
44   MOCK_METHOD(void, AdaptUp, (), (override));
45   MOCK_METHOD(void, AdaptDown, (), (override));
46 };
47 
48 class CpuOveruseObserverImpl : public OveruseFrameDetectorObserverInterface {
49  public:
CpuOveruseObserverImpl()50   CpuOveruseObserverImpl() : overuse_(0), normaluse_(0) {}
~CpuOveruseObserverImpl()51   virtual ~CpuOveruseObserverImpl() {}
52 
AdaptDown()53   void AdaptDown() override { ++overuse_; }
AdaptUp()54   void AdaptUp() override { ++normaluse_; }
55 
56   int overuse_;
57   int normaluse_;
58 };
59 
60 class OveruseFrameDetectorUnderTest : public OveruseFrameDetector {
61  public:
OveruseFrameDetectorUnderTest(CpuOveruseMetricsObserver * metrics_observer)62   explicit OveruseFrameDetectorUnderTest(
63       CpuOveruseMetricsObserver* metrics_observer)
64       : OveruseFrameDetector(metrics_observer) {}
~OveruseFrameDetectorUnderTest()65   ~OveruseFrameDetectorUnderTest() {}
66 
67   using OveruseFrameDetector::CheckForOveruse;
68   using OveruseFrameDetector::SetOptions;
69 };
70 
71 class OveruseFrameDetectorTest : public ::testing::Test,
72                                  public CpuOveruseMetricsObserver {
73  protected:
SetUp()74   void SetUp() override {
75     observer_ = &mock_observer_;
76     options_.min_process_count = 0;
77     overuse_detector_ = std::make_unique<OveruseFrameDetectorUnderTest>(this);
78     // Unfortunately, we can't call SetOptions here, since that would break
79     // single-threading requirements in the RunOnTqNormalUsage test.
80   }
81 
OnEncodedFrameTimeMeasured(int encode_time_ms,int encode_usage_percent)82   void OnEncodedFrameTimeMeasured(int encode_time_ms,
83                                   int encode_usage_percent) override {
84     encode_usage_percent_ = encode_usage_percent;
85   }
86 
InitialUsage()87   int InitialUsage() {
88     return ((options_.low_encode_usage_threshold_percent +
89              options_.high_encode_usage_threshold_percent) /
90             2.0f) +
91            0.5;
92   }
93 
InsertAndSendFramesWithInterval(int num_frames,int interval_us,int width,int height,int delay_us)94   virtual void InsertAndSendFramesWithInterval(int num_frames,
95                                                int interval_us,
96                                                int width,
97                                                int height,
98                                                int delay_us) {
99     VideoFrame frame =
100         VideoFrame::Builder()
101             .set_video_frame_buffer(I420Buffer::Create(width, height))
102             .set_rotation(webrtc::kVideoRotation_0)
103             .set_timestamp_us(0)
104             .build();
105     uint32_t timestamp = 0;
106     while (num_frames-- > 0) {
107       frame.set_timestamp(timestamp);
108       int64_t capture_time_us = rtc::TimeMicros();
109       overuse_detector_->FrameCaptured(frame, capture_time_us);
110       clock_.AdvanceTime(TimeDelta::Micros(delay_us));
111       overuse_detector_->FrameSent(timestamp, rtc::TimeMicros(),
112                                    capture_time_us, delay_us);
113       clock_.AdvanceTime(TimeDelta::Micros(interval_us - delay_us));
114       timestamp += interval_us * 90 / 1000;
115     }
116   }
117 
InsertAndSendSimulcastFramesWithInterval(int num_frames,int interval_us,int width,int height,rtc::ArrayView<const int> delays_us)118   virtual void InsertAndSendSimulcastFramesWithInterval(
119       int num_frames,
120       int interval_us,
121       int width,
122       int height,
123       // One element per layer
124       rtc::ArrayView<const int> delays_us) {
125     VideoFrame frame =
126         VideoFrame::Builder()
127             .set_video_frame_buffer(I420Buffer::Create(width, height))
128             .set_rotation(webrtc::kVideoRotation_0)
129             .set_timestamp_us(0)
130             .build();
131     uint32_t timestamp = 0;
132     while (num_frames-- > 0) {
133       frame.set_timestamp(timestamp);
134       int64_t capture_time_us = rtc::TimeMicros();
135       overuse_detector_->FrameCaptured(frame, capture_time_us);
136       int max_delay_us = 0;
137       for (int delay_us : delays_us) {
138         if (delay_us > max_delay_us) {
139           clock_.AdvanceTime(TimeDelta::Micros(delay_us - max_delay_us));
140           max_delay_us = delay_us;
141         }
142 
143         overuse_detector_->FrameSent(timestamp, rtc::TimeMicros(),
144                                      capture_time_us, delay_us);
145       }
146       overuse_detector_->CheckForOveruse(observer_);
147       clock_.AdvanceTime(TimeDelta::Micros(interval_us - max_delay_us));
148       timestamp += interval_us * 90 / 1000;
149     }
150   }
151 
InsertAndSendFramesWithRandomInterval(int num_frames,int min_interval_us,int max_interval_us,int width,int height,int delay_us)152   virtual void InsertAndSendFramesWithRandomInterval(int num_frames,
153                                                      int min_interval_us,
154                                                      int max_interval_us,
155                                                      int width,
156                                                      int height,
157                                                      int delay_us) {
158     webrtc::Random random(17);
159 
160     VideoFrame frame =
161         VideoFrame::Builder()
162             .set_video_frame_buffer(I420Buffer::Create(width, height))
163             .set_rotation(webrtc::kVideoRotation_0)
164             .set_timestamp_us(0)
165             .build();
166     uint32_t timestamp = 0;
167     while (num_frames-- > 0) {
168       frame.set_timestamp(timestamp);
169       int interval_us = random.Rand(min_interval_us, max_interval_us);
170       int64_t capture_time_us = rtc::TimeMicros();
171       overuse_detector_->FrameCaptured(frame, capture_time_us);
172       clock_.AdvanceTime(TimeDelta::Micros(delay_us));
173       overuse_detector_->FrameSent(timestamp, rtc::TimeMicros(),
174                                    capture_time_us,
175                                    absl::optional<int>(delay_us));
176 
177       overuse_detector_->CheckForOveruse(observer_);
178       // Avoid turning clock backwards.
179       if (interval_us > delay_us)
180         clock_.AdvanceTime(TimeDelta::Micros(interval_us - delay_us));
181 
182       timestamp += interval_us * 90 / 1000;
183     }
184   }
185 
ForceUpdate(int width,int height)186   virtual void ForceUpdate(int width, int height) {
187     // Insert one frame, wait a second and then put in another to force update
188     // the usage. From the tests where these are used, adding another sample
189     // doesn't affect the expected outcome (this is mainly to check initial
190     // values and whether the overuse detector has been reset or not).
191     InsertAndSendFramesWithInterval(2, rtc::kNumMicrosecsPerSec, width, height,
192                                     kFrameIntervalUs);
193   }
TriggerOveruse(int num_times)194   void TriggerOveruse(int num_times) {
195     const int kDelayUs = 32 * rtc::kNumMicrosecsPerMillisec;
196     for (int i = 0; i < num_times; ++i) {
197       InsertAndSendFramesWithInterval(1000, kFrameIntervalUs, kWidth, kHeight,
198                                       kDelayUs);
199       overuse_detector_->CheckForOveruse(observer_);
200     }
201   }
202 
TriggerUnderuse()203   void TriggerUnderuse() {
204     const int kDelayUs1 = 5000;
205     const int kDelayUs2 = 6000;
206     InsertAndSendFramesWithInterval(1300, kFrameIntervalUs, kWidth, kHeight,
207                                     kDelayUs1);
208     InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight,
209                                     kDelayUs2);
210     overuse_detector_->CheckForOveruse(observer_);
211   }
212 
UsagePercent()213   int UsagePercent() { return encode_usage_percent_; }
214 
OveruseProcessingTimeLimitForFramerate(int fps) const215   int64_t OveruseProcessingTimeLimitForFramerate(int fps) const {
216     int64_t frame_interval = rtc::kNumMicrosecsPerSec / fps;
217     int64_t max_processing_time_us =
218         (frame_interval * options_.high_encode_usage_threshold_percent) / 100;
219     return max_processing_time_us;
220   }
221 
UnderuseProcessingTimeLimitForFramerate(int fps) const222   int64_t UnderuseProcessingTimeLimitForFramerate(int fps) const {
223     int64_t frame_interval = rtc::kNumMicrosecsPerSec / fps;
224     int64_t max_processing_time_us =
225         (frame_interval * options_.low_encode_usage_threshold_percent) / 100;
226     return max_processing_time_us;
227   }
228 
229   CpuOveruseOptions options_;
230   rtc::ScopedFakeClock clock_;
231   MockCpuOveruseObserver mock_observer_;
232   OveruseFrameDetectorObserverInterface* observer_;
233   std::unique_ptr<OveruseFrameDetectorUnderTest> overuse_detector_;
234   int encode_usage_percent_ = -1;
235 };
236 
237 // UsagePercent() > high_encode_usage_threshold_percent => overuse.
238 // UsagePercent() < low_encode_usage_threshold_percent => underuse.
TEST_F(OveruseFrameDetectorTest,TriggerOveruse)239 TEST_F(OveruseFrameDetectorTest, TriggerOveruse) {
240   // usage > high => overuse
241   overuse_detector_->SetOptions(options_);
242   EXPECT_CALL(mock_observer_, AdaptDown()).Times(1);
243   TriggerOveruse(options_.high_threshold_consecutive_count);
244 }
245 
TEST_F(OveruseFrameDetectorTest,OveruseAndRecover)246 TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) {
247   // usage > high => overuse
248   overuse_detector_->SetOptions(options_);
249   EXPECT_CALL(mock_observer_, AdaptDown()).Times(1);
250   TriggerOveruse(options_.high_threshold_consecutive_count);
251   // usage < low => underuse
252   EXPECT_CALL(mock_observer_, AdaptUp()).Times(::testing::AtLeast(1));
253   TriggerUnderuse();
254 }
255 
TEST_F(OveruseFrameDetectorTest,DoubleOveruseAndRecover)256 TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) {
257   overuse_detector_->SetOptions(options_);
258   EXPECT_CALL(mock_observer_, AdaptDown()).Times(2);
259   TriggerOveruse(options_.high_threshold_consecutive_count);
260   TriggerOveruse(options_.high_threshold_consecutive_count);
261   EXPECT_CALL(mock_observer_, AdaptUp()).Times(::testing::AtLeast(1));
262   TriggerUnderuse();
263 }
264 
TEST_F(OveruseFrameDetectorTest,TriggerUnderuseWithMinProcessCount)265 TEST_F(OveruseFrameDetectorTest, TriggerUnderuseWithMinProcessCount) {
266   const int kProcessIntervalUs = 5 * rtc::kNumMicrosecsPerSec;
267   options_.min_process_count = 1;
268   CpuOveruseObserverImpl overuse_observer;
269   observer_ = nullptr;
270   overuse_detector_->SetOptions(options_);
271   InsertAndSendFramesWithInterval(1200, kFrameIntervalUs, kWidth, kHeight,
272                                   kProcessTimeUs);
273   overuse_detector_->CheckForOveruse(&overuse_observer);
274   EXPECT_EQ(0, overuse_observer.normaluse_);
275   clock_.AdvanceTime(TimeDelta::Micros(kProcessIntervalUs));
276   overuse_detector_->CheckForOveruse(&overuse_observer);
277   EXPECT_EQ(1, overuse_observer.normaluse_);
278 }
279 
TEST_F(OveruseFrameDetectorTest,ConstantOveruseGivesNoNormalUsage)280 TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) {
281   overuse_detector_->SetOptions(options_);
282   EXPECT_CALL(mock_observer_, AdaptUp()).Times(0);
283   EXPECT_CALL(mock_observer_, AdaptDown()).Times(64);
284   for (size_t i = 0; i < 64; ++i) {
285     TriggerOveruse(options_.high_threshold_consecutive_count);
286   }
287 }
288 
TEST_F(OveruseFrameDetectorTest,ConsecutiveCountTriggersOveruse)289 TEST_F(OveruseFrameDetectorTest, ConsecutiveCountTriggersOveruse) {
290   overuse_detector_->SetOptions(options_);
291   EXPECT_CALL(mock_observer_, AdaptDown()).Times(1);
292   options_.high_threshold_consecutive_count = 2;
293   overuse_detector_->SetOptions(options_);
294   TriggerOveruse(2);
295 }
296 
TEST_F(OveruseFrameDetectorTest,IncorrectConsecutiveCountTriggersNoOveruse)297 TEST_F(OveruseFrameDetectorTest, IncorrectConsecutiveCountTriggersNoOveruse) {
298   overuse_detector_->SetOptions(options_);
299   EXPECT_CALL(mock_observer_, AdaptDown()).Times(0);
300   options_.high_threshold_consecutive_count = 2;
301   overuse_detector_->SetOptions(options_);
302   TriggerOveruse(1);
303 }
304 
TEST_F(OveruseFrameDetectorTest,ProcessingUsage)305 TEST_F(OveruseFrameDetectorTest, ProcessingUsage) {
306   overuse_detector_->SetOptions(options_);
307   InsertAndSendFramesWithInterval(1000, kFrameIntervalUs, kWidth, kHeight,
308                                   kProcessTimeUs);
309   EXPECT_EQ(kProcessTimeUs * 100 / kFrameIntervalUs, UsagePercent());
310 }
311 
TEST_F(OveruseFrameDetectorTest,ResetAfterResolutionChange)312 TEST_F(OveruseFrameDetectorTest, ResetAfterResolutionChange) {
313   overuse_detector_->SetOptions(options_);
314   ForceUpdate(kWidth, kHeight);
315   EXPECT_EQ(InitialUsage(), UsagePercent());
316   InsertAndSendFramesWithInterval(1000, kFrameIntervalUs, kWidth, kHeight,
317                                   kProcessTimeUs);
318   EXPECT_NE(InitialUsage(), UsagePercent());
319   // Verify reset (with new width/height).
320   ForceUpdate(kWidth, kHeight + 1);
321   EXPECT_EQ(InitialUsage(), UsagePercent());
322 }
323 
TEST_F(OveruseFrameDetectorTest,ResetAfterFrameTimeout)324 TEST_F(OveruseFrameDetectorTest, ResetAfterFrameTimeout) {
325   overuse_detector_->SetOptions(options_);
326   ForceUpdate(kWidth, kHeight);
327   EXPECT_EQ(InitialUsage(), UsagePercent());
328   InsertAndSendFramesWithInterval(1000, kFrameIntervalUs, kWidth, kHeight,
329                                   kProcessTimeUs);
330   EXPECT_NE(InitialUsage(), UsagePercent());
331   InsertAndSendFramesWithInterval(
332       2, options_.frame_timeout_interval_ms * rtc::kNumMicrosecsPerMillisec,
333       kWidth, kHeight, kProcessTimeUs);
334   EXPECT_NE(InitialUsage(), UsagePercent());
335   // Verify reset.
336   InsertAndSendFramesWithInterval(
337       2,
338       (options_.frame_timeout_interval_ms + 1) * rtc::kNumMicrosecsPerMillisec,
339       kWidth, kHeight, kProcessTimeUs);
340   ForceUpdate(kWidth, kHeight);
341   EXPECT_EQ(InitialUsage(), UsagePercent());
342 }
343 
TEST_F(OveruseFrameDetectorTest,MinFrameSamplesBeforeUpdating)344 TEST_F(OveruseFrameDetectorTest, MinFrameSamplesBeforeUpdating) {
345   options_.min_frame_samples = 40;
346   overuse_detector_->SetOptions(options_);
347   InsertAndSendFramesWithInterval(40, kFrameIntervalUs, kWidth, kHeight,
348                                   kProcessTimeUs);
349   EXPECT_EQ(InitialUsage(), UsagePercent());
350   // Pass time far enough to digest all previous samples.
351   clock_.AdvanceTime(TimeDelta::Seconds(1));
352   InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight,
353                                   kProcessTimeUs);
354   // The last sample has not been processed here.
355   EXPECT_EQ(InitialUsage(), UsagePercent());
356 
357   // Pass time far enough to digest all previous samples, 41 in total.
358   clock_.AdvanceTime(TimeDelta::Seconds(1));
359   InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight,
360                                   kProcessTimeUs);
361   EXPECT_NE(InitialUsage(), UsagePercent());
362 }
363 
TEST_F(OveruseFrameDetectorTest,InitialProcessingUsage)364 TEST_F(OveruseFrameDetectorTest, InitialProcessingUsage) {
365   overuse_detector_->SetOptions(options_);
366   ForceUpdate(kWidth, kHeight);
367   EXPECT_EQ(InitialUsage(), UsagePercent());
368 }
369 
TEST_F(OveruseFrameDetectorTest,MeasuresMultipleConcurrentSamples)370 TEST_F(OveruseFrameDetectorTest, MeasuresMultipleConcurrentSamples) {
371   overuse_detector_->SetOptions(options_);
372   EXPECT_CALL(mock_observer_, AdaptDown()).Times(::testing::AtLeast(1));
373   static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
374   static const size_t kNumFramesEncodingDelay = 3;
375   VideoFrame frame =
376       VideoFrame::Builder()
377           .set_video_frame_buffer(I420Buffer::Create(kWidth, kHeight))
378           .set_rotation(webrtc::kVideoRotation_0)
379           .set_timestamp_us(0)
380           .build();
381   for (size_t i = 0; i < 1000; ++i) {
382     // Unique timestamps.
383     frame.set_timestamp(static_cast<uint32_t>(i));
384     int64_t capture_time_us = rtc::TimeMicros();
385     overuse_detector_->FrameCaptured(frame, capture_time_us);
386     clock_.AdvanceTime(TimeDelta::Micros(kIntervalUs));
387     if (i > kNumFramesEncodingDelay) {
388       overuse_detector_->FrameSent(
389           static_cast<uint32_t>(i - kNumFramesEncodingDelay), rtc::TimeMicros(),
390           capture_time_us, kIntervalUs);
391     }
392     overuse_detector_->CheckForOveruse(observer_);
393   }
394 }
395 
TEST_F(OveruseFrameDetectorTest,UpdatesExistingSamples)396 TEST_F(OveruseFrameDetectorTest, UpdatesExistingSamples) {
397   // >85% encoding time should trigger overuse.
398   overuse_detector_->SetOptions(options_);
399   EXPECT_CALL(mock_observer_, AdaptDown()).Times(::testing::AtLeast(1));
400   static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
401   static const int kDelayUs = 30 * rtc::kNumMicrosecsPerMillisec;
402   VideoFrame frame =
403       VideoFrame::Builder()
404           .set_video_frame_buffer(I420Buffer::Create(kWidth, kHeight))
405           .set_rotation(webrtc::kVideoRotation_0)
406           .set_timestamp_us(0)
407           .build();
408   uint32_t timestamp = 0;
409   for (size_t i = 0; i < 1000; ++i) {
410     frame.set_timestamp(timestamp);
411     int64_t capture_time_us = rtc::TimeMicros();
412     overuse_detector_->FrameCaptured(frame, capture_time_us);
413     // Encode and send first parts almost instantly.
414     clock_.AdvanceTime(TimeDelta::Millis(1));
415     overuse_detector_->FrameSent(timestamp, rtc::TimeMicros(), capture_time_us,
416                                  rtc::kNumMicrosecsPerMillisec);
417     // Encode heavier part, resulting in >85% usage total.
418     clock_.AdvanceTime(TimeDelta::Micros(kDelayUs) - TimeDelta::Millis(1));
419     overuse_detector_->FrameSent(timestamp, rtc::TimeMicros(), capture_time_us,
420                                  kDelayUs);
421     clock_.AdvanceTime(TimeDelta::Micros(kIntervalUs - kDelayUs));
422     timestamp += kIntervalUs * 90 / 1000;
423     overuse_detector_->CheckForOveruse(observer_);
424   }
425 }
426 
TEST_F(OveruseFrameDetectorTest,RunOnTqNormalUsage)427 TEST_F(OveruseFrameDetectorTest, RunOnTqNormalUsage) {
428   TaskQueueForTest queue("OveruseFrameDetectorTestQueue");
429 
430   queue.SendTask(
431       [&] {
432         overuse_detector_->StartCheckForOveruse(queue.Get(), options_,
433                                                 observer_);
434       },
435       RTC_FROM_HERE);
436 
437   rtc::Event event;
438   // Expect NormalUsage(). When called, stop the |overuse_detector_| and then
439   // set |event| to end the test.
440   EXPECT_CALL(mock_observer_, AdaptUp())
441       .WillOnce(InvokeWithoutArgs([this, &event] {
442         overuse_detector_->StopCheckForOveruse();
443         event.Set();
444       }));
445 
446   queue.PostTask([this] {
447     const int kDelayUs1 = 5 * rtc::kNumMicrosecsPerMillisec;
448     const int kDelayUs2 = 6 * rtc::kNumMicrosecsPerMillisec;
449     InsertAndSendFramesWithInterval(1300, kFrameIntervalUs, kWidth, kHeight,
450                                     kDelayUs1);
451     InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight,
452                                     kDelayUs2);
453   });
454 
455   EXPECT_TRUE(event.Wait(10000));
456 }
457 
TEST_F(OveruseFrameDetectorTest,MaxIntervalScalesWithFramerate)458 TEST_F(OveruseFrameDetectorTest, MaxIntervalScalesWithFramerate) {
459   const int kCapturerMaxFrameRate = 30;
460   const int kEncodeMaxFrameRate = 20;  // Maximum fps the encoder can sustain.
461 
462   overuse_detector_->SetOptions(options_);
463   // Trigger overuse.
464   int64_t frame_interval_us = rtc::kNumMicrosecsPerSec / kCapturerMaxFrameRate;
465   // Processing time just below over use limit given kEncodeMaxFrameRate.
466   int64_t processing_time_us =
467       (98 * OveruseProcessingTimeLimitForFramerate(kEncodeMaxFrameRate)) / 100;
468   EXPECT_CALL(mock_observer_, AdaptDown()).Times(1);
469   for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
470     InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
471                                     processing_time_us);
472     overuse_detector_->CheckForOveruse(observer_);
473   }
474 
475   // Simulate frame rate reduction and normal usage.
476   frame_interval_us = rtc::kNumMicrosecsPerSec / kEncodeMaxFrameRate;
477   overuse_detector_->OnTargetFramerateUpdated(kEncodeMaxFrameRate);
478   EXPECT_CALL(mock_observer_, AdaptDown()).Times(0);
479   for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
480     InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
481                                     processing_time_us);
482     overuse_detector_->CheckForOveruse(observer_);
483   }
484 
485   // Reduce processing time to trigger underuse.
486   processing_time_us =
487       (98 * UnderuseProcessingTimeLimitForFramerate(kEncodeMaxFrameRate)) / 100;
488   EXPECT_CALL(mock_observer_, AdaptUp()).Times(1);
489   InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
490                                   processing_time_us);
491   overuse_detector_->CheckForOveruse(observer_);
492 }
493 
TEST_F(OveruseFrameDetectorTest,RespectsMinFramerate)494 TEST_F(OveruseFrameDetectorTest, RespectsMinFramerate) {
495   const int kMinFrameRate = 7;  // Minimum fps allowed by current detector impl.
496   overuse_detector_->SetOptions(options_);
497   overuse_detector_->OnTargetFramerateUpdated(kMinFrameRate);
498 
499   // Normal usage just at the limit.
500   int64_t frame_interval_us = rtc::kNumMicrosecsPerSec / kMinFrameRate;
501   // Processing time just below over use limit given kEncodeMaxFrameRate.
502   int64_t processing_time_us =
503       (98 * OveruseProcessingTimeLimitForFramerate(kMinFrameRate)) / 100;
504   EXPECT_CALL(mock_observer_, AdaptDown()).Times(0);
505   for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
506     InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
507                                     processing_time_us);
508     overuse_detector_->CheckForOveruse(observer_);
509   }
510 
511   // Over the limit to overuse.
512   processing_time_us =
513       (102 * OveruseProcessingTimeLimitForFramerate(kMinFrameRate)) / 100;
514   EXPECT_CALL(mock_observer_, AdaptDown()).Times(1);
515   for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
516     InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
517                                     processing_time_us);
518     overuse_detector_->CheckForOveruse(observer_);
519   }
520 
521   // Reduce input frame rate. Should still trigger overuse.
522   overuse_detector_->OnTargetFramerateUpdated(kMinFrameRate - 1);
523   EXPECT_CALL(mock_observer_, AdaptDown()).Times(1);
524   for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
525     InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
526                                     processing_time_us);
527     overuse_detector_->CheckForOveruse(observer_);
528   }
529 }
530 
TEST_F(OveruseFrameDetectorTest,LimitsMaxFrameInterval)531 TEST_F(OveruseFrameDetectorTest, LimitsMaxFrameInterval) {
532   const int kMaxFrameRate = 20;
533   overuse_detector_->SetOptions(options_);
534   overuse_detector_->OnTargetFramerateUpdated(kMaxFrameRate);
535   int64_t frame_interval_us = rtc::kNumMicrosecsPerSec / kMaxFrameRate;
536   // Maximum frame interval allowed is 35% above ideal.
537   int64_t max_frame_interval_us = (135 * frame_interval_us) / 100;
538   // Maximum processing time, without triggering overuse, allowed with the above
539   // frame interval.
540   int64_t max_processing_time_us =
541       (max_frame_interval_us * options_.high_encode_usage_threshold_percent) /
542       100;
543 
544   // Processing time just below overuse limit given kMaxFrameRate.
545   int64_t processing_time_us = (98 * max_processing_time_us) / 100;
546   EXPECT_CALL(mock_observer_, AdaptDown()).Times(0);
547   for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
548     InsertAndSendFramesWithInterval(1200, max_frame_interval_us, kWidth,
549                                     kHeight, processing_time_us);
550     overuse_detector_->CheckForOveruse(observer_);
551   }
552 
553   // Go above limit, trigger overuse.
554   processing_time_us = (102 * max_processing_time_us) / 100;
555   EXPECT_CALL(mock_observer_, AdaptDown()).Times(1);
556   for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
557     InsertAndSendFramesWithInterval(1200, max_frame_interval_us, kWidth,
558                                     kHeight, processing_time_us);
559     overuse_detector_->CheckForOveruse(observer_);
560   }
561 
562   // Increase frame interval, should still trigger overuse.
563   max_frame_interval_us *= 2;
564   EXPECT_CALL(mock_observer_, AdaptDown()).Times(1);
565   for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
566     InsertAndSendFramesWithInterval(1200, max_frame_interval_us, kWidth,
567                                     kHeight, processing_time_us);
568     overuse_detector_->CheckForOveruse(observer_);
569   }
570 }
571 
572 // Models screencast, with irregular arrival of frames which are heavy
573 // to encode.
TEST_F(OveruseFrameDetectorTest,NoOveruseForLargeRandomFrameInterval)574 TEST_F(OveruseFrameDetectorTest, NoOveruseForLargeRandomFrameInterval) {
575   // TODO(bugs.webrtc.org/8504): When new estimator is relanded,
576   // behavior is improved in this scenario, with only AdaptUp events,
577   // and estimated load closer to the true average.
578 
579   // EXPECT_CALL(mock_observer_, AdaptDown()).Times(0);
580   // EXPECT_CALL(mock_observer_, AdaptUp())
581   //     .Times(::testing::AtLeast(1));
582   overuse_detector_->SetOptions(options_);
583 
584   const int kNumFrames = 500;
585   const int kEncodeTimeUs = 100 * rtc::kNumMicrosecsPerMillisec;
586 
587   const int kMinIntervalUs = 30 * rtc::kNumMicrosecsPerMillisec;
588   const int kMaxIntervalUs = 1000 * rtc::kNumMicrosecsPerMillisec;
589 
590   const int kTargetFramerate = 5;
591 
592   overuse_detector_->OnTargetFramerateUpdated(kTargetFramerate);
593 
594   InsertAndSendFramesWithRandomInterval(kNumFrames, kMinIntervalUs,
595                                         kMaxIntervalUs, kWidth, kHeight,
596                                         kEncodeTimeUs);
597   // Average usage 19%. Check that estimate is in the right ball park.
598   // EXPECT_NEAR(UsagePercent(), 20, 10);
599   EXPECT_NEAR(UsagePercent(), 20, 35);
600 }
601 
602 // Models screencast, with irregular arrival of frames, often
603 // exceeding the timeout interval.
TEST_F(OveruseFrameDetectorTest,NoOveruseForRandomFrameIntervalWithReset)604 TEST_F(OveruseFrameDetectorTest, NoOveruseForRandomFrameIntervalWithReset) {
605   // TODO(bugs.webrtc.org/8504): When new estimator is relanded,
606   // behavior is improved in this scenario, and we get AdaptUp events.
607   overuse_detector_->SetOptions(options_);
608   EXPECT_CALL(mock_observer_, AdaptDown()).Times(0);
609   // EXPECT_CALL(mock_observer_, AdaptUp())
610   //     .Times(::testing::AtLeast(1));
611 
612   const int kNumFrames = 500;
613   const int kEncodeTimeUs = 100 * rtc::kNumMicrosecsPerMillisec;
614 
615   const int kMinIntervalUs = 30 * rtc::kNumMicrosecsPerMillisec;
616   const int kMaxIntervalUs = 3000 * rtc::kNumMicrosecsPerMillisec;
617 
618   const int kTargetFramerate = 5;
619 
620   overuse_detector_->OnTargetFramerateUpdated(kTargetFramerate);
621 
622   InsertAndSendFramesWithRandomInterval(kNumFrames, kMinIntervalUs,
623                                         kMaxIntervalUs, kWidth, kHeight,
624                                         kEncodeTimeUs);
625 
626   // Average usage 6.6%, but since the frame_timeout_interval_ms is
627   // only 1500 ms, we often reset the estimate to the initial value.
628   // Check that estimate is in the right ball park.
629   EXPECT_GE(UsagePercent(), 1);
630   EXPECT_LE(UsagePercent(), InitialUsage() + 5);
631 }
632 
633 // Models simulcast, with multiple encoded frames for each input frame.
634 // Load estimate should be based on the maximum encode time per input frame.
TEST_F(OveruseFrameDetectorTest,NoOveruseForSimulcast)635 TEST_F(OveruseFrameDetectorTest, NoOveruseForSimulcast) {
636   overuse_detector_->SetOptions(options_);
637   EXPECT_CALL(mock_observer_, AdaptDown()).Times(0);
638 
639   constexpr int kNumFrames = 500;
640   constexpr int kEncodeTimesUs[] = {
641       10 * rtc::kNumMicrosecsPerMillisec,
642       8 * rtc::kNumMicrosecsPerMillisec,
643       12 * rtc::kNumMicrosecsPerMillisec,
644   };
645   constexpr int kIntervalUs = 30 * rtc::kNumMicrosecsPerMillisec;
646 
647   InsertAndSendSimulcastFramesWithInterval(kNumFrames, kIntervalUs, kWidth,
648                                            kHeight, kEncodeTimesUs);
649 
650   // Average usage 40%. 12 ms / 30 ms.
651   EXPECT_GE(UsagePercent(), 35);
652   EXPECT_LE(UsagePercent(), 45);
653 }
654 
655 // Tests using new cpu load estimator
656 class OveruseFrameDetectorTest2 : public OveruseFrameDetectorTest {
657  protected:
SetUp()658   void SetUp() override {
659     options_.filter_time_ms = 5 * rtc::kNumMillisecsPerSec;
660     OveruseFrameDetectorTest::SetUp();
661   }
662 
InsertAndSendFramesWithInterval(int num_frames,int interval_us,int width,int height,int delay_us)663   void InsertAndSendFramesWithInterval(int num_frames,
664                                        int interval_us,
665                                        int width,
666                                        int height,
667                                        int delay_us) override {
668     VideoFrame frame =
669         VideoFrame::Builder()
670             .set_video_frame_buffer(I420Buffer::Create(width, height))
671             .set_rotation(webrtc::kVideoRotation_0)
672             .set_timestamp_us(0)
673             .build();
674     while (num_frames-- > 0) {
675       int64_t capture_time_us = rtc::TimeMicros();
676       overuse_detector_->FrameCaptured(frame, capture_time_us /* ignored */);
677       overuse_detector_->FrameSent(0 /* ignored timestamp */,
678                                    0 /* ignored send_time_us */,
679                                    capture_time_us, delay_us);
680       clock_.AdvanceTime(TimeDelta::Micros(interval_us));
681     }
682   }
683 
InsertAndSendFramesWithRandomInterval(int num_frames,int min_interval_us,int max_interval_us,int width,int height,int delay_us)684   void InsertAndSendFramesWithRandomInterval(int num_frames,
685                                              int min_interval_us,
686                                              int max_interval_us,
687                                              int width,
688                                              int height,
689                                              int delay_us) override {
690     webrtc::Random random(17);
691 
692     VideoFrame frame =
693         VideoFrame::Builder()
694             .set_video_frame_buffer(I420Buffer::Create(width, height))
695             .set_rotation(webrtc::kVideoRotation_0)
696             .set_timestamp_us(0)
697             .build();
698     for (int i = 0; i < num_frames; i++) {
699       int interval_us = random.Rand(min_interval_us, max_interval_us);
700       int64_t capture_time_us = rtc::TimeMicros();
701       overuse_detector_->FrameCaptured(frame, capture_time_us);
702       overuse_detector_->FrameSent(0 /* ignored timestamp */,
703                                    0 /* ignored send_time_us */,
704                                    capture_time_us, delay_us);
705 
706       overuse_detector_->CheckForOveruse(observer_);
707       clock_.AdvanceTime(TimeDelta::Micros(interval_us));
708     }
709   }
710 
ForceUpdate(int width,int height)711   void ForceUpdate(int width, int height) override {
712     // This is mainly to check initial values and whether the overuse
713     // detector has been reset or not.
714     InsertAndSendFramesWithInterval(1, rtc::kNumMicrosecsPerSec, width, height,
715                                     kFrameIntervalUs);
716   }
717 };
718 
719 // UsagePercent() > high_encode_usage_threshold_percent => overuse.
720 // UsagePercent() < low_encode_usage_threshold_percent => underuse.
TEST_F(OveruseFrameDetectorTest2,TriggerOveruse)721 TEST_F(OveruseFrameDetectorTest2, TriggerOveruse) {
722   // usage > high => overuse
723   overuse_detector_->SetOptions(options_);
724   EXPECT_CALL(mock_observer_, AdaptDown()).Times(1);
725   TriggerOveruse(options_.high_threshold_consecutive_count);
726 }
727 
TEST_F(OveruseFrameDetectorTest2,OveruseAndRecover)728 TEST_F(OveruseFrameDetectorTest2, OveruseAndRecover) {
729   // usage > high => overuse
730   overuse_detector_->SetOptions(options_);
731   EXPECT_CALL(mock_observer_, AdaptDown()).Times(1);
732   TriggerOveruse(options_.high_threshold_consecutive_count);
733   // usage < low => underuse
734   EXPECT_CALL(mock_observer_, AdaptUp()).Times(::testing::AtLeast(1));
735   TriggerUnderuse();
736 }
737 
TEST_F(OveruseFrameDetectorTest2,DoubleOveruseAndRecover)738 TEST_F(OveruseFrameDetectorTest2, DoubleOveruseAndRecover) {
739   overuse_detector_->SetOptions(options_);
740   EXPECT_CALL(mock_observer_, AdaptDown()).Times(2);
741   TriggerOveruse(options_.high_threshold_consecutive_count);
742   TriggerOveruse(options_.high_threshold_consecutive_count);
743   EXPECT_CALL(mock_observer_, AdaptUp()).Times(::testing::AtLeast(1));
744   TriggerUnderuse();
745 }
746 
TEST_F(OveruseFrameDetectorTest2,TriggerUnderuseWithMinProcessCount)747 TEST_F(OveruseFrameDetectorTest2, TriggerUnderuseWithMinProcessCount) {
748   const int kProcessIntervalUs = 5 * rtc::kNumMicrosecsPerSec;
749   options_.min_process_count = 1;
750   CpuOveruseObserverImpl overuse_observer;
751   observer_ = nullptr;
752   overuse_detector_->SetOptions(options_);
753   InsertAndSendFramesWithInterval(1200, kFrameIntervalUs, kWidth, kHeight,
754                                   kProcessTimeUs);
755   overuse_detector_->CheckForOveruse(&overuse_observer);
756   EXPECT_EQ(0, overuse_observer.normaluse_);
757   clock_.AdvanceTime(TimeDelta::Micros(kProcessIntervalUs));
758   overuse_detector_->CheckForOveruse(&overuse_observer);
759   EXPECT_EQ(1, overuse_observer.normaluse_);
760 }
761 
TEST_F(OveruseFrameDetectorTest2,ConstantOveruseGivesNoNormalUsage)762 TEST_F(OveruseFrameDetectorTest2, ConstantOveruseGivesNoNormalUsage) {
763   overuse_detector_->SetOptions(options_);
764   EXPECT_CALL(mock_observer_, AdaptUp()).Times(0);
765   EXPECT_CALL(mock_observer_, AdaptDown()).Times(64);
766   for (size_t i = 0; i < 64; ++i) {
767     TriggerOveruse(options_.high_threshold_consecutive_count);
768   }
769 }
770 
TEST_F(OveruseFrameDetectorTest2,ConsecutiveCountTriggersOveruse)771 TEST_F(OveruseFrameDetectorTest2, ConsecutiveCountTriggersOveruse) {
772   EXPECT_CALL(mock_observer_, AdaptDown()).Times(1);
773   options_.high_threshold_consecutive_count = 2;
774   overuse_detector_->SetOptions(options_);
775   TriggerOveruse(2);
776 }
777 
TEST_F(OveruseFrameDetectorTest2,IncorrectConsecutiveCountTriggersNoOveruse)778 TEST_F(OveruseFrameDetectorTest2, IncorrectConsecutiveCountTriggersNoOveruse) {
779   EXPECT_CALL(mock_observer_, AdaptDown()).Times(0);
780   options_.high_threshold_consecutive_count = 2;
781   overuse_detector_->SetOptions(options_);
782   TriggerOveruse(1);
783 }
784 
TEST_F(OveruseFrameDetectorTest2,ProcessingUsage)785 TEST_F(OveruseFrameDetectorTest2, ProcessingUsage) {
786   overuse_detector_->SetOptions(options_);
787   InsertAndSendFramesWithInterval(1000, kFrameIntervalUs, kWidth, kHeight,
788                                   kProcessTimeUs);
789   EXPECT_EQ(kProcessTimeUs * 100 / kFrameIntervalUs, UsagePercent());
790 }
791 
TEST_F(OveruseFrameDetectorTest2,ResetAfterResolutionChange)792 TEST_F(OveruseFrameDetectorTest2, ResetAfterResolutionChange) {
793   overuse_detector_->SetOptions(options_);
794   ForceUpdate(kWidth, kHeight);
795   EXPECT_EQ(InitialUsage(), UsagePercent());
796   InsertAndSendFramesWithInterval(1000, kFrameIntervalUs, kWidth, kHeight,
797                                   kProcessTimeUs);
798   EXPECT_NE(InitialUsage(), UsagePercent());
799   // Verify reset (with new width/height).
800   ForceUpdate(kWidth, kHeight + 1);
801   EXPECT_EQ(InitialUsage(), UsagePercent());
802 }
803 
TEST_F(OveruseFrameDetectorTest2,ResetAfterFrameTimeout)804 TEST_F(OveruseFrameDetectorTest2, ResetAfterFrameTimeout) {
805   overuse_detector_->SetOptions(options_);
806   ForceUpdate(kWidth, kHeight);
807   EXPECT_EQ(InitialUsage(), UsagePercent());
808   InsertAndSendFramesWithInterval(1000, kFrameIntervalUs, kWidth, kHeight,
809                                   kProcessTimeUs);
810   EXPECT_NE(InitialUsage(), UsagePercent());
811   InsertAndSendFramesWithInterval(
812       2, options_.frame_timeout_interval_ms * rtc::kNumMicrosecsPerMillisec,
813       kWidth, kHeight, kProcessTimeUs);
814   EXPECT_NE(InitialUsage(), UsagePercent());
815   // Verify reset.
816   InsertAndSendFramesWithInterval(
817       2,
818       (options_.frame_timeout_interval_ms + 1) * rtc::kNumMicrosecsPerMillisec,
819       kWidth, kHeight, kProcessTimeUs);
820   ForceUpdate(kWidth, kHeight);
821   EXPECT_EQ(InitialUsage(), UsagePercent());
822 }
823 
TEST_F(OveruseFrameDetectorTest2,ConvergesSlowly)824 TEST_F(OveruseFrameDetectorTest2, ConvergesSlowly) {
825   overuse_detector_->SetOptions(options_);
826   InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight,
827                                   kProcessTimeUs);
828   // No update for the first sample.
829   EXPECT_EQ(InitialUsage(), UsagePercent());
830 
831   // Total time approximately 40 * 33ms = 1.3s, significantly less
832   // than the 5s time constant.
833   InsertAndSendFramesWithInterval(40, kFrameIntervalUs, kWidth, kHeight,
834                                   kProcessTimeUs);
835 
836   // Should have started to approach correct load of 15%, but not very far.
837   EXPECT_LT(UsagePercent(), InitialUsage());
838   EXPECT_GT(UsagePercent(), (InitialUsage() * 3 + 15) / 4);
839 
840   // Run for roughly 10s more, should now be closer.
841   InsertAndSendFramesWithInterval(300, kFrameIntervalUs, kWidth, kHeight,
842                                   kProcessTimeUs);
843   EXPECT_NEAR(UsagePercent(), 20, 5);
844 }
845 
TEST_F(OveruseFrameDetectorTest2,InitialProcessingUsage)846 TEST_F(OveruseFrameDetectorTest2, InitialProcessingUsage) {
847   overuse_detector_->SetOptions(options_);
848   ForceUpdate(kWidth, kHeight);
849   EXPECT_EQ(InitialUsage(), UsagePercent());
850 }
851 
TEST_F(OveruseFrameDetectorTest2,MeasuresMultipleConcurrentSamples)852 TEST_F(OveruseFrameDetectorTest2, MeasuresMultipleConcurrentSamples) {
853   overuse_detector_->SetOptions(options_);
854   EXPECT_CALL(mock_observer_, AdaptDown()).Times(::testing::AtLeast(1));
855   static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
856   static const size_t kNumFramesEncodingDelay = 3;
857   VideoFrame frame =
858       VideoFrame::Builder()
859           .set_video_frame_buffer(I420Buffer::Create(kWidth, kHeight))
860           .set_rotation(webrtc::kVideoRotation_0)
861           .set_timestamp_us(0)
862           .build();
863   for (size_t i = 0; i < 1000; ++i) {
864     // Unique timestamps.
865     frame.set_timestamp(static_cast<uint32_t>(i));
866     int64_t capture_time_us = rtc::TimeMicros();
867     overuse_detector_->FrameCaptured(frame, capture_time_us);
868     clock_.AdvanceTime(TimeDelta::Micros(kIntervalUs));
869     if (i > kNumFramesEncodingDelay) {
870       overuse_detector_->FrameSent(
871           static_cast<uint32_t>(i - kNumFramesEncodingDelay), rtc::TimeMicros(),
872           capture_time_us, kIntervalUs);
873     }
874     overuse_detector_->CheckForOveruse(observer_);
875   }
876 }
877 
TEST_F(OveruseFrameDetectorTest2,UpdatesExistingSamples)878 TEST_F(OveruseFrameDetectorTest2, UpdatesExistingSamples) {
879   // >85% encoding time should trigger overuse.
880   overuse_detector_->SetOptions(options_);
881   EXPECT_CALL(mock_observer_, AdaptDown()).Times(::testing::AtLeast(1));
882   static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
883   static const int kDelayUs = 30 * rtc::kNumMicrosecsPerMillisec;
884   VideoFrame frame =
885       VideoFrame::Builder()
886           .set_video_frame_buffer(I420Buffer::Create(kWidth, kHeight))
887           .set_rotation(webrtc::kVideoRotation_0)
888           .set_timestamp_us(0)
889           .build();
890   uint32_t timestamp = 0;
891   for (size_t i = 0; i < 1000; ++i) {
892     frame.set_timestamp(timestamp);
893     int64_t capture_time_us = rtc::TimeMicros();
894     overuse_detector_->FrameCaptured(frame, capture_time_us);
895     // Encode and send first parts almost instantly.
896     clock_.AdvanceTime(TimeDelta::Millis(1));
897     overuse_detector_->FrameSent(timestamp, rtc::TimeMicros(), capture_time_us,
898                                  rtc::kNumMicrosecsPerMillisec);
899     // Encode heavier part, resulting in >85% usage total.
900     clock_.AdvanceTime(TimeDelta::Micros(kDelayUs) - TimeDelta::Millis(1));
901     overuse_detector_->FrameSent(timestamp, rtc::TimeMicros(), capture_time_us,
902                                  kDelayUs);
903     clock_.AdvanceTime(TimeDelta::Micros(kIntervalUs - kDelayUs));
904     timestamp += kIntervalUs * 90 / 1000;
905     overuse_detector_->CheckForOveruse(observer_);
906   }
907 }
908 
TEST_F(OveruseFrameDetectorTest2,RunOnTqNormalUsage)909 TEST_F(OveruseFrameDetectorTest2, RunOnTqNormalUsage) {
910   TaskQueueForTest queue("OveruseFrameDetectorTestQueue");
911 
912   queue.SendTask(
913       [&] {
914         overuse_detector_->StartCheckForOveruse(queue.Get(), options_,
915                                                 observer_);
916       },
917       RTC_FROM_HERE);
918 
919   rtc::Event event;
920   // Expect NormalUsage(). When called, stop the |overuse_detector_| and then
921   // set |event| to end the test.
922   EXPECT_CALL(mock_observer_, AdaptUp())
923       .WillOnce(InvokeWithoutArgs([this, &event] {
924         overuse_detector_->StopCheckForOveruse();
925         event.Set();
926       }));
927 
928   queue.PostTask([this] {
929     const int kDelayUs1 = 5 * rtc::kNumMicrosecsPerMillisec;
930     const int kDelayUs2 = 6 * rtc::kNumMicrosecsPerMillisec;
931     InsertAndSendFramesWithInterval(1300, kFrameIntervalUs, kWidth, kHeight,
932                                     kDelayUs1);
933     InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight,
934                                     kDelayUs2);
935   });
936 
937   EXPECT_TRUE(event.Wait(10000));
938 }
939 
940 // Models screencast, with irregular arrival of frames which are heavy
941 // to encode.
TEST_F(OveruseFrameDetectorTest2,NoOveruseForLargeRandomFrameInterval)942 TEST_F(OveruseFrameDetectorTest2, NoOveruseForLargeRandomFrameInterval) {
943   overuse_detector_->SetOptions(options_);
944   EXPECT_CALL(mock_observer_, AdaptDown()).Times(0);
945   EXPECT_CALL(mock_observer_, AdaptUp()).Times(::testing::AtLeast(1));
946 
947   const int kNumFrames = 500;
948   const int kEncodeTimeUs = 100 * rtc::kNumMicrosecsPerMillisec;
949 
950   const int kMinIntervalUs = 30 * rtc::kNumMicrosecsPerMillisec;
951   const int kMaxIntervalUs = 1000 * rtc::kNumMicrosecsPerMillisec;
952 
953   InsertAndSendFramesWithRandomInterval(kNumFrames, kMinIntervalUs,
954                                         kMaxIntervalUs, kWidth, kHeight,
955                                         kEncodeTimeUs);
956   // Average usage 19%. Check that estimate is in the right ball park.
957   EXPECT_NEAR(UsagePercent(), 20, 10);
958 }
959 
960 // Models screencast, with irregular arrival of frames, often
961 // exceeding the timeout interval.
TEST_F(OveruseFrameDetectorTest2,NoOveruseForRandomFrameIntervalWithReset)962 TEST_F(OveruseFrameDetectorTest2, NoOveruseForRandomFrameIntervalWithReset) {
963   overuse_detector_->SetOptions(options_);
964   EXPECT_CALL(mock_observer_, AdaptDown()).Times(0);
965   EXPECT_CALL(mock_observer_, AdaptUp()).Times(::testing::AtLeast(1));
966 
967   const int kNumFrames = 500;
968   const int kEncodeTimeUs = 100 * rtc::kNumMicrosecsPerMillisec;
969 
970   const int kMinIntervalUs = 30 * rtc::kNumMicrosecsPerMillisec;
971   const int kMaxIntervalUs = 3000 * rtc::kNumMicrosecsPerMillisec;
972 
973   InsertAndSendFramesWithRandomInterval(kNumFrames, kMinIntervalUs,
974                                         kMaxIntervalUs, kWidth, kHeight,
975                                         kEncodeTimeUs);
976 
977   // Average usage 6.6%, but since the frame_timeout_interval_ms is
978   // only 1500 ms, we often reset the estimate to the initial value.
979   // Check that estimate is in the right ball park.
980   EXPECT_GE(UsagePercent(), 1);
981   EXPECT_LE(UsagePercent(), InitialUsage() + 5);
982 }
983 
TEST_F(OveruseFrameDetectorTest2,ToleratesOutOfOrderFrames)984 TEST_F(OveruseFrameDetectorTest2, ToleratesOutOfOrderFrames) {
985   overuse_detector_->SetOptions(options_);
986   // Represents a cpu utilization close to 100%. First input frame results in
987   // three encoded frames, and the last of those isn't finished until after the
988   // first encoded frame corresponding to the next input frame.
989   const int kEncodeTimeUs = 30 * rtc::kNumMicrosecsPerMillisec;
990   const int kCaptureTimesMs[] = {33, 33, 66, 33};
991 
992   for (int capture_time_ms : kCaptureTimesMs) {
993     overuse_detector_->FrameSent(
994         0, 0, capture_time_ms * rtc::kNumMicrosecsPerMillisec, kEncodeTimeUs);
995   }
996   EXPECT_GE(UsagePercent(), InitialUsage());
997 }
998 
999 // Models simulcast, with multiple encoded frames for each input frame.
1000 // Load estimate should be based on the maximum encode time per input frame.
TEST_F(OveruseFrameDetectorTest2,NoOveruseForSimulcast)1001 TEST_F(OveruseFrameDetectorTest2, NoOveruseForSimulcast) {
1002   overuse_detector_->SetOptions(options_);
1003   EXPECT_CALL(mock_observer_, AdaptDown()).Times(0);
1004 
1005   constexpr int kNumFrames = 500;
1006   constexpr int kEncodeTimesUs[] = {
1007       10 * rtc::kNumMicrosecsPerMillisec,
1008       8 * rtc::kNumMicrosecsPerMillisec,
1009       12 * rtc::kNumMicrosecsPerMillisec,
1010   };
1011   constexpr int kIntervalUs = 30 * rtc::kNumMicrosecsPerMillisec;
1012 
1013   InsertAndSendSimulcastFramesWithInterval(kNumFrames, kIntervalUs, kWidth,
1014                                            kHeight, kEncodeTimesUs);
1015 
1016   // Average usage 40%. 12 ms / 30 ms.
1017   EXPECT_GE(UsagePercent(), 35);
1018   EXPECT_LE(UsagePercent(), 45);
1019 }
1020 
1021 }  // namespace webrtc
1022