ratectrl_rtc_test.cc (26443B)
1 /* 2 * Copyright (c) 2021, Alliance for Open Media. All rights reserved. 3 * 4 * This source code is subject to the terms of the BSD 2 Clause License and 5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License 6 * was not distributed with this source code in the LICENSE file, you can 7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open 8 * Media Patent License 1.0 was not distributed with this source code in the 9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent. 10 */ 11 12 #include "av1/ratectrl_rtc.h" 13 14 #include <memory> 15 16 #include "gtest/gtest.h" 17 #include "test/codec_factory.h" 18 #include "test/encode_test_driver.h" 19 #include "test/i420_video_source.h" 20 #include "test/util.h" 21 22 namespace { 23 24 constexpr size_t kNumFrames = 450; 25 26 const int kTemporalId3Layer[4] = { 0, 2, 1, 2 }; 27 const int kTemporalId2Layer[2] = { 0, 1 }; 28 const int kTemporalRateAllocation3Layer[3] = { 50, 70, 100 }; 29 const int kTemporalRateAllocation2Layer[2] = { 60, 100 }; 30 const int kSpatialLayerBitrate[3] = { 200, 500, 900 }; 31 32 // Parameter: aq mode: 0 and 3 33 class RcInterfaceTest : public ::libaom_test::EncoderTest, 34 public ::libaom_test::CodecTestWithParam<int> { 35 public: 36 RcInterfaceTest() 37 : EncoderTest(GET_PARAM(0)), aq_mode_(GET_PARAM(1)), key_interval_(3000), 38 encoder_exit_(false), layer_frame_cnt_(0), superframe_cnt_(0), 39 frame_cnt_(0), dynamic_temporal_layers_(false), 40 dynamic_spatial_layers_(false), num_drops_(0), max_consec_drop_ms_(0), 41 frame_drop_thresh_(0) { 42 memset(&svc_params_, 0, sizeof(svc_params_)); 43 memset(&layer_id_, 0, sizeof(layer_id_)); 44 } 45 46 ~RcInterfaceTest() override = default; 47 48 protected: 49 void SetUp() override { InitializeConfig(::libaom_test::kRealTime); } 50 51 int GetNumSpatialLayers() override { return rc_cfg_.ss_number_layers; } 52 53 void PreEncodeFrameHook(libaom_test::VideoSource *video, 54 libaom_test::Encoder *encoder) override { 55 int key_int = key_interval_; 56 const int use_svc = 57 rc_cfg_.ss_number_layers > 1 || rc_cfg_.ts_number_layers > 1; 58 encoder->Control(AV1E_SET_RTC_EXTERNAL_RC, 1); 59 if (video->frame() == 0 && layer_frame_cnt_ == 0) { 60 encoder->Control(AOME_SET_CPUUSED, 7); 61 encoder->Control(AV1E_SET_AQ_MODE, aq_mode_); 62 encoder->Control(AV1E_SET_ENABLE_ORDER_HINT, 0); 63 if (rc_cfg_.is_screen) { 64 encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_SCREEN); 65 } else { 66 encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_DEFAULT); 67 } 68 encoder->Control(AOME_SET_MAX_INTRA_BITRATE_PCT, 69 rc_cfg_.max_intra_bitrate_pct); 70 if (use_svc) encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_); 71 encoder->Control(AV1E_SET_MAX_CONSEC_FRAME_DROP_MS_CBR, 72 max_consec_drop_ms_); 73 } 74 // SVC specific settings 75 if (use_svc) { 76 frame_params_.spatial_layer_id = 77 layer_frame_cnt_ % rc_cfg_.ss_number_layers; 78 if (rc_cfg_.ts_number_layers == 3) 79 frame_params_.temporal_layer_id = 80 kTemporalId3Layer[superframe_cnt_ % 4]; 81 else if (rc_cfg_.ts_number_layers == 2) 82 frame_params_.temporal_layer_id = 83 kTemporalId2Layer[superframe_cnt_ % 2]; 84 else 85 frame_params_.temporal_layer_id = 0; 86 layer_id_.spatial_layer_id = frame_params_.spatial_layer_id; 87 layer_id_.temporal_layer_id = frame_params_.temporal_layer_id; 88 encoder->Control(AV1E_SET_SVC_LAYER_ID, &layer_id_); 89 key_int = key_interval_ * rc_cfg_.ss_number_layers; 90 } 91 frame_params_.frame_type = 92 layer_frame_cnt_ % key_int == 0 ? aom::kKeyFrame : aom::kInterFrame; 93 encoder_exit_ = video->frame() == kNumFrames; 94 frame_flags_ = 0; 95 96 if (dynamic_temporal_layers_) { 97 if (superframe_cnt_ == 100 && layer_id_.spatial_layer_id == 0) { 98 // Go down to 2 temporal layers. 99 SetConfigSvc(3, 2); 100 encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_); 101 frame_flags_ = AOM_EFLAG_FORCE_KF; 102 frame_params_.frame_type = aom::kKeyFrame; 103 ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_)); 104 } else if (superframe_cnt_ == 200 && layer_id_.spatial_layer_id == 0) { 105 // Go down to 1 temporal layer. 106 SetConfigSvc(3, 1); 107 encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_); 108 frame_flags_ = AOM_EFLAG_FORCE_KF; 109 frame_params_.frame_type = aom::kKeyFrame; 110 ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_)); 111 } else if (superframe_cnt_ == 300 && layer_id_.spatial_layer_id == 0) { 112 // Go back up to 3 temporal layers. 113 SetConfigSvc(3, 3); 114 frame_flags_ = AOM_EFLAG_FORCE_KF; 115 frame_params_.frame_type = aom::kKeyFrame; 116 encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_); 117 ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_)); 118 } 119 } else if (dynamic_spatial_layers_) { 120 // In this example the #spatial layers is modified on the fly, 121 // so we go from (120p,240p,480p) to (240p,480p), etc. 122 if (superframe_cnt_ == 100 && layer_id_.spatial_layer_id == 0) { 123 // Change to 2 spatial layers (240p, 480p). 124 SetConfigSvc(2, 3); 125 encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_); 126 frame_flags_ = AOM_EFLAG_FORCE_KF; 127 frame_params_.frame_type = aom::kKeyFrame; 128 ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_)); 129 } else if (superframe_cnt_ == 200 && layer_id_.spatial_layer_id == 0) { 130 // Change to 1 spatial layer (480p). 131 SetConfigSvc(1, 3); 132 encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_); 133 frame_flags_ = AOM_EFLAG_FORCE_KF; 134 frame_params_.frame_type = aom::kKeyFrame; 135 ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_)); 136 } else if (superframe_cnt_ == 300 && layer_id_.spatial_layer_id == 0) { 137 // Go back to 3 spatial layers (120p, 240p, 480p). 138 SetConfigSvc(3, 3); 139 encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_); 140 // In the fixed SVC mode (which is what is used in this test): 141 // Key frame is required here on SL0 since 120p will try to predict 142 // from LAST which was the 480p, so decoder will throw an error 143 // (reference must be smaller than 4x4). In the flexible mode 144 // (not used here) we can set the frame flags to predict off the 2x2 145 // reference instead, 146 frame_flags_ = AOM_EFLAG_FORCE_KF; 147 frame_params_.frame_type = aom::kKeyFrame; 148 ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_)); 149 } 150 } 151 // TODO(marpan): Add dynamic spatial layers based on 0 layer bitrate. 152 // That is actual usage in SW where configuration (#spatial, #temporal) 153 // layers is fixed, but top layer is dropped or re-enabled based on 154 // bitrate. This requires external RC to handle dropped (zero-size) frames. 155 } 156 157 void PostEncodeFrameHook(::libaom_test::Encoder *encoder) override { 158 if (encoder_exit_) { 159 return; 160 } 161 int num_operating_points; 162 encoder->Control(AV1E_GET_NUM_OPERATING_POINTS, &num_operating_points); 163 ASSERT_EQ(num_operating_points, 164 rc_cfg_.ss_number_layers * rc_cfg_.ts_number_layers); 165 layer_frame_cnt_++; 166 frame_cnt_++; 167 if (layer_id_.spatial_layer_id == rc_cfg_.ss_number_layers - 1) 168 superframe_cnt_++; 169 int qp; 170 encoder->Control(AOME_GET_LAST_QUANTIZER, &qp); 171 if (rc_api_->ComputeQP(frame_params_) == aom::kFrameDropDecisionOk) { 172 ASSERT_EQ(rc_api_->GetQP(), qp) << "at frame " << frame_cnt_ - 1; 173 int encoder_lpf_level; 174 encoder->Control(AOME_GET_LOOPFILTER_LEVEL, &encoder_lpf_level); 175 aom::AV1LoopfilterLevel loopfilter_level = rc_api_->GetLoopfilterLevel(); 176 ASSERT_EQ(loopfilter_level.filter_level[0], encoder_lpf_level); 177 aom::AV1CdefInfo cdef_level = rc_api_->GetCdefInfo(); 178 int cdef_y_strengths[16]; 179 encoder->Control(AV1E_GET_LUMA_CDEF_STRENGTH, cdef_y_strengths); 180 ASSERT_EQ(cdef_level.cdef_strength_y, cdef_y_strengths[0]); 181 } else { 182 num_drops_++; 183 } 184 } 185 186 void FramePktHook(const aom_codec_cx_pkt_t *pkt) override { 187 if (layer_id_.spatial_layer_id == 0) 188 rc_api_->PostEncodeUpdate(pkt->data.frame.sz - 2); 189 else 190 rc_api_->PostEncodeUpdate(pkt->data.frame.sz); 191 } 192 193 void MismatchHook(const aom_image_t *img1, const aom_image_t *img2) override { 194 (void)img1; 195 (void)img2; 196 } 197 198 void RunOneLayer() { 199 key_interval_ = 10000; 200 SetConfig(); 201 rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_); 202 frame_params_.spatial_layer_id = 0; 203 frame_params_.temporal_layer_id = 0; 204 205 ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 206 1, 0, kNumFrames); 207 208 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 209 } 210 211 void RunOneLayerScreen() { 212 key_interval_ = 10000; 213 SetConfig(); 214 rc_cfg_.is_screen = true; 215 rc_cfg_.width = 352; 216 rc_cfg_.height = 288; 217 rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_); 218 frame_params_.spatial_layer_id = 0; 219 frame_params_.temporal_layer_id = 0; 220 221 ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 222 288, 30, 1, 0, 140); 223 224 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 225 } 226 227 void RunOneLayerDropFramesCBR() { 228 key_interval_ = 10000; 229 max_consec_drop_ms_ = 250; 230 frame_drop_thresh_ = 30; 231 SetConfig(); 232 rc_cfg_.target_bandwidth = 100; 233 cfg_.rc_target_bitrate = 100; 234 rc_cfg_.max_quantizer = 50; 235 cfg_.rc_max_quantizer = 50; 236 rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_); 237 frame_params_.spatial_layer_id = 0; 238 frame_params_.temporal_layer_id = 0; 239 240 ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 241 1, 0, kNumFrames); 242 243 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 244 // Check that some frames were dropped, otherwise test has no value. 245 ASSERT_GE(num_drops_, 1); 246 } 247 248 void RunOneLayerPeriodicKey() { 249 key_interval_ = 100; 250 SetConfig(); 251 rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_); 252 frame_params_.spatial_layer_id = 0; 253 frame_params_.temporal_layer_id = 0; 254 255 ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 256 1, 0, kNumFrames); 257 258 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 259 } 260 261 void RunSvc() { 262 key_interval_ = 10000; 263 SetConfigSvc(3, 3); 264 rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_); 265 frame_params_.spatial_layer_id = 0; 266 frame_params_.temporal_layer_id = 0; 267 268 ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 269 1, 0, kNumFrames); 270 271 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 272 } 273 274 void RunSvcPeriodicKey() { 275 key_interval_ = 100; 276 SetConfigSvc(3, 3); 277 rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_); 278 frame_params_.spatial_layer_id = 0; 279 frame_params_.temporal_layer_id = 0; 280 281 ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 282 1, 0, kNumFrames); 283 284 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 285 } 286 287 void RunSvcDynamicTemporal() { 288 dynamic_temporal_layers_ = true; 289 key_interval_ = 10000; 290 SetConfigSvc(3, 3); 291 rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_); 292 frame_params_.spatial_layer_id = 0; 293 frame_params_.temporal_layer_id = 0; 294 295 ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 296 1, 0, kNumFrames); 297 298 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 299 } 300 301 void RunSvcDynamicSpatial() { 302 dynamic_spatial_layers_ = true; 303 key_interval_ = 10000; 304 SetConfigSvc(3, 3); 305 rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_); 306 frame_params_.spatial_layer_id = 0; 307 frame_params_.temporal_layer_id = 0; 308 309 ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 310 1, 0, kNumFrames); 311 312 ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); 313 } 314 315 private: 316 void SetConfig() { 317 rc_cfg_.width = 640; 318 rc_cfg_.height = 480; 319 rc_cfg_.max_quantizer = 52; 320 rc_cfg_.min_quantizer = 2; 321 rc_cfg_.target_bandwidth = 1000; 322 rc_cfg_.buf_initial_sz = 600; 323 rc_cfg_.buf_optimal_sz = 600; 324 rc_cfg_.buf_sz = 1000; 325 rc_cfg_.undershoot_pct = 50; 326 rc_cfg_.overshoot_pct = 50; 327 rc_cfg_.max_intra_bitrate_pct = 1000; 328 rc_cfg_.framerate = 30.0; 329 rc_cfg_.ss_number_layers = 1; 330 rc_cfg_.ts_number_layers = 1; 331 rc_cfg_.scaling_factor_num[0] = 1; 332 rc_cfg_.scaling_factor_den[0] = 1; 333 rc_cfg_.layer_target_bitrate[0] = 1000; 334 rc_cfg_.max_quantizers[0] = 52; 335 rc_cfg_.min_quantizers[0] = 2; 336 rc_cfg_.aq_mode = aq_mode_; 337 rc_cfg_.frame_drop_thresh = frame_drop_thresh_; 338 rc_cfg_.max_consec_drop_ms = max_consec_drop_ms_; 339 340 // Encoder settings for ground truth. 341 cfg_.g_w = 640; 342 cfg_.g_h = 480; 343 cfg_.rc_undershoot_pct = 50; 344 cfg_.rc_overshoot_pct = 50; 345 cfg_.rc_buf_initial_sz = 600; 346 cfg_.rc_buf_optimal_sz = 600; 347 cfg_.rc_buf_sz = 1000; 348 cfg_.rc_dropframe_thresh = 0; 349 cfg_.rc_min_quantizer = 2; 350 cfg_.rc_max_quantizer = 52; 351 cfg_.rc_end_usage = AOM_CBR; 352 cfg_.g_lag_in_frames = 0; 353 cfg_.g_error_resilient = 0; 354 cfg_.rc_target_bitrate = 1000; 355 cfg_.kf_min_dist = key_interval_; 356 cfg_.kf_max_dist = key_interval_; 357 cfg_.rc_dropframe_thresh = frame_drop_thresh_; 358 } 359 360 void SetConfigSvc(int number_spatial_layers, int number_temporal_layers) { 361 rc_cfg_.width = 640; 362 rc_cfg_.height = 480; 363 rc_cfg_.max_quantizer = 56; 364 rc_cfg_.min_quantizer = 2; 365 rc_cfg_.buf_initial_sz = 600; 366 rc_cfg_.buf_optimal_sz = 600; 367 rc_cfg_.buf_sz = 1000; 368 rc_cfg_.undershoot_pct = 50; 369 rc_cfg_.overshoot_pct = 50; 370 rc_cfg_.max_intra_bitrate_pct = 1000; 371 rc_cfg_.framerate = 30.0; 372 rc_cfg_.aq_mode = aq_mode_; 373 rc_cfg_.ss_number_layers = number_spatial_layers; 374 rc_cfg_.ts_number_layers = number_temporal_layers; 375 376 // Encoder settings for ground truth. 377 cfg_.g_w = 640; 378 cfg_.g_h = 480; 379 cfg_.rc_max_quantizer = 56; 380 cfg_.rc_min_quantizer = 2; 381 cfg_.rc_buf_initial_sz = 600; 382 cfg_.rc_buf_optimal_sz = 600; 383 cfg_.rc_buf_sz = 1000; 384 cfg_.rc_overshoot_pct = 50; 385 cfg_.rc_undershoot_pct = 50; 386 cfg_.g_threads = 1; 387 cfg_.kf_min_dist = key_interval_; 388 cfg_.kf_max_dist = key_interval_; 389 cfg_.g_timebase.num = 1; 390 cfg_.g_timebase.den = 30; 391 cfg_.rc_end_usage = AOM_CBR; 392 cfg_.g_lag_in_frames = 0; 393 cfg_.g_error_resilient = 0; 394 svc_params_.number_spatial_layers = number_spatial_layers; 395 svc_params_.number_temporal_layers = number_temporal_layers; 396 397 // Scale factors. 398 if (number_spatial_layers == 3) { 399 rc_cfg_.scaling_factor_num[0] = 1; 400 rc_cfg_.scaling_factor_den[0] = 4; 401 rc_cfg_.scaling_factor_num[1] = 2; 402 rc_cfg_.scaling_factor_den[1] = 4; 403 rc_cfg_.scaling_factor_num[2] = 4; 404 rc_cfg_.scaling_factor_den[2] = 4; 405 svc_params_.scaling_factor_num[0] = 1; 406 svc_params_.scaling_factor_den[0] = 4; 407 svc_params_.scaling_factor_num[1] = 2; 408 svc_params_.scaling_factor_den[1] = 4; 409 svc_params_.scaling_factor_num[2] = 4; 410 svc_params_.scaling_factor_den[2] = 4; 411 } else if (number_spatial_layers == 2) { 412 rc_cfg_.scaling_factor_num[0] = 1; 413 rc_cfg_.scaling_factor_den[0] = 2; 414 rc_cfg_.scaling_factor_num[1] = 2; 415 rc_cfg_.scaling_factor_den[1] = 2; 416 svc_params_.scaling_factor_num[0] = 1; 417 svc_params_.scaling_factor_den[0] = 2; 418 svc_params_.scaling_factor_num[1] = 2; 419 svc_params_.scaling_factor_den[1] = 2; 420 } else if (number_spatial_layers == 1) { 421 rc_cfg_.scaling_factor_num[0] = 1; 422 rc_cfg_.scaling_factor_den[0] = 1; 423 svc_params_.scaling_factor_num[0] = 1; 424 svc_params_.scaling_factor_den[0] = 1; 425 } 426 427 // TS rate decimator. 428 if (number_temporal_layers == 3) { 429 rc_cfg_.ts_rate_decimator[0] = 4; 430 rc_cfg_.ts_rate_decimator[1] = 2; 431 rc_cfg_.ts_rate_decimator[2] = 1; 432 svc_params_.framerate_factor[0] = 4; 433 svc_params_.framerate_factor[1] = 2; 434 svc_params_.framerate_factor[2] = 1; 435 } else if (number_temporal_layers == 2) { 436 rc_cfg_.ts_rate_decimator[0] = 2; 437 rc_cfg_.ts_rate_decimator[1] = 1; 438 svc_params_.framerate_factor[0] = 2; 439 svc_params_.framerate_factor[1] = 1; 440 } else if (number_temporal_layers == 1) { 441 rc_cfg_.ts_rate_decimator[0] = 1; 442 svc_params_.framerate_factor[0] = 1; 443 } 444 445 // Bitate. 446 rc_cfg_.target_bandwidth = 0; 447 cfg_.rc_target_bitrate = 0; 448 for (int sl = 0; sl < number_spatial_layers; sl++) { 449 int spatial_bitrate = 0; 450 if (number_spatial_layers <= 3) 451 spatial_bitrate = kSpatialLayerBitrate[sl]; 452 for (int tl = 0; tl < number_temporal_layers; tl++) { 453 int layer = sl * number_temporal_layers + tl; 454 if (number_temporal_layers == 3) { 455 rc_cfg_.layer_target_bitrate[layer] = 456 kTemporalRateAllocation3Layer[tl] * spatial_bitrate / 100; 457 svc_params_.layer_target_bitrate[layer] = 458 kTemporalRateAllocation3Layer[tl] * spatial_bitrate / 100; 459 } else if (number_temporal_layers == 2) { 460 rc_cfg_.layer_target_bitrate[layer] = 461 kTemporalRateAllocation2Layer[tl] * spatial_bitrate / 100; 462 svc_params_.layer_target_bitrate[layer] = 463 kTemporalRateAllocation2Layer[tl] * spatial_bitrate / 100; 464 } else if (number_temporal_layers == 1) { 465 rc_cfg_.layer_target_bitrate[layer] = spatial_bitrate; 466 svc_params_.layer_target_bitrate[layer] = spatial_bitrate; 467 } 468 } 469 rc_cfg_.target_bandwidth += spatial_bitrate; 470 cfg_.rc_target_bitrate += spatial_bitrate; 471 } 472 473 // Layer min/max quantizer. 474 for (int sl = 0; sl < number_spatial_layers; ++sl) { 475 for (int tl = 0; tl < number_temporal_layers; ++tl) { 476 const int i = sl * number_temporal_layers + tl; 477 rc_cfg_.max_quantizers[i] = rc_cfg_.max_quantizer; 478 rc_cfg_.min_quantizers[i] = rc_cfg_.min_quantizer; 479 svc_params_.max_quantizers[i] = cfg_.rc_max_quantizer; 480 svc_params_.min_quantizers[i] = cfg_.rc_min_quantizer; 481 } 482 } 483 } 484 485 std::unique_ptr<aom::AV1RateControlRTC> rc_api_; 486 aom::AV1RateControlRtcConfig rc_cfg_; 487 int aq_mode_; 488 int key_interval_; 489 aom::AV1FrameParamsRTC frame_params_; 490 bool encoder_exit_; 491 aom_svc_params_t svc_params_; 492 aom_svc_layer_id_t layer_id_; 493 int layer_frame_cnt_; 494 int superframe_cnt_; 495 int frame_cnt_; 496 bool dynamic_temporal_layers_; 497 bool dynamic_spatial_layers_; 498 int num_drops_; 499 int max_consec_drop_ms_; 500 int frame_drop_thresh_; 501 }; 502 503 class RcExternMethodsInterfaceTest 504 : public ::libaom_test::EncoderTest, 505 public ::libaom_test::CodecTestWithParam<int> { 506 public: 507 RcExternMethodsInterfaceTest() 508 : EncoderTest(GET_PARAM(0)), aq_mode_(GET_PARAM(1)) { 509 SetConfig(); 510 } 511 ~RcExternMethodsInterfaceTest() = default; 512 513 // Test APIS 514 void TestCreateRateControl(); 515 void TestUpdateRateControl(); 516 void TestGetLoopFilterLevelRateControl(); 517 void TestPostEncodeUpdateRateControl(); 518 void TestGetQPRateControl(); 519 void TestComputeQPRateControl(); 520 void TestGetSegmentationDataRateControl(); 521 void TestGetCdefInfoRateControl(); 522 void TestCreateRateControlConfig(); 523 void TestDestroyRateControlRTC(); 524 void SetConfig(); 525 526 private: 527 aom::AV1RateControlRtcConfig rc_cfg_; 528 int aq_mode_; 529 aom::AV1FrameParamsRTC frame_params_; 530 }; 531 532 void RcExternMethodsInterfaceTest::SetConfig() { 533 rc_cfg_.width = 640; 534 rc_cfg_.height = 480; 535 rc_cfg_.max_quantizer = 52; 536 rc_cfg_.min_quantizer = 2; 537 rc_cfg_.target_bandwidth = 1000; 538 rc_cfg_.buf_initial_sz = 600; 539 rc_cfg_.buf_optimal_sz = 600; 540 rc_cfg_.buf_sz = 1000; 541 rc_cfg_.undershoot_pct = 50; 542 rc_cfg_.overshoot_pct = 50; 543 rc_cfg_.max_intra_bitrate_pct = 1000; 544 rc_cfg_.framerate = 30.0; 545 rc_cfg_.ss_number_layers = 1; 546 rc_cfg_.ts_number_layers = 1; 547 rc_cfg_.scaling_factor_num[0] = 1; 548 rc_cfg_.scaling_factor_den[0] = 1; 549 rc_cfg_.layer_target_bitrate[0] = 1000; 550 rc_cfg_.max_quantizers[0] = 52; 551 rc_cfg_.min_quantizers[0] = 2; 552 rc_cfg_.aq_mode = aq_mode_; 553 } 554 555 void RcExternMethodsInterfaceTest::TestCreateRateControl() { 556 AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_); 557 558 ASSERT_NE(controller, nullptr); 559 560 av1_ratecontrol_rtc_destroy(controller); 561 } 562 563 void RcExternMethodsInterfaceTest::TestUpdateRateControl() { 564 AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_); 565 566 ASSERT_NE(controller, nullptr); 567 568 ASSERT_TRUE(av1_ratecontrol_rtc_update(controller, &rc_cfg_)); 569 570 av1_ratecontrol_rtc_destroy(controller); 571 } 572 573 void RcExternMethodsInterfaceTest::TestGetQPRateControl() { 574 frame_params_.spatial_layer_id = 0; 575 frame_params_.temporal_layer_id = 0; 576 frame_params_.frame_type = kAomKeyFrame; 577 578 AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_); 579 ASSERT_NE(controller, nullptr); 580 581 const AomFrameDropDecision decision = 582 av1_ratecontrol_rtc_compute_qp(controller, &frame_params_); 583 if (decision == kAomFrameDropDecisionOk) { 584 int qp = av1_ratecontrol_rtc_get_qp(controller); 585 ASSERT_NE(qp, 0); // 0 is invalid for qp 586 } 587 av1_ratecontrol_rtc_destroy(controller); 588 } 589 590 void RcExternMethodsInterfaceTest::TestComputeQPRateControl() { 591 frame_params_.spatial_layer_id = 0; 592 frame_params_.temporal_layer_id = 0; 593 frame_params_.frame_type = kAomKeyFrame; 594 595 AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_); 596 ASSERT_NE(controller, nullptr); 597 598 const AomFrameDropDecision decision = 599 av1_ratecontrol_rtc_compute_qp(controller, &frame_params_); 600 ASSERT_EQ(decision, kAomFrameDropDecisionOk); 601 av1_ratecontrol_rtc_destroy(controller); 602 } 603 604 void RcExternMethodsInterfaceTest::TestGetLoopFilterLevelRateControl() { 605 AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_); 606 ASSERT_NE(controller, nullptr); 607 608 AomAV1LoopfilterLevel lpf_level; 609 lpf_level.filter_level[0] = 0xfdbd; 610 lpf_level.filter_level[1] = 0xfdbd; 611 lpf_level.filter_level_u = 0xfdbd; 612 lpf_level.filter_level_v = 0xfdbd; 613 614 lpf_level = av1_ratecontrol_rtc_get_loop_filter_level(controller); 615 616 ASSERT_NE(lpf_level.filter_level[0], 0xfdbd); 617 ASSERT_NE(lpf_level.filter_level[1], 0xfdbd); 618 ASSERT_NE(lpf_level.filter_level_u, 0xfdbd); 619 ASSERT_NE(lpf_level.filter_level_v, 0xfdbd); 620 621 av1_ratecontrol_rtc_destroy(controller); 622 } 623 624 void RcExternMethodsInterfaceTest::TestPostEncodeUpdateRateControl() { 625 AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_); 626 ASSERT_NE(controller, nullptr); 627 av1_ratecontrol_rtc_post_encode_update(controller, 380); 628 av1_ratecontrol_rtc_destroy(controller); 629 } 630 631 void RcExternMethodsInterfaceTest::TestGetSegmentationDataRateControl() { 632 rc_cfg_.aq_mode = 1; // VARIANCE_AQ = 1 633 AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_); 634 ASSERT_NE(controller, nullptr); 635 AomAV1SegmentationData segmentation_data; 636 // This should return false as this test case doesn't run any part of the 637 // underlying rate control, and cyclic refresh will not be turned on. 638 ASSERT_FALSE( 639 av1_ratecontrol_rtc_get_segmentation(controller, &segmentation_data)); 640 av1_ratecontrol_rtc_destroy(controller); 641 } 642 643 void RcExternMethodsInterfaceTest::TestGetCdefInfoRateControl() { 644 AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_); 645 ASSERT_NE(controller, nullptr); 646 AomAV1CdefInfo cdef_level; 647 cdef_level.cdef_strength_y = 0xabcd; 648 cdef_level.cdef_strength_uv = 0xabcd; 649 cdef_level.damping = 0xabcd; 650 cdef_level = av1_ratecontrol_rtc_get_cdef_info(controller); 651 652 ASSERT_NE(cdef_level.cdef_strength_y, 0xabcd); 653 ASSERT_NE(cdef_level.cdef_strength_uv, 0xabcd); 654 ASSERT_NE(cdef_level.damping, 0xabcd); 655 656 av1_ratecontrol_rtc_destroy(controller); 657 } 658 659 void RcExternMethodsInterfaceTest::TestCreateRateControlConfig() { 660 AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_); 661 ASSERT_NE(controller, nullptr); 662 663 AomAV1RateControlRtcConfig config; 664 av1_ratecontrol_rtc_init_ratecontrol_config(&config); 665 ASSERT_EQ(config.width, 1280); 666 ASSERT_EQ(config.height, 720); 667 // only width and height is checked. can be extended 668 669 av1_ratecontrol_rtc_destroy(controller); 670 } 671 672 void RcExternMethodsInterfaceTest::TestDestroyRateControlRTC() { 673 AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_); 674 ASSERT_NE(controller, nullptr); 675 676 av1_ratecontrol_rtc_destroy(controller); 677 } 678 679 TEST_P(RcInterfaceTest, OneLayer) { RunOneLayer(); } 680 681 TEST_P(RcInterfaceTest, OneLayerDropFramesCBR) { RunOneLayerDropFramesCBR(); } 682 683 TEST_P(RcInterfaceTest, OneLayerPeriodicKey) { RunOneLayerPeriodicKey(); } 684 685 TEST_P(RcInterfaceTest, OneLayerScreen) { RunOneLayerScreen(); } 686 687 TEST_P(RcInterfaceTest, Svc) { RunSvc(); } 688 689 TEST_P(RcInterfaceTest, SvcPeriodicKey) { RunSvcPeriodicKey(); } 690 691 TEST_P(RcInterfaceTest, SvcDynamicTemporal) { RunSvcDynamicTemporal(); } 692 693 TEST_P(RcInterfaceTest, SvcDynamicSpatial) { RunSvcDynamicSpatial(); } 694 695 TEST_P(RcExternMethodsInterfaceTest, CreateRateControlTest) { 696 TestCreateRateControl(); 697 } 698 699 TEST_P(RcExternMethodsInterfaceTest, UpdateRateControllerTest) { 700 TestUpdateRateControl(); 701 } 702 703 TEST_P(RcExternMethodsInterfaceTest, GetQpRateControllerTest) { 704 TestGetQPRateControl(); 705 } 706 707 TEST_P(RcExternMethodsInterfaceTest, ComputeQPRateControllerTest) { 708 TestComputeQPRateControl(); 709 } 710 711 TEST_P(RcExternMethodsInterfaceTest, GetLoopFilterLevelRateControllerTest) { 712 TestGetLoopFilterLevelRateControl(); 713 } 714 715 TEST_P(RcExternMethodsInterfaceTest, PostEncodeUpdateRateControllerTest) { 716 TestPostEncodeUpdateRateControl(); 717 } 718 719 TEST_P(RcExternMethodsInterfaceTest, GetSegmenationDataRateControllerTest) { 720 TestGetSegmentationDataRateControl(); 721 } 722 723 TEST_P(RcExternMethodsInterfaceTest, GetCdedInfoRateControllerTest) { 724 TestGetCdefInfoRateControl(); 725 } 726 727 TEST_P(RcExternMethodsInterfaceTest, CreateRateControlConfigTest) { 728 TestCreateRateControlConfig(); 729 } 730 731 TEST_P(RcExternMethodsInterfaceTest, DestroyRateControlRTCTest) { 732 TestDestroyRateControlRTC(); 733 } 734 735 AV1_INSTANTIATE_TEST_SUITE(RcInterfaceTest, ::testing::Values(0, 3)); 736 AV1_INSTANTIATE_TEST_SUITE(RcExternMethodsInterfaceTest, 737 ::testing::Values(0, 3)); 738 739 } // namespace