blob: 044b11f1fbd22cf30b0a068d34e0b549599276f2 [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
nisseaf916892017-01-10 07:44:26 -080013#include "webrtc/api/video/i420_buffer.h"
perkjd52063f2016-09-07 06:32:18 -070014#include "webrtc/base/event.h"
nissee0e3bdf2017-01-18 02:16:20 -080015#include "webrtc/base/fakeclock.h"
kwibergac9f8762016-09-30 22:29:43 -070016#include "webrtc/test/gmock.h"
17#include "webrtc/test/gtest.h"
18#include "webrtc/video/overuse_frame_detector.h"
Peter Boströme4499152016-02-05 11:13:28 +010019#include "webrtc/video_frame.h"
kthelgason876222f2016-11-29 01:44:11 -080020#include "webrtc/modules/video_coding/utility/quality_scaler.h"
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000021
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000022namespace webrtc {
perkjd52063f2016-09-07 06:32:18 -070023
kthelgason876222f2016-11-29 01:44:11 -080024using ::testing::InvokeWithoutArgs;
perkjd52063f2016-09-07 06:32:18 -070025
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +000026namespace {
27 const int kWidth = 640;
28 const int kHeight = 480;
nissee0e3bdf2017-01-18 02:16:20 -080029 const int kFrameIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
30 const int kProcessTimeUs = 5 * rtc::kNumMicrosecsPerMillisec;
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +000031} // namespace
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000032
sprangb1ca0732017-02-01 08:38:12 -080033class MockCpuOveruseObserver : public AdaptationObserverInterface {
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000034 public:
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +000035 MockCpuOveruseObserver() {}
36 virtual ~MockCpuOveruseObserver() {}
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000037
sprangb1ca0732017-02-01 08:38:12 -080038 MOCK_METHOD1(AdaptUp, void(AdaptReason));
39 MOCK_METHOD1(AdaptDown, void(AdaptReason));
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000040};
41
sprangb1ca0732017-02-01 08:38:12 -080042class CpuOveruseObserverImpl : public AdaptationObserverInterface {
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +000043 public:
44 CpuOveruseObserverImpl() :
45 overuse_(0),
46 normaluse_(0) {}
47 virtual ~CpuOveruseObserverImpl() {}
48
sprangb1ca0732017-02-01 08:38:12 -080049 void AdaptDown(AdaptReason) { ++overuse_; }
50 void AdaptUp(AdaptReason) { ++normaluse_; }
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +000051
52 int overuse_;
53 int normaluse_;
54};
55
perkjd52063f2016-09-07 06:32:18 -070056class OveruseFrameDetectorUnderTest : public OveruseFrameDetector {
57 public:
nissee0e3bdf2017-01-18 02:16:20 -080058 OveruseFrameDetectorUnderTest(const CpuOveruseOptions& options,
sprangb1ca0732017-02-01 08:38:12 -080059 AdaptationObserverInterface* overuse_observer,
perkjd52063f2016-09-07 06:32:18 -070060 EncodedFrameObserver* encoder_timing,
61 CpuOveruseMetricsObserver* metrics_observer)
nissee0e3bdf2017-01-18 02:16:20 -080062 : OveruseFrameDetector(options,
perkjd52063f2016-09-07 06:32:18 -070063 overuse_observer,
64 encoder_timing,
65 metrics_observer) {}
66 ~OveruseFrameDetectorUnderTest() {}
67
68 using OveruseFrameDetector::CheckForOveruse;
69};
70
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +000071class OveruseFrameDetectorTest : public ::testing::Test,
72 public CpuOveruseMetricsObserver {
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000073 protected:
nisseef8b61e2016-04-29 06:09:15 -070074 void SetUp() override {
mflodman@webrtc.org6879c8a2013-07-23 11:35:00 +000075 observer_.reset(new MockCpuOveruseObserver());
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +000076 options_.min_process_count = 0;
Peter Boström4b91bd02015-06-26 06:58:16 +020077 ReinitializeOveruseDetector();
78 }
79
80 void ReinitializeOveruseDetector() {
perkjd52063f2016-09-07 06:32:18 -070081 overuse_detector_.reset(new OveruseFrameDetectorUnderTest(
nissee0e3bdf2017-01-18 02:16:20 -080082 options_, observer_.get(), nullptr, this));
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +000083 }
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +000084
Peter Boströme4499152016-02-05 11:13:28 +010085 void OnEncodedFrameTimeMeasured(int encode_time_ms,
86 const CpuOveruseMetrics& metrics) override {
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +000087 metrics_ = metrics;
88 }
89
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +000090 int InitialUsage() {
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +000091 return ((options_.low_encode_usage_threshold_percent +
92 options_.high_encode_usage_threshold_percent) / 2.0f) + 0.5;
93 }
94
Peter Boströme4499152016-02-05 11:13:28 +010095 void InsertAndSendFramesWithInterval(int num_frames,
nissee0e3bdf2017-01-18 02:16:20 -080096 int interval_us,
Peter Boströme4499152016-02-05 11:13:28 +010097 int width,
98 int height,
nissee0e3bdf2017-01-18 02:16:20 -080099 int delay_us) {
nissef122a852016-10-04 23:27:30 -0700100 VideoFrame frame(I420Buffer::Create(width, height),
101 webrtc::kVideoRotation_0, 0);
Peter Boströme4499152016-02-05 11:13:28 +0100102 uint32_t timestamp = 0;
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000103 while (num_frames-- > 0) {
Peter Boströme4499152016-02-05 11:13:28 +0100104 frame.set_timestamp(timestamp);
nissee0e3bdf2017-01-18 02:16:20 -0800105 overuse_detector_->FrameCaptured(frame, rtc::TimeMicros());
106 clock_.AdvanceTimeMicros(delay_us);
107 overuse_detector_->FrameSent(timestamp, rtc::TimeMicros());
108 clock_.AdvanceTimeMicros(interval_us - delay_us);
109 timestamp += interval_us * 90 / 1000;
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000110 }
111 }
112
Peter Boströme4499152016-02-05 11:13:28 +0100113 void ForceUpdate(int width, int height) {
114 // Insert one frame, wait a second and then put in another to force update
115 // the usage. From the tests where these are used, adding another sample
116 // doesn't affect the expected outcome (this is mainly to check initial
117 // values and whether the overuse detector has been reset or not).
nissee0e3bdf2017-01-18 02:16:20 -0800118 InsertAndSendFramesWithInterval(2, rtc::kNumMicrosecsPerSec,
119 width, height, kFrameIntervalUs);
Peter Boströme4499152016-02-05 11:13:28 +0100120 }
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000121 void TriggerOveruse(int num_times) {
nissee0e3bdf2017-01-18 02:16:20 -0800122 const int kDelayUs = 32 * rtc::kNumMicrosecsPerMillisec;
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000123 for (int i = 0; i < num_times; ++i) {
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +0000124 InsertAndSendFramesWithInterval(
nissee0e3bdf2017-01-18 02:16:20 -0800125 1000, kFrameIntervalUs, kWidth, kHeight, kDelayUs);
perkjd52063f2016-09-07 06:32:18 -0700126 overuse_detector_->CheckForOveruse();
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000127 }
128 }
129
Åsa Persson746210f2015-09-08 10:52:42 +0200130 void TriggerUnderuse() {
nissee0e3bdf2017-01-18 02:16:20 -0800131 const int kDelayUs1 = 5000;
132 const int kDelayUs2 = 6000;
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +0000133 InsertAndSendFramesWithInterval(
nissee0e3bdf2017-01-18 02:16:20 -0800134 1300, kFrameIntervalUs, kWidth, kHeight, kDelayUs1);
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +0000135 InsertAndSendFramesWithInterval(
nissee0e3bdf2017-01-18 02:16:20 -0800136 1, kFrameIntervalUs, kWidth, kHeight, kDelayUs2);
perkjd52063f2016-09-07 06:32:18 -0700137 overuse_detector_->CheckForOveruse();
asapersson@webrtc.orgce12f1f2014-03-24 21:59:16 +0000138 }
139
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +0000140 int UsagePercent() { return metrics_.encode_usage_percent; }
asapersson@webrtc.orgab6bf4f2014-05-27 07:43:15 +0000141
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000142 CpuOveruseOptions options_;
nissee0e3bdf2017-01-18 02:16:20 -0800143 rtc::ScopedFakeClock clock_;
kwiberg27f982b2016-03-01 11:52:33 -0800144 std::unique_ptr<MockCpuOveruseObserver> observer_;
perkjd52063f2016-09-07 06:32:18 -0700145 std::unique_ptr<OveruseFrameDetectorUnderTest> overuse_detector_;
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +0000146 CpuOveruseMetrics metrics_;
kthelgason876222f2016-11-29 01:44:11 -0800147
sprangb1ca0732017-02-01 08:38:12 -0800148 static const auto reason_ = AdaptationObserverInterface::AdaptReason::kCpu;
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000149};
150
Åsa Persson746210f2015-09-08 10:52:42 +0200151
Åsa Persson746210f2015-09-08 10:52:42 +0200152// UsagePercent() > high_encode_usage_threshold_percent => overuse.
153// UsagePercent() < low_encode_usage_threshold_percent => underuse.
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000154TEST_F(OveruseFrameDetectorTest, TriggerOveruse) {
Åsa Persson746210f2015-09-08 10:52:42 +0200155 // usage > high => overuse
sprangb1ca0732017-02-01 08:38:12 -0800156 EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000157 TriggerOveruse(options_.high_threshold_consecutive_count);
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +0000158}
159
160TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) {
Åsa Persson746210f2015-09-08 10:52:42 +0200161 // usage > high => overuse
sprangb1ca0732017-02-01 08:38:12 -0800162 EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000163 TriggerOveruse(options_.high_threshold_consecutive_count);
Åsa Persson746210f2015-09-08 10:52:42 +0200164 // usage < low => underuse
sprangb1ca0732017-02-01 08:38:12 -0800165 EXPECT_CALL(*(observer_.get()), AdaptUp(reason_)).Times(testing::AtLeast(1));
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +0000166 TriggerUnderuse();
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000167}
168
asapersson@webrtc.org2881ab12014-06-12 08:46:46 +0000169TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithNoObserver) {
perkjd52063f2016-09-07 06:32:18 -0700170 overuse_detector_.reset(new OveruseFrameDetectorUnderTest(
nissee0e3bdf2017-01-18 02:16:20 -0800171 options_, nullptr, nullptr, this));
sprangb1ca0732017-02-01 08:38:12 -0800172 EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(0);
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000173 TriggerOveruse(options_.high_threshold_consecutive_count);
sprangb1ca0732017-02-01 08:38:12 -0800174 EXPECT_CALL(*(observer_.get()), AdaptUp(reason_)).Times(0);
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +0000175 TriggerUnderuse();
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000176}
177
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +0000178TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) {
sprangb1ca0732017-02-01 08:38:12 -0800179 EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(2);
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000180 TriggerOveruse(options_.high_threshold_consecutive_count);
181 TriggerOveruse(options_.high_threshold_consecutive_count);
sprangb1ca0732017-02-01 08:38:12 -0800182 EXPECT_CALL(*(observer_.get()), AdaptUp(reason_)).Times(testing::AtLeast(1));
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +0000183 TriggerUnderuse();
pbos@webrtc.orga9575702013-08-30 17:16:32 +0000184}
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +0000185
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +0000186TEST_F(OveruseFrameDetectorTest, TriggerUnderuseWithMinProcessCount) {
nissee0e3bdf2017-01-18 02:16:20 -0800187 const int kProcessIntervalUs = 5 * rtc::kNumMicrosecsPerSec;
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000188 options_.min_process_count = 1;
Peter Boström4b91bd02015-06-26 06:58:16 +0200189 CpuOveruseObserverImpl overuse_observer;
perkjd52063f2016-09-07 06:32:18 -0700190 overuse_detector_.reset(new OveruseFrameDetectorUnderTest(
nissee0e3bdf2017-01-18 02:16:20 -0800191 options_, &overuse_observer, nullptr, this));
Åsa Persson746210f2015-09-08 10:52:42 +0200192 InsertAndSendFramesWithInterval(
nissee0e3bdf2017-01-18 02:16:20 -0800193 1200, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
perkjd52063f2016-09-07 06:32:18 -0700194 overuse_detector_->CheckForOveruse();
Peter Boström4b91bd02015-06-26 06:58:16 +0200195 EXPECT_EQ(0, overuse_observer.normaluse_);
nissee0e3bdf2017-01-18 02:16:20 -0800196 clock_.AdvanceTimeMicros(kProcessIntervalUs);
perkjd52063f2016-09-07 06:32:18 -0700197 overuse_detector_->CheckForOveruse();
Peter Boström4b91bd02015-06-26 06:58:16 +0200198 EXPECT_EQ(1, overuse_observer.normaluse_);
asapersson@webrtc.orgb60346e2014-02-17 19:02:15 +0000199}
200
pbos@webrtc.orga9575702013-08-30 17:16:32 +0000201TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) {
sprangb1ca0732017-02-01 08:38:12 -0800202 EXPECT_CALL(*(observer_.get()), AdaptUp(reason_)).Times(0);
203 EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(64);
kjellander@webrtc.org0fcaf992015-11-26 15:24:52 +0100204 for (size_t i = 0; i < 64; ++i) {
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000205 TriggerOveruse(options_.high_threshold_consecutive_count);
206 }
mflodman@webrtc.orgd4412fe2013-07-31 16:42:21 +0000207}
208
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000209TEST_F(OveruseFrameDetectorTest, ConsecutiveCountTriggersOveruse) {
sprangb1ca0732017-02-01 08:38:12 -0800210 EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(1);
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000211 options_.high_threshold_consecutive_count = 2;
Peter Boström4b91bd02015-06-26 06:58:16 +0200212 ReinitializeOveruseDetector();
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000213 TriggerOveruse(2);
214}
215
216TEST_F(OveruseFrameDetectorTest, IncorrectConsecutiveCountTriggersNoOveruse) {
sprangb1ca0732017-02-01 08:38:12 -0800217 EXPECT_CALL(*(observer_.get()), AdaptDown(reason_)).Times(0);
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000218 options_.high_threshold_consecutive_count = 2;
Peter Boström4b91bd02015-06-26 06:58:16 +0200219 ReinitializeOveruseDetector();
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000220 TriggerOveruse(1);
221}
222
Åsa Persson746210f2015-09-08 10:52:42 +0200223TEST_F(OveruseFrameDetectorTest, ProcessingUsage) {
224 InsertAndSendFramesWithInterval(
nissee0e3bdf2017-01-18 02:16:20 -0800225 1000, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
226 EXPECT_EQ(kProcessTimeUs * 100 / kFrameIntervalUs, UsagePercent());
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000227}
228
Åsa Persson746210f2015-09-08 10:52:42 +0200229TEST_F(OveruseFrameDetectorTest, ResetAfterResolutionChange) {
Peter Boströme4499152016-02-05 11:13:28 +0100230 ForceUpdate(kWidth, kHeight);
Åsa Persson746210f2015-09-08 10:52:42 +0200231 EXPECT_EQ(InitialUsage(), UsagePercent());
232 InsertAndSendFramesWithInterval(
nissee0e3bdf2017-01-18 02:16:20 -0800233 1000, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
Åsa Persson746210f2015-09-08 10:52:42 +0200234 EXPECT_NE(InitialUsage(), UsagePercent());
Peter Boströme4499152016-02-05 11:13:28 +0100235 // Verify reset (with new width/height).
236 ForceUpdate(kWidth, kHeight + 1);
Åsa Persson746210f2015-09-08 10:52:42 +0200237 EXPECT_EQ(InitialUsage(), UsagePercent());
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000238}
239
Åsa Persson746210f2015-09-08 10:52:42 +0200240TEST_F(OveruseFrameDetectorTest, ResetAfterFrameTimeout) {
Peter Boströme4499152016-02-05 11:13:28 +0100241 ForceUpdate(kWidth, kHeight);
Åsa Persson746210f2015-09-08 10:52:42 +0200242 EXPECT_EQ(InitialUsage(), UsagePercent());
243 InsertAndSendFramesWithInterval(
nissee0e3bdf2017-01-18 02:16:20 -0800244 1000, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
Åsa Persson746210f2015-09-08 10:52:42 +0200245 EXPECT_NE(InitialUsage(), UsagePercent());
246 InsertAndSendFramesWithInterval(
nissee0e3bdf2017-01-18 02:16:20 -0800247 2, options_.frame_timeout_interval_ms *
248 rtc::kNumMicrosecsPerMillisec, kWidth, kHeight, kProcessTimeUs);
Åsa Persson746210f2015-09-08 10:52:42 +0200249 EXPECT_NE(InitialUsage(), UsagePercent());
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000250 // Verify reset.
Åsa Persson746210f2015-09-08 10:52:42 +0200251 InsertAndSendFramesWithInterval(
nissee0e3bdf2017-01-18 02:16:20 -0800252 2, (options_.frame_timeout_interval_ms + 1) *
253 rtc::kNumMicrosecsPerMillisec, kWidth, kHeight, kProcessTimeUs);
Peter Boströme4499152016-02-05 11:13:28 +0100254 ForceUpdate(kWidth, kHeight);
Åsa Persson746210f2015-09-08 10:52:42 +0200255 EXPECT_EQ(InitialUsage(), UsagePercent());
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000256}
257
Åsa Persson746210f2015-09-08 10:52:42 +0200258TEST_F(OveruseFrameDetectorTest, MinFrameSamplesBeforeUpdating) {
asapersson@webrtc.org8a8c3ef2014-03-20 13:15:01 +0000259 options_.min_frame_samples = 40;
Peter Boström4b91bd02015-06-26 06:58:16 +0200260 ReinitializeOveruseDetector();
Åsa Persson746210f2015-09-08 10:52:42 +0200261 InsertAndSendFramesWithInterval(
nissee0e3bdf2017-01-18 02:16:20 -0800262 40, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
Åsa Persson746210f2015-09-08 10:52:42 +0200263 EXPECT_EQ(InitialUsage(), UsagePercent());
Peter Boströme4499152016-02-05 11:13:28 +0100264 // Pass time far enough to digest all previous samples.
nissee0e3bdf2017-01-18 02:16:20 -0800265 clock_.AdvanceTimeMicros(rtc::kNumMicrosecsPerSec);
266 InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight,
267 kProcessTimeUs);
Peter Boströme4499152016-02-05 11:13:28 +0100268 // The last sample has not been processed here.
269 EXPECT_EQ(InitialUsage(), UsagePercent());
270
271 // Pass time far enough to digest all previous samples, 41 in total.
nissee0e3bdf2017-01-18 02:16:20 -0800272 clock_.AdvanceTimeMicros(rtc::kNumMicrosecsPerSec);
Åsa Persson746210f2015-09-08 10:52:42 +0200273 InsertAndSendFramesWithInterval(
nissee0e3bdf2017-01-18 02:16:20 -0800274 1, kFrameIntervalUs, kWidth, kHeight, kProcessTimeUs);
Åsa Persson746210f2015-09-08 10:52:42 +0200275 EXPECT_NE(InitialUsage(), UsagePercent());
276}
277
278TEST_F(OveruseFrameDetectorTest, InitialProcessingUsage) {
Peter Boströme4499152016-02-05 11:13:28 +0100279 ForceUpdate(kWidth, kHeight);
Åsa Persson746210f2015-09-08 10:52:42 +0200280 EXPECT_EQ(InitialUsage(), UsagePercent());
asapersson@webrtc.orgb24d3352013-11-20 13:51:40 +0000281}
282
Peter Boströme4499152016-02-05 11:13:28 +0100283TEST_F(OveruseFrameDetectorTest, MeasuresMultipleConcurrentSamples) {
sprangb1ca0732017-02-01 08:38:12 -0800284 EXPECT_CALL(*(observer_.get()), AdaptDown(reason_))
kthelgason876222f2016-11-29 01:44:11 -0800285 .Times(testing::AtLeast(1));
nissee0e3bdf2017-01-18 02:16:20 -0800286 static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
Peter Boströme4499152016-02-05 11:13:28 +0100287 static const size_t kNumFramesEncodingDelay = 3;
nissef122a852016-10-04 23:27:30 -0700288 VideoFrame frame(I420Buffer::Create(kWidth, kHeight),
289 webrtc::kVideoRotation_0, 0);
Peter Boströme4499152016-02-05 11:13:28 +0100290 for (size_t i = 0; i < 1000; ++i) {
291 // Unique timestamps.
292 frame.set_timestamp(static_cast<uint32_t>(i));
nissee0e3bdf2017-01-18 02:16:20 -0800293 overuse_detector_->FrameCaptured(frame, rtc::TimeMicros());
294 clock_.AdvanceTimeMicros(kIntervalUs);
Peter Boströme4499152016-02-05 11:13:28 +0100295 if (i > kNumFramesEncodingDelay) {
296 overuse_detector_->FrameSent(
perkjd52063f2016-09-07 06:32:18 -0700297 static_cast<uint32_t>(i - kNumFramesEncodingDelay),
nissee0e3bdf2017-01-18 02:16:20 -0800298 rtc::TimeMicros());
Peter Boströme4499152016-02-05 11:13:28 +0100299 }
perkjd52063f2016-09-07 06:32:18 -0700300 overuse_detector_->CheckForOveruse();
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +0000301 }
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +0000302}
303
Peter Boströme4499152016-02-05 11:13:28 +0100304TEST_F(OveruseFrameDetectorTest, UpdatesExistingSamples) {
305 // >85% encoding time should trigger overuse.
sprangb1ca0732017-02-01 08:38:12 -0800306 EXPECT_CALL(*(observer_.get()), AdaptDown(reason_))
kthelgason876222f2016-11-29 01:44:11 -0800307 .Times(testing::AtLeast(1));
nissee0e3bdf2017-01-18 02:16:20 -0800308 static const int kIntervalUs = 33 * rtc::kNumMicrosecsPerMillisec;
309 static const int kDelayUs = 30 * rtc::kNumMicrosecsPerMillisec;
nissef122a852016-10-04 23:27:30 -0700310 VideoFrame frame(I420Buffer::Create(kWidth, kHeight),
311 webrtc::kVideoRotation_0, 0);
Peter Boströme4499152016-02-05 11:13:28 +0100312 uint32_t timestamp = 0;
313 for (size_t i = 0; i < 1000; ++i) {
314 frame.set_timestamp(timestamp);
nissee0e3bdf2017-01-18 02:16:20 -0800315 overuse_detector_->FrameCaptured(frame, rtc::TimeMicros());
Peter Boströme4499152016-02-05 11:13:28 +0100316 // Encode and send first parts almost instantly.
nissee0e3bdf2017-01-18 02:16:20 -0800317 clock_.AdvanceTimeMicros(rtc::kNumMicrosecsPerMillisec);
318 overuse_detector_->FrameSent(timestamp, rtc::TimeMicros());
Peter Boströme4499152016-02-05 11:13:28 +0100319 // Encode heavier part, resulting in >85% usage total.
nissee0e3bdf2017-01-18 02:16:20 -0800320 clock_.AdvanceTimeMicros(kDelayUs - rtc::kNumMicrosecsPerMillisec);
321 overuse_detector_->FrameSent(timestamp, rtc::TimeMicros());
322 clock_.AdvanceTimeMicros(kIntervalUs - kDelayUs);
323 timestamp += kIntervalUs * 90 / 1000;
perkjd52063f2016-09-07 06:32:18 -0700324 overuse_detector_->CheckForOveruse();
Peter Boströme4499152016-02-05 11:13:28 +0100325 }
asapersson@webrtc.org9aed0022014-10-16 06:57:12 +0000326}
327
perkjd52063f2016-09-07 06:32:18 -0700328TEST_F(OveruseFrameDetectorTest, RunOnTqNormalUsage) {
329 rtc::TaskQueue queue("OveruseFrameDetectorTestQueue");
330
331 rtc::Event event(false, false);
332 queue.PostTask([this, &event] {
333 overuse_detector_->StartCheckForOveruse();
334 event.Set();
335 });
336 event.Wait(rtc::Event::kForever);
337
338 // Expect NormalUsage(). When called, stop the |overuse_detector_| and then
339 // set |event| to end the test.
sprangb1ca0732017-02-01 08:38:12 -0800340 EXPECT_CALL(*(observer_.get()), AdaptUp(reason_))
kthelgason876222f2016-11-29 01:44:11 -0800341 .WillOnce(InvokeWithoutArgs([this, &event] {
perkjd52063f2016-09-07 06:32:18 -0700342 overuse_detector_->StopCheckForOveruse();
343 event.Set();
344 }));
345
346 queue.PostTask([this, &event] {
nissee0e3bdf2017-01-18 02:16:20 -0800347 const int kDelayUs1 = 5 * rtc::kNumMicrosecsPerMillisec;
348 const int kDelayUs2 = 6 * rtc::kNumMicrosecsPerMillisec;
349 InsertAndSendFramesWithInterval(1300, kFrameIntervalUs, kWidth, kHeight,
350 kDelayUs1);
351 InsertAndSendFramesWithInterval(1, kFrameIntervalUs, kWidth, kHeight,
352 kDelayUs2);
perkjd52063f2016-09-07 06:32:18 -0700353 });
354
355 EXPECT_TRUE(event.Wait(10000));
356}
357
mflodman@webrtc.orge6168f52013-06-26 11:23:01 +0000358} // namespace webrtc