From 4f5b2b28924fa63f88449e203905ec88168bbda7 Mon Sep 17 00:00:00 2001 From: Minghai Shang Date: Thu, 18 Sep 2014 11:10:11 -0700 Subject: [PATCH] [spatial svc]Remove quantizers option. Use max/min quantizers for each layer. Change-Id: I214bc4169f6c5eaee4957cd308a74d309e999005 --- examples/vp9_spatial_svc_encoder.c | 20 +++++++------------- test/svc_test.cc | 21 ++++++++++++++++++--- vpx/src/svc_encodeframe.c | 34 ++++++++++++++++++++-------------- 3 files changed, 45 insertions(+), 30 deletions(-) diff --git a/examples/vp9_spatial_svc_encoder.c b/examples/vp9_spatial_svc_encoder.c index df8f4f1..14d2372 100644 --- a/examples/vp9_spatial_svc_encoder.c +++ b/examples/vp9_spatial_svc_encoder.c @@ -46,10 +46,6 @@ static const arg_def_t kf_dist_arg = ARG_DEF("k", "kf-dist", 1, "number of frames between keyframes"); static const arg_def_t scale_factors_arg = ARG_DEF("r", "scale-factors", 1, "scale factors (lowest to highest layer)"); -static const arg_def_t quantizers_arg = - ARG_DEF("q", "quantizers", 1, "quantizers for non key frames, also will " - "be applied to key frames if -qn is not specified (lowest to " - "highest layer)"); static const arg_def_t passes_arg = ARG_DEF("p", "passes", 1, "Number of passes (1/2)"); static const arg_def_t pass_arg = @@ -68,10 +64,9 @@ static const arg_def_t max_bitrate_arg = static const arg_def_t *svc_args[] = { &frames_arg, &width_arg, &height_arg, &timebase_arg, &bitrate_arg, &skip_frames_arg, &spatial_layers_arg, - &kf_dist_arg, &scale_factors_arg, &quantizers_arg, &passes_arg, - &pass_arg, &fpf_name_arg, &min_q_arg, &max_q_arg, - &min_bitrate_arg, &max_bitrate_arg, &temporal_layers_arg, - NULL + &kf_dist_arg, &scale_factors_arg, &passes_arg, &pass_arg, + &fpf_name_arg, &min_q_arg, &max_q_arg, &min_bitrate_arg, + &max_bitrate_arg, &temporal_layers_arg, NULL }; static const uint32_t default_frames_to_skip = 0; @@ -172,9 +167,6 @@ static void parse_command_line(int argc, const char **argv_, } else if (arg_match(&arg, &scale_factors_arg, argi)) { snprintf(string_options, 1024, "%s scale-factors=%s", string_options, arg.val); - } else if (arg_match(&arg, &quantizers_arg, argi)) { - snprintf(string_options, 1024, "%s quantizers=%s", - string_options, arg.val); } else if (arg_match(&arg, &passes_arg, argi)) { passes = arg_parse_uint(&arg); if (passes < 1 || passes > 2) { @@ -188,9 +180,11 @@ static void parse_command_line(int argc, const char **argv_, } else if (arg_match(&arg, &fpf_name_arg, argi)) { fpf_file_name = arg.val; } else if (arg_match(&arg, &min_q_arg, argi)) { - enc_cfg->rc_min_quantizer = arg_parse_uint(&arg); + snprintf(string_options, 1024, "%s min-quantizers=%s", + string_options, arg.val); } else if (arg_match(&arg, &max_q_arg, argi)) { - enc_cfg->rc_max_quantizer = arg_parse_uint(&arg); + snprintf(string_options, 1024, "%s max-quantizers=%s", + string_options, arg.val); } else if (arg_match(&arg, &min_bitrate_arg, argi)) { min_bitrate = arg_parse_uint(&arg); } else if (arg_match(&arg, &max_bitrate_arg, argi)) { diff --git a/test/svc_test.cc b/test/svc_test.cc index a877a9d..a61629d 100644 --- a/test/svc_test.cc +++ b/test/svc_test.cc @@ -452,17 +452,32 @@ TEST_F(SvcTest, SetScaleFactorsOption) { TEST_F(SvcTest, SetQuantizersOption) { svc_.spatial_layers = 2; - vpx_codec_err_t res = vpx_svc_set_options(&svc_, "quantizers=not-quantizers"); + vpx_codec_err_t res = vpx_svc_set_options(&svc_, "max-quantizers=nothing"); EXPECT_EQ(VPX_CODEC_OK, res); res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_); EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); - res = vpx_svc_set_options(&svc_, "40"); + res = vpx_svc_set_options(&svc_, "min-quantizers=nothing"); EXPECT_EQ(VPX_CODEC_OK, res); res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_); EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); - vpx_svc_set_options(&svc_, "quantizers=40,45"); + res = vpx_svc_set_options(&svc_, "max-quantizers=40"); + EXPECT_EQ(VPX_CODEC_OK, res); + res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_); + EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); + + res = vpx_svc_set_options(&svc_, "min-quantizers=40"); + EXPECT_EQ(VPX_CODEC_OK, res); + res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_); + EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); + + res = vpx_svc_set_options(&svc_, "max-quantizers=30,30 min-quantizers=40,40"); + EXPECT_EQ(VPX_CODEC_OK, res); + res = vpx_svc_init(&svc_, &codec_, vpx_codec_vp9_cx(), &codec_enc_); + EXPECT_EQ(VPX_CODEC_INVALID_PARAM, res); + + res = vpx_svc_set_options(&svc_, "max-quantizers=40,40 min-quantizers=30,30"); InitializeEncoder(); } diff --git a/vpx/src/svc_encodeframe.c b/vpx/src/svc_encodeframe.c index 7b36ff4..a74d4cc 100644 --- a/vpx/src/svc_encodeframe.c +++ b/vpx/src/svc_encodeframe.c @@ -47,9 +47,7 @@ _CRTIMP char *__cdecl strtok_s(char *str, const char *delim, char **context); #define OPTION_BUFFER_SIZE 1024 #define COMPONENTS 4 // psnr & sse statistics maintained for total, y, u, v -static const int DEFAULT_QUANTIZER_VALUES[VPX_SS_MAX_LAYERS] = { - 60, 53, 39, 33, 27 -}; +#define MAX_QUANTIZER 63 static const int DEFAULT_SCALE_FACTORS_NUM[VPX_SS_MAX_LAYERS] = { 4, 5, 7, 11, 16 @@ -89,7 +87,8 @@ typedef struct SvcInternal { // values extracted from option, quantizers int scaling_factor_num[VPX_SS_MAX_LAYERS]; int scaling_factor_den[VPX_SS_MAX_LAYERS]; - int quantizer[VPX_SS_MAX_LAYERS]; + int max_quantizers[VPX_SS_MAX_LAYERS]; + int min_quantizers[VPX_SS_MAX_LAYERS]; int enable_auto_alt_ref[VPX_SS_MAX_LAYERS]; int bitrates[VPX_SS_MAX_LAYERS]; @@ -263,9 +262,13 @@ static vpx_codec_err_t parse_options(SvcContext *svc_ctx, const char *options) { si->scaling_factor_num, si->scaling_factor_den); if (res != VPX_CODEC_OK) break; - } else if (strcmp("quantizers", option_name) == 0) { + } else if (strcmp("max-quantizers", option_name) == 0) { + res = parse_layer_options_from_string(svc_ctx, QUANTIZER, option_value, + si->max_quantizers, NULL); + if (res != VPX_CODEC_OK) break; + } else if (strcmp("min-quantizers", option_name) == 0) { res = parse_layer_options_from_string(svc_ctx, QUANTIZER, option_value, - si->quantizer, NULL); + si->min_quantizers, NULL); if (res != VPX_CODEC_OK) break; } else if (strcmp("auto-alt-refs", option_name) == 0) { res = parse_layer_options_from_string(svc_ctx, AUTO_ALT_REF, option_value, @@ -286,6 +289,13 @@ static vpx_codec_err_t parse_options(SvcContext *svc_ctx, const char *options) { } free(input_string); + for (i = 0; i < svc_ctx->spatial_layers; ++i) { + if (si->max_quantizers[i] > MAX_QUANTIZER || si->max_quantizers[i] < 0 || + si->min_quantizers[i] > si->max_quantizers[i] || + si->min_quantizers[i] < 0) + res = VPX_CODEC_INVALID_PARAM; + } + if (si->use_multiple_frame_contexts && (svc_ctx->spatial_layers > 3 || svc_ctx->spatial_layers * svc_ctx->temporal_layers > 4)) @@ -382,7 +392,8 @@ vpx_codec_err_t vpx_svc_init(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx, } for (i = 0; i < VPX_SS_MAX_LAYERS; ++i) { - si->quantizer[i] = DEFAULT_QUANTIZER_VALUES[i]; + si->max_quantizers[i] = MAX_QUANTIZER; + si->min_quantizers[i] = 0; si->scaling_factor_num[i] = DEFAULT_SCALE_FACTORS_NUM[i]; si->scaling_factor_den[i] = DEFAULT_SCALE_FACTORS_DEN[i]; } @@ -483,13 +494,8 @@ static void set_svc_parameters(SvcContext *svc_ctx, svc_log(svc_ctx, SVC_LOG_ERROR, "vpx_svc_get_layer_resolution failed\n"); } - if (codec_ctx->config.enc->g_pass == VPX_RC_ONE_PASS) { - svc_params.min_quantizer = si->quantizer[layer]; - svc_params.max_quantizer = si->quantizer[layer]; - } else { - svc_params.min_quantizer = codec_ctx->config.enc->rc_min_quantizer; - svc_params.max_quantizer = codec_ctx->config.enc->rc_max_quantizer; - } + svc_params.min_quantizer = si->min_quantizers[layer]; + svc_params.max_quantizer = si->max_quantizers[layer]; vpx_codec_control(codec_ctx, VP9E_SET_SVC_PARAMETERS, &svc_params); } -- 2.7.4