rtc: Add tests for dynamically disabling layers Add datarate tests for dynamically disabling and enabling spatial enhancement layer. Also add condition that avg_frame_motion is > 0 when used, since when dropping the top spatial from first frame, it will stay at 0. And somes fixes to the SVC tests: remove aq-mode=1,2 from the SVC tests as RTC does not use those modes, and only set the initial controls on the very first frame (not for all frames within superframe). Change-Id: I3fb7224f05c04347a913ec2a2ac8a8b58d657aa6
diff --git a/av1/encoder/aq_cyclicrefresh.c b/av1/encoder/aq_cyclicrefresh.c index cc97802..5fb8943 100644 --- a/av1/encoder/aq_cyclicrefresh.c +++ b/av1/encoder/aq_cyclicrefresh.c
@@ -408,7 +408,8 @@ cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame) || (rc->frames_since_key > 20 && p_rc->avg_frame_qindex[INTER_FRAME] > qp_max_thresh) || - (rc->avg_frame_low_motion < 45 && rc->frames_since_key > 40)) { + (rc->avg_frame_low_motion && rc->avg_frame_low_motion < 45 && + rc->frames_since_key > 40)) { cr->apply_cyclic_refresh = 0; return; }
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c index 9ee0c3a..fa13bc4 100644 --- a/av1/encoder/ratectrl.c +++ b/av1/encoder/ratectrl.c
@@ -2361,7 +2361,7 @@ gf_update_changed = 1; } else if (allow_gf_update && ((cm->quant_params.base_qindex < thresh * avg_qp / 100) || - (rc->avg_frame_low_motion < 20))) { + (rc->avg_frame_low_motion && rc->avg_frame_low_motion < 20))) { // Force refresh since QP is well below average QP or this is a high // motion frame. svc->refresh[svc->gld_idx_1layer] = 1;
diff --git a/test/svc_datarate_test.cc b/test/svc_datarate_test.cc index 243fcc1..0fc6510 100644 --- a/test/svc_datarate_test.cc +++ b/test/svc_datarate_test.cc
@@ -83,14 +83,22 @@ multi_ref_ = 0; use_fixed_mode_svc_ = 0; comp_pred_ = 0; + dynamic_enable_disable_mode_ = 0; } virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, ::libaom_test::Encoder *encoder) { int spatial_layer_id = 0; - if (video->frame() == 0) { + // video->frame() is called every superframe, so we should condition + // this on layer_frame_cnt_ = 0, so we only do this once on the very + // first frame. + if (video->frame() == 0 && layer_frame_cnt_ == 0) { initialize_svc(number_temporal_layers_, number_spatial_layers_, &svc_params_); + if (dynamic_enable_disable_mode_ == 1) { + svc_params_.layer_target_bitrate[2] = 0; + cfg_.rc_target_bitrate -= target_layer_bitrate_[2]; + } encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_); // TODO(aomedia:3032): Configure KSVC in fixed mode. encoder->Control(AV1E_SET_ENABLE_ORDER_HINT, 0); @@ -125,6 +133,29 @@ (layer_id_.spatial_layer_id > 0 || layer_id_.temporal_layer_id > 0); encoder->Control(AV1E_SET_ERROR_RESILIENT_MODE, mode); } + if (dynamic_enable_disable_mode_ == 1) { + if (layer_frame_cnt_ == 300 && spatial_layer_id == 0) { + // Enable: set top spatial layer bitrate back to non-zero. + svc_params_.layer_target_bitrate[2] = target_layer_bitrate_[2]; + cfg_.rc_target_bitrate += target_layer_bitrate_[2]; + encoder->Config(&cfg_); + encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_); + } + } else if (dynamic_enable_disable_mode_ == 2) { + if (layer_frame_cnt_ == 300 && spatial_layer_id == 0) { + // Disable top spatial layer mid-stream. + svc_params_.layer_target_bitrate[2] = 0; + cfg_.rc_target_bitrate -= target_layer_bitrate_[2]; + encoder->Config(&cfg_); + encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_); + } else if (layer_frame_cnt_ == 600 && spatial_layer_id == 0) { + // Enable top spatial layer mid-stream. + svc_params_.layer_target_bitrate[2] = target_layer_bitrate_[2]; + cfg_.rc_target_bitrate += target_layer_bitrate_[2]; + encoder->Config(&cfg_); + encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_); + } + } layer_frame_cnt_++; DatarateTest::PreEncodeFrameHook(video, encoder); } @@ -1176,6 +1207,70 @@ } } + virtual void BasicRateTargetingSVC1TL3SLDynEnablTest() { + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 500; + cfg_.rc_buf_sz = 1000; + cfg_.rc_dropframe_thresh = 0; + cfg_.rc_min_quantizer = 0; + cfg_.rc_max_quantizer = 63; + cfg_.rc_end_usage = AOM_CBR; + cfg_.g_lag_in_frames = 0; + cfg_.g_error_resilient = 0; + + ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, + 1, 0, 400); + const int bitrate_array[2] = { 500, 1000 }; + cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)]; + ResetModel(); + number_temporal_layers_ = 1; + number_spatial_layers_ = 3; + target_layer_bitrate_[0] = 1 * cfg_.rc_target_bitrate / 8; + target_layer_bitrate_[1] = 3 * cfg_.rc_target_bitrate / 8; + target_layer_bitrate_[2] = 4 * cfg_.rc_target_bitrate / 8; + dynamic_enable_disable_mode_ = 1; + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + // No need to check RC on top layer which is disabled part of the time. + for (int i = 0; i < number_spatial_layers_ - 1; i++) { + ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.80) + << " The datarate for the file is lower than target by too much!"; + ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.38) + << " The datarate for the file is greater than target by too much!"; + } + } + + virtual void BasicRateTargetingSVC1TL3SLDynDisEnablTest() { + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 500; + cfg_.rc_buf_sz = 1000; + cfg_.rc_dropframe_thresh = 0; + cfg_.rc_min_quantizer = 0; + cfg_.rc_max_quantizer = 63; + cfg_.rc_end_usage = AOM_CBR; + cfg_.g_lag_in_frames = 0; + cfg_.g_error_resilient = 0; + + ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, + 288, 30, 1, 0, 300); + const int bitrate_array[2] = { 500, 1000 }; + cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)]; + ResetModel(); + number_temporal_layers_ = 1; + number_spatial_layers_ = 3; + target_layer_bitrate_[0] = 1 * cfg_.rc_target_bitrate / 8; + target_layer_bitrate_[1] = 3 * cfg_.rc_target_bitrate / 8; + target_layer_bitrate_[2] = 4 * cfg_.rc_target_bitrate / 8; + dynamic_enable_disable_mode_ = 2; + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + // No need to check RC on top layer which is disabled part of the time. + for (int i = 0; i < number_spatial_layers_ - 1; i++) { + ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.80) + << " The datarate for the file is lower than target by too much!"; + ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.38) + << " The datarate for the file is greater than target by too much!"; + } + } + int layer_frame_cnt_; int superframe_cnt_; int number_temporal_layers_; @@ -1196,6 +1291,7 @@ int multi_ref_; int use_fixed_mode_svc_; int comp_pred_; + int dynamic_enable_disable_mode_; }; // Check basic rate targeting for CBR, for 3 temporal layers, 1 spatial. @@ -1313,10 +1409,23 @@ BasicRateTargetingSVC3TL1SLMultiRefCompoundTest(); } +// Check basic rate targeting for CBR, for 3 spatial layers, 1 temporal, +// with the top spatial layer starting disabled (0 bitrate) and then +// dynamically enabled after x frames with nonzero bitrate. +TEST_P(DatarateTestSVC, BasicRateTargetingSVC1TL3SLDynEnabl) { + BasicRateTargetingSVC1TL3SLDynEnablTest(); +} + +// Check basic rate targeting for CBR, for 3 spatial layers, 1 temporal, +// with the top spatial layer dynamically disabled snd enabled during the +// middle of the sequence. +TEST_P(DatarateTestSVC, BasicRateTargetingSVC1TL3SLDynDisEnabl) { + BasicRateTargetingSVC1TL3SLDynDisEnablTest(); +} + AV1_INSTANTIATE_TEST_SUITE(DatarateTestSVC, ::testing::Values(::libaom_test::kRealTime), - ::testing::Range(7, 10), - ::testing::Range<unsigned int>(0, 4), + ::testing::Range(7, 10), ::testing::Values(0, 3), ::testing::Values(0, 1)); } // namespace