blob: cb454825c20cafe69f7ec8aebebc3a0b4fe0da11 [file] [log] [blame]
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +00001/*
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
kwiberg27f982b2016-03-01 11:52:33 -080011#include <memory>
12
Steve Anton40d55332019-01-07 10:21:47 -080013#include "absl/memory/memory.h"
Niels Möller4dc66c52018-10-05 14:17:58 +020014#include "api/video/encoded_image.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "api/video/i420_buffer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "modules/video_coding/utility/quality_scaler.h"
17#include "rtc_base/event.h"
Steve Anton10542f22019-01-11 09:11:00 -080018#include "rtc_base/fake_clock.h"
Niels Möllere541be72017-12-13 13:03:10 +010019#include "rtc_base/random.h"
Danil Chapovalov07122bc2019-03-26 14:37:01 +010020#include "rtc_base/task_queue_for_test.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "test/gmock.h"
22#include "test/gtest.h"
23#include "video/overuse_frame_detector.h"
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000024
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000025namespace webrtc {
perkjd52063f2016-09-07 06:32:18 -070026
kthelgason876222f2016-11-29 01:44:11 -080027using ::testing::InvokeWithoutArgs;
Niels Möllere541be72017-12-13 13:03:10 +010028using ::testing::_;
perkjd52063f2016-09-07 06:32:18 -070029
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +000030namespace {
Yves Gerey665174f2018-06-19 15:03:05 +020031const int kWidth = 640;
32const int kHeight = 480;
33// Corresponds to load of 15%
34const int kFrameIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
35const int kProcessTimeUs = 5 * rtc::kNumMicrosecsPerMillisec;
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +000036} // namespace
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000037
sprangb1ca0732017-02-01 08:38:12 -080038class MockCpuOveruseObserver : public AdaptationObserverInterface {
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000039 public:
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +000040 MockCpuOveruseObserver() {}
41 virtual ~MockCpuOveruseObserver() {}
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000042
sprangb1ca0732017-02-01 08:38:12 -080043 MOCK_METHOD1(AdaptUp, void(AdaptReason));
44 MOCK_METHOD1(AdaptDown, void(AdaptReason));
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000045};
46
sprangb1ca0732017-02-01 08:38:12 -080047class CpuOveruseObserverImpl : public AdaptationObserverInterface {
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +000048 public:
Yves Gerey665174f2018-06-19 15:03:05 +020049 CpuOveruseObserverImpl() : overuse_(0), normaluse_(0) {}
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +000050 virtual ~CpuOveruseObserverImpl() {}
51
sprangb1ca0732017-02-01 08:38:12 -080052 void AdaptDown(AdaptReason) { ++overuse_; }
53 void AdaptUp(AdaptReason) { ++normaluse_; }
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +000054
55 int overuse_;
56 int normaluse_;
57};
58
perkjd52063f2016-09-07 06:32:18 -070059class OveruseFrameDetectorUnderTest : public OveruseFrameDetector {
60 public:
Niels Möllerd1f7eb62018-03-28 16:40:58 +020061 explicit OveruseFrameDetectorUnderTest(
62 CpuOveruseMetricsObserver* metrics_observer)
63 : OveruseFrameDetector(metrics_observer) {}
perkjd52063f2016-09-07 06:32:18 -070064 ~OveruseFrameDetectorUnderTest() {}
65
66 using OveruseFrameDetector::CheckForOveruse;
Niels Möllerd1f7eb62018-03-28 16:40:58 +020067 using OveruseFrameDetector::SetOptions;
perkjd52063f2016-09-07 06:32:18 -070068};
69
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +000070class OveruseFrameDetectorTest : public ::testing::Test,
71 public CpuOveruseMetricsObserver {
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000072 protected:
nisseef8b61e2016-04-29 06:09:15 -070073 void SetUp() override {
Niels Möller73f29cb2018-01-31 16:09:31 +010074 observer_ = &mock_observer_;
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +000075 options_.min_process_count = 0;
Karl Wiberg918f50c2018-07-05 11:40:33 +020076 overuse_detector_ = absl::make_unique<OveruseFrameDetectorUnderTest>(this);
Niels Möllerd1f7eb62018-03-28 16:40:58 +020077 // Unfortunately, we can't call SetOptions here, since that would break
78 // single-threading requirements in the RunOnTqNormalUsage test.
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000079 }
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +000080
Peter Boströme4499152016-02-05 11:13:28 +010081 void OnEncodedFrameTimeMeasured(int encode_time_ms,
Niels Möller213618e2018-07-24 09:29:58 +020082 int encode_usage_percent) override {
83 encode_usage_percent_ = encode_usage_percent;
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +000084 }
85
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +000086 int InitialUsage() {
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +000087 return ((options_.low_encode_usage_threshold_percent +
Yves Gerey665174f2018-06-19 15:03:05 +020088 options_.high_encode_usage_threshold_percent) /
89 2.0f) +
90 0.5;
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +000091 }
92
Niels Möller83dbeac2017-12-14 16:39:44 +010093 virtual void InsertAndSendFramesWithInterval(int num_frames,
94 int interval_us,
95 int width,
96 int height,
97 int delay_us) {
Artem Titov1ebfb6a2019-01-03 23:49:37 +010098 VideoFrame frame =
99 VideoFrame::Builder()
100 .set_video_frame_buffer(I420Buffer::Create(width, height))
101 .set_rotation(webrtc::kVideoRotation_0)
102 .set_timestamp_us(0)
103 .build();
Niels Möller7dc26b72017-12-06 10:27:48 +0100104 uint32_t timestamp = 0;
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000105 while (num_frames-- > 0) {
Niels Möller7dc26b72017-12-06 10:27:48 +0100106 frame.set_timestamp(timestamp);
Niels Möller83dbeac2017-12-14 16:39:44 +0100107 int64_t capture_time_us = rtc::TimeMicros();
108 overuse_detector_->FrameCaptured(frame, capture_time_us);
Sebastian Jansson40889f32019-04-17 12:11:20 +0200109 clock_.AdvanceTime(TimeDelta::us(delay_us));
Niels Möller83dbeac2017-12-14 16:39:44 +0100110 overuse_detector_->FrameSent(timestamp, rtc::TimeMicros(),
111 capture_time_us, delay_us);
Sebastian Jansson40889f32019-04-17 12:11:20 +0200112 clock_.AdvanceTime(TimeDelta::us(interval_us - delay_us));
Niels Möller7dc26b72017-12-06 10:27:48 +0100113 timestamp += interval_us * 90 / 1000;
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000114 }
115 }
116
Niels Möllerf5033ad2018-08-14 17:00:46 +0200117 virtual void InsertAndSendSimulcastFramesWithInterval(
118 int num_frames,
119 int interval_us,
120 int width,
121 int height,
122 // One element per layer
123 rtc::ArrayView<const int> delays_us) {
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100124 VideoFrame frame =
125 VideoFrame::Builder()
126 .set_video_frame_buffer(I420Buffer::Create(width, height))
127 .set_rotation(webrtc::kVideoRotation_0)
128 .set_timestamp_us(0)
129 .build();
Niels Möllerf5033ad2018-08-14 17:00:46 +0200130 uint32_t timestamp = 0;
131 while (num_frames-- > 0) {
132 frame.set_timestamp(timestamp);
133 int64_t capture_time_us = rtc::TimeMicros();
134 overuse_detector_->FrameCaptured(frame, capture_time_us);
135 int max_delay_us = 0;
136 for (int delay_us : delays_us) {
137 if (delay_us > max_delay_us) {
Sebastian Jansson40889f32019-04-17 12:11:20 +0200138 clock_.AdvanceTime(TimeDelta::us(delay_us - max_delay_us));
Niels Möllerf5033ad2018-08-14 17:00:46 +0200139 max_delay_us = delay_us;
140 }
141
142 overuse_detector_->FrameSent(timestamp, rtc::TimeMicros(),
143 capture_time_us, delay_us);
144 }
145 overuse_detector_->CheckForOveruse(observer_);
Sebastian Jansson40889f32019-04-17 12:11:20 +0200146 clock_.AdvanceTime(TimeDelta::us(interval_us - max_delay_us));
Niels Möllerf5033ad2018-08-14 17:00:46 +0200147 timestamp += interval_us * 90 / 1000;
148 }
149 }
150
Niels Möller83dbeac2017-12-14 16:39:44 +0100151 virtual void InsertAndSendFramesWithRandomInterval(int num_frames,
152 int min_interval_us,
153 int max_interval_us,
154 int width,
155 int height,
156 int delay_us) {
Niels Möllere541be72017-12-13 13:03:10 +0100157 webrtc::Random random(17);
158
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100159 VideoFrame frame =
160 VideoFrame::Builder()
161 .set_video_frame_buffer(I420Buffer::Create(width, height))
162 .set_rotation(webrtc::kVideoRotation_0)
163 .set_timestamp_us(0)
164 .build();
Niels Möllere541be72017-12-13 13:03:10 +0100165 uint32_t timestamp = 0;
166 while (num_frames-- > 0) {
167 frame.set_timestamp(timestamp);
168 int interval_us = random.Rand(min_interval_us, max_interval_us);
Niels Möller83dbeac2017-12-14 16:39:44 +0100169 int64_t capture_time_us = rtc::TimeMicros();
170 overuse_detector_->FrameCaptured(frame, capture_time_us);
Sebastian Jansson40889f32019-04-17 12:11:20 +0200171 clock_.AdvanceTime(TimeDelta::us(delay_us));
Niels Möller83dbeac2017-12-14 16:39:44 +0100172 overuse_detector_->FrameSent(timestamp, rtc::TimeMicros(),
173 capture_time_us,
Danil Chapovalovb9b146c2018-06-15 12:28:07 +0200174 absl::optional<int>(delay_us));
Niels Möllere541be72017-12-13 13:03:10 +0100175
Niels Möller73f29cb2018-01-31 16:09:31 +0100176 overuse_detector_->CheckForOveruse(observer_);
Niels Möllere541be72017-12-13 13:03:10 +0100177 // Avoid turning clock backwards.
178 if (interval_us > delay_us)
Sebastian Jansson40889f32019-04-17 12:11:20 +0200179 clock_.AdvanceTime(TimeDelta::us(interval_us - delay_us));
Niels Möllere541be72017-12-13 13:03:10 +0100180
181 timestamp += interval_us * 90 / 1000;
182 }
183 }
184
Niels Möller83dbeac2017-12-14 16:39:44 +0100185 virtual void ForceUpdate(int width, int height) {
Niels Möller7dc26b72017-12-06 10:27:48 +0100186 // Insert one frame, wait a second and then put in another to force update
187 // the usage. From the tests where these are used, adding another sample
188 // doesn't affect the expected outcome (this is mainly to check initial
189 // values and whether the overuse detector has been reset or not).
Yves Gerey665174f2018-06-19 15:03:05 +0200190 InsertAndSendFramesWithInterval(2, rtc::kNumMicrosecsPerSec, width, height,
191 kFrameIntervalUs);
Peter Boströme4499152016-02-05 11:13:28 +0100192 }
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000193 void TriggerOveruse(int num_times) {
nissee0e3bdf2017-01-18 02:16:20 -0800194 const int kDelayUs = 32 * rtc::kNumMicrosecsPerMillisec;
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000195 for (int i = 0; i < num_times; ++i) {
Yves Gerey665174f2018-06-19 15:03:05 +0200196 InsertAndSendFramesWithInterval(1000, kFrameIntervalUs, kWidth, kHeight,
197 kDelayUs);
Niels Möller73f29cb2018-01-31 16:09:31 +0100198 overuse_detector_->CheckForOveruse(observer_);
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000199 }
200 }
201
Åsa Persson746210f2015-09-08 10:52:42 +0200202 void TriggerUnderuse() {
nissee0e3bdf2017-01-18 02:16:20 -0800203 const int kDelayUs1 = 5000;
204 const int kDelayUs2 = 6000;
Yves Gerey665174f2018-06-19 15:03:05 +0200205 InsertAndSendFramesWithInterval(1300, kFrameIntervalUs, kWidth, kHeight,
206 kDelayUs1);
207 InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight,
208 kDelayUs2);
Niels Möller73f29cb2018-01-31 16:09:31 +0100209 overuse_detector_->CheckForOveruse(observer_);
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000210 }
211
Niels Möller213618e2018-07-24 09:29:58 +0200212 int UsagePercent() { return encode_usage_percent_; }
asapersson@webrtc.orgab6bf4f2014-05-27 07:43:15 +0000213
sprangfda496a2017-06-15 04:21:07 -0700214 int64_t OveruseProcessingTimeLimitForFramerate(int fps) const {
215 int64_t frame_interval = rtc::kNumMicrosecsPerSec / fps;
216 int64_t max_processing_time_us =
217 (frame_interval * options_.high_encode_usage_threshold_percent) / 100;
218 return max_processing_time_us;
219 }
220
221 int64_t UnderuseProcessingTimeLimitForFramerate(int fps) const {
222 int64_t frame_interval = rtc::kNumMicrosecsPerSec / fps;
223 int64_t max_processing_time_us =
224 (frame_interval * options_.low_encode_usage_threshold_percent) / 100;
225 return max_processing_time_us;
226 }
227
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000228 CpuOveruseOptions options_;
nissee0e3bdf2017-01-18 02:16:20 -0800229 rtc::ScopedFakeClock clock_;
Niels Möller73f29cb2018-01-31 16:09:31 +0100230 MockCpuOveruseObserver mock_observer_;
231 AdaptationObserverInterface* observer_;
perkjd52063f2016-09-07 06:32:18 -0700232 std::unique_ptr<OveruseFrameDetectorUnderTest> overuse_detector_;
Niels Möller213618e2018-07-24 09:29:58 +0200233 int encode_usage_percent_ = -1;
kthelgason876222f2016-11-29 01:44:11 -0800234
sprangb1ca0732017-02-01 08:38:12 -0800235 static const auto reason_ = AdaptationObserverInterface::AdaptReason::kCpu;
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000236};
237
Åsa Persson746210f2015-09-08 10:52:42 +0200238// UsagePercent() > high_encode_usage_threshold_percent => overuse.
239// UsagePercent() < low_encode_usage_threshold_percent => underuse.
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000240TEST_F(OveruseFrameDetectorTest, TriggerOveruse) {
Åsa Persson746210f2015-09-08 10:52:42 +0200241 // usage > high => overuse
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200242 overuse_detector_->SetOptions(options_);
Niels Möller73f29cb2018-01-31 16:09:31 +0100243 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000244 TriggerOveruse(options_.high_threshold_consecutive_count);
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +0000245}
246
247TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) {
Åsa Persson746210f2015-09-08 10:52:42 +0200248 // usage > high => overuse
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200249 overuse_detector_->SetOptions(options_);
Niels Möller73f29cb2018-01-31 16:09:31 +0100250 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000251 TriggerOveruse(options_.high_threshold_consecutive_count);
Åsa Persson746210f2015-09-08 10:52:42 +0200252 // usage < low => underuse
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200253 EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(::testing::AtLeast(1));
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +0000254 TriggerUnderuse();
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000255}
256
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +0000257TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) {
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200258 overuse_detector_->SetOptions(options_);
Niels Möller73f29cb2018-01-31 16:09:31 +0100259 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(2);
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000260 TriggerOveruse(options_.high_threshold_consecutive_count);
261 TriggerOveruse(options_.high_threshold_consecutive_count);
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200262 EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(::testing::AtLeast(1));
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +0000263 TriggerUnderuse();
pbos@webrtc.orga9575702013-08-30 17:16:32 +0000264}
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +0000265
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +0000266TEST_F(OveruseFrameDetectorTest, TriggerUnderuseWithMinProcessCount) {
nissee0e3bdf2017-01-18 02:16:20 -0800267 const int kProcessIntervalUs = 5 * rtc::kNumMicrosecsPerSec;
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000268 options_.min_process_count = 1;
Peter Boström4b91bd02015-06-26 06:58:16 +0200269 CpuOveruseObserverImpl overuse_observer;
Niels Möller73f29cb2018-01-31 16:09:31 +0100270 observer_ = nullptr;
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200271 overuse_detector_->SetOptions(options_);
Yves Gerey665174f2018-06-19 15:03:05 +0200272 InsertAndSendFramesWithInterval(1200, kFrameIntervalUs, kWidth, kHeight,
273 kProcessTimeUs);
Niels Möller73f29cb2018-01-31 16:09:31 +0100274 overuse_detector_->CheckForOveruse(&overuse_observer);
Peter Boström4b91bd02015-06-26 06:58:16 +0200275 EXPECT_EQ(0, overuse_observer.normaluse_);
Sebastian Jansson40889f32019-04-17 12:11:20 +0200276 clock_.AdvanceTime(TimeDelta::us(kProcessIntervalUs));
Niels Möller73f29cb2018-01-31 16:09:31 +0100277 overuse_detector_->CheckForOveruse(&overuse_observer);
Peter Boström4b91bd02015-06-26 06:58:16 +0200278 EXPECT_EQ(1, overuse_observer.normaluse_);
asapersson@webrtc.orgb60346e2014-02-17 19:02:15 +0000279}
280
pbos@webrtc.orga9575702013-08-30 17:16:32 +0000281TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) {
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200282 overuse_detector_->SetOptions(options_);
Niels Möller73f29cb2018-01-31 16:09:31 +0100283 EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(0);
284 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(64);
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +0100285 for (size_t i = 0; i < 64; ++i) {
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000286 TriggerOveruse(options_.high_threshold_consecutive_count);
287 }
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +0000288}
289
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000290TEST_F(OveruseFrameDetectorTest, ConsecutiveCountTriggersOveruse) {
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200291 overuse_detector_->SetOptions(options_);
Niels Möller73f29cb2018-01-31 16:09:31 +0100292 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000293 options_.high_threshold_consecutive_count = 2;
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200294 overuse_detector_->SetOptions(options_);
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000295 TriggerOveruse(2);
296}
297
298TEST_F(OveruseFrameDetectorTest, IncorrectConsecutiveCountTriggersNoOveruse) {
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200299 overuse_detector_->SetOptions(options_);
Niels Möller73f29cb2018-01-31 16:09:31 +0100300 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(0);
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000301 options_.high_threshold_consecutive_count = 2;
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200302 overuse_detector_->SetOptions(options_);
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000303 TriggerOveruse(1);
304}
305
Åsa Persson746210f2015-09-08 10:52:42 +0200306TEST_F(OveruseFrameDetectorTest, ProcessingUsage) {
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200307 overuse_detector_->SetOptions(options_);
Yves Gerey665174f2018-06-19 15:03:05 +0200308 InsertAndSendFramesWithInterval(1000, kFrameIntervalUs, kWidth, kHeight,
309 kProcessTimeUs);
nissee0e3bdf2017-01-18 02:16:20 -0800310 EXPECT_EQ(kProcessTimeUs * 100 / kFrameIntervalUs, UsagePercent());
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000311}
312
Åsa Persson746210f2015-09-08 10:52:42 +0200313TEST_F(OveruseFrameDetectorTest, ResetAfterResolutionChange) {
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200314 overuse_detector_->SetOptions(options_);
Peter Boströme4499152016-02-05 11:13:28 +0100315 ForceUpdate(kWidth, kHeight);
Åsa Persson746210f2015-09-08 10:52:42 +0200316 EXPECT_EQ(InitialUsage(), UsagePercent());
Yves Gerey665174f2018-06-19 15:03:05 +0200317 InsertAndSendFramesWithInterval(1000, kFrameIntervalUs, kWidth, kHeight,
318 kProcessTimeUs);
Åsa Persson746210f2015-09-08 10:52:42 +0200319 EXPECT_NE(InitialUsage(), UsagePercent());
Peter Boströme4499152016-02-05 11:13:28 +0100320 // Verify reset (with new width/height).
321 ForceUpdate(kWidth, kHeight + 1);
Åsa Persson746210f2015-09-08 10:52:42 +0200322 EXPECT_EQ(InitialUsage(), UsagePercent());
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000323}
324
Åsa Persson746210f2015-09-08 10:52:42 +0200325TEST_F(OveruseFrameDetectorTest, ResetAfterFrameTimeout) {
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200326 overuse_detector_->SetOptions(options_);
Peter Boströme4499152016-02-05 11:13:28 +0100327 ForceUpdate(kWidth, kHeight);
Åsa Persson746210f2015-09-08 10:52:42 +0200328 EXPECT_EQ(InitialUsage(), UsagePercent());
Yves Gerey665174f2018-06-19 15:03:05 +0200329 InsertAndSendFramesWithInterval(1000, kFrameIntervalUs, kWidth, kHeight,
330 kProcessTimeUs);
Åsa Persson746210f2015-09-08 10:52:42 +0200331 EXPECT_NE(InitialUsage(), UsagePercent());
332 InsertAndSendFramesWithInterval(
Yves Gerey665174f2018-06-19 15:03:05 +0200333 2, options_.frame_timeout_interval_ms * rtc::kNumMicrosecsPerMillisec,
334 kWidth, kHeight, kProcessTimeUs);
Åsa Persson746210f2015-09-08 10:52:42 +0200335 EXPECT_NE(InitialUsage(), UsagePercent());
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000336 // Verify reset.
Åsa Persson746210f2015-09-08 10:52:42 +0200337 InsertAndSendFramesWithInterval(
Yves Gerey665174f2018-06-19 15:03:05 +0200338 2,
339 (options_.frame_timeout_interval_ms + 1) * rtc::kNumMicrosecsPerMillisec,
340 kWidth, kHeight, kProcessTimeUs);
Peter Boströme4499152016-02-05 11:13:28 +0100341 ForceUpdate(kWidth, kHeight);
Åsa Persson746210f2015-09-08 10:52:42 +0200342 EXPECT_EQ(InitialUsage(), UsagePercent());
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000343}
344
Niels Möller7dc26b72017-12-06 10:27:48 +0100345TEST_F(OveruseFrameDetectorTest, MinFrameSamplesBeforeUpdating) {
346 options_.min_frame_samples = 40;
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200347 overuse_detector_->SetOptions(options_);
Yves Gerey665174f2018-06-19 15:03:05 +0200348 InsertAndSendFramesWithInterval(40, kFrameIntervalUs, kWidth, kHeight,
349 kProcessTimeUs);
Niels Möller7dc26b72017-12-06 10:27:48 +0100350 EXPECT_EQ(InitialUsage(), UsagePercent());
351 // Pass time far enough to digest all previous samples.
Sebastian Jansson40889f32019-04-17 12:11:20 +0200352 clock_.AdvanceTime(TimeDelta::seconds(1));
Niels Möller7dc26b72017-12-06 10:27:48 +0100353 InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight,
354 kProcessTimeUs);
355 // The last sample has not been processed here.
356 EXPECT_EQ(InitialUsage(), UsagePercent());
357
358 // Pass time far enough to digest all previous samples, 41 in total.
Sebastian Jansson40889f32019-04-17 12:11:20 +0200359 clock_.AdvanceTime(TimeDelta::seconds(1));
Yves Gerey665174f2018-06-19 15:03:05 +0200360 InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight,
361 kProcessTimeUs);
Niels Möller7dc26b72017-12-06 10:27:48 +0100362 EXPECT_NE(InitialUsage(), UsagePercent());
363}
364
Åsa Persson746210f2015-09-08 10:52:42 +0200365TEST_F(OveruseFrameDetectorTest, InitialProcessingUsage) {
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200366 overuse_detector_->SetOptions(options_);
Peter Boströme4499152016-02-05 11:13:28 +0100367 ForceUpdate(kWidth, kHeight);
Åsa Persson746210f2015-09-08 10:52:42 +0200368 EXPECT_EQ(InitialUsage(), UsagePercent());
asapersson@webrtc.orgb24d3352013-11-20 13:51:40 +0000369}
370
Niels Möller7dc26b72017-12-06 10:27:48 +0100371TEST_F(OveruseFrameDetectorTest, MeasuresMultipleConcurrentSamples) {
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200372 overuse_detector_->SetOptions(options_);
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200373 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(::testing::AtLeast(1));
Niels Möller7dc26b72017-12-06 10:27:48 +0100374 static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
375 static const size_t kNumFramesEncodingDelay = 3;
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100376 VideoFrame frame =
377 VideoFrame::Builder()
378 .set_video_frame_buffer(I420Buffer::Create(kWidth, kHeight))
379 .set_rotation(webrtc::kVideoRotation_0)
380 .set_timestamp_us(0)
381 .build();
Niels Möller7dc26b72017-12-06 10:27:48 +0100382 for (size_t i = 0; i < 1000; ++i) {
383 // Unique timestamps.
384 frame.set_timestamp(static_cast<uint32_t>(i));
Niels Möller83dbeac2017-12-14 16:39:44 +0100385 int64_t capture_time_us = rtc::TimeMicros();
386 overuse_detector_->FrameCaptured(frame, capture_time_us);
Sebastian Jansson40889f32019-04-17 12:11:20 +0200387 clock_.AdvanceTime(TimeDelta::us(kIntervalUs));
Niels Möller7dc26b72017-12-06 10:27:48 +0100388 if (i > kNumFramesEncodingDelay) {
389 overuse_detector_->FrameSent(
Niels Möller83dbeac2017-12-14 16:39:44 +0100390 static_cast<uint32_t>(i - kNumFramesEncodingDelay), rtc::TimeMicros(),
391 capture_time_us, kIntervalUs);
Niels Möller7dc26b72017-12-06 10:27:48 +0100392 }
Niels Möller73f29cb2018-01-31 16:09:31 +0100393 overuse_detector_->CheckForOveruse(observer_);
Niels Möller7dc26b72017-12-06 10:27:48 +0100394 }
395}
396
397TEST_F(OveruseFrameDetectorTest, UpdatesExistingSamples) {
398 // >85% encoding time should trigger overuse.
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200399 overuse_detector_->SetOptions(options_);
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200400 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(::testing::AtLeast(1));
Niels Möller7dc26b72017-12-06 10:27:48 +0100401 static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
402 static const int kDelayUs = 30 * rtc::kNumMicrosecsPerMillisec;
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100403 VideoFrame frame =
404 VideoFrame::Builder()
405 .set_video_frame_buffer(I420Buffer::Create(kWidth, kHeight))
406 .set_rotation(webrtc::kVideoRotation_0)
407 .set_timestamp_us(0)
408 .build();
Niels Möller7dc26b72017-12-06 10:27:48 +0100409 uint32_t timestamp = 0;
410 for (size_t i = 0; i < 1000; ++i) {
411 frame.set_timestamp(timestamp);
Niels Möller83dbeac2017-12-14 16:39:44 +0100412 int64_t capture_time_us = rtc::TimeMicros();
413 overuse_detector_->FrameCaptured(frame, capture_time_us);
Niels Möller7dc26b72017-12-06 10:27:48 +0100414 // Encode and send first parts almost instantly.
Sebastian Jansson40889f32019-04-17 12:11:20 +0200415 clock_.AdvanceTime(TimeDelta::ms(1));
Niels Möller83dbeac2017-12-14 16:39:44 +0100416 overuse_detector_->FrameSent(timestamp, rtc::TimeMicros(), capture_time_us,
417 rtc::kNumMicrosecsPerMillisec);
Niels Möller7dc26b72017-12-06 10:27:48 +0100418 // Encode heavier part, resulting in >85% usage total.
Sebastian Jansson40889f32019-04-17 12:11:20 +0200419 clock_.AdvanceTime(TimeDelta::us(kDelayUs) - TimeDelta::ms(1));
Niels Möller83dbeac2017-12-14 16:39:44 +0100420 overuse_detector_->FrameSent(timestamp, rtc::TimeMicros(), capture_time_us,
421 kDelayUs);
Sebastian Jansson40889f32019-04-17 12:11:20 +0200422 clock_.AdvanceTime(TimeDelta::us(kIntervalUs - kDelayUs));
Niels Möller7dc26b72017-12-06 10:27:48 +0100423 timestamp += kIntervalUs * 90 / 1000;
Niels Möller73f29cb2018-01-31 16:09:31 +0100424 overuse_detector_->CheckForOveruse(observer_);
Niels Möller7dc26b72017-12-06 10:27:48 +0100425 }
426}
427
perkjd52063f2016-09-07 06:32:18 -0700428TEST_F(OveruseFrameDetectorTest, RunOnTqNormalUsage) {
Danil Chapovalov07122bc2019-03-26 14:37:01 +0100429 TaskQueueForTest queue("OveruseFrameDetectorTestQueue");
430
431 queue.SendTask([&] {
432 overuse_detector_->StartCheckForOveruse(&queue, options_, observer_);
433 });
perkjd52063f2016-09-07 06:32:18 -0700434
Niels Möllerc572ff32018-11-07 08:43:50 +0100435 rtc::Event event;
perkjd52063f2016-09-07 06:32:18 -0700436 // Expect NormalUsage(). When called, stop the |overuse_detector_| and then
437 // set |event| to end the test.
Niels Möller73f29cb2018-01-31 16:09:31 +0100438 EXPECT_CALL(mock_observer_, AdaptUp(reason_))
kthelgason876222f2016-11-29 01:44:11 -0800439 .WillOnce(InvokeWithoutArgs([this, &event] {
perkjd52063f2016-09-07 06:32:18 -0700440 overuse_detector_->StopCheckForOveruse();
441 event.Set();
442 }));
443
eladalon1cc5fc32017-08-23 04:15:18 -0700444 queue.PostTask([this] {
nissee0e3bdf2017-01-18 02:16:20 -0800445 const int kDelayUs1 = 5 * rtc::kNumMicrosecsPerMillisec;
446 const int kDelayUs2 = 6 * rtc::kNumMicrosecsPerMillisec;
447 InsertAndSendFramesWithInterval(1300, kFrameIntervalUs, kWidth, kHeight,
448 kDelayUs1);
449 InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight,
450 kDelayUs2);
perkjd52063f2016-09-07 06:32:18 -0700451 });
452
453 EXPECT_TRUE(event.Wait(10000));
454}
455
Niels Möller7dc26b72017-12-06 10:27:48 +0100456TEST_F(OveruseFrameDetectorTest, MaxIntervalScalesWithFramerate) {
457 const int kCapturerMaxFrameRate = 30;
458 const int kEncodeMaxFrameRate = 20; // Maximum fps the encoder can sustain.
sprangfda496a2017-06-15 04:21:07 -0700459
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200460 overuse_detector_->SetOptions(options_);
Niels Möller7dc26b72017-12-06 10:27:48 +0100461 // Trigger overuse.
462 int64_t frame_interval_us = rtc::kNumMicrosecsPerSec / kCapturerMaxFrameRate;
463 // Processing time just below over use limit given kEncodeMaxFrameRate.
464 int64_t processing_time_us =
465 (98 * OveruseProcessingTimeLimitForFramerate(kEncodeMaxFrameRate)) / 100;
Niels Möller73f29cb2018-01-31 16:09:31 +0100466 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
Niels Möller7dc26b72017-12-06 10:27:48 +0100467 for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
468 InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
469 processing_time_us);
Niels Möller73f29cb2018-01-31 16:09:31 +0100470 overuse_detector_->CheckForOveruse(observer_);
sprangfda496a2017-06-15 04:21:07 -0700471 }
Niels Möller7dc26b72017-12-06 10:27:48 +0100472
473 // Simulate frame rate reduction and normal usage.
474 frame_interval_us = rtc::kNumMicrosecsPerSec / kEncodeMaxFrameRate;
475 overuse_detector_->OnTargetFramerateUpdated(kEncodeMaxFrameRate);
Niels Möller73f29cb2018-01-31 16:09:31 +0100476 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(0);
Niels Möller7dc26b72017-12-06 10:27:48 +0100477 for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
478 InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
479 processing_time_us);
Niels Möller73f29cb2018-01-31 16:09:31 +0100480 overuse_detector_->CheckForOveruse(observer_);
Niels Möller7dc26b72017-12-06 10:27:48 +0100481 }
482
483 // Reduce processing time to trigger underuse.
484 processing_time_us =
485 (98 * UnderuseProcessingTimeLimitForFramerate(kEncodeMaxFrameRate)) / 100;
Niels Möller73f29cb2018-01-31 16:09:31 +0100486 EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(1);
Niels Möller7dc26b72017-12-06 10:27:48 +0100487 InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
488 processing_time_us);
Niels Möller73f29cb2018-01-31 16:09:31 +0100489 overuse_detector_->CheckForOveruse(observer_);
sprangfda496a2017-06-15 04:21:07 -0700490}
491
Niels Möller7dc26b72017-12-06 10:27:48 +0100492TEST_F(OveruseFrameDetectorTest, RespectsMinFramerate) {
493 const int kMinFrameRate = 7; // Minimum fps allowed by current detector impl.
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200494 overuse_detector_->SetOptions(options_);
Niels Möller7dc26b72017-12-06 10:27:48 +0100495 overuse_detector_->OnTargetFramerateUpdated(kMinFrameRate);
sprangfda496a2017-06-15 04:21:07 -0700496
Niels Möller7dc26b72017-12-06 10:27:48 +0100497 // Normal usage just at the limit.
498 int64_t frame_interval_us = rtc::kNumMicrosecsPerSec / kMinFrameRate;
499 // Processing time just below over use limit given kEncodeMaxFrameRate.
500 int64_t processing_time_us =
501 (98 * OveruseProcessingTimeLimitForFramerate(kMinFrameRate)) / 100;
Niels Möller73f29cb2018-01-31 16:09:31 +0100502 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(0);
Niels Möller7dc26b72017-12-06 10:27:48 +0100503 for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
504 InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
505 processing_time_us);
Niels Möller73f29cb2018-01-31 16:09:31 +0100506 overuse_detector_->CheckForOveruse(observer_);
sprangfda496a2017-06-15 04:21:07 -0700507 }
Niels Möller7dc26b72017-12-06 10:27:48 +0100508
509 // Over the limit to overuse.
510 processing_time_us =
511 (102 * OveruseProcessingTimeLimitForFramerate(kMinFrameRate)) / 100;
Niels Möller73f29cb2018-01-31 16:09:31 +0100512 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
Niels Möller7dc26b72017-12-06 10:27:48 +0100513 for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
514 InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
515 processing_time_us);
Niels Möller73f29cb2018-01-31 16:09:31 +0100516 overuse_detector_->CheckForOveruse(observer_);
Niels Möller7dc26b72017-12-06 10:27:48 +0100517 }
518
519 // Reduce input frame rate. Should still trigger overuse.
520 overuse_detector_->OnTargetFramerateUpdated(kMinFrameRate - 1);
Niels Möller73f29cb2018-01-31 16:09:31 +0100521 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
Niels Möller7dc26b72017-12-06 10:27:48 +0100522 for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
523 InsertAndSendFramesWithInterval(1200, frame_interval_us, kWidth, kHeight,
524 processing_time_us);
Niels Möller73f29cb2018-01-31 16:09:31 +0100525 overuse_detector_->CheckForOveruse(observer_);
Niels Möller7dc26b72017-12-06 10:27:48 +0100526 }
527}
528
529TEST_F(OveruseFrameDetectorTest, LimitsMaxFrameInterval) {
530 const int kMaxFrameRate = 20;
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200531 overuse_detector_->SetOptions(options_);
Niels Möller7dc26b72017-12-06 10:27:48 +0100532 overuse_detector_->OnTargetFramerateUpdated(kMaxFrameRate);
533 int64_t frame_interval_us = rtc::kNumMicrosecsPerSec / kMaxFrameRate;
534 // Maximum frame interval allowed is 35% above ideal.
535 int64_t max_frame_interval_us = (135 * frame_interval_us) / 100;
536 // Maximum processing time, without triggering overuse, allowed with the above
537 // frame interval.
538 int64_t max_processing_time_us =
539 (max_frame_interval_us * options_.high_encode_usage_threshold_percent) /
540 100;
541
542 // Processing time just below overuse limit given kMaxFrameRate.
543 int64_t processing_time_us = (98 * max_processing_time_us) / 100;
Niels Möller73f29cb2018-01-31 16:09:31 +0100544 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(0);
Niels Möller7dc26b72017-12-06 10:27:48 +0100545 for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
546 InsertAndSendFramesWithInterval(1200, max_frame_interval_us, kWidth,
547 kHeight, processing_time_us);
Niels Möller73f29cb2018-01-31 16:09:31 +0100548 overuse_detector_->CheckForOveruse(observer_);
Niels Möller7dc26b72017-12-06 10:27:48 +0100549 }
550
551 // Go above limit, trigger overuse.
552 processing_time_us = (102 * max_processing_time_us) / 100;
Niels Möller73f29cb2018-01-31 16:09:31 +0100553 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
Niels Möller7dc26b72017-12-06 10:27:48 +0100554 for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
555 InsertAndSendFramesWithInterval(1200, max_frame_interval_us, kWidth,
556 kHeight, processing_time_us);
Niels Möller73f29cb2018-01-31 16:09:31 +0100557 overuse_detector_->CheckForOveruse(observer_);
Niels Möller7dc26b72017-12-06 10:27:48 +0100558 }
559
560 // Increase frame interval, should still trigger overuse.
561 max_frame_interval_us *= 2;
Niels Möller73f29cb2018-01-31 16:09:31 +0100562 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
Niels Möller7dc26b72017-12-06 10:27:48 +0100563 for (int i = 0; i < options_.high_threshold_consecutive_count; ++i) {
564 InsertAndSendFramesWithInterval(1200, max_frame_interval_us, kWidth,
565 kHeight, processing_time_us);
Niels Möller73f29cb2018-01-31 16:09:31 +0100566 overuse_detector_->CheckForOveruse(observer_);
Niels Möller7dc26b72017-12-06 10:27:48 +0100567 }
sprangfda496a2017-06-15 04:21:07 -0700568}
569
Niels Möllere541be72017-12-13 13:03:10 +0100570// Models screencast, with irregular arrival of frames which are heavy
571// to encode.
572TEST_F(OveruseFrameDetectorTest, NoOveruseForLargeRandomFrameInterval) {
573 // TODO(bugs.webrtc.org/8504): When new estimator is relanded,
574 // behavior is improved in this scenario, with only AdaptUp events,
575 // and estimated load closer to the true average.
576
Niels Möller73f29cb2018-01-31 16:09:31 +0100577 // EXPECT_CALL(mock_observer_, AdaptDown(_)).Times(0);
578 // EXPECT_CALL(mock_observer_, AdaptUp(reason_))
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200579 // .Times(::testing::AtLeast(1));
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200580 overuse_detector_->SetOptions(options_);
Niels Möllere541be72017-12-13 13:03:10 +0100581
582 const int kNumFrames = 500;
583 const int kEncodeTimeUs = 100 * rtc::kNumMicrosecsPerMillisec;
584
585 const int kMinIntervalUs = 30 * rtc::kNumMicrosecsPerMillisec;
586 const int kMaxIntervalUs = 1000 * rtc::kNumMicrosecsPerMillisec;
587
588 const int kTargetFramerate = 5;
589
590 overuse_detector_->OnTargetFramerateUpdated(kTargetFramerate);
591
Yves Gerey665174f2018-06-19 15:03:05 +0200592 InsertAndSendFramesWithRandomInterval(kNumFrames, kMinIntervalUs,
593 kMaxIntervalUs, kWidth, kHeight,
594 kEncodeTimeUs);
Niels Möllere541be72017-12-13 13:03:10 +0100595 // Average usage 19%. Check that estimate is in the right ball park.
596 // EXPECT_NEAR(UsagePercent(), 20, 10);
597 EXPECT_NEAR(UsagePercent(), 20, 35);
598}
599
600// Models screencast, with irregular arrival of frames, often
601// exceeding the timeout interval.
602TEST_F(OveruseFrameDetectorTest, NoOveruseForRandomFrameIntervalWithReset) {
603 // TODO(bugs.webrtc.org/8504): When new estimator is relanded,
604 // behavior is improved in this scenario, and we get AdaptUp events.
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200605 overuse_detector_->SetOptions(options_);
Niels Möller73f29cb2018-01-31 16:09:31 +0100606 EXPECT_CALL(mock_observer_, AdaptDown(_)).Times(0);
607 // EXPECT_CALL(mock_observer_, AdaptUp(reason_))
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200608 // .Times(::testing::AtLeast(1));
Niels Möllere541be72017-12-13 13:03:10 +0100609
610 const int kNumFrames = 500;
611 const int kEncodeTimeUs = 100 * rtc::kNumMicrosecsPerMillisec;
612
613 const int kMinIntervalUs = 30 * rtc::kNumMicrosecsPerMillisec;
614 const int kMaxIntervalUs = 3000 * rtc::kNumMicrosecsPerMillisec;
615
616 const int kTargetFramerate = 5;
617
618 overuse_detector_->OnTargetFramerateUpdated(kTargetFramerate);
619
Yves Gerey665174f2018-06-19 15:03:05 +0200620 InsertAndSendFramesWithRandomInterval(kNumFrames, kMinIntervalUs,
621 kMaxIntervalUs, kWidth, kHeight,
622 kEncodeTimeUs);
Niels Möllere541be72017-12-13 13:03:10 +0100623
624 // Average usage 6.6%, but since the frame_timeout_interval_ms is
625 // only 1500 ms, we often reset the estimate to the initial value.
626 // Check that estimate is in the right ball park.
627 EXPECT_GE(UsagePercent(), 1);
628 EXPECT_LE(UsagePercent(), InitialUsage() + 5);
629}
630
Niels Möllerf5033ad2018-08-14 17:00:46 +0200631// Models simulcast, with multiple encoded frames for each input frame.
632// Load estimate should be based on the maximum encode time per input frame.
633TEST_F(OveruseFrameDetectorTest, NoOveruseForSimulcast) {
634 overuse_detector_->SetOptions(options_);
635 EXPECT_CALL(mock_observer_, AdaptDown(_)).Times(0);
636
637 constexpr int kNumFrames = 500;
638 constexpr int kEncodeTimesUs[] = {
639 10 * rtc::kNumMicrosecsPerMillisec, 8 * rtc::kNumMicrosecsPerMillisec,
640 12 * rtc::kNumMicrosecsPerMillisec,
641 };
642 constexpr int kIntervalUs = 30 * rtc::kNumMicrosecsPerMillisec;
643
644 InsertAndSendSimulcastFramesWithInterval(kNumFrames, kIntervalUs, kWidth,
645 kHeight, kEncodeTimesUs);
646
647 // Average usage 40%. 12 ms / 30 ms.
648 EXPECT_GE(UsagePercent(), 35);
649 EXPECT_LE(UsagePercent(), 45);
650}
651
Niels Möller83dbeac2017-12-14 16:39:44 +0100652// Tests using new cpu load estimator
653class OveruseFrameDetectorTest2 : public OveruseFrameDetectorTest {
654 protected:
655 void SetUp() override {
656 options_.filter_time_ms = 5 * rtc::kNumMillisecsPerSec;
657 OveruseFrameDetectorTest::SetUp();
658 }
659
660 void InsertAndSendFramesWithInterval(int num_frames,
661 int interval_us,
662 int width,
663 int height,
664 int delay_us) override {
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100665 VideoFrame frame =
666 VideoFrame::Builder()
667 .set_video_frame_buffer(I420Buffer::Create(width, height))
668 .set_rotation(webrtc::kVideoRotation_0)
669 .set_timestamp_us(0)
670 .build();
Niels Möller83dbeac2017-12-14 16:39:44 +0100671 while (num_frames-- > 0) {
672 int64_t capture_time_us = rtc::TimeMicros();
673 overuse_detector_->FrameCaptured(frame, capture_time_us /* ignored */);
674 overuse_detector_->FrameSent(0 /* ignored timestamp */,
675 0 /* ignored send_time_us */,
676 capture_time_us, delay_us);
Sebastian Jansson40889f32019-04-17 12:11:20 +0200677 clock_.AdvanceTime(TimeDelta::us(interval_us));
Niels Möller83dbeac2017-12-14 16:39:44 +0100678 }
679 }
680
681 void InsertAndSendFramesWithRandomInterval(int num_frames,
682 int min_interval_us,
683 int max_interval_us,
684 int width,
685 int height,
686 int delay_us) override {
687 webrtc::Random random(17);
688
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100689 VideoFrame frame =
690 VideoFrame::Builder()
691 .set_video_frame_buffer(I420Buffer::Create(width, height))
692 .set_rotation(webrtc::kVideoRotation_0)
693 .set_timestamp_us(0)
694 .build();
Niels Möller83dbeac2017-12-14 16:39:44 +0100695 for (int i = 0; i < num_frames; i++) {
696 int interval_us = random.Rand(min_interval_us, max_interval_us);
697 int64_t capture_time_us = rtc::TimeMicros();
698 overuse_detector_->FrameCaptured(frame, capture_time_us);
699 overuse_detector_->FrameSent(0 /* ignored timestamp */,
700 0 /* ignored send_time_us */,
701 capture_time_us, delay_us);
702
Niels Möller73f29cb2018-01-31 16:09:31 +0100703 overuse_detector_->CheckForOveruse(observer_);
Sebastian Jansson40889f32019-04-17 12:11:20 +0200704 clock_.AdvanceTime(TimeDelta::us(interval_us));
Niels Möller83dbeac2017-12-14 16:39:44 +0100705 }
706 }
707
708 void ForceUpdate(int width, int height) override {
709 // This is mainly to check initial values and whether the overuse
710 // detector has been reset or not.
711 InsertAndSendFramesWithInterval(1, rtc::kNumMicrosecsPerSec, width, height,
712 kFrameIntervalUs);
713 }
714};
715
716// UsagePercent() > high_encode_usage_threshold_percent => overuse.
717// UsagePercent() < low_encode_usage_threshold_percent => underuse.
718TEST_F(OveruseFrameDetectorTest2, TriggerOveruse) {
719 // usage > high => overuse
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200720 overuse_detector_->SetOptions(options_);
Niels Möller73f29cb2018-01-31 16:09:31 +0100721 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
Niels Möller83dbeac2017-12-14 16:39:44 +0100722 TriggerOveruse(options_.high_threshold_consecutive_count);
723}
724
725TEST_F(OveruseFrameDetectorTest2, OveruseAndRecover) {
726 // usage > high => overuse
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200727 overuse_detector_->SetOptions(options_);
Niels Möller73f29cb2018-01-31 16:09:31 +0100728 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
Niels Möller83dbeac2017-12-14 16:39:44 +0100729 TriggerOveruse(options_.high_threshold_consecutive_count);
730 // usage < low => underuse
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200731 EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(::testing::AtLeast(1));
Niels Möller83dbeac2017-12-14 16:39:44 +0100732 TriggerUnderuse();
733}
734
735TEST_F(OveruseFrameDetectorTest2, DoubleOveruseAndRecover) {
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200736 overuse_detector_->SetOptions(options_);
Niels Möller73f29cb2018-01-31 16:09:31 +0100737 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(2);
Niels Möller83dbeac2017-12-14 16:39:44 +0100738 TriggerOveruse(options_.high_threshold_consecutive_count);
739 TriggerOveruse(options_.high_threshold_consecutive_count);
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200740 EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(::testing::AtLeast(1));
Niels Möller83dbeac2017-12-14 16:39:44 +0100741 TriggerUnderuse();
742}
743
744TEST_F(OveruseFrameDetectorTest2, TriggerUnderuseWithMinProcessCount) {
745 const int kProcessIntervalUs = 5 * rtc::kNumMicrosecsPerSec;
746 options_.min_process_count = 1;
747 CpuOveruseObserverImpl overuse_observer;
Niels Möller73f29cb2018-01-31 16:09:31 +0100748 observer_ = nullptr;
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200749 overuse_detector_->SetOptions(options_);
Yves Gerey665174f2018-06-19 15:03:05 +0200750 InsertAndSendFramesWithInterval(1200, kFrameIntervalUs, kWidth, kHeight,
751 kProcessTimeUs);
Niels Möller73f29cb2018-01-31 16:09:31 +0100752 overuse_detector_->CheckForOveruse(&overuse_observer);
Niels Möller83dbeac2017-12-14 16:39:44 +0100753 EXPECT_EQ(0, overuse_observer.normaluse_);
Sebastian Jansson40889f32019-04-17 12:11:20 +0200754 clock_.AdvanceTime(TimeDelta::us(kProcessIntervalUs));
Niels Möller73f29cb2018-01-31 16:09:31 +0100755 overuse_detector_->CheckForOveruse(&overuse_observer);
Niels Möller83dbeac2017-12-14 16:39:44 +0100756 EXPECT_EQ(1, overuse_observer.normaluse_);
757}
758
759TEST_F(OveruseFrameDetectorTest2, ConstantOveruseGivesNoNormalUsage) {
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200760 overuse_detector_->SetOptions(options_);
Niels Möller73f29cb2018-01-31 16:09:31 +0100761 EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(0);
762 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(64);
Niels Möller83dbeac2017-12-14 16:39:44 +0100763 for (size_t i = 0; i < 64; ++i) {
764 TriggerOveruse(options_.high_threshold_consecutive_count);
765 }
766}
767
768TEST_F(OveruseFrameDetectorTest2, ConsecutiveCountTriggersOveruse) {
Niels Möller73f29cb2018-01-31 16:09:31 +0100769 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(1);
Niels Möller83dbeac2017-12-14 16:39:44 +0100770 options_.high_threshold_consecutive_count = 2;
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200771 overuse_detector_->SetOptions(options_);
Niels Möller83dbeac2017-12-14 16:39:44 +0100772 TriggerOveruse(2);
773}
774
775TEST_F(OveruseFrameDetectorTest2, IncorrectConsecutiveCountTriggersNoOveruse) {
Niels Möller73f29cb2018-01-31 16:09:31 +0100776 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(0);
Niels Möller83dbeac2017-12-14 16:39:44 +0100777 options_.high_threshold_consecutive_count = 2;
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200778 overuse_detector_->SetOptions(options_);
Niels Möller83dbeac2017-12-14 16:39:44 +0100779 TriggerOveruse(1);
780}
781
782TEST_F(OveruseFrameDetectorTest2, ProcessingUsage) {
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200783 overuse_detector_->SetOptions(options_);
Yves Gerey665174f2018-06-19 15:03:05 +0200784 InsertAndSendFramesWithInterval(1000, kFrameIntervalUs, kWidth, kHeight,
785 kProcessTimeUs);
Niels Möller83dbeac2017-12-14 16:39:44 +0100786 EXPECT_EQ(kProcessTimeUs * 100 / kFrameIntervalUs, UsagePercent());
787}
788
789TEST_F(OveruseFrameDetectorTest2, ResetAfterResolutionChange) {
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200790 overuse_detector_->SetOptions(options_);
Niels Möller83dbeac2017-12-14 16:39:44 +0100791 ForceUpdate(kWidth, kHeight);
792 EXPECT_EQ(InitialUsage(), UsagePercent());
Yves Gerey665174f2018-06-19 15:03:05 +0200793 InsertAndSendFramesWithInterval(1000, kFrameIntervalUs, kWidth, kHeight,
794 kProcessTimeUs);
Niels Möller83dbeac2017-12-14 16:39:44 +0100795 EXPECT_NE(InitialUsage(), UsagePercent());
796 // Verify reset (with new width/height).
797 ForceUpdate(kWidth, kHeight + 1);
798 EXPECT_EQ(InitialUsage(), UsagePercent());
799}
800
801TEST_F(OveruseFrameDetectorTest2, ResetAfterFrameTimeout) {
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200802 overuse_detector_->SetOptions(options_);
Niels Möller83dbeac2017-12-14 16:39:44 +0100803 ForceUpdate(kWidth, kHeight);
804 EXPECT_EQ(InitialUsage(), UsagePercent());
Yves Gerey665174f2018-06-19 15:03:05 +0200805 InsertAndSendFramesWithInterval(1000, kFrameIntervalUs, kWidth, kHeight,
806 kProcessTimeUs);
Niels Möller83dbeac2017-12-14 16:39:44 +0100807 EXPECT_NE(InitialUsage(), UsagePercent());
808 InsertAndSendFramesWithInterval(
Yves Gerey665174f2018-06-19 15:03:05 +0200809 2, options_.frame_timeout_interval_ms * rtc::kNumMicrosecsPerMillisec,
810 kWidth, kHeight, kProcessTimeUs);
Niels Möller83dbeac2017-12-14 16:39:44 +0100811 EXPECT_NE(InitialUsage(), UsagePercent());
812 // Verify reset.
813 InsertAndSendFramesWithInterval(
Yves Gerey665174f2018-06-19 15:03:05 +0200814 2,
815 (options_.frame_timeout_interval_ms + 1) * rtc::kNumMicrosecsPerMillisec,
816 kWidth, kHeight, kProcessTimeUs);
Niels Möller83dbeac2017-12-14 16:39:44 +0100817 ForceUpdate(kWidth, kHeight);
818 EXPECT_EQ(InitialUsage(), UsagePercent());
819}
820
821TEST_F(OveruseFrameDetectorTest2, ConvergesSlowly) {
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200822 overuse_detector_->SetOptions(options_);
Niels Möller83dbeac2017-12-14 16:39:44 +0100823 InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight,
824 kProcessTimeUs);
825 // No update for the first sample.
826 EXPECT_EQ(InitialUsage(), UsagePercent());
827
828 // Total time approximately 40 * 33ms = 1.3s, significantly less
829 // than the 5s time constant.
Yves Gerey665174f2018-06-19 15:03:05 +0200830 InsertAndSendFramesWithInterval(40, kFrameIntervalUs, kWidth, kHeight,
831 kProcessTimeUs);
Niels Möller83dbeac2017-12-14 16:39:44 +0100832
833 // Should have started to approach correct load of 15%, but not very far.
834 EXPECT_LT(UsagePercent(), InitialUsage());
835 EXPECT_GT(UsagePercent(), (InitialUsage() * 3 + 15) / 4);
836
837 // Run for roughly 10s more, should now be closer.
Yves Gerey665174f2018-06-19 15:03:05 +0200838 InsertAndSendFramesWithInterval(300, kFrameIntervalUs, kWidth, kHeight,
839 kProcessTimeUs);
Niels Möller83dbeac2017-12-14 16:39:44 +0100840 EXPECT_NEAR(UsagePercent(), 20, 5);
841}
842
843TEST_F(OveruseFrameDetectorTest2, InitialProcessingUsage) {
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200844 overuse_detector_->SetOptions(options_);
Niels Möller83dbeac2017-12-14 16:39:44 +0100845 ForceUpdate(kWidth, kHeight);
846 EXPECT_EQ(InitialUsage(), UsagePercent());
847}
848
849TEST_F(OveruseFrameDetectorTest2, MeasuresMultipleConcurrentSamples) {
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200850 overuse_detector_->SetOptions(options_);
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200851 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(::testing::AtLeast(1));
Niels Möller83dbeac2017-12-14 16:39:44 +0100852 static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
853 static const size_t kNumFramesEncodingDelay = 3;
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100854 VideoFrame frame =
855 VideoFrame::Builder()
856 .set_video_frame_buffer(I420Buffer::Create(kWidth, kHeight))
857 .set_rotation(webrtc::kVideoRotation_0)
858 .set_timestamp_us(0)
859 .build();
Niels Möller83dbeac2017-12-14 16:39:44 +0100860 for (size_t i = 0; i < 1000; ++i) {
861 // Unique timestamps.
862 frame.set_timestamp(static_cast<uint32_t>(i));
863 int64_t capture_time_us = rtc::TimeMicros();
864 overuse_detector_->FrameCaptured(frame, capture_time_us);
Sebastian Jansson40889f32019-04-17 12:11:20 +0200865 clock_.AdvanceTime(TimeDelta::us(kIntervalUs));
Niels Möller83dbeac2017-12-14 16:39:44 +0100866 if (i > kNumFramesEncodingDelay) {
867 overuse_detector_->FrameSent(
868 static_cast<uint32_t>(i - kNumFramesEncodingDelay), rtc::TimeMicros(),
869 capture_time_us, kIntervalUs);
870 }
Niels Möller73f29cb2018-01-31 16:09:31 +0100871 overuse_detector_->CheckForOveruse(observer_);
Niels Möller83dbeac2017-12-14 16:39:44 +0100872 }
873}
874
875TEST_F(OveruseFrameDetectorTest2, UpdatesExistingSamples) {
876 // >85% encoding time should trigger overuse.
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200877 overuse_detector_->SetOptions(options_);
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200878 EXPECT_CALL(mock_observer_, AdaptDown(reason_)).Times(::testing::AtLeast(1));
Niels Möller83dbeac2017-12-14 16:39:44 +0100879 static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
880 static const int kDelayUs = 30 * rtc::kNumMicrosecsPerMillisec;
Artem Titov1ebfb6a2019-01-03 23:49:37 +0100881 VideoFrame frame =
882 VideoFrame::Builder()
883 .set_video_frame_buffer(I420Buffer::Create(kWidth, kHeight))
884 .set_rotation(webrtc::kVideoRotation_0)
885 .set_timestamp_us(0)
886 .build();
Niels Möller83dbeac2017-12-14 16:39:44 +0100887 uint32_t timestamp = 0;
888 for (size_t i = 0; i < 1000; ++i) {
889 frame.set_timestamp(timestamp);
890 int64_t capture_time_us = rtc::TimeMicros();
891 overuse_detector_->FrameCaptured(frame, capture_time_us);
892 // Encode and send first parts almost instantly.
Sebastian Jansson40889f32019-04-17 12:11:20 +0200893 clock_.AdvanceTime(TimeDelta::ms(1));
Niels Möller83dbeac2017-12-14 16:39:44 +0100894 overuse_detector_->FrameSent(timestamp, rtc::TimeMicros(), capture_time_us,
895 rtc::kNumMicrosecsPerMillisec);
896 // Encode heavier part, resulting in >85% usage total.
Sebastian Jansson40889f32019-04-17 12:11:20 +0200897 clock_.AdvanceTime(TimeDelta::us(kDelayUs) - TimeDelta::ms(1));
Niels Möller83dbeac2017-12-14 16:39:44 +0100898 overuse_detector_->FrameSent(timestamp, rtc::TimeMicros(), capture_time_us,
899 kDelayUs);
Sebastian Jansson40889f32019-04-17 12:11:20 +0200900 clock_.AdvanceTime(TimeDelta::us(kIntervalUs - kDelayUs));
Niels Möller83dbeac2017-12-14 16:39:44 +0100901 timestamp += kIntervalUs * 90 / 1000;
Niels Möller73f29cb2018-01-31 16:09:31 +0100902 overuse_detector_->CheckForOveruse(observer_);
Niels Möller83dbeac2017-12-14 16:39:44 +0100903 }
904}
905
906TEST_F(OveruseFrameDetectorTest2, RunOnTqNormalUsage) {
Danil Chapovalov07122bc2019-03-26 14:37:01 +0100907 TaskQueueForTest queue("OveruseFrameDetectorTestQueue");
908
909 queue.SendTask([&] {
910 overuse_detector_->StartCheckForOveruse(&queue, options_, observer_);
911 });
Niels Möller83dbeac2017-12-14 16:39:44 +0100912
Niels Möllerc572ff32018-11-07 08:43:50 +0100913 rtc::Event event;
Niels Möller83dbeac2017-12-14 16:39:44 +0100914 // Expect NormalUsage(). When called, stop the |overuse_detector_| and then
915 // set |event| to end the test.
Niels Möller73f29cb2018-01-31 16:09:31 +0100916 EXPECT_CALL(mock_observer_, AdaptUp(reason_))
Niels Möller83dbeac2017-12-14 16:39:44 +0100917 .WillOnce(InvokeWithoutArgs([this, &event] {
918 overuse_detector_->StopCheckForOveruse();
919 event.Set();
920 }));
921
922 queue.PostTask([this] {
923 const int kDelayUs1 = 5 * rtc::kNumMicrosecsPerMillisec;
924 const int kDelayUs2 = 6 * rtc::kNumMicrosecsPerMillisec;
925 InsertAndSendFramesWithInterval(1300, kFrameIntervalUs, kWidth, kHeight,
926 kDelayUs1);
927 InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight,
928 kDelayUs2);
929 });
930
931 EXPECT_TRUE(event.Wait(10000));
932}
933
934// Models screencast, with irregular arrival of frames which are heavy
935// to encode.
936TEST_F(OveruseFrameDetectorTest2, NoOveruseForLargeRandomFrameInterval) {
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200937 overuse_detector_->SetOptions(options_);
Niels Möller73f29cb2018-01-31 16:09:31 +0100938 EXPECT_CALL(mock_observer_, AdaptDown(_)).Times(0);
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200939 EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(::testing::AtLeast(1));
Niels Möller83dbeac2017-12-14 16:39:44 +0100940
941 const int kNumFrames = 500;
942 const int kEncodeTimeUs = 100 * rtc::kNumMicrosecsPerMillisec;
943
944 const int kMinIntervalUs = 30 * rtc::kNumMicrosecsPerMillisec;
945 const int kMaxIntervalUs = 1000 * rtc::kNumMicrosecsPerMillisec;
946
Yves Gerey665174f2018-06-19 15:03:05 +0200947 InsertAndSendFramesWithRandomInterval(kNumFrames, kMinIntervalUs,
948 kMaxIntervalUs, kWidth, kHeight,
949 kEncodeTimeUs);
Niels Möller83dbeac2017-12-14 16:39:44 +0100950 // Average usage 19%. Check that estimate is in the right ball park.
951 EXPECT_NEAR(UsagePercent(), 20, 10);
952}
953
954// Models screencast, with irregular arrival of frames, often
955// exceeding the timeout interval.
956TEST_F(OveruseFrameDetectorTest2, NoOveruseForRandomFrameIntervalWithReset) {
Niels Möllerd1f7eb62018-03-28 16:40:58 +0200957 overuse_detector_->SetOptions(options_);
Niels Möller73f29cb2018-01-31 16:09:31 +0100958 EXPECT_CALL(mock_observer_, AdaptDown(_)).Times(0);
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200959 EXPECT_CALL(mock_observer_, AdaptUp(reason_)).Times(::testing::AtLeast(1));
Niels Möller83dbeac2017-12-14 16:39:44 +0100960
961 const int kNumFrames = 500;
962 const int kEncodeTimeUs = 100 * rtc::kNumMicrosecsPerMillisec;
963
964 const int kMinIntervalUs = 30 * rtc::kNumMicrosecsPerMillisec;
965 const int kMaxIntervalUs = 3000 * rtc::kNumMicrosecsPerMillisec;
966
Yves Gerey665174f2018-06-19 15:03:05 +0200967 InsertAndSendFramesWithRandomInterval(kNumFrames, kMinIntervalUs,
968 kMaxIntervalUs, kWidth, kHeight,
969 kEncodeTimeUs);
Niels Möller83dbeac2017-12-14 16:39:44 +0100970
971 // Average usage 6.6%, but since the frame_timeout_interval_ms is
972 // only 1500 ms, we often reset the estimate to the initial value.
973 // Check that estimate is in the right ball park.
974 EXPECT_GE(UsagePercent(), 1);
975 EXPECT_LE(UsagePercent(), InitialUsage() + 5);
976}
977
Niels Möller58d2a5e2018-08-07 16:37:18 +0200978TEST_F(OveruseFrameDetectorTest2, ToleratesOutOfOrderFrames) {
979 overuse_detector_->SetOptions(options_);
980 // Represents a cpu utilization close to 100%. First input frame results in
981 // three encoded frames, and the last of those isn't finished until after the
982 // first encoded frame corresponding to the next input frame.
983 const int kEncodeTimeUs = 30 * rtc::kNumMicrosecsPerMillisec;
984 const int kCaptureTimesMs[] = { 33, 33, 66, 33 };
985
986 for (int capture_time_ms : kCaptureTimesMs) {
987 overuse_detector_->FrameSent(
988 0, 0, capture_time_ms * rtc::kNumMicrosecsPerMillisec, kEncodeTimeUs);
989 }
990 EXPECT_GE(UsagePercent(), InitialUsage());
991}
992
Niels Möllerf5033ad2018-08-14 17:00:46 +0200993// Models simulcast, with multiple encoded frames for each input frame.
994// Load estimate should be based on the maximum encode time per input frame.
995TEST_F(OveruseFrameDetectorTest2, NoOveruseForSimulcast) {
996 overuse_detector_->SetOptions(options_);
997 EXPECT_CALL(mock_observer_, AdaptDown(_)).Times(0);
998
999 constexpr int kNumFrames = 500;
1000 constexpr int kEncodeTimesUs[] = {
1001 10 * rtc::kNumMicrosecsPerMillisec, 8 * rtc::kNumMicrosecsPerMillisec,
1002 12 * rtc::kNumMicrosecsPerMillisec,
1003 };
1004 constexpr int kIntervalUs = 30 * rtc::kNumMicrosecsPerMillisec;
1005
1006 InsertAndSendSimulcastFramesWithInterval(kNumFrames, kIntervalUs, kWidth,
1007 kHeight, kEncodeTimesUs);
1008
1009 // Average usage 40%. 12 ms / 30 ms.
1010 EXPECT_GE(UsagePercent(), 35);
1011 EXPECT_LE(UsagePercent(), 45);
1012}
1013
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +00001014} // namespace webrtc