shithub: libvpx

Download patch

ref: ff38b8dfaed089cb36d651dcdc6c1fb74acab657
parent: 7f31bfeddbe4a0309b2a79129c1d526ba5725864
author: Marco <marpan@google.com>
date: Mon Oct 17 10:32:28 EDT 2016

vp8: Add control for gf boost for 1 pass cbr.

Control already exists for vp9, adding it to vp8.
Usage is only when error_resilient is off.
Added a datarate unittest for non-zero boost.

Change-Id: I4296055ebe2f4f048e8210f344531f6486ac9e35

--- a/test/datarate_test.cc
+++ b/test/datarate_test.cc
@@ -43,6 +43,7 @@
     duration_ = 0.0;
     denoiser_offon_test_ = 0;
     denoiser_offon_period_ = -1;
+    gf_boost_ = 0;
   }
 
   virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
@@ -50,6 +51,7 @@
     if (video->frame() == 0) {
       encoder->Control(VP8E_SET_NOISE_SENSITIVITY, denoiser_on_);
       encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
+      encoder->Control(VP8E_SET_GF_CBR_BOOST_PCT, gf_boost_);
     }
 
     if (denoiser_offon_test_) {
@@ -142,6 +144,7 @@
   int denoiser_offon_test_;
   int denoiser_offon_period_;
   int set_cpu_used_;
+  int gf_boost_;
 };
 
 #if CONFIG_TEMPORAL_DENOISING
@@ -424,6 +427,29 @@
       << " The datarate for the file missed the target!";
 }
 #endif
+
+TEST_P(DatarateTestRealTime, GFBoost) {
+  denoiser_on_ = 0;
+  cfg_.rc_buf_initial_sz = 500;
+  cfg_.rc_dropframe_thresh = 0;
+  cfg_.rc_max_quantizer = 56;
+  cfg_.rc_end_usage = VPX_CBR;
+  cfg_.g_error_resilient = 0;
+
+  ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
+                                       30, 1, 0, 300);
+  cfg_.rc_target_bitrate = 300;
+  ResetModel();
+  // Apply a gf boost.
+  gf_boost_ = 50;
+
+  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+  ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
+      << " The datarate for the file exceeds the target!";
+
+  ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
+      << " The datarate for the file missed the target!";
+}
 
 class DatarateTestVP9Large
     : public ::libvpx_test::EncoderTest,
--- a/vp8/common/onyx.h
+++ b/vp8/common/onyx.h
@@ -110,6 +110,8 @@
   int Sharpness;
   int cpu_used;
   unsigned int rc_max_intra_bitrate_pct;
+  /* percent of rate boost for golden frame in CBR mode. */
+  unsigned int gf_cbr_boost_pct;
   unsigned int screen_content_mode;
 
   /* mode ->
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -1005,9 +1005,14 @@
         cpi->current_gf_interval = cpi->frames_till_gf_update_due;
       }
     } else {
-      // Special case for 1 pass CBR: for now no boost and fixed gf period.
+      // Special case for 1 pass CBR: fixed gf period.
       // TODO(marpan): Adjust this boost/interval logic.
-      cpi->gf_noboost_onepass_cbr = 1;
+      // If gf_cbr_boost_pct is small (below threshold) set the flag
+      // gf_noboost_onepass_cbr = 1, which forces the gf to use the same
+      // rate correction factor as last.
+      cpi->gf_noboost_onepass_cbr = (cpi->oxcf.gf_cbr_boost_pct <= 50);
+      cpi->this_frame_target =
+          (cpi->this_frame_target * (100 + cpi->oxcf.gf_cbr_boost_pct)) / 100;
       cpi->baseline_gf_interval = cpi->gf_interval_onepass_cbr;
       // Skip this update if the zero_mvcount is low.
       if (cpi->zeromv_count > (cpi->common.MBs >> 1))
--- a/vp8/vp8_cx_iface.c
+++ b/vp8/vp8_cx_iface.c
@@ -40,6 +40,7 @@
   vp8e_tuning tuning;
   unsigned int cq_level; /* constrained quality level */
   unsigned int rc_max_intra_bitrate_pct;
+  unsigned int gf_cbr_boost_pct;
   unsigned int screen_content_mode;
 };
 
@@ -65,6 +66,7 @@
   0,  /* tuning*/
   10, /* cq_level */
   0,  /* rc_max_intra_bitrate_pct */
+  0,  /* gf_cbr_boost_pct */
   0,  /* screen_content_mode */
 };
 
@@ -315,6 +317,7 @@
 
   oxcf->target_bandwidth = cfg.rc_target_bitrate;
   oxcf->rc_max_intra_bitrate_pct = vp8_cfg.rc_max_intra_bitrate_pct;
+  oxcf->gf_cbr_boost_pct = vp8_cfg.gf_cbr_boost_pct;
 
   oxcf->best_allowed_q = cfg.rc_min_quantizer;
   oxcf->worst_allowed_q = cfg.rc_max_quantizer;
@@ -558,6 +561,13 @@
   return update_extracfg(ctx, &extra_cfg);
 }
 
+static vpx_codec_err_t ctrl_set_rc_gf_cbr_boost_pct(vpx_codec_alg_priv_t *ctx,
+                                                    va_list args) {
+  struct vp8_extracfg extra_cfg = ctx->vp8_cfg;
+  extra_cfg.gf_cbr_boost_pct = CAST(VP8E_SET_GF_CBR_BOOST_PCT, args);
+  return update_extracfg(ctx, &extra_cfg);
+}
+
 static vpx_codec_err_t set_screen_content_mode(vpx_codec_alg_priv_t *ctx,
                                                va_list args) {
   struct vp8_extracfg extra_cfg = ctx->vp8_cfg;
@@ -1159,6 +1169,7 @@
   { VP8E_SET_CQ_LEVEL, set_cq_level },
   { VP8E_SET_MAX_INTRA_BITRATE_PCT, set_rc_max_intra_bitrate_pct },
   { VP8E_SET_SCREEN_CONTENT_MODE, set_screen_content_mode },
+  { VP8E_SET_GF_CBR_BOOST_PCT, ctrl_set_rc_gf_cbr_boost_pct },
   { -1, NULL },
 };
 
--- a/vpx/vp8cx.h
+++ b/vpx/vp8cx.h
@@ -561,7 +561,22 @@
    *
    * Supported in codecs: VP9
    */
-  VP9E_SET_ALT_REF_AQ
+  VP9E_SET_ALT_REF_AQ,
+
+  /*!\brief Boost percentage for Golden Frame in CBR mode.
+    *
+    * This value controls the amount of boost given to Golden Frame in
+    * CBR mode. It is expressed as a percentage of the average
+    * per-frame bitrate, with the special (and default) value 0 meaning
+    * the feature is off, i.e., no golden frame boost in CBR mode and
+    * average bitrate target is used.
+    *
+    * For example, to allow 100% more bits, i.e, 2X, in a golden frame
+    * than average frame, set this to 100.
+    *
+    * Supported in codecs: VP8
+    */
+  VP8E_SET_GF_CBR_BOOST_PCT,
 };
 
 /*!\brief vpx 1-D scaling mode
@@ -768,6 +783,9 @@
 #define VPX_CTRL_VP8E_SET_MAX_INTRA_BITRATE_PCT
 VPX_CTRL_USE_TYPE(VP8E_SET_MAX_INTER_BITRATE_PCT, unsigned int)
 #define VPX_CTRL_VP8E_SET_MAX_INTER_BITRATE_PCT
+
+VPX_CTRL_USE_TYPE(VP8E_SET_GF_CBR_BOOST_PCT, unsigned int)
+#define VPX_CTRL_VP8E_SET_GF_CBR_BOOST_PCT
 
 VPX_CTRL_USE_TYPE(VP8E_SET_SCREEN_CONTENT_MODE, unsigned int)
 #define VPX_CTRL_VP8E_SET_SCREEN_CONTENT_MODE
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -355,6 +355,8 @@
     ARG_DEF(NULL, "cq-level", 1, "Constant/Constrained Quality level");
 static const arg_def_t max_intra_rate_pct =
     ARG_DEF(NULL, "max-intra-rate", 1, "Max I-frame bitrate (pct)");
+static const arg_def_t gf_cbr_boost_pct = ARG_DEF(
+    NULL, "gf-cbr-boost", 1, "Boost for Golden Frame in CBR mode (pct)");
 
 #if CONFIG_VP8_ENCODER
 static const arg_def_t cpu_used_vp8 =
@@ -363,12 +365,21 @@
     ARG_DEF(NULL, "token-parts", 1, "Number of token partitions to use, log2");
 static const arg_def_t screen_content_mode =
     ARG_DEF(NULL, "screen-content-mode", 1, "Screen content mode");
-static const arg_def_t *vp8_args[] = {
-  &cpu_used_vp8,        &auto_altref, &noise_sens,     &sharpness,
-  &static_thresh,       &token_parts, &arnr_maxframes, &arnr_strength,
-  &arnr_type,           &tune_ssim,   &cq_level,       &max_intra_rate_pct,
-  &screen_content_mode, NULL
-};
+static const arg_def_t *vp8_args[] = { &cpu_used_vp8,
+                                       &auto_altref,
+                                       &noise_sens,
+                                       &sharpness,
+                                       &static_thresh,
+                                       &token_parts,
+                                       &arnr_maxframes,
+                                       &arnr_strength,
+                                       &arnr_type,
+                                       &tune_ssim,
+                                       &cq_level,
+                                       &max_intra_rate_pct,
+                                       &gf_cbr_boost_pct,
+                                       &screen_content_mode,
+                                       NULL };
 static const int vp8_arg_ctrl_map[] = { VP8E_SET_CPUUSED,
                                         VP8E_SET_ENABLEAUTOALTREF,
                                         VP8E_SET_NOISE_SENSITIVITY,
@@ -381,6 +392,7 @@
                                         VP8E_SET_TUNING,
                                         VP8E_SET_CQ_LEVEL,
                                         VP8E_SET_MAX_INTRA_BITRATE_PCT,
+                                        VP8E_SET_GF_CBR_BOOST_PCT,
                                         VP8E_SET_SCREEN_CONTENT_MODE,
                                         0 };
 #endif
@@ -407,8 +419,6 @@
 static const arg_def_t frame_periodic_boost =
     ARG_DEF(NULL, "frame-boost", 1,
             "Enable frame periodic boost (0: off (default), 1: on)");
-static const arg_def_t gf_cbr_boost_pct = ARG_DEF(
-    NULL, "gf-cbr-boost", 1, "Boost for Golden Frame in CBR mode (pct)");
 static const arg_def_t max_inter_rate_pct =
     ARG_DEF(NULL, "max-inter-rate", 1, "Max P-frame bitrate (pct)");
 static const arg_def_t min_gf_interval = ARG_DEF(