shithub: libvpx

Download patch

ref: 4f5b2b28924fa63f88449e203905ec88168bbda7
parent: 76885de5ad2eb02970231d0f92e9691d9a5beb24
author: Minghai Shang <[email protected]>
date: Thu Sep 18 07:10:11 EDT 2014

[spatial svc]Remove quantizers option. Use max/min quantizers for each layer.

Change-Id: I214bc4169f6c5eaee4957cd308a74d309e999005

--- a/examples/vp9_spatial_svc_encoder.c
+++ b/examples/vp9_spatial_svc_encoder.c
@@ -46,10 +46,6 @@
     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 *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 @@
     } 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 @@
     } 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)) {
--- a/test/svc_test.cc
+++ b/test/svc_test.cc
@@ -452,17 +452,32 @@
 
 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();
 }
 
--- a/vpx/src/svc_encodeframe.c
+++ b/vpx/src/svc_encodeframe.c
@@ -47,9 +47,7 @@
 #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 @@
   // 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,10 +262,14 @@
                                             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->quantizer, NULL);
+                                            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->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,
                                             si->enable_auto_alt_ref, NULL);
@@ -286,6 +289,13 @@
   }
   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 @@
   }
 
   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 @@
     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);
 }