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

Side by Side Diff: webrtc/modules/video_coding/qm_select_unittest.cc

Issue 1917323002: Remove remaining quality-analysis (QM). (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: rebase Created 4 years, 7 months 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
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 #include "webrtc/modules/include/module_common_types.h"
14 #include "webrtc/modules/video_coding/qm_select.h"
15
16 namespace webrtc {
17
18 // Representative values of content metrics for: low/high/medium(default) state,
19 // based on parameters settings in qm_select_data.h.
20 const float kSpatialLow = 0.01f;
21 const float kSpatialMedium = 0.03f;
22 const float kSpatialHigh = 0.1f;
23 const float kTemporalLow = 0.01f;
24 const float kTemporalMedium = 0.06f;
25 const float kTemporalHigh = 0.1f;
26
27 class QmSelectTest : public ::testing::Test {
28 protected:
29 QmSelectTest()
30 : qm_resolution_(new VCMQmResolution()),
31 content_metrics_(new VideoContentMetrics()),
32 qm_scale_(NULL) {}
33 VCMQmResolution* qm_resolution_;
34 VideoContentMetrics* content_metrics_;
35 VCMResolutionScale* qm_scale_;
36
37 void InitQmNativeData(float initial_bit_rate,
38 int user_frame_rate,
39 int native_width,
40 int native_height,
41 int num_layers);
42
43 void UpdateQmEncodedFrame(size_t* encoded_size, size_t num_updates);
44
45 void UpdateQmRateData(int* target_rate,
46 int* encoder_sent_rate,
47 int* incoming_frame_rate,
48 uint8_t* fraction_lost,
49 int num_updates);
50
51 void UpdateQmContentData(float motion_metric,
52 float spatial_metric,
53 float spatial_metric_horiz,
54 float spatial_metric_vert);
55
56 bool IsSelectedActionCorrect(VCMResolutionScale* qm_scale,
57 float fac_width,
58 float fac_height,
59 float fac_temp,
60 uint16_t new_width,
61 uint16_t new_height,
62 float new_frame_rate);
63
64 void TearDown() {
65 delete qm_resolution_;
66 delete content_metrics_;
67 }
68 };
69
70 TEST_F(QmSelectTest, HandleInputs) {
71 // Expect parameter error. Initialize with invalid inputs.
72 EXPECT_EQ(-4, qm_resolution_->Initialize(1000, 0, 640, 480, 1));
73 EXPECT_EQ(-4, qm_resolution_->Initialize(1000, 30, 640, 0, 1));
74 EXPECT_EQ(-4, qm_resolution_->Initialize(1000, 30, 0, 480, 1));
75
76 // Expect uninitialized error.: No valid initialization before selection.
77 EXPECT_EQ(-7, qm_resolution_->SelectResolution(&qm_scale_));
78
79 VideoContentMetrics* content_metrics = NULL;
80 EXPECT_EQ(0, qm_resolution_->Initialize(1000, 30, 640, 480, 1));
81 qm_resolution_->UpdateContent(content_metrics);
82 // Content metrics are NULL: Expect success and no down-sampling action.
83 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
84 EXPECT_TRUE(
85 IsSelectedActionCorrect(qm_scale_, 1.0, 1.0, 1.0, 640, 480, 30.0f));
86 }
87
88 // TODO(marpan): Add a test for number of temporal layers > 1.
89
90 // No down-sampling action at high rates.
91 TEST_F(QmSelectTest, NoActionHighRate) {
92 // Initialize with bitrate, frame rate, native system width/height, and
93 // number of temporal layers.
94 InitQmNativeData(800, 30, 640, 480, 1);
95
96 // Update with encoder frame size.
97 uint16_t codec_width = 640;
98 uint16_t codec_height = 480;
99 qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height);
100 EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height));
101
102 // Update rates for a sequence of intervals.
103 int target_rate[] = {800, 800, 800};
104 int encoder_sent_rate[] = {800, 800, 800};
105 int incoming_frame_rate[] = {30, 30, 30};
106 uint8_t fraction_lost[] = {10, 10, 10};
107 UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate,
108 fraction_lost, 3);
109
110 // Update content: motion level, and 3 spatial prediction errors.
111 UpdateQmContentData(kTemporalLow, kSpatialLow, kSpatialLow, kSpatialLow);
112 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
113 EXPECT_EQ(0, qm_resolution_->ComputeContentClass());
114 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
115 EXPECT_TRUE(
116 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.0f, 640, 480, 30.0f));
117 }
118
119 // Rate is well below transition, down-sampling action is taken,
120 // depending on the content state.
121 TEST_F(QmSelectTest, DownActionLowRate) {
122 // Initialize with bitrate, frame rate, native system width/height, and
123 // number of temporal layers.
124 InitQmNativeData(50, 30, 640, 480, 1);
125
126 // Update with encoder frame size.
127 uint16_t codec_width = 640;
128 uint16_t codec_height = 480;
129 qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height);
130 EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height));
131
132 // Update rates for a sequence of intervals.
133 int target_rate[] = {50, 50, 50};
134 int encoder_sent_rate[] = {50, 50, 50};
135 int incoming_frame_rate[] = {30, 30, 30};
136 uint8_t fraction_lost[] = {10, 10, 10};
137 UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate,
138 fraction_lost, 3);
139
140 // Update content: motion level, and 3 spatial prediction errors.
141 // High motion, low spatial: 2x2 spatial expected.
142 UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow);
143 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
144 EXPECT_EQ(3, qm_resolution_->ComputeContentClass());
145 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
146 EXPECT_TRUE(
147 IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 320, 240, 30.0f));
148
149 qm_resolution_->ResetDownSamplingState();
150 // Low motion, low spatial: 2/3 temporal is expected.
151 UpdateQmContentData(kTemporalLow, kSpatialLow, kSpatialLow, kSpatialLow);
152 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
153 EXPECT_EQ(0, qm_resolution_->ComputeContentClass());
154 EXPECT_TRUE(
155 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.5f, 640, 480, 20.5f));
156
157 qm_resolution_->ResetDownSamplingState();
158 // Medium motion, low spatial: 2x2 spatial expected.
159 UpdateQmContentData(kTemporalMedium, kSpatialLow, kSpatialLow, kSpatialLow);
160 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
161 EXPECT_EQ(6, qm_resolution_->ComputeContentClass());
162 EXPECT_TRUE(
163 IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 320, 240, 30.0f));
164
165 qm_resolution_->ResetDownSamplingState();
166 // High motion, high spatial: 2/3 temporal expected.
167 UpdateQmContentData(kTemporalHigh, kSpatialHigh, kSpatialHigh, kSpatialHigh);
168 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
169 EXPECT_EQ(4, qm_resolution_->ComputeContentClass());
170 EXPECT_TRUE(
171 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.5f, 640, 480, 20.5f));
172
173 qm_resolution_->ResetDownSamplingState();
174 // Low motion, high spatial: 1/2 temporal expected.
175 UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh);
176 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
177 EXPECT_EQ(1, qm_resolution_->ComputeContentClass());
178 EXPECT_TRUE(
179 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 2.0f, 640, 480, 15.5f));
180
181 qm_resolution_->ResetDownSamplingState();
182 // Medium motion, high spatial: 1/2 temporal expected.
183 UpdateQmContentData(kTemporalMedium, kSpatialHigh, kSpatialHigh,
184 kSpatialHigh);
185 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
186 EXPECT_EQ(7, qm_resolution_->ComputeContentClass());
187 EXPECT_TRUE(
188 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 2.0f, 640, 480, 15.5f));
189
190 qm_resolution_->ResetDownSamplingState();
191 // High motion, medium spatial: 2x2 spatial expected.
192 UpdateQmContentData(kTemporalHigh, kSpatialMedium, kSpatialMedium,
193 kSpatialMedium);
194 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
195 EXPECT_EQ(5, qm_resolution_->ComputeContentClass());
196 // Target frame rate for frame dropper should be the same as previous == 15.
197 EXPECT_TRUE(
198 IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 320, 240, 30.0f));
199
200 qm_resolution_->ResetDownSamplingState();
201 // Low motion, medium spatial: high frame rate, so 1/2 temporal expected.
202 UpdateQmContentData(kTemporalLow, kSpatialMedium, kSpatialMedium,
203 kSpatialMedium);
204 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
205 EXPECT_EQ(2, qm_resolution_->ComputeContentClass());
206 EXPECT_TRUE(
207 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 2.0f, 640, 480, 15.5f));
208
209 qm_resolution_->ResetDownSamplingState();
210 // Medium motion, medium spatial: high frame rate, so 2/3 temporal expected.
211 UpdateQmContentData(kTemporalMedium, kSpatialMedium, kSpatialMedium,
212 kSpatialMedium);
213 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
214 EXPECT_EQ(8, qm_resolution_->ComputeContentClass());
215 EXPECT_TRUE(
216 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.5f, 640, 480, 20.5f));
217 }
218
219 // Rate mis-match is high, and we have over-shooting.
220 // since target rate is below max for down-sampling, down-sampling is selected.
221 TEST_F(QmSelectTest, DownActionHighRateMMOvershoot) {
222 // Initialize with bitrate, frame rate, native system width/height, and
223 // number of temporal layers.
224 InitQmNativeData(300, 30, 640, 480, 1);
225
226 // Update with encoder frame size.
227 uint16_t codec_width = 640;
228 uint16_t codec_height = 480;
229 qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height);
230 EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height));
231
232 // Update rates for a sequence of intervals.
233 int target_rate[] = {300, 300, 300};
234 int encoder_sent_rate[] = {900, 900, 900};
235 int incoming_frame_rate[] = {30, 30, 30};
236 uint8_t fraction_lost[] = {10, 10, 10};
237 UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate,
238 fraction_lost, 3);
239
240 // Update content: motion level, and 3 spatial prediction errors.
241 // High motion, low spatial.
242 UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow);
243 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
244 EXPECT_EQ(3, qm_resolution_->ComputeContentClass());
245 EXPECT_EQ(kStressedEncoding, qm_resolution_->GetEncoderState());
246 EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 4.0f / 3.0f, 4.0f / 3.0f, 1.0f,
247 480, 360, 30.0f));
248
249 qm_resolution_->ResetDownSamplingState();
250 // Low motion, high spatial
251 UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh);
252 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
253 EXPECT_EQ(1, qm_resolution_->ComputeContentClass());
254 EXPECT_TRUE(
255 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.5f, 640, 480, 20.5f));
256 }
257
258 // Rate mis-match is high, target rate is below max for down-sampling,
259 // but since we have consistent under-shooting, no down-sampling action.
260 TEST_F(QmSelectTest, NoActionHighRateMMUndershoot) {
261 // Initialize with bitrate, frame rate, native system width/height, and
262 // number of temporal layers.
263 InitQmNativeData(300, 30, 640, 480, 1);
264
265 // Update with encoder frame size.
266 uint16_t codec_width = 640;
267 uint16_t codec_height = 480;
268 qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height);
269 EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height));
270
271 // Update rates for a sequence of intervals.
272 int target_rate[] = {300, 300, 300};
273 int encoder_sent_rate[] = {100, 100, 100};
274 int incoming_frame_rate[] = {30, 30, 30};
275 uint8_t fraction_lost[] = {10, 10, 10};
276 UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate,
277 fraction_lost, 3);
278
279 // Update content: motion level, and 3 spatial prediction errors.
280 // High motion, low spatial.
281 UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow);
282 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
283 EXPECT_EQ(3, qm_resolution_->ComputeContentClass());
284 EXPECT_EQ(kEasyEncoding, qm_resolution_->GetEncoderState());
285 EXPECT_TRUE(
286 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.0f, 640, 480, 30.0f));
287
288 qm_resolution_->ResetDownSamplingState();
289 // Low motion, high spatial
290 UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh);
291 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
292 EXPECT_EQ(1, qm_resolution_->ComputeContentClass());
293 EXPECT_TRUE(
294 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.0f, 640, 480, 30.0f));
295 }
296
297 // Buffer is underflowing, and target rate is below max for down-sampling,
298 // so action is taken.
299 TEST_F(QmSelectTest, DownActionBufferUnderflow) {
300 // Initialize with bitrate, frame rate, native system width/height, and
301 // number of temporal layers.
302 InitQmNativeData(300, 30, 640, 480, 1);
303
304 // Update with encoder frame size.
305 uint16_t codec_width = 640;
306 uint16_t codec_height = 480;
307 qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height);
308 EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height));
309
310 // Update with encoded size over a number of frames.
311 // per-frame bandwidth = 15 = 450/30: simulate (decoder) buffer underflow:
312 size_t encoded_size[] = {200, 100, 50, 30, 60, 40, 20, 30, 20, 40};
313 UpdateQmEncodedFrame(encoded_size, GTEST_ARRAY_SIZE_(encoded_size));
314
315 // Update rates for a sequence of intervals.
316 int target_rate[] = {300, 300, 300};
317 int encoder_sent_rate[] = {450, 450, 450};
318 int incoming_frame_rate[] = {30, 30, 30};
319 uint8_t fraction_lost[] = {10, 10, 10};
320 UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate,
321 fraction_lost, 3);
322
323 // Update content: motion level, and 3 spatial prediction errors.
324 // High motion, low spatial.
325 UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow);
326 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
327 EXPECT_EQ(3, qm_resolution_->ComputeContentClass());
328 EXPECT_EQ(kStressedEncoding, qm_resolution_->GetEncoderState());
329 EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 4.0f / 3.0f, 4.0f / 3.0f, 1.0f,
330 480, 360, 30.0f));
331
332 qm_resolution_->ResetDownSamplingState();
333 // Low motion, high spatial
334 UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh);
335 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
336 EXPECT_EQ(1, qm_resolution_->ComputeContentClass());
337 EXPECT_TRUE(
338 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.5f, 640, 480, 20.5f));
339 }
340
341 // Target rate is below max for down-sampling, but buffer level is stable,
342 // so no action is taken.
343 TEST_F(QmSelectTest, NoActionBufferStable) {
344 // Initialize with bitrate, frame rate, native system width/height, and
345 // number of temporal layers.
346 InitQmNativeData(350, 30, 640, 480, 1);
347
348 // Update with encoder frame size.
349 uint16_t codec_width = 640;
350 uint16_t codec_height = 480;
351 qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height);
352 EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height));
353
354 // Update with encoded size over a number of frames.
355 // per-frame bandwidth = 15 = 450/30: simulate stable (decoder) buffer levels.
356 size_t encoded_size[] = {40, 10, 10, 16, 18, 20, 17, 20, 16, 15};
357 UpdateQmEncodedFrame(encoded_size, GTEST_ARRAY_SIZE_(encoded_size));
358
359 // Update rates for a sequence of intervals.
360 int target_rate[] = {350, 350, 350};
361 int encoder_sent_rate[] = {350, 450, 450};
362 int incoming_frame_rate[] = {30, 30, 30};
363 uint8_t fraction_lost[] = {10, 10, 10};
364 UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate,
365 fraction_lost, 3);
366
367 // Update content: motion level, and 3 spatial prediction errors.
368 // High motion, low spatial.
369 UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow);
370 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
371 EXPECT_EQ(3, qm_resolution_->ComputeContentClass());
372 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
373 EXPECT_TRUE(
374 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.0f, 640, 480, 30.0f));
375
376 qm_resolution_->ResetDownSamplingState();
377 // Low motion, high spatial
378 UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh);
379 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
380 EXPECT_EQ(1, qm_resolution_->ComputeContentClass());
381 EXPECT_TRUE(
382 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.0f, 640, 480, 30.0f));
383 }
384
385 // Very low rate, but no spatial down-sampling below some size (QCIF).
386 TEST_F(QmSelectTest, LimitDownSpatialAction) {
387 // Initialize with bitrate, frame rate, native system width/height, and
388 // number of temporal layers.
389 InitQmNativeData(10, 30, 176, 144, 1);
390
391 // Update with encoder frame size.
392 uint16_t codec_width = 176;
393 uint16_t codec_height = 144;
394 qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height);
395 EXPECT_EQ(0, qm_resolution_->GetImageType(codec_width, codec_height));
396
397 // Update rates for a sequence of intervals.
398 int target_rate[] = {10, 10, 10};
399 int encoder_sent_rate[] = {10, 10, 10};
400 int incoming_frame_rate[] = {30, 30, 30};
401 uint8_t fraction_lost[] = {10, 10, 10};
402 UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate,
403 fraction_lost, 3);
404
405 // Update content: motion level, and 3 spatial prediction errors.
406 // High motion, low spatial.
407 UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow);
408 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
409 EXPECT_EQ(3, qm_resolution_->ComputeContentClass());
410 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
411 EXPECT_TRUE(
412 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.0f, 176, 144, 30.0f));
413 }
414
415 // Very low rate, but no frame reduction below some frame_rate (8fps).
416 TEST_F(QmSelectTest, LimitDownTemporalAction) {
417 // Initialize with bitrate, frame rate, native system width/height, and
418 // number of temporal layers.
419 InitQmNativeData(10, 8, 640, 480, 1);
420
421 // Update with encoder frame size.
422 uint16_t codec_width = 640;
423 uint16_t codec_height = 480;
424 qm_resolution_->UpdateCodecParameters(8.0f, codec_width, codec_height);
425 EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height));
426
427 // Update rates for a sequence of intervals.
428 int target_rate[] = {10, 10, 10};
429 int encoder_sent_rate[] = {10, 10, 10};
430 int incoming_frame_rate[] = {8, 8, 8};
431 uint8_t fraction_lost[] = {10, 10, 10};
432 UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate,
433 fraction_lost, 3);
434
435 // Update content: motion level, and 3 spatial prediction errors.
436 // Low motion, medium spatial.
437 UpdateQmContentData(kTemporalLow, kSpatialMedium, kSpatialMedium,
438 kSpatialMedium);
439 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
440 EXPECT_EQ(2, qm_resolution_->ComputeContentClass());
441 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
442 EXPECT_TRUE(
443 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.0f, 640, 480, 8.0f));
444 }
445
446 // Two stages: spatial down-sample and then back up spatially,
447 // as rate as increased.
448 TEST_F(QmSelectTest, 2StageDownSpatialUpSpatial) {
449 // Initialize with bitrate, frame rate, native system width/height, and
450 // number of temporal layers.
451 InitQmNativeData(50, 30, 640, 480, 1);
452
453 // Update with encoder frame size.
454 uint16_t codec_width = 640;
455 uint16_t codec_height = 480;
456 qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height);
457 EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height));
458
459 // Update rates for a sequence of intervals.
460 int target_rate[] = {50, 50, 50};
461 int encoder_sent_rate[] = {50, 50, 50};
462 int incoming_frame_rate[] = {30, 30, 30};
463 uint8_t fraction_lost[] = {10, 10, 10};
464 UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate,
465 fraction_lost, 3);
466
467 // Update content: motion level, and 3 spatial prediction errors.
468 // High motion, low spatial.
469 UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow);
470 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
471 EXPECT_EQ(3, qm_resolution_->ComputeContentClass());
472 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
473 EXPECT_TRUE(
474 IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 320, 240, 30.0f));
475
476 // Reset and go up in rate: expected to go back up, in 2 stages of 3/4.
477 qm_resolution_->ResetRates();
478 qm_resolution_->UpdateCodecParameters(30.0f, 320, 240);
479 EXPECT_EQ(2, qm_resolution_->GetImageType(320, 240));
480 // Update rates for a sequence of intervals.
481 int target_rate2[] = {400, 400, 400, 400, 400};
482 int encoder_sent_rate2[] = {400, 400, 400, 400, 400};
483 int incoming_frame_rate2[] = {30, 30, 30, 30, 30};
484 uint8_t fraction_lost2[] = {10, 10, 10, 10, 10};
485 UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2,
486 fraction_lost2, 5);
487 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
488 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
489 float scale = (4.0f / 3.0f) / 2.0f;
490 EXPECT_TRUE(
491 IsSelectedActionCorrect(qm_scale_, scale, scale, 1.0f, 480, 360, 30.0f));
492
493 qm_resolution_->UpdateCodecParameters(30.0f, 480, 360);
494 EXPECT_EQ(4, qm_resolution_->GetImageType(480, 360));
495 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
496 EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 3.0f / 4.0f, 3.0f / 4.0f, 1.0f,
497 640, 480, 30.0f));
498 }
499
500 // Two stages: spatial down-sample and then back up spatially, since encoder
501 // is under-shooting target even though rate has not increased much.
502 TEST_F(QmSelectTest, 2StageDownSpatialUpSpatialUndershoot) {
503 // Initialize with bitrate, frame rate, native system width/height, and
504 // number of temporal layers.
505 InitQmNativeData(50, 30, 640, 480, 1);
506
507 // Update with encoder frame size.
508 uint16_t codec_width = 640;
509 uint16_t codec_height = 480;
510 qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height);
511 EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height));
512
513 // Update rates for a sequence of intervals.
514 int target_rate[] = {50, 50, 50};
515 int encoder_sent_rate[] = {50, 50, 50};
516 int incoming_frame_rate[] = {30, 30, 30};
517 uint8_t fraction_lost[] = {10, 10, 10};
518 UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate,
519 fraction_lost, 3);
520
521 // Update content: motion level, and 3 spatial prediction errors.
522 // High motion, low spatial.
523 UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow);
524 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
525 EXPECT_EQ(3, qm_resolution_->ComputeContentClass());
526 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
527 EXPECT_TRUE(
528 IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 320, 240, 30.0f));
529
530 // Reset rates and simulate under-shooting scenario.: expect to go back up.
531 // Goes up spatially in two stages for 1/2x1/2 down-sampling.
532 qm_resolution_->ResetRates();
533 qm_resolution_->UpdateCodecParameters(30.0f, 320, 240);
534 EXPECT_EQ(2, qm_resolution_->GetImageType(320, 240));
535 // Update rates for a sequence of intervals.
536 int target_rate2[] = {200, 200, 200, 200, 200};
537 int encoder_sent_rate2[] = {50, 50, 50, 50, 50};
538 int incoming_frame_rate2[] = {30, 30, 30, 30, 30};
539 uint8_t fraction_lost2[] = {10, 10, 10, 10, 10};
540 UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2,
541 fraction_lost2, 5);
542 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
543 EXPECT_EQ(kEasyEncoding, qm_resolution_->GetEncoderState());
544 float scale = (4.0f / 3.0f) / 2.0f;
545 EXPECT_TRUE(
546 IsSelectedActionCorrect(qm_scale_, scale, scale, 1.0f, 480, 360, 30.0f));
547
548 qm_resolution_->UpdateCodecParameters(30.0f, 480, 360);
549 EXPECT_EQ(4, qm_resolution_->GetImageType(480, 360));
550 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
551 EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 3.0f / 4.0f, 3.0f / 4.0f, 1.0f,
552 640, 480, 30.0f));
553 }
554
555 // Two stages: spatial down-sample and then no action to go up,
556 // as encoding rate mis-match is too high.
557 TEST_F(QmSelectTest, 2StageDownSpatialNoActionUp) {
558 // Initialize with bitrate, frame rate, native system width/height, and
559 // number of temporal layers.
560 InitQmNativeData(50, 30, 640, 480, 1);
561
562 // Update with encoder frame size.
563 uint16_t codec_width = 640;
564 uint16_t codec_height = 480;
565 qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height);
566 EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height));
567
568 // Update rates for a sequence of intervals.
569 int target_rate[] = {50, 50, 50};
570 int encoder_sent_rate[] = {50, 50, 50};
571 int incoming_frame_rate[] = {30, 30, 30};
572 uint8_t fraction_lost[] = {10, 10, 10};
573 UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate,
574 fraction_lost, 3);
575
576 // Update content: motion level, and 3 spatial prediction errors.
577 // High motion, low spatial.
578 UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow);
579 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
580 EXPECT_EQ(3, qm_resolution_->ComputeContentClass());
581 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
582 EXPECT_TRUE(
583 IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 320, 240, 30.0f));
584
585 // Reset and simulate large rate mis-match: expect no action to go back up.
586 qm_resolution_->ResetRates();
587 qm_resolution_->UpdateCodecParameters(30.0f, 320, 240);
588 EXPECT_EQ(2, qm_resolution_->GetImageType(320, 240));
589 // Update rates for a sequence of intervals.
590 int target_rate2[] = {400, 400, 400, 400, 400};
591 int encoder_sent_rate2[] = {1000, 1000, 1000, 1000, 1000};
592 int incoming_frame_rate2[] = {30, 30, 30, 30, 30};
593 uint8_t fraction_lost2[] = {10, 10, 10, 10, 10};
594 UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2,
595 fraction_lost2, 5);
596 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
597 EXPECT_EQ(kStressedEncoding, qm_resolution_->GetEncoderState());
598 EXPECT_TRUE(
599 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.0f, 320, 240, 30.0f));
600 }
601
602 // Two stages: temporally down-sample and then back up temporally,
603 // as rate as increased.
604 TEST_F(QmSelectTest, 2StatgeDownTemporalUpTemporal) {
605 // Initialize with bitrate, frame rate, native system width/height, and
606 // number of temporal layers.
607 InitQmNativeData(50, 30, 640, 480, 1);
608
609 // Update with encoder frame size.
610 uint16_t codec_width = 640;
611 uint16_t codec_height = 480;
612 qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height);
613 EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height));
614
615 // Update rates for a sequence of intervals.
616 int target_rate[] = {50, 50, 50};
617 int encoder_sent_rate[] = {50, 50, 50};
618 int incoming_frame_rate[] = {30, 30, 30};
619 uint8_t fraction_lost[] = {10, 10, 10};
620 UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate,
621 fraction_lost, 3);
622
623 // Update content: motion level, and 3 spatial prediction errors.
624 // Low motion, high spatial.
625 UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh);
626 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
627 EXPECT_EQ(1, qm_resolution_->ComputeContentClass());
628 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
629 EXPECT_TRUE(
630 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 2.0f, 640, 480, 15.5f));
631
632 // Reset rates and go up in rate: expect to go back up.
633 qm_resolution_->ResetRates();
634 // Update rates for a sequence of intervals.
635 int target_rate2[] = {400, 400, 400, 400, 400};
636 int encoder_sent_rate2[] = {400, 400, 400, 400, 400};
637 int incoming_frame_rate2[] = {15, 15, 15, 15, 15};
638 uint8_t fraction_lost2[] = {10, 10, 10, 10, 10};
639 UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2,
640 fraction_lost2, 5);
641 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
642 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
643 EXPECT_TRUE(
644 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 0.5f, 640, 480, 30.0f));
645 }
646
647 // Two stages: temporal down-sample and then back up temporally, since encoder
648 // is under-shooting target even though rate has not increased much.
649 TEST_F(QmSelectTest, 2StatgeDownTemporalUpTemporalUndershoot) {
650 // Initialize with bitrate, frame rate, native system width/height, and
651 // number of temporal layers.
652 InitQmNativeData(50, 30, 640, 480, 1);
653
654 // Update with encoder frame size.
655 uint16_t codec_width = 640;
656 uint16_t codec_height = 480;
657 qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height);
658 EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height));
659
660 // Update rates for a sequence of intervals.
661 int target_rate[] = {50, 50, 50};
662 int encoder_sent_rate[] = {50, 50, 50};
663 int incoming_frame_rate[] = {30, 30, 30};
664 uint8_t fraction_lost[] = {10, 10, 10};
665 UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate,
666 fraction_lost, 3);
667
668 // Update content: motion level, and 3 spatial prediction errors.
669 // Low motion, high spatial.
670 UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh);
671 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
672 EXPECT_EQ(1, qm_resolution_->ComputeContentClass());
673 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
674 EXPECT_TRUE(
675 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 2.0f, 640, 480, 15.5f));
676
677 // Reset rates and simulate under-shooting scenario.: expect to go back up.
678 qm_resolution_->ResetRates();
679 // Update rates for a sequence of intervals.
680 int target_rate2[] = {150, 150, 150, 150, 150};
681 int encoder_sent_rate2[] = {50, 50, 50, 50, 50};
682 int incoming_frame_rate2[] = {15, 15, 15, 15, 15};
683 uint8_t fraction_lost2[] = {10, 10, 10, 10, 10};
684 UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2,
685 fraction_lost2, 5);
686 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
687 EXPECT_EQ(kEasyEncoding, qm_resolution_->GetEncoderState());
688 EXPECT_TRUE(
689 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 0.5f, 640, 480, 30.0f));
690 }
691
692 // Two stages: temporal down-sample and then no action to go up,
693 // as encoding rate mis-match is too high.
694 TEST_F(QmSelectTest, 2StageDownTemporalNoActionUp) {
695 // Initialize with bitrate, frame rate, native system width/height, and
696 // number of temporal layers.
697 InitQmNativeData(50, 30, 640, 480, 1);
698
699 // Update with encoder frame size.
700 uint16_t codec_width = 640;
701 uint16_t codec_height = 480;
702 qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height);
703 EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height));
704
705 // Update rates for a sequence of intervals.
706 int target_rate[] = {50, 50, 50};
707 int encoder_sent_rate[] = {50, 50, 50};
708 int incoming_frame_rate[] = {30, 30, 30};
709 uint8_t fraction_lost[] = {10, 10, 10};
710 UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate,
711 fraction_lost, 3);
712
713 // Update content: motion level, and 3 spatial prediction errors.
714 // Low motion, high spatial.
715 UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh);
716 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
717 EXPECT_EQ(1, qm_resolution_->ComputeContentClass());
718 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
719 EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1, 1, 2, 640, 480, 15.5f));
720
721 // Reset and simulate large rate mis-match: expect no action to go back up.
722 qm_resolution_->UpdateCodecParameters(15.0f, codec_width, codec_height);
723 qm_resolution_->ResetRates();
724 // Update rates for a sequence of intervals.
725 int target_rate2[] = {600, 600, 600, 600, 600};
726 int encoder_sent_rate2[] = {1000, 1000, 1000, 1000, 1000};
727 int incoming_frame_rate2[] = {15, 15, 15, 15, 15};
728 uint8_t fraction_lost2[] = {10, 10, 10, 10, 10};
729 UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2,
730 fraction_lost2, 5);
731 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
732 EXPECT_EQ(kStressedEncoding, qm_resolution_->GetEncoderState());
733 EXPECT_TRUE(
734 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.0f, 640, 480, 15.0f));
735 }
736 // 3 stages: spatial down-sample, followed by temporal down-sample,
737 // and then go up to full state, as encoding rate has increased.
738 TEST_F(QmSelectTest, 3StageDownSpatialTemporlaUpSpatialTemporal) {
739 // Initialize with bitrate, frame rate, native system width/height, and
740 // number of temporal layers.
741 InitQmNativeData(80, 30, 640, 480, 1);
742
743 // Update with encoder frame size.
744 uint16_t codec_width = 640;
745 uint16_t codec_height = 480;
746 qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height);
747 EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height));
748
749 // Update rates for a sequence of intervals.
750 int target_rate[] = {80, 80, 80};
751 int encoder_sent_rate[] = {80, 80, 80};
752 int incoming_frame_rate[] = {30, 30, 30};
753 uint8_t fraction_lost[] = {10, 10, 10};
754 UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate,
755 fraction_lost, 3);
756
757 // Update content: motion level, and 3 spatial prediction errors.
758 // High motion, low spatial.
759 UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow);
760 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
761 EXPECT_EQ(3, qm_resolution_->ComputeContentClass());
762 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
763 EXPECT_TRUE(
764 IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 320, 240, 30.0f));
765
766 // Change content data: expect temporal down-sample.
767 qm_resolution_->UpdateCodecParameters(30.0f, 320, 240);
768 EXPECT_EQ(2, qm_resolution_->GetImageType(320, 240));
769
770 // Reset rates and go lower in rate.
771 qm_resolution_->ResetRates();
772 int target_rate2[] = {40, 40, 40, 40, 40};
773 int encoder_sent_rate2[] = {40, 40, 40, 40, 40};
774 int incoming_frame_rate2[] = {30, 30, 30, 30, 30};
775 uint8_t fraction_lost2[] = {10, 10, 10, 10, 10};
776 UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2,
777 fraction_lost2, 5);
778
779 // Update content: motion level, and 3 spatial prediction errors.
780 // Low motion, high spatial.
781 UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh);
782 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
783 EXPECT_EQ(1, qm_resolution_->ComputeContentClass());
784 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
785 EXPECT_TRUE(
786 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.5f, 320, 240, 20.5f));
787
788 // Reset rates and go high up in rate: expect to go back up both spatial
789 // and temporally. The 1/2x1/2 spatial is undone in two stages.
790 qm_resolution_->ResetRates();
791 // Update rates for a sequence of intervals.
792 int target_rate3[] = {1000, 1000, 1000, 1000, 1000};
793 int encoder_sent_rate3[] = {1000, 1000, 1000, 1000, 1000};
794 int incoming_frame_rate3[] = {20, 20, 20, 20, 20};
795 uint8_t fraction_lost3[] = {10, 10, 10, 10, 10};
796 UpdateQmRateData(target_rate3, encoder_sent_rate3, incoming_frame_rate3,
797 fraction_lost3, 5);
798
799 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
800 EXPECT_EQ(1, qm_resolution_->ComputeContentClass());
801 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
802 float scale = (4.0f / 3.0f) / 2.0f;
803 EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, scale, scale, 2.0f / 3.0f, 480,
804 360, 30.0f));
805
806 qm_resolution_->UpdateCodecParameters(30.0f, 480, 360);
807 EXPECT_EQ(4, qm_resolution_->GetImageType(480, 360));
808 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
809 EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 3.0f / 4.0f, 3.0f / 4.0f, 1.0f,
810 640, 480, 30.0f));
811 }
812
813 // No down-sampling below some total amount.
814 TEST_F(QmSelectTest, NoActionTooMuchDownSampling) {
815 // Initialize with bitrate, frame rate, native system width/height, and
816 // number of temporal layers.
817 InitQmNativeData(150, 30, 1280, 720, 1);
818
819 // Update with encoder frame size.
820 uint16_t codec_width = 1280;
821 uint16_t codec_height = 720;
822 qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height);
823 EXPECT_EQ(7, qm_resolution_->GetImageType(codec_width, codec_height));
824
825 // Update rates for a sequence of intervals.
826 int target_rate[] = {150, 150, 150};
827 int encoder_sent_rate[] = {150, 150, 150};
828 int incoming_frame_rate[] = {30, 30, 30};
829 uint8_t fraction_lost[] = {10, 10, 10};
830 UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate,
831 fraction_lost, 3);
832
833 // Update content: motion level, and 3 spatial prediction errors.
834 // High motion, low spatial.
835 UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow);
836 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
837 EXPECT_EQ(3, qm_resolution_->ComputeContentClass());
838 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
839 EXPECT_TRUE(
840 IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 640, 360, 30.0f));
841
842 // Reset and lower rates to get another spatial action (3/4x3/4).
843 // Lower the frame rate for spatial to be selected again.
844 qm_resolution_->ResetRates();
845 qm_resolution_->UpdateCodecParameters(10.0f, 640, 360);
846 EXPECT_EQ(4, qm_resolution_->GetImageType(640, 360));
847 // Update rates for a sequence of intervals.
848 int target_rate2[] = {70, 70, 70, 70, 70};
849 int encoder_sent_rate2[] = {70, 70, 70, 70, 70};
850 int incoming_frame_rate2[] = {10, 10, 10, 10, 10};
851 uint8_t fraction_lost2[] = {10, 10, 10, 10, 10};
852 UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2,
853 fraction_lost2, 5);
854
855 // Update content: motion level, and 3 spatial prediction errors.
856 // High motion, medium spatial.
857 UpdateQmContentData(kTemporalHigh, kSpatialMedium, kSpatialMedium,
858 kSpatialMedium);
859 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
860 EXPECT_EQ(5, qm_resolution_->ComputeContentClass());
861 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
862 EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 4.0f / 3.0f, 4.0f / 3.0f, 1.0f,
863 480, 270, 10.0f));
864
865 // Reset and go to very low rate: no action should be taken,
866 // we went down too much already.
867 qm_resolution_->ResetRates();
868 qm_resolution_->UpdateCodecParameters(10.0f, 480, 270);
869 EXPECT_EQ(3, qm_resolution_->GetImageType(480, 270));
870 // Update rates for a sequence of intervals.
871 int target_rate3[] = {10, 10, 10, 10, 10};
872 int encoder_sent_rate3[] = {10, 10, 10, 10, 10};
873 int incoming_frame_rate3[] = {10, 10, 10, 10, 10};
874 uint8_t fraction_lost3[] = {10, 10, 10, 10, 10};
875 UpdateQmRateData(target_rate3, encoder_sent_rate3, incoming_frame_rate3,
876 fraction_lost3, 5);
877 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
878 EXPECT_EQ(5, qm_resolution_->ComputeContentClass());
879 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
880 EXPECT_TRUE(
881 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.0f, 480, 270, 10.0f));
882 }
883
884 // Multiple down-sampling stages and then undo all of them.
885 // Spatial down-sample 3/4x3/4, followed by temporal down-sample 2/3,
886 // followed by spatial 3/4x3/4. Then go up to full state,
887 // as encoding rate has increased.
888 TEST_F(QmSelectTest, MultipleStagesCheckActionHistory1) {
889 // Initialize with bitrate, frame rate, native system width/height, and
890 // number of temporal layers.
891 InitQmNativeData(150, 30, 640, 480, 1);
892
893 // Update with encoder frame size.
894 uint16_t codec_width = 640;
895 uint16_t codec_height = 480;
896 qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height);
897 EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height));
898
899 // Go down spatial 3/4x3/4.
900 // Update rates for a sequence of intervals.
901 int target_rate[] = {150, 150, 150};
902 int encoder_sent_rate[] = {150, 150, 150};
903 int incoming_frame_rate[] = {30, 30, 30};
904 uint8_t fraction_lost[] = {10, 10, 10};
905 UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate,
906 fraction_lost, 3);
907
908 // Update content: motion level, and 3 spatial prediction errors.
909 // Medium motion, low spatial.
910 UpdateQmContentData(kTemporalMedium, kSpatialLow, kSpatialLow, kSpatialLow);
911 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
912 EXPECT_EQ(6, qm_resolution_->ComputeContentClass());
913 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
914 EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 4.0f / 3.0f, 4.0f / 3.0f, 1.0f,
915 480, 360, 30.0f));
916 // Go down 2/3 temporal.
917 qm_resolution_->UpdateCodecParameters(30.0f, 480, 360);
918 EXPECT_EQ(4, qm_resolution_->GetImageType(480, 360));
919 qm_resolution_->ResetRates();
920 int target_rate2[] = {100, 100, 100, 100, 100};
921 int encoder_sent_rate2[] = {100, 100, 100, 100, 100};
922 int incoming_frame_rate2[] = {30, 30, 30, 30, 30};
923 uint8_t fraction_lost2[] = {10, 10, 10, 10, 10};
924 UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2,
925 fraction_lost2, 5);
926
927 // Update content: motion level, and 3 spatial prediction errors.
928 // Low motion, high spatial.
929 UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh);
930 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
931 EXPECT_EQ(1, qm_resolution_->ComputeContentClass());
932 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
933 EXPECT_TRUE(
934 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.5f, 480, 360, 20.5f));
935
936 // Go down 3/4x3/4 spatial:
937 qm_resolution_->UpdateCodecParameters(20.0f, 480, 360);
938 qm_resolution_->ResetRates();
939 int target_rate3[] = {80, 80, 80, 80, 80};
940 int encoder_sent_rate3[] = {80, 80, 80, 80, 80};
941 int incoming_frame_rate3[] = {20, 20, 20, 20, 20};
942 uint8_t fraction_lost3[] = {10, 10, 10, 10, 10};
943 UpdateQmRateData(target_rate3, encoder_sent_rate3, incoming_frame_rate3,
944 fraction_lost3, 5);
945
946 // Update content: motion level, and 3 spatial prediction errors.
947 // High motion, low spatial.
948 UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow);
949 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
950 EXPECT_EQ(3, qm_resolution_->ComputeContentClass());
951 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
952 // The two spatial actions of 3/4x3/4 are converted to 1/2x1/2,
953 // so scale factor is 2.0.
954 EXPECT_TRUE(
955 IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 320, 240, 20.0f));
956
957 // Reset rates and go high up in rate: expect to go up:
958 // 1/2x1x2 spatial and 1/2 temporally.
959
960 // Go up 1/2x1/2 spatially and 1/2 temporally. Spatial is done in 2 stages.
961 qm_resolution_->UpdateCodecParameters(15.0f, 320, 240);
962 EXPECT_EQ(2, qm_resolution_->GetImageType(320, 240));
963 qm_resolution_->ResetRates();
964 // Update rates for a sequence of intervals.
965 int target_rate4[] = {1000, 1000, 1000, 1000, 1000};
966 int encoder_sent_rate4[] = {1000, 1000, 1000, 1000, 1000};
967 int incoming_frame_rate4[] = {15, 15, 15, 15, 15};
968 uint8_t fraction_lost4[] = {10, 10, 10, 10, 10};
969 UpdateQmRateData(target_rate4, encoder_sent_rate4, incoming_frame_rate4,
970 fraction_lost4, 5);
971
972 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
973 EXPECT_EQ(3, qm_resolution_->ComputeContentClass());
974 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
975 float scale = (4.0f / 3.0f) / 2.0f;
976 EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, scale, scale, 2.0f / 3.0f, 480,
977 360, 30.0f));
978
979 qm_resolution_->UpdateCodecParameters(30.0f, 480, 360);
980 EXPECT_EQ(4, qm_resolution_->GetImageType(480, 360));
981 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
982 EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 3.0f / 4.0f, 3.0f / 4.0f, 1.0f,
983 640, 480, 30.0f));
984 }
985
986 // Multiple down-sampling and up-sample stages, with partial undoing.
987 // Spatial down-sample 1/2x1/2, followed by temporal down-sample 2/3, undo the
988 // temporal, then another temporal, and then undo both spatial and temporal.
989 TEST_F(QmSelectTest, MultipleStagesCheckActionHistory2) {
990 // Initialize with bitrate, frame rate, native system width/height, and
991 // number of temporal layers.
992 InitQmNativeData(80, 30, 640, 480, 1);
993
994 // Update with encoder frame size.
995 uint16_t codec_width = 640;
996 uint16_t codec_height = 480;
997 qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height);
998 EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height));
999
1000 // Go down 1/2x1/2 spatial.
1001 // Update rates for a sequence of intervals.
1002 int target_rate[] = {80, 80, 80};
1003 int encoder_sent_rate[] = {80, 80, 80};
1004 int incoming_frame_rate[] = {30, 30, 30};
1005 uint8_t fraction_lost[] = {10, 10, 10};
1006 UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate,
1007 fraction_lost, 3);
1008
1009 // Update content: motion level, and 3 spatial prediction errors.
1010 // Medium motion, low spatial.
1011 UpdateQmContentData(kTemporalMedium, kSpatialLow, kSpatialLow, kSpatialLow);
1012 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
1013 EXPECT_EQ(6, qm_resolution_->ComputeContentClass());
1014 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
1015 EXPECT_TRUE(
1016 IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 320, 240, 30.0f));
1017
1018 // Go down 2/3 temporal.
1019 qm_resolution_->UpdateCodecParameters(30.0f, 320, 240);
1020 EXPECT_EQ(2, qm_resolution_->GetImageType(320, 240));
1021 qm_resolution_->ResetRates();
1022 int target_rate2[] = {40, 40, 40, 40, 40};
1023 int encoder_sent_rate2[] = {40, 40, 40, 40, 40};
1024 int incoming_frame_rate2[] = {30, 30, 30, 30, 30};
1025 uint8_t fraction_lost2[] = {10, 10, 10, 10, 10};
1026 UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2,
1027 fraction_lost2, 5);
1028
1029 // Update content: motion level, and 3 spatial prediction errors.
1030 // Medium motion, high spatial.
1031 UpdateQmContentData(kTemporalMedium, kSpatialHigh, kSpatialHigh,
1032 kSpatialHigh);
1033 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
1034 EXPECT_EQ(7, qm_resolution_->ComputeContentClass());
1035 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
1036 EXPECT_TRUE(
1037 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.5f, 320, 240, 20.5f));
1038
1039 // Go up 2/3 temporally.
1040 qm_resolution_->UpdateCodecParameters(20.0f, 320, 240);
1041 qm_resolution_->ResetRates();
1042 // Update rates for a sequence of intervals.
1043 int target_rate3[] = {150, 150, 150, 150, 150};
1044 int encoder_sent_rate3[] = {150, 150, 150, 150, 150};
1045 int incoming_frame_rate3[] = {20, 20, 20, 20, 20};
1046 uint8_t fraction_lost3[] = {10, 10, 10, 10, 10};
1047 UpdateQmRateData(target_rate3, encoder_sent_rate3, incoming_frame_rate3,
1048 fraction_lost3, 5);
1049
1050 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
1051 EXPECT_EQ(7, qm_resolution_->ComputeContentClass());
1052 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
1053 EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 2.0f / 3.0f, 320,
1054 240, 30.0f));
1055
1056 // Go down 2/3 temporal.
1057 qm_resolution_->UpdateCodecParameters(30.0f, 320, 240);
1058 EXPECT_EQ(2, qm_resolution_->GetImageType(320, 240));
1059 qm_resolution_->ResetRates();
1060 int target_rate4[] = {40, 40, 40, 40, 40};
1061 int encoder_sent_rate4[] = {40, 40, 40, 40, 40};
1062 int incoming_frame_rate4[] = {30, 30, 30, 30, 30};
1063 uint8_t fraction_lost4[] = {10, 10, 10, 10, 10};
1064 UpdateQmRateData(target_rate4, encoder_sent_rate4, incoming_frame_rate4,
1065 fraction_lost4, 5);
1066
1067 // Update content: motion level, and 3 spatial prediction errors.
1068 // Low motion, high spatial.
1069 UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh);
1070 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
1071 EXPECT_EQ(1, qm_resolution_->ComputeContentClass());
1072 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
1073 EXPECT_TRUE(
1074 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.5f, 320, 240, 20.5f));
1075
1076 // Go up spatial and temporal. Spatial undoing is done in 2 stages.
1077 qm_resolution_->UpdateCodecParameters(20.5f, 320, 240);
1078 qm_resolution_->ResetRates();
1079 // Update rates for a sequence of intervals.
1080 int target_rate5[] = {1000, 1000, 1000, 1000, 1000};
1081 int encoder_sent_rate5[] = {1000, 1000, 1000, 1000, 1000};
1082 int incoming_frame_rate5[] = {20, 20, 20, 20, 20};
1083 uint8_t fraction_lost5[] = {10, 10, 10, 10, 10};
1084 UpdateQmRateData(target_rate5, encoder_sent_rate5, incoming_frame_rate5,
1085 fraction_lost5, 5);
1086
1087 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
1088 float scale = (4.0f / 3.0f) / 2.0f;
1089 EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, scale, scale, 2.0f / 3.0f, 480,
1090 360, 30.0f));
1091
1092 qm_resolution_->UpdateCodecParameters(30.0f, 480, 360);
1093 EXPECT_EQ(4, qm_resolution_->GetImageType(480, 360));
1094 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
1095 EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 3.0f / 4.0f, 3.0f / 4.0f, 1.0f,
1096 640, 480, 30.0f));
1097 }
1098
1099 // Multiple down-sampling and up-sample stages, with partial undoing.
1100 // Spatial down-sample 3/4x3/4, followed by temporal down-sample 2/3,
1101 // undo the temporal 2/3, and then undo the spatial.
1102 TEST_F(QmSelectTest, MultipleStagesCheckActionHistory3) {
1103 // Initialize with bitrate, frame rate, native system width/height, and
1104 // number of temporal layers.
1105 InitQmNativeData(100, 30, 640, 480, 1);
1106
1107 // Update with encoder frame size.
1108 uint16_t codec_width = 640;
1109 uint16_t codec_height = 480;
1110 qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height);
1111 EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height));
1112
1113 // Go down 3/4x3/4 spatial.
1114 // Update rates for a sequence of intervals.
1115 int target_rate[] = {100, 100, 100};
1116 int encoder_sent_rate[] = {100, 100, 100};
1117 int incoming_frame_rate[] = {30, 30, 30};
1118 uint8_t fraction_lost[] = {10, 10, 10};
1119 UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate,
1120 fraction_lost, 3);
1121
1122 // Update content: motion level, and 3 spatial prediction errors.
1123 // Medium motion, low spatial.
1124 UpdateQmContentData(kTemporalMedium, kSpatialLow, kSpatialLow, kSpatialLow);
1125 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
1126 EXPECT_EQ(6, qm_resolution_->ComputeContentClass());
1127 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
1128 EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 4.0f / 3.0f, 4.0f / 3.0f, 1.0f,
1129 480, 360, 30.0f));
1130
1131 // Go down 2/3 temporal.
1132 qm_resolution_->UpdateCodecParameters(30.0f, 480, 360);
1133 EXPECT_EQ(4, qm_resolution_->GetImageType(480, 360));
1134 qm_resolution_->ResetRates();
1135 int target_rate2[] = {100, 100, 100, 100, 100};
1136 int encoder_sent_rate2[] = {100, 100, 100, 100, 100};
1137 int incoming_frame_rate2[] = {30, 30, 30, 30, 30};
1138 uint8_t fraction_lost2[] = {10, 10, 10, 10, 10};
1139 UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2,
1140 fraction_lost2, 5);
1141
1142 // Update content: motion level, and 3 spatial prediction errors.
1143 // Low motion, high spatial.
1144 UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh);
1145 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
1146 EXPECT_EQ(1, qm_resolution_->ComputeContentClass());
1147 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
1148 EXPECT_TRUE(
1149 IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.5f, 480, 360, 20.5f));
1150
1151 // Go up 2/3 temporal.
1152 qm_resolution_->UpdateCodecParameters(20.5f, 480, 360);
1153 qm_resolution_->ResetRates();
1154 // Update rates for a sequence of intervals.
1155 int target_rate3[] = {250, 250, 250, 250, 250};
1156 int encoder_sent_rate3[] = {250, 250, 250, 250, 250};
1157 int incoming_frame_rate3[] = {20, 20, 20, 20, 120};
1158 uint8_t fraction_lost3[] = {10, 10, 10, 10, 10};
1159 UpdateQmRateData(target_rate3, encoder_sent_rate3, incoming_frame_rate3,
1160 fraction_lost3, 5);
1161
1162 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
1163 EXPECT_EQ(1, qm_resolution_->ComputeContentClass());
1164 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
1165 EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 2.0f / 3.0f, 480,
1166 360, 30.0f));
1167
1168 // Go up spatial.
1169 qm_resolution_->UpdateCodecParameters(30.0f, 480, 360);
1170 EXPECT_EQ(4, qm_resolution_->GetImageType(480, 360));
1171 qm_resolution_->ResetRates();
1172 int target_rate4[] = {500, 500, 500, 500, 500};
1173 int encoder_sent_rate4[] = {500, 500, 500, 500, 500};
1174 int incoming_frame_rate4[] = {30, 30, 30, 30, 30};
1175 uint8_t fraction_lost4[] = {30, 30, 30, 30, 30};
1176 UpdateQmRateData(target_rate4, encoder_sent_rate4, incoming_frame_rate4,
1177 fraction_lost4, 5);
1178
1179 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
1180 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
1181 EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 3.0f / 4.0f, 3.0f / 4.0f, 1.0f,
1182 640, 480, 30.0f));
1183 }
1184
1185 // Two stages of 3/4x3/4 converted to one stage of 1/2x1/2.
1186 TEST_F(QmSelectTest, ConvertThreeQuartersToOneHalf) {
1187 // Initialize with bitrate, frame rate, native system width/height, and
1188 // number of temporal layers.
1189 InitQmNativeData(150, 30, 640, 480, 1);
1190
1191 // Update with encoder frame size.
1192 uint16_t codec_width = 640;
1193 uint16_t codec_height = 480;
1194 qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height);
1195 EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height));
1196
1197 // Go down 3/4x3/4 spatial.
1198 // Update rates for a sequence of intervals.
1199 int target_rate[] = {150, 150, 150};
1200 int encoder_sent_rate[] = {150, 150, 150};
1201 int incoming_frame_rate[] = {30, 30, 30};
1202 uint8_t fraction_lost[] = {10, 10, 10};
1203 UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate,
1204 fraction_lost, 3);
1205
1206 // Update content: motion level, and 3 spatial prediction errors.
1207 // Medium motion, low spatial.
1208 UpdateQmContentData(kTemporalMedium, kSpatialLow, kSpatialLow, kSpatialLow);
1209 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
1210 EXPECT_EQ(6, qm_resolution_->ComputeContentClass());
1211 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
1212 EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 4.0f / 3.0f, 4.0f / 3.0f, 1.0f,
1213 480, 360, 30.0f));
1214
1215 // Set rates to go down another 3/4 spatial. Should be converted ton 1/2.
1216 qm_resolution_->UpdateCodecParameters(30.0f, 480, 360);
1217 EXPECT_EQ(4, qm_resolution_->GetImageType(480, 360));
1218 qm_resolution_->ResetRates();
1219 int target_rate2[] = {100, 100, 100, 100, 100};
1220 int encoder_sent_rate2[] = {100, 100, 100, 100, 100};
1221 int incoming_frame_rate2[] = {30, 30, 30, 30, 30};
1222 uint8_t fraction_lost2[] = {10, 10, 10, 10, 10};
1223 UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2,
1224 fraction_lost2, 5);
1225
1226 // Update content: motion level, and 3 spatial prediction errors.
1227 // Medium motion, low spatial.
1228 UpdateQmContentData(kTemporalMedium, kSpatialLow, kSpatialLow, kSpatialLow);
1229 EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_));
1230 EXPECT_EQ(6, qm_resolution_->ComputeContentClass());
1231 EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState());
1232 EXPECT_TRUE(
1233 IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 320, 240, 30.0f));
1234 }
1235
1236 void QmSelectTest::InitQmNativeData(float initial_bit_rate,
1237 int user_frame_rate,
1238 int native_width,
1239 int native_height,
1240 int num_layers) {
1241 EXPECT_EQ(
1242 0, qm_resolution_->Initialize(initial_bit_rate, user_frame_rate,
1243 native_width, native_height, num_layers));
1244 }
1245
1246 void QmSelectTest::UpdateQmContentData(float motion_metric,
1247 float spatial_metric,
1248 float spatial_metric_horiz,
1249 float spatial_metric_vert) {
1250 content_metrics_->motion_magnitude = motion_metric;
1251 content_metrics_->spatial_pred_err = spatial_metric;
1252 content_metrics_->spatial_pred_err_h = spatial_metric_horiz;
1253 content_metrics_->spatial_pred_err_v = spatial_metric_vert;
1254 qm_resolution_->UpdateContent(content_metrics_);
1255 }
1256
1257 void QmSelectTest::UpdateQmEncodedFrame(size_t* encoded_size,
1258 size_t num_updates) {
1259 for (size_t i = 0; i < num_updates; ++i) {
1260 // Convert to bytes.
1261 size_t encoded_size_update = 1000 * encoded_size[i] / 8;
1262 qm_resolution_->UpdateEncodedSize(encoded_size_update);
1263 }
1264 }
1265
1266 void QmSelectTest::UpdateQmRateData(int* target_rate,
1267 int* encoder_sent_rate,
1268 int* incoming_frame_rate,
1269 uint8_t* fraction_lost,
1270 int num_updates) {
1271 for (int i = 0; i < num_updates; ++i) {
1272 float target_rate_update = target_rate[i];
1273 float encoder_sent_rate_update = encoder_sent_rate[i];
1274 float incoming_frame_rate_update = incoming_frame_rate[i];
1275 uint8_t fraction_lost_update = fraction_lost[i];
1276 qm_resolution_->UpdateRates(target_rate_update, encoder_sent_rate_update,
1277 incoming_frame_rate_update,
1278 fraction_lost_update);
1279 }
1280 }
1281
1282 // Check is the selected action from the QmResolution class is the same
1283 // as the expected scales from |fac_width|, |fac_height|, |fac_temp|.
1284 bool QmSelectTest::IsSelectedActionCorrect(VCMResolutionScale* qm_scale,
1285 float fac_width,
1286 float fac_height,
1287 float fac_temp,
1288 uint16_t new_width,
1289 uint16_t new_height,
1290 float new_frame_rate) {
1291 if (qm_scale->spatial_width_fact == fac_width &&
1292 qm_scale->spatial_height_fact == fac_height &&
1293 qm_scale->temporal_fact == fac_temp &&
1294 qm_scale->codec_width == new_width &&
1295 qm_scale->codec_height == new_height &&
1296 qm_scale->frame_rate == new_frame_rate) {
1297 return true;
1298 } else {
1299 return false;
1300 }
1301 }
1302 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/qm_select_data.h ('k') | webrtc/modules/video_coding/video_coding.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698