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