Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(198)

Side by Side Diff: webrtc/video_engine/overuse_frame_detector_unittest.cc

Issue 1510183002: Reland of Merge webrtc/video_engine/ into webrtc/video/ (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: rebase Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/video_engine/overuse_frame_detector.cc ('k') | webrtc/video_engine/payload_router.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "webrtc/video_engine/overuse_frame_detector.h"
12
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 #include "webrtc/base/scoped_ptr.h"
17 #include "webrtc/system_wrappers/include/clock.h"
18
19 namespace webrtc {
20 namespace {
21 const int kWidth = 640;
22 const int kHeight = 480;
23 const int kFrameInterval33ms = 33;
24 const int kProcessIntervalMs = 5000;
25 const int kProcessTime5ms = 5;
26 } // namespace
27
28 class MockCpuOveruseObserver : public CpuOveruseObserver {
29 public:
30 MockCpuOveruseObserver() {}
31 virtual ~MockCpuOveruseObserver() {}
32
33 MOCK_METHOD0(OveruseDetected, void());
34 MOCK_METHOD0(NormalUsage, void());
35 };
36
37 class CpuOveruseObserverImpl : public CpuOveruseObserver {
38 public:
39 CpuOveruseObserverImpl() :
40 overuse_(0),
41 normaluse_(0) {}
42 virtual ~CpuOveruseObserverImpl() {}
43
44 void OveruseDetected() { ++overuse_; }
45 void NormalUsage() { ++normaluse_; }
46
47 int overuse_;
48 int normaluse_;
49 };
50
51 class OveruseFrameDetectorTest : public ::testing::Test,
52 public CpuOveruseMetricsObserver {
53 protected:
54 virtual void SetUp() {
55 clock_.reset(new SimulatedClock(1234));
56 observer_.reset(new MockCpuOveruseObserver());
57 options_.min_process_count = 0;
58 ReinitializeOveruseDetector();
59 }
60
61 void ReinitializeOveruseDetector() {
62 overuse_detector_.reset(new OveruseFrameDetector(clock_.get(), options_,
63 observer_.get(), this));
64 }
65
66 void CpuOveruseMetricsUpdated(const CpuOveruseMetrics& metrics) override {
67 metrics_ = metrics;
68 }
69
70 int InitialUsage() {
71 return ((options_.low_encode_usage_threshold_percent +
72 options_.high_encode_usage_threshold_percent) / 2.0f) + 0.5;
73 }
74
75 void InsertAndSendFramesWithInterval(
76 int num_frames, int interval_ms, int width, int height, int delay_ms) {
77 while (num_frames-- > 0) {
78 int64_t capture_time_ms = clock_->TimeInMilliseconds();
79 overuse_detector_->FrameCaptured(width, height, capture_time_ms);
80 clock_->AdvanceTimeMilliseconds(delay_ms);
81 overuse_detector_->FrameEncoded(delay_ms);
82 overuse_detector_->FrameSent(capture_time_ms);
83 clock_->AdvanceTimeMilliseconds(interval_ms - delay_ms);
84 }
85 }
86
87 void TriggerOveruse(int num_times) {
88 const int kDelayMs = 32;
89 for (int i = 0; i < num_times; ++i) {
90 InsertAndSendFramesWithInterval(
91 1000, kFrameInterval33ms, kWidth, kHeight, kDelayMs);
92 overuse_detector_->Process();
93 }
94 }
95
96 void TriggerUnderuse() {
97 const int kDelayMs1 = 5;
98 const int kDelayMs2 = 6;
99 InsertAndSendFramesWithInterval(
100 1300, kFrameInterval33ms, kWidth, kHeight, kDelayMs1);
101 InsertAndSendFramesWithInterval(
102 1, kFrameInterval33ms, kWidth, kHeight, kDelayMs2);
103 overuse_detector_->Process();
104 }
105
106 int UsagePercent() { return metrics_.encode_usage_percent; }
107
108 CpuOveruseOptions options_;
109 rtc::scoped_ptr<SimulatedClock> clock_;
110 rtc::scoped_ptr<MockCpuOveruseObserver> observer_;
111 rtc::scoped_ptr<OveruseFrameDetector> overuse_detector_;
112 CpuOveruseMetrics metrics_;
113 };
114
115
116 // enable_encode_usage_method = true;
117 // enable_extended_processing_usage = false;
118 // UsagePercent() > high_encode_usage_threshold_percent => overuse.
119 // UsagePercent() < low_encode_usage_threshold_percent => underuse.
120 TEST_F(OveruseFrameDetectorTest, TriggerOveruse) {
121 options_.enable_extended_processing_usage = false;
122 ReinitializeOveruseDetector();
123 // usage > high => overuse
124 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
125 TriggerOveruse(options_.high_threshold_consecutive_count);
126 }
127
128 TEST_F(OveruseFrameDetectorTest, OveruseAndRecover) {
129 options_.enable_extended_processing_usage = false;
130 ReinitializeOveruseDetector();
131 // usage > high => overuse
132 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
133 TriggerOveruse(options_.high_threshold_consecutive_count);
134 // usage < low => underuse
135 EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(testing::AtLeast(1));
136 TriggerUnderuse();
137 }
138
139 TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithNoObserver) {
140 options_.enable_extended_processing_usage = false;
141 overuse_detector_.reset(
142 new OveruseFrameDetector(clock_.get(), options_, nullptr, this));
143 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0);
144 TriggerOveruse(options_.high_threshold_consecutive_count);
145 EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
146 TriggerUnderuse();
147 }
148
149 TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithMethodDisabled) {
150 options_.enable_encode_usage_method = false;
151 options_.enable_extended_processing_usage = false;
152 ReinitializeOveruseDetector();
153 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0);
154 TriggerOveruse(options_.high_threshold_consecutive_count);
155 EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
156 TriggerUnderuse();
157 }
158
159 TEST_F(OveruseFrameDetectorTest, DoubleOveruseAndRecover) {
160 options_.enable_extended_processing_usage = false;
161 ReinitializeOveruseDetector();
162 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(2);
163 TriggerOveruse(options_.high_threshold_consecutive_count);
164 TriggerOveruse(options_.high_threshold_consecutive_count);
165 EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(testing::AtLeast(1));
166 TriggerUnderuse();
167 }
168
169 TEST_F(OveruseFrameDetectorTest, TriggerUnderuseWithMinProcessCount) {
170 options_.enable_extended_processing_usage = false;
171 options_.min_process_count = 1;
172 CpuOveruseObserverImpl overuse_observer;
173 overuse_detector_.reset(new OveruseFrameDetector(clock_.get(), options_,
174 &overuse_observer, this));
175 InsertAndSendFramesWithInterval(
176 1200, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms);
177 overuse_detector_->Process();
178 EXPECT_EQ(0, overuse_observer.normaluse_);
179 clock_->AdvanceTimeMilliseconds(kProcessIntervalMs);
180 overuse_detector_->Process();
181 EXPECT_EQ(1, overuse_observer.normaluse_);
182 }
183
184 TEST_F(OveruseFrameDetectorTest, ConstantOveruseGivesNoNormalUsage) {
185 options_.enable_extended_processing_usage = false;
186 ReinitializeOveruseDetector();
187 EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
188 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(64);
189 for (size_t i = 0; i < 64; ++i) {
190 TriggerOveruse(options_.high_threshold_consecutive_count);
191 }
192 }
193
194 TEST_F(OveruseFrameDetectorTest, ConsecutiveCountTriggersOveruse) {
195 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
196 options_.enable_extended_processing_usage = false;
197 options_.high_threshold_consecutive_count = 2;
198 ReinitializeOveruseDetector();
199 TriggerOveruse(2);
200 }
201
202 TEST_F(OveruseFrameDetectorTest, IncorrectConsecutiveCountTriggersNoOveruse) {
203 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0);
204 options_.enable_extended_processing_usage = false;
205 options_.high_threshold_consecutive_count = 2;
206 ReinitializeOveruseDetector();
207 TriggerOveruse(1);
208 }
209
210 TEST_F(OveruseFrameDetectorTest, ProcessingUsage) {
211 InsertAndSendFramesWithInterval(
212 1000, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms);
213 EXPECT_EQ(kProcessTime5ms * 100 / kFrameInterval33ms, UsagePercent());
214 }
215
216 TEST_F(OveruseFrameDetectorTest, ResetAfterResolutionChange) {
217 EXPECT_EQ(InitialUsage(), UsagePercent());
218 InsertAndSendFramesWithInterval(
219 1000, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms);
220 EXPECT_NE(InitialUsage(), UsagePercent());
221 // Verify reset.
222 InsertAndSendFramesWithInterval(
223 1, kFrameInterval33ms, kWidth, kHeight + 1, kProcessTime5ms);
224 EXPECT_EQ(InitialUsage(), UsagePercent());
225 }
226
227 TEST_F(OveruseFrameDetectorTest, ResetAfterFrameTimeout) {
228 EXPECT_EQ(InitialUsage(), UsagePercent());
229 InsertAndSendFramesWithInterval(
230 1000, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms);
231 EXPECT_NE(InitialUsage(), UsagePercent());
232 InsertAndSendFramesWithInterval(
233 2, options_.frame_timeout_interval_ms, kWidth, kHeight, kProcessTime5ms);
234 EXPECT_NE(InitialUsage(), UsagePercent());
235 // Verify reset.
236 InsertAndSendFramesWithInterval(
237 2, options_.frame_timeout_interval_ms + 1, kWidth, kHeight,
238 kProcessTime5ms);
239 EXPECT_EQ(InitialUsage(), UsagePercent());
240 }
241
242 TEST_F(OveruseFrameDetectorTest, MinFrameSamplesBeforeUpdating) {
243 options_.min_frame_samples = 40;
244 ReinitializeOveruseDetector();
245 InsertAndSendFramesWithInterval(
246 40, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms);
247 EXPECT_EQ(InitialUsage(), UsagePercent());
248 InsertAndSendFramesWithInterval(
249 1, kFrameInterval33ms, kWidth, kHeight, kProcessTime5ms);
250 EXPECT_NE(InitialUsage(), UsagePercent());
251 }
252
253 TEST_F(OveruseFrameDetectorTest, InitialProcessingUsage) {
254 EXPECT_EQ(InitialUsage(), UsagePercent());
255 }
256
257 TEST_F(OveruseFrameDetectorTest, FrameDelay_OneFrameDisabled) {
258 options_.enable_extended_processing_usage = false;
259 ReinitializeOveruseDetector();
260 const int kProcessingTimeMs = 100;
261 overuse_detector_->FrameCaptured(kWidth, kHeight, 33);
262 clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
263 overuse_detector_->FrameSent(33);
264 EXPECT_EQ(-1, overuse_detector_->LastProcessingTimeMs());
265 }
266
267 TEST_F(OveruseFrameDetectorTest, FrameDelay_OneFrame) {
268 options_.enable_extended_processing_usage = true;
269 ReinitializeOveruseDetector();
270 const int kProcessingTimeMs = 100;
271 overuse_detector_->FrameCaptured(kWidth, kHeight, 33);
272 clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
273 EXPECT_EQ(-1, overuse_detector_->LastProcessingTimeMs());
274 overuse_detector_->FrameSent(33);
275 EXPECT_EQ(kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs());
276 EXPECT_EQ(0, overuse_detector_->FramesInQueue());
277 }
278
279 TEST_F(OveruseFrameDetectorTest, FrameDelay_TwoFrames) {
280 options_.enable_extended_processing_usage = true;
281 ReinitializeOveruseDetector();
282 const int kProcessingTimeMs1 = 100;
283 const int kProcessingTimeMs2 = 50;
284 const int kTimeBetweenFramesMs = 200;
285 overuse_detector_->FrameCaptured(kWidth, kHeight, 33);
286 clock_->AdvanceTimeMilliseconds(kProcessingTimeMs1);
287 overuse_detector_->FrameSent(33);
288 EXPECT_EQ(kProcessingTimeMs1, overuse_detector_->LastProcessingTimeMs());
289 clock_->AdvanceTimeMilliseconds(kTimeBetweenFramesMs);
290 overuse_detector_->FrameCaptured(kWidth, kHeight, 66);
291 clock_->AdvanceTimeMilliseconds(kProcessingTimeMs2);
292 overuse_detector_->FrameSent(66);
293 EXPECT_EQ(kProcessingTimeMs2, overuse_detector_->LastProcessingTimeMs());
294 }
295
296 TEST_F(OveruseFrameDetectorTest, FrameDelay_MaxQueueSize) {
297 options_.enable_extended_processing_usage = true;
298 ReinitializeOveruseDetector();
299 const int kMaxQueueSize = 91;
300 for (int i = 0; i < kMaxQueueSize * 2; ++i) {
301 overuse_detector_->FrameCaptured(kWidth, kHeight, i);
302 }
303 EXPECT_EQ(kMaxQueueSize, overuse_detector_->FramesInQueue());
304 }
305
306 TEST_F(OveruseFrameDetectorTest, FrameDelay_NonProcessedFramesRemoved) {
307 options_.enable_extended_processing_usage = true;
308 ReinitializeOveruseDetector();
309 const int kProcessingTimeMs = 100;
310 overuse_detector_->FrameCaptured(kWidth, kHeight, 33);
311 clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
312 overuse_detector_->FrameCaptured(kWidth, kHeight, 35);
313 clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
314 overuse_detector_->FrameCaptured(kWidth, kHeight, 66);
315 clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
316 overuse_detector_->FrameCaptured(kWidth, kHeight, 99);
317 clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
318 EXPECT_EQ(-1, overuse_detector_->LastProcessingTimeMs());
319 EXPECT_EQ(4, overuse_detector_->FramesInQueue());
320 overuse_detector_->FrameSent(66);
321 // Frame 33, 35 removed, 66 processed, 99 not processed.
322 EXPECT_EQ(2 * kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs());
323 EXPECT_EQ(1, overuse_detector_->FramesInQueue());
324 overuse_detector_->FrameSent(99);
325 EXPECT_EQ(kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs());
326 EXPECT_EQ(0, overuse_detector_->FramesInQueue());
327 }
328
329 TEST_F(OveruseFrameDetectorTest, FrameDelay_ResetClearsFrames) {
330 options_.enable_extended_processing_usage = true;
331 ReinitializeOveruseDetector();
332 const int kProcessingTimeMs = 100;
333 overuse_detector_->FrameCaptured(kWidth, kHeight, 33);
334 EXPECT_EQ(1, overuse_detector_->FramesInQueue());
335 clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
336 // Verify reset (resolution changed).
337 overuse_detector_->FrameCaptured(kWidth, kHeight + 1, 66);
338 EXPECT_EQ(1, overuse_detector_->FramesInQueue());
339 clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
340 overuse_detector_->FrameSent(66);
341 EXPECT_EQ(kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs());
342 EXPECT_EQ(0, overuse_detector_->FramesInQueue());
343 }
344
345 TEST_F(OveruseFrameDetectorTest, FrameDelay_NonMatchingSendFrameIgnored) {
346 options_.enable_extended_processing_usage = true;
347 ReinitializeOveruseDetector();
348 const int kProcessingTimeMs = 100;
349 overuse_detector_->FrameCaptured(kWidth, kHeight, 33);
350 clock_->AdvanceTimeMilliseconds(kProcessingTimeMs);
351 overuse_detector_->FrameSent(34);
352 EXPECT_EQ(-1, overuse_detector_->LastProcessingTimeMs());
353 overuse_detector_->FrameSent(33);
354 EXPECT_EQ(kProcessingTimeMs, overuse_detector_->LastProcessingTimeMs());
355 }
356
357 // enable_encode_usage_method = true;
358 // enable_extended_processing_usage = true;
359 // UsagePercent() > high_encode_usage_threshold_percent => overuse.
360 // UsagePercent() < low_encode_usage_threshold_percent => underuse.
361 TEST_F(OveruseFrameDetectorTest, TriggerOveruseWithExtendedProcessingUsage) {
362 options_.enable_extended_processing_usage = true;
363 ReinitializeOveruseDetector();
364 // usage > high => overuse
365 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
366 TriggerOveruse(options_.high_threshold_consecutive_count);
367 }
368
369 TEST_F(OveruseFrameDetectorTest, OveruseAndRecoverWithExtendedProcessingUsage) {
370 options_.enable_extended_processing_usage = true;
371 ReinitializeOveruseDetector();
372 // usage > high => overuse
373 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(1);
374 TriggerOveruse(options_.high_threshold_consecutive_count);
375 // usage < low => underuse
376 EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(testing::AtLeast(1));
377 TriggerUnderuse();
378 }
379
380 TEST_F(OveruseFrameDetectorTest,
381 OveruseAndRecoverWithExtendedProcessingUsageMethodDisabled) {
382 options_.enable_encode_usage_method = false;
383 options_.enable_extended_processing_usage = true;
384 ReinitializeOveruseDetector();
385 // usage > high => overuse
386 EXPECT_CALL(*(observer_.get()), OveruseDetected()).Times(0);
387 TriggerOveruse(options_.high_threshold_consecutive_count);
388 // usage < low => underuse
389 EXPECT_CALL(*(observer_.get()), NormalUsage()).Times(0);
390 TriggerUnderuse();
391 }
392
393 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/video_engine/overuse_frame_detector.cc ('k') | webrtc/video_engine/payload_router.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698