shithub: libvpx

Download patch

ref: 9f57bc4d6c7a577538042a49ede8ee98dc8cc300
parent: c15555c62fc35872a4ff803c4d57ef5d2f4f81d9
author: Paul Wilkins <paulwilkins@google.com>
date: Mon Apr 26 11:06:54 EDT 2021

Add limits to Vizier input parameters.

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

--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -1832,12 +1832,12 @@
 }
 
 /* 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,
@@ -1844,21 +1844,23 @@
                                 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 @@
   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 @@
       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 @@
     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
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -664,41 +664,118 @@
   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;
 }