]> granicus.if.org Git - libvpx/commitdiff
vp9: add delta q for uv channel. add tests.
authorJerome Jiang <jianj@google.com>
Fri, 17 Jan 2020 07:17:26 +0000 (23:17 -0800)
committerJerome Jiang <jianj@google.com>
Fri, 17 Jan 2020 17:19:23 +0000 (09:19 -0800)
Add control for delta q for uv. 0 by default.

Change-Id: Ib8ed160b1a5c9a61ba15985076f6c6f121477103

test/vp9_datarate_test.cc
vp9/encoder/vp9_encoder.c
vp9/encoder/vp9_encoder.h
vp9/encoder/vp9_firstpass.c
vp9/encoder/vp9_quantize.c
vp9/encoder/vp9_quantize.h
vp9/vp9_cx_iface.c
vpx/vp8cx.h

index b8be275eaf7a739938e44e7a2e906ba4f231c807..f9f2aaaffaf1fa5866eacc54b00d1a91e1e20d73 100644 (file)
@@ -46,6 +46,7 @@ class DatarateTestVP9 : public ::libvpx_test::EncoderTest {
     denoiser_offon_test_ = 0;
     denoiser_offon_period_ = -1;
     frame_parallel_decoding_mode_ = 1;
+    delta_q_uv_ = 0;
     use_roi_ = false;
   }
 
@@ -138,6 +139,10 @@ class DatarateTestVP9 : public ::libvpx_test::EncoderTest {
       encoder->Control(VP9E_SET_AQ_MODE, 0);
     }
 
+    if (delta_q_uv_ != 0) {
+      encoder->Control(VP9E_SET_DELTA_Q_UV, delta_q_uv_);
+    }
+
     if (cfg_.ts_number_layers > 1) {
       if (video->frame() == 0) {
         encoder->Control(VP9E_SET_SVC, 1);
@@ -222,6 +227,7 @@ class DatarateTestVP9 : public ::libvpx_test::EncoderTest {
   int denoiser_offon_test_;
   int denoiser_offon_period_;
   int frame_parallel_decoding_mode_;
+  int delta_q_uv_;
   bool use_roi_;
   vpx_roi_map_t roi_;
 };
@@ -716,6 +722,52 @@ TEST_P(DatarateTestVP9RealTime, RegionOfInterest) {
   free(roi_.roi_map);
 }
 
+// Params: speed setting, delta q UV.
+class DatarateTestVP9RealTimeDeltaQUV
+    : public DatarateTestVP9,
+      public ::libvpx_test::CodecTestWith2Params<int, int> {
+ public:
+  DatarateTestVP9RealTimeDeltaQUV() : DatarateTestVP9(GET_PARAM(0)) {}
+  virtual ~DatarateTestVP9RealTimeDeltaQUV() {}
+
+ protected:
+  virtual void SetUp() {
+    InitializeConfig();
+    SetMode(::libvpx_test::kRealTime);
+    set_cpu_used_ = GET_PARAM(1);
+    ResetModel();
+  }
+};
+
+TEST_P(DatarateTestVP9RealTimeDeltaQUV, DeltaQUV) {
+  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 = VPX_CBR;
+  cfg_.g_lag_in_frames = 0;
+
+  ::libvpx_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30, 1,
+                                       0, 400);
+
+  cfg_.rc_target_bitrate = 450;
+  cfg_.g_w = 640;
+  cfg_.g_h = 480;
+
+  ResetModel();
+
+  delta_q_uv_ = GET_PARAM(2);
+
+  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+  ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_[0] * 0.90)
+      << " The datarate for the file exceeds the target!";
+
+  ASSERT_LE(cfg_.rc_target_bitrate, effective_datarate_[0] * 1.4)
+      << " The datarate for the file missed the target!";
+}
+
 // Params: test mode, speed setting and index for bitrate array.
 class DatarateTestVP9PostEncodeDrop
     : public DatarateTestVP9,
@@ -891,6 +943,10 @@ VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9LargeVBR, ::testing::Range(5, 9),
 
 VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9RealTime, ::testing::Range(5, 10));
 
+VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9RealTimeDeltaQUV,
+                          ::testing::Range(5, 10),
+                          ::testing::Values(-5, -10, -15));
+
 VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9PostEncodeDrop,
                           ::testing::Range(5, 6));
 
index 9b03b2099102c391bff55cec9e8c1d18f54b8a9a..182064c485043a512d86641ca5a989947ca83a91 100644 (file)
@@ -4065,7 +4065,7 @@ static int encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
                                  cpi->oxcf.rc_mode == VPX_CBR &&
                                  cm->frame_type != KEY_FRAME;
 
-  vp9_set_quantizer(cm, q);
+  vp9_set_quantizer(cpi, q);
   vp9_set_variance_partition_thresholds(cpi, q, 0);
 
   setup_frame(cpi);
@@ -4094,7 +4094,7 @@ static int encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
       (cpi->rc.high_source_sad ||
        (cpi->use_svc && svc->high_source_sad_superframe))) {
     if (vp9_encodedframe_overshoot(cpi, -1, &q)) {
-      vp9_set_quantizer(cm, q);
+      vp9_set_quantizer(cpi, q);
       vp9_set_variance_partition_thresholds(cpi, q, 0);
     }
   }
@@ -4144,7 +4144,7 @@ static int encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
     // adjust some rate control parameters, and return to re-encode the frame.
     if (vp9_encodedframe_overshoot(cpi, frame_size, &q)) {
       vpx_clear_system_state();
-      vp9_set_quantizer(cm, q);
+      vp9_set_quantizer(cpi, q);
       vp9_set_variance_partition_thresholds(cpi, q, 0);
       suppress_active_map(cpi);
       // Turn-off cyclic refresh for re-encoded frame.
@@ -4294,7 +4294,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size,
     }
 #endif
 
-    vp9_set_quantizer(cm, q);
+    vp9_set_quantizer(cpi, q);
 
     if (loop_count == 0) setup_frame(cpi);
 
index c2bdebb4dc18672cfa5dc77679f16a05ba0cb9ed..388653ddcea6876fe7e3ef6174ac62adc4c73fb8 100644 (file)
@@ -282,6 +282,7 @@ typedef struct VP9EncoderConfig {
 
   int row_mt;
   unsigned int motion_vector_unit_test;
+  int delta_q_uv;
 } VP9EncoderConfig;
 
 static INLINE int is_lossless_requested(const VP9EncoderConfig *cfg) {
index cfaa68cfaba18ba64a1c80cdc4c62b747e72d2ce..ba35e6b9c0ecf451419fde31c17b9f407a3245fd 100644 (file)
@@ -1366,7 +1366,7 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
 #endif
 
   set_first_pass_params(cpi);
-  vp9_set_quantizer(cm, find_fp_qindex(cm->bit_depth));
+  vp9_set_quantizer(cpi, find_fp_qindex(cm->bit_depth));
 
   vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);
 
index 26d1434c3492ebe7ccfdf132f7d15d59e1b46f59..c996b751678037fb4b411365d4d4f5309baaf0e5 100644 (file)
@@ -323,13 +323,18 @@ void vp9_frame_init_quantizer(VP9_COMP *cpi) {
   vp9_init_plane_quantizers(cpi, &cpi->td.mb);
 }
 
-void vp9_set_quantizer(VP9_COMMON *cm, int q) {
+void vp9_set_quantizer(VP9_COMP *cpi, int q) {
+  VP9_COMMON *cm = &cpi->common;
   // quantizer has to be reinitialized with vp9_init_quantizer() if any
   // delta_q changes.
   cm->base_qindex = q;
   cm->y_dc_delta_q = 0;
   cm->uv_dc_delta_q = 0;
   cm->uv_ac_delta_q = 0;
+  if (cpi->oxcf.delta_q_uv != 0) {
+    cm->uv_dc_delta_q = cm->uv_ac_delta_q = cpi->oxcf.delta_q_uv;
+    vp9_init_quantizer(cpi);
+  }
 }
 
 // Table that converts 0-63 Q-range values passed in outside to the Qindex
index ed9b8495849925eab8d31faf27e74ec2f517c137..2e6d7da2b6622c6e761ce2241e90493bfe260b90 100644 (file)
@@ -49,7 +49,7 @@ void vp9_init_plane_quantizers(struct VP9_COMP *cpi, MACROBLOCK *x);
 
 void vp9_init_quantizer(struct VP9_COMP *cpi);
 
-void vp9_set_quantizer(struct VP9Common *cm, int q);
+void vp9_set_quantizer(struct VP9_COMP *cm, int q);
 
 int vp9_quantizer_to_qindex(int quantizer);
 
index f415e50f71f02d380752f2f78f0b9bf60f88692d..baea0ece1931a41f572881bcc9137e1d847b194d 100644 (file)
@@ -581,6 +581,8 @@ static vpx_codec_err_t set_encoder_config(
   oxcf->min_gf_interval = extra_cfg->min_gf_interval;
   oxcf->max_gf_interval = extra_cfg->max_gf_interval;
 
+  oxcf->delta_q_uv = 0;
+
   oxcf->tuning = extra_cfg->tuning;
   oxcf->content = extra_cfg->content;
 
@@ -1655,6 +1657,15 @@ static vpx_codec_err_t ctrl_set_svc_spatial_layer_sync(
   return VPX_CODEC_OK;
 }
 
+static vpx_codec_err_t ctrl_set_delta_q_uv(vpx_codec_alg_priv_t *ctx,
+                                           va_list args) {
+  int data = va_arg(args, int);
+  VP9_COMP *const cpi = ctx->cpi;
+  data = VPXMIN(VPXMAX(data, -20), 20);
+  cpi->oxcf.delta_q_uv = data;
+  return VPX_CODEC_OK;
+}
+
 static vpx_codec_err_t ctrl_register_cx_callback(vpx_codec_alg_priv_t *ctx,
                                                  va_list args) {
   vpx_codec_priv_output_cx_pkt_cb_pair_t *cbp =
@@ -1752,6 +1763,7 @@ static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
   { VP9E_SET_SVC_FRAME_DROP_LAYER, ctrl_set_svc_frame_drop_layer },
   { VP9E_SET_SVC_GF_TEMPORAL_REF, ctrl_set_svc_gf_temporal_ref },
   { VP9E_SET_SVC_SPATIAL_LAYER_SYNC, ctrl_set_svc_spatial_layer_sync },
+  { VP9E_SET_DELTA_Q_UV, ctrl_set_delta_q_uv },
 
   // Getters
   { VP8E_GET_LAST_QUANTIZER, ctrl_get_quantizer },
index 95e2493b1e1e4511675f0c7aa1081abe1bb24f36..d8b769b87c71bd26c5aba828d58ed4b641085e65 100644 (file)
@@ -676,6 +676,14 @@ enum vp8e_enc_control_id {
    * Supported in codecs: VP9
    */
   VP9E_SET_POSTENCODE_DROP,
+
+  /*!\brief Codec control function to set delta q for uv.
+   *
+   * Cap it at +/-20 for now.
+   *
+   * Supported in codecs: VP9
+   */
+  VP9E_SET_DELTA_Q_UV,
 };
 
 /*!\brief vpx 1-D scaling mode
@@ -1023,6 +1031,9 @@ VPX_CTRL_USE_TYPE(VP9E_SET_SVC_SPATIAL_LAYER_SYNC,
 VPX_CTRL_USE_TYPE(VP9E_SET_POSTENCODE_DROP, unsigned int)
 #define VPX_CTRL_VP9E_SET_POSTENCODE_DROP
 
+VPX_CTRL_USE_TYPE(VP9E_SET_DELTA_Q_UV, int)
+#define VPX_CTRL_VP9E_SET_DELTA_Q_UV
+
 /*!\endcond */
 /*! @} - end defgroup vp8_encoder */
 #ifdef __cplusplus