diff options
-rw-r--r-- | test/datarate_test.cc | 112 | ||||
-rw-r--r-- | vp9/encoder/vp9_encoder.c | 2 | ||||
-rw-r--r-- | vp9/encoder/vp9_ratectrl.c | 9 |
3 files changed, 103 insertions, 20 deletions
diff --git a/test/datarate_test.cc b/test/datarate_test.cc index d6b1b5247..c0796dff3 100644 --- a/test/datarate_test.cc +++ b/test/datarate_test.cc @@ -901,8 +901,6 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers) { svc_params_.scaling_factor_num[1] = 288; svc_params_.scaling_factor_den[1] = 288; cfg_.rc_dropframe_thresh = 10; - // TODO(marpan): another test should be added for default/small kf_max_dist - // once https://bugs.chromium.org/p/webm/issues/detail?id=1150 is fixed. cfg_.kf_max_dist = 9999; ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, 30, 1, 0, 200); @@ -918,10 +916,90 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers) { << " The datarate for the file exceeds the target by too much!"; ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15) << " The datarate for the file is lower than the target by too much!"; - EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0); + EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames()); } } +// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and +// 3 temporal layers. Run CIF clip with 1 thread. Use short key frame period. +TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayersSmallKf_dist) { + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 500; + cfg_.rc_buf_sz = 1000; + cfg_.rc_min_quantizer = 0; + cfg_.rc_max_quantizer = 63; + cfg_.rc_end_usage = VPX_CBR; + cfg_.g_lag_in_frames = 0; + cfg_.ss_number_layers = 2; + cfg_.ts_number_layers = 3; + cfg_.ts_rate_decimator[0] = 4; + cfg_.ts_rate_decimator[1] = 2; + cfg_.ts_rate_decimator[2] = 1; + cfg_.g_error_resilient = 1; + cfg_.g_threads = 1; + cfg_.temporal_layering_mode = 3; + svc_params_.scaling_factor_num[0] = 144; + svc_params_.scaling_factor_den[0] = 288; + svc_params_.scaling_factor_num[1] = 288; + svc_params_.scaling_factor_den[1] = 288; + cfg_.rc_dropframe_thresh = 10; + cfg_.kf_max_dist = 64; + ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288, + 30, 1, 0, 200); + // TODO(wonkap/marpan): Check that effective_datarate for each layer hits the + // layer target_bitrate. Also check if test can pass at lower bitrate (~200k). + for (int i = 400; i <= 800; i += 200) { + cfg_.rc_target_bitrate = i; + ResetModel(); + assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers, + cfg_.ts_number_layers, cfg_.temporal_layering_mode); + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85) + << " The datarate for the file exceeds the target by too much!"; + ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15) + << " The datarate for the file is lower than the target by too much!"; + EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames()); + } +} + +// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and +// 3 temporal layers. Run HD clip with 4 threads. +TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers4threads) { + cfg_.rc_buf_initial_sz = 500; + cfg_.rc_buf_optimal_sz = 500; + cfg_.rc_buf_sz = 1000; + cfg_.rc_min_quantizer = 0; + cfg_.rc_max_quantizer = 63; + cfg_.rc_end_usage = VPX_CBR; + cfg_.g_lag_in_frames = 0; + cfg_.ss_number_layers = 2; + cfg_.ts_number_layers = 3; + cfg_.ts_rate_decimator[0] = 4; + cfg_.ts_rate_decimator[1] = 2; + cfg_.ts_rate_decimator[2] = 1; + cfg_.g_error_resilient = 1; + cfg_.g_threads = 4; + cfg_.temporal_layering_mode = 3; + svc_params_.scaling_factor_num[0] = 144; + svc_params_.scaling_factor_den[0] = 288; + svc_params_.scaling_factor_num[1] = 288; + svc_params_.scaling_factor_den[1] = 288; + cfg_.rc_dropframe_thresh = 10; + cfg_.kf_max_dist = 9999; + ::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720, + 30, 1, 0, 300); + cfg_.rc_target_bitrate = 800; + ResetModel(); + assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers, + cfg_.ts_number_layers, cfg_.temporal_layering_mode); + ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); + ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85) + << " The datarate for the file exceeds the target by too much!"; + ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15) + << " The datarate for the file is lower than the target by too much!"; + EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames()); +} + // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and // 3 temporal layers. Run CIF clip with 1 thread. TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayers) { @@ -959,12 +1037,12 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayers) { << " The datarate for the file exceeds the target by too much!"; ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.22) << " The datarate for the file is lower than the target by too much!"; - EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0); + EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames()); } -// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and -// 3 temporal layers. Run HD clip with 4 threads. -TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers4threads) { +// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and +// 3 temporal layers. Run CIF clip with 1 thread. Use short key frame period. +TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayersSmallKf) { cfg_.rc_buf_initial_sz = 500; cfg_.rc_buf_optimal_sz = 500; cfg_.rc_buf_sz = 1000; @@ -972,32 +1050,34 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers4threads) { cfg_.rc_max_quantizer = 63; cfg_.rc_end_usage = VPX_CBR; cfg_.g_lag_in_frames = 0; - cfg_.ss_number_layers = 2; + cfg_.ss_number_layers = 3; cfg_.ts_number_layers = 3; cfg_.ts_rate_decimator[0] = 4; cfg_.ts_rate_decimator[1] = 2; cfg_.ts_rate_decimator[2] = 1; cfg_.g_error_resilient = 1; - cfg_.g_threads = 4; + cfg_.g_threads = 1; cfg_.temporal_layering_mode = 3; - svc_params_.scaling_factor_num[0] = 144; + svc_params_.scaling_factor_num[0] = 72; svc_params_.scaling_factor_den[0] = 288; - svc_params_.scaling_factor_num[1] = 288; + svc_params_.scaling_factor_num[1] = 144; svc_params_.scaling_factor_den[1] = 288; + svc_params_.scaling_factor_num[2] = 288; + svc_params_.scaling_factor_den[2] = 288; cfg_.rc_dropframe_thresh = 10; - cfg_.kf_max_dist = 9999; + cfg_.kf_max_dist = 32; ::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720, 30, 1, 0, 300); cfg_.rc_target_bitrate = 800; ResetModel(); assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers, - cfg_.ts_number_layers, cfg_.temporal_layering_mode); + cfg_.ts_number_layers, cfg_.temporal_layering_mode); ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85) << " The datarate for the file exceeds the target by too much!"; - ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15) + ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.30) << " The datarate for the file is lower than the target by too much!"; - EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0); + EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames()); } // Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and @@ -1037,7 +1117,7 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayers4threads) { << " The datarate for the file exceeds the target by too much!"; ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.22) << " The datarate for the file is lower than the target by too much!"; - EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0); + EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames()); } VP8_INSTANTIATE_TEST_CASE(DatarateTestLarge, ALL_TEST_MODES); diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 6d6915c8d..332db300c 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -3983,6 +3983,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi, ++cm->current_video_frame; cpi->ext_refresh_frame_flags_pending = 0; cpi->svc.rc_drop_superframe = 1; + if (cpi->use_svc) + vp9_inc_frame_in_layer(cpi); return; } } diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index d64b5c53b..7804b712a 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -1594,14 +1594,15 @@ void vp9_rc_get_svc_params(VP9_COMP *cpi) { int target = rc->avg_frame_bandwidth; int layer = LAYER_IDS_TO_IDX(cpi->svc.spatial_layer_id, cpi->svc.temporal_layer_id, cpi->svc.number_temporal_layers); - + // Periodic key frames is based on the super-frame counter + // (svc.current_superframe), also only base spatial layer is key frame. if ((cm->current_video_frame == 0) || (cpi->frame_flags & FRAMEFLAGS_KEY) || - (cpi->oxcf.auto_key && (rc->frames_since_key % - cpi->oxcf.key_freq == 0))) { + (cpi->oxcf.auto_key && + (cpi->svc.current_superframe % cpi->oxcf.key_freq == 0) && + cpi->svc.spatial_layer_id == 0)) { cm->frame_type = KEY_FRAME; rc->source_alt_ref_active = 0; - if (is_two_pass_svc(cpi)) { cpi->svc.layer_context[layer].is_key_frame = 1; cpi->ref_frame_flags &= |