ref: 076d4bd91ad0ec042924d2772b2002c9e7d3d48b
parent: 7ba9d31e3f547128ea3eed9cddc94caf160f916a
author: Marco <[email protected]>
date: Wed Dec 7 04:50:27 EST 2016
vp9: Fix to crash in svc code. use_base_mv assumes 2x2 scaling, so fix is to shutoff this feature unless spatial scale factors are 2. Added svc unittest for 2 spatial layers with 5x5 scaling, which generates the issue without this fix. Also fix some settings in svc unittest: let the speed setting vary (from 5 to 8), and enable static threshold. BUG=webm:1344 Change-Id: Idfd0a6c633c21b49a0479601506302cfe974e30e
--- a/test/datarate_test.cc
+++ b/test/datarate_test.cc
@@ -1052,7 +1052,7 @@
}
svc_params_.speed_per_layer[0] = 5;
for (i = 1; i < VPX_SS_MAX_LAYERS; ++i) {
- svc_params_.speed_per_layer[i] = 7;
+ svc_params_.speed_per_layer[i] = speed_setting_;
}
encoder->Control(VP9E_SET_SVC, 1);
encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_);
@@ -1060,6 +1060,7 @@
encoder->Control(VP9E_SET_TILE_COLUMNS, 0);
encoder->Control(VP8E_SET_MAX_INTRA_BITRATE_PCT, 300);
encoder->Control(VP9E_SET_TILE_COLUMNS, (cfg_.g_threads >> 1));
+ encoder->Control(VP8E_SET_STATIC_THRESHOLD, 1);
}
const vpx_rational_t tb = video->timebase();
timebase_ = static_cast<double>(tb.num) / tb.den;
@@ -1387,6 +1388,41 @@
<< " 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(static_cast<unsigned int>(0), GetMismatchFrames());
+}
+
+// Run SVC encoder for 1 temporal layer, 2 spatial layers, with spatial
+// downscale 5x5.
+TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers5x5MultipleRuns) {
+ 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 = 1;
+ cfg_.ts_rate_decimator[0] = 1;
+ cfg_.g_error_resilient = 1;
+ cfg_.g_threads = 3;
+ cfg_.temporal_layering_mode = 0;
+ svc_params_.scaling_factor_num[0] = 256;
+ svc_params_.scaling_factor_den[0] = 1280;
+ svc_params_.scaling_factor_num[1] = 1280;
+ svc_params_.scaling_factor_den[1] = 1280;
+ cfg_.rc_dropframe_thresh = 0;
+ cfg_.kf_max_dist = 999999;
+ cfg_.kf_min_dist = 0;
+ cfg_.ss_target_bitrate[0] = 300;
+ cfg_.ss_target_bitrate[1] = 1400;
+ cfg_.layer_target_bitrate[0] = 300;
+ cfg_.layer_target_bitrate[1] = 1400;
+ cfg_.rc_target_bitrate = 1700;
+ ::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720, 30,
+ 1, 0, 30);
+ ResetModel();
+ ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
}
--- a/vp9/encoder/vp9_svc_layercontext.c
+++ b/vp9/encoder/vp9_svc_layercontext.c
@@ -650,6 +650,21 @@
lc->scaling_factor_num, lc->scaling_factor_den, &width,
&height);
+ // The usage of use_base_mv assumes down-scale of 2x2. For now, turn off use
+ // of base motion vectors if spatial scale factors for any layers are not 2.
+ // TODO(marpan): Fix this to allow for use_base_mv for scale factors != 2.
+ if (cpi->svc.number_spatial_layers > 1) {
+ int sl;
+ for (sl = 0; sl < cpi->svc.number_spatial_layers - 1; ++sl) {
+ lc = &cpi->svc.layer_context[sl * cpi->svc.number_temporal_layers +
+ cpi->svc.temporal_layer_id];
+ if (lc->scaling_factor_num != lc->scaling_factor_den >> 1) {
+ cpi->svc.use_base_mv = 0;
+ break;
+ }
+ }
+ }
+
if (vp9_set_size_literal(cpi, width, height) != 0)
return VPX_CODEC_INVALID_PARAM;