Add limits to Vizier input parameters.
authorPaul Wilkins <paulwilkins@google.com>
Mon, 26 Apr 2021 14:06:54 +0000 (15:06 +0100)
committerPaul Wilkins <paulwilkins@google.com>
Mon, 26 Apr 2021 15:35:53 +0000 (16:35 +0100)
Imposed provisional upper and lower limits to each parameter
that can be adjusted in the Vizier ML experiment.

Also in some cases applied secondary limits on on the
range of the final "used" values.

Defaults and limits may well require further tuning after
subsequent rounds of experimentation.

Re-factor get_sr_decay_rate().

Change-Id: I28e804ce3d3710f30cd51a203348e4ab23ef06c0

vp9/encoder/vp9_firstpass.c
vp9/vp9_cx_iface.c

index a4717ad..ce7590f 100644 (file)
@@ -1832,33 +1832,35 @@ void vp9_init_second_pass(VP9_COMP *cpi) {
 }
 
 /* This function considers how the quality of prediction may be deteriorating
- * with distance. It comapres the coded error for the last frame and the
+ * with distance. It compares the coded error for the last frame and the
  * second reference frame (usually two frames old) and also applies a factor
  * based on the extent of INTRA coding.
  *
  * The decay factor is then used to reduce the contribution of frames further
- * from the alt-ref or golden frame, to the bitframe boost calculation for that
+ * from the alt-ref or golden frame, to the bitrate boost calculation for that
  * alt-ref or golden frame.
  */
 static double get_sr_decay_rate(const TWO_PASS *const twopass,
                                 const FIRSTPASS_STATS *frame) {
   double sr_diff = (frame->sr_coded_error - frame->coded_error);
   double sr_decay = 1.0;
-  double modified_pct_inter;
-  double modified_pcnt_intra;
-
-  modified_pct_inter = frame->pcnt_inter;
-  if ((frame->coded_error > LOW_CODED_ERR_PER_MB) &&
-      ((frame->intra_error / DOUBLE_DIVIDE_CHECK(frame->coded_error)) <
-       (double)NCOUNT_FRAME_II_THRESH)) {
-    modified_pct_inter =
-        frame->pcnt_inter + frame->pcnt_intra_low - frame->pcnt_neutral;
-  }
-  modified_pcnt_intra = 100 * (1.0 - modified_pct_inter);
 
+  // Do nothing if the second ref to last frame error difference is
+  // very small or even negative.
   if ((sr_diff > LOW_SR_DIFF_TRHESH)) {
-    double sr_diff_part =
+    const double sr_diff_part =
         twopass->sr_diff_factor * ((sr_diff * 0.25) / frame->intra_error);
+    double modified_pct_inter = frame->pcnt_inter;
+    double modified_pcnt_intra;
+
+    if ((frame->coded_error > LOW_CODED_ERR_PER_MB) &&
+        ((frame->intra_error / DOUBLE_DIVIDE_CHECK(frame->coded_error)) <
+         (double)NCOUNT_FRAME_II_THRESH)) {
+      modified_pct_inter =
+          frame->pcnt_inter + frame->pcnt_intra_low - frame->pcnt_neutral;
+    }
+    modified_pcnt_intra = 100 * (1.0 - modified_pct_inter);
+
     sr_decay = 1.0 - sr_diff_part - (INTRA_PART * modified_pcnt_intra);
   }
   return VPXMAX(sr_decay, twopass->sr_default_decay_limit);
@@ -1979,7 +1981,7 @@ static double calc_frame_boost(const FRAME_INFO *frame_info,
   const double boost_q_correction = VPXMIN((0.5 + (lq * 0.015)), 1.5);
   const double active_area = calculate_active_area(frame_info, this_frame);
 
-  // Underlying boost factor is based on inter error ratio.
+  // Frame booost is based on inter error.
   frame_boost = (twopass->err_per_mb * active_area) /
                 DOUBLE_DIVIDE_CHECK(this_frame->coded_error);
 
@@ -2007,7 +2009,7 @@ static double calc_kf_frame_boost(VP9_COMP *cpi,
       calculate_active_area(&cpi->frame_info, this_frame);
   double max_boost;
 
-  // Underlying boost factor is based on inter error ratio.
+  // Frame booost is based on inter error.
   frame_boost = (twopass->kf_err_per_mb * active_area) /
                 DOUBLE_DIVIDE_CHECK(this_frame->coded_error + *sr_accumulator);
 
@@ -3499,14 +3501,21 @@ static void init_vizier_params(TWO_PASS *const twopass, int screen_area) {
     twopass->active_wq_factor *= AV_WQ_FACTOR;
     twopass->err_per_mb *= BASELINE_ERR_PER_MB;
     twopass->sr_default_decay_limit *= DEFAULT_DECAY_LIMIT;
+    if (twopass->sr_default_decay_limit > 1.0)  // > 1.0 here makes no sense
+      twopass->sr_default_decay_limit = 1.0;
     twopass->sr_diff_factor *= 1.0;
     twopass->gf_frame_max_boost *= GF_MAX_FRAME_BOOST;
     twopass->gf_max_total_boost *= MAX_GF_BOOST;
+    // NOTE: In use max boost has precedence over min boost. So even if min is
+    // somehow set higher than max the final boost value will be clamped to the
+    // appropriate maximum.
     twopass->kf_frame_min_boost *= KF_MIN_FRAME_BOOST;
     twopass->kf_frame_max_boost_first *= KF_MAX_FRAME_BOOST;
     twopass->kf_frame_max_boost_subs *= KF_MAX_FRAME_BOOST;
     twopass->kf_max_total_boost *= MAX_KF_TOT_BOOST;
     twopass->zm_factor *= DEFAULT_ZM_FACTOR;
+    if (twopass->zm_factor > 1.0)  // > 1.0 here makes no sense
+      twopass->zm_factor = 1.0;
 
     // Correction for the fact that the kf_err_per_mb_factor default is
     // already different for different video formats and ensures that a passed
index c700620..438f9b5 100644 (file)
@@ -664,41 +664,118 @@ static vpx_codec_err_t set_twopass_params_from_config(
   cpi->twopass.use_vizier_rc_params = cfg->use_vizier_rc_params;
 
   // The values set here are factors that will be applied to default values
-  // to get the final value used in the two pass code. 1.0 will hence
+  // to get the final value used in the two pass code. Hence 1.0 will
   // match the default behaviour when not using passed in values.
+  // We also apply limits here to prevent the user from applying settings
+  // that make no sense.
   cpi->twopass.active_wq_factor =
       (double)cfg->active_wq_factor.num / (double)cfg->active_wq_factor.den;
+  if (cpi->twopass.active_wq_factor < 0.25)
+    cpi->twopass.active_wq_factor = 0.25;
+  else if (cpi->twopass.active_wq_factor > 16.0)
+    cpi->twopass.active_wq_factor = 16.0;
+
   cpi->twopass.err_per_mb =
       (double)cfg->err_per_mb_factor.num / (double)cfg->err_per_mb_factor.den;
+  if (cpi->twopass.err_per_mb < 0.25)
+    cpi->twopass.err_per_mb = 0.25;
+  else if (cpi->twopass.err_per_mb > 4.0)
+    cpi->twopass.err_per_mb = 4.0;
+
   cpi->twopass.sr_default_decay_limit =
       (double)cfg->sr_default_decay_limit.num /
       (double)cfg->sr_default_decay_limit.den;
+  if (cpi->twopass.sr_default_decay_limit < 0.25)
+    cpi->twopass.sr_default_decay_limit = 0.25;
+  // If the default changes this will need to change.
+  else if (cpi->twopass.sr_default_decay_limit > 1.33)
+    cpi->twopass.sr_default_decay_limit = 1.33;
+
   cpi->twopass.sr_diff_factor =
       (double)cfg->sr_diff_factor.num / (double)cfg->sr_diff_factor.den;
+  if (cpi->twopass.sr_diff_factor < 0.25)
+    cpi->twopass.sr_diff_factor = 0.25;
+  else if (cpi->twopass.sr_diff_factor > 4.0)
+    cpi->twopass.sr_diff_factor = 4.0;
+
   cpi->twopass.kf_err_per_mb = (double)cfg->kf_err_per_mb_factor.num /
                                (double)cfg->kf_err_per_mb_factor.den;
+  if (cpi->twopass.kf_err_per_mb < 0.25)
+    cpi->twopass.kf_err_per_mb = 0.25;
+  else if (cpi->twopass.kf_err_per_mb > 4.0)
+    cpi->twopass.kf_err_per_mb = 4.0;
+
   cpi->twopass.kf_frame_min_boost = (double)cfg->kf_frame_min_boost_factor.num /
                                     (double)cfg->kf_frame_min_boost_factor.den;
+  if (cpi->twopass.kf_frame_min_boost < 0.25)
+    cpi->twopass.kf_frame_min_boost = 0.25;
+  else if (cpi->twopass.kf_frame_min_boost > 4.0)
+    cpi->twopass.kf_frame_min_boost = 4.0;
+
   cpi->twopass.kf_frame_max_boost_first =
       (double)cfg->kf_frame_max_boost_first_factor.num /
       (double)cfg->kf_frame_max_boost_first_factor.den;
+  if (cpi->twopass.kf_frame_max_boost_first < 0.25)
+    cpi->twopass.kf_frame_max_boost_first = 0.25;
+  else if (cpi->twopass.kf_frame_max_boost_first > 4.0)
+    cpi->twopass.kf_frame_max_boost_first = 4.0;
+
   cpi->twopass.kf_frame_max_boost_subs =
       (double)cfg->kf_frame_max_boost_subs_factor.num /
       (double)cfg->kf_frame_max_boost_subs_factor.den;
+  if (cpi->twopass.kf_frame_max_boost_subs < 0.25)
+    cpi->twopass.kf_frame_max_boost_subs = 0.25;
+  else if (cpi->twopass.kf_frame_max_boost_subs > 4.0)
+    cpi->twopass.kf_frame_max_boost_subs = 4.0;
+
   cpi->twopass.kf_max_total_boost = (double)cfg->kf_max_total_boost_factor.num /
                                     (double)cfg->kf_max_total_boost_factor.den;
+  if (cpi->twopass.kf_max_total_boost < 0.25)
+    cpi->twopass.kf_max_total_boost = 0.25;
+  else if (cpi->twopass.kf_max_total_boost > 4.0)
+    cpi->twopass.kf_max_total_boost = 4.0;
+
   cpi->twopass.gf_max_total_boost = (double)cfg->gf_max_total_boost_factor.num /
                                     (double)cfg->gf_max_total_boost_factor.den;
+  if (cpi->twopass.gf_max_total_boost < 0.25)
+    cpi->twopass.gf_max_total_boost = 0.25;
+  else if (cpi->twopass.gf_max_total_boost > 4.0)
+    cpi->twopass.gf_max_total_boost = 4.0;
+
   cpi->twopass.gf_frame_max_boost = (double)cfg->gf_frame_max_boost_factor.num /
                                     (double)cfg->gf_frame_max_boost_factor.den;
+  if (cpi->twopass.gf_frame_max_boost < 0.25)
+    cpi->twopass.gf_frame_max_boost = 0.25;
+  else if (cpi->twopass.gf_frame_max_boost > 4.0)
+    cpi->twopass.gf_frame_max_boost = 4.0;
+
   cpi->twopass.zm_factor =
       (double)cfg->zm_factor.num / (double)cfg->zm_factor.den;
+  if (cpi->twopass.zm_factor < 0.25)
+    cpi->twopass.zm_factor = 0.25;
+  else if (cpi->twopass.zm_factor > 2.0)
+    cpi->twopass.zm_factor = 2.0;
+
   cpi->rd_ctrl.rd_mult_inter_qp_fac = (double)cfg->rd_mult_inter_qp_fac.num /
                                       (double)cfg->rd_mult_inter_qp_fac.den;
+  if (cpi->rd_ctrl.rd_mult_inter_qp_fac < 0.25)
+    cpi->rd_ctrl.rd_mult_inter_qp_fac = 0.25;
+  else if (cpi->rd_ctrl.rd_mult_inter_qp_fac > 4.0)
+    cpi->rd_ctrl.rd_mult_inter_qp_fac = 4.0;
+
   cpi->rd_ctrl.rd_mult_arf_qp_fac =
       (double)cfg->rd_mult_arf_qp_fac.num / (double)cfg->rd_mult_arf_qp_fac.den;
+  if (cpi->rd_ctrl.rd_mult_arf_qp_fac < 0.25)
+    cpi->rd_ctrl.rd_mult_arf_qp_fac = 0.25;
+  else if (cpi->rd_ctrl.rd_mult_arf_qp_fac > 4.0)
+    cpi->rd_ctrl.rd_mult_arf_qp_fac = 4.0;
+
   cpi->rd_ctrl.rd_mult_key_qp_fac =
       (double)cfg->rd_mult_key_qp_fac.num / (double)cfg->rd_mult_key_qp_fac.den;
+  if (cpi->rd_ctrl.rd_mult_key_qp_fac < 0.25)
+    cpi->rd_ctrl.rd_mult_key_qp_fac = 0.25;
+  else if (cpi->rd_ctrl.rd_mult_key_qp_fac > 4.0)
+    cpi->rd_ctrl.rd_mult_key_qp_fac = 4.0;
 
   return VPX_CODEC_OK;
 }