Change zm_factor for Vizier.
authorPaul Wilkins <paulwilkins@google.com>
Tue, 6 Apr 2021 19:05:48 +0000 (20:05 +0100)
committerPaul Wilkins <paulwilkins@google.com>
Tue, 6 Apr 2021 20:04:48 +0000 (21:04 +0100)
Changes the exposed zm_factor parameter.

This patch alters the meaning of the zm_factor
parameter that will be exposed for the Vizier project.

The previous power factor was hard to interpret in terms
of its meaning and effect and has been replaced by a linear factor.
Given that the initial Vizier results suggested a lower zero motion
effect for all formats, the default impact has been reduced.

The patch as it stands gives a modest improvement for PSNR
but is slightly down on some sets for SSIM

(overall psnr, ssim % bdrate change: -ve is better)

lowres    -0.111, 0.001
ugc360p   -0.282, -0.068
midres2   -0.183, 0.059
hdres2    -0.042, 0.172

Change-Id: Id6566433ceed8470d5fad1f30282daed56de385d

vp8/vp8_cx_iface.c
vp9/encoder/vp9_firstpass.c
vp9/encoder/vp9_firstpass.h
vp9/vp9_cx_iface.c
vpx/vpx_encoder.h
vpxenc.c

index 3f09ec3..1ffd819 100644 (file)
@@ -268,7 +268,7 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
   RANGE_CHECK(cfg, kf_max_total_boost.den, 1, 1000);
   RANGE_CHECK(cfg, gf_max_total_boost.den, 1, 1000);
   RANGE_CHECK(cfg, gf_frame_max_boost.den, 1, 1000);
-  RANGE_CHECK(cfg, zm_power_factor.den, 1, 1000);
+  RANGE_CHECK(cfg, zm_factor.den, 1, 1000);
 
   return VPX_CODEC_OK;
 }
@@ -1313,7 +1313,7 @@ static vpx_codec_enc_cfg_map_t vp8e_usage_cfg_map[] = {
         { 0, 1 }, /* kf_max_total_boost */
         { 0, 1 }, /* gf_max_total_boost */
         { 0, 1 }, /* gf_frame_max_boost */
-        { 0, 1 }, /* zm_power_factor */
+        { 0, 1 }, /* zm_factor */
     } },
 };
 
index a43099e..f142f26 100644 (file)
@@ -73,7 +73,7 @@
 #define MAX_KF_TOT_BOOST 5400
 #endif
 
-#define ZM_POWER_FACTOR 0.75
+#define DEFAULT_ZM_FACTOR 0.5
 #define MINQ_ADJ_LIMIT 48
 #define MINQ_ADJ_LIMIT_CQ 20
 #define HIGH_UNDERSHOOT_RATIO 2
@@ -1878,9 +1878,17 @@ static double get_zero_motion_factor(const TWO_PASS *const twopass,
 static double get_prediction_decay_rate(const TWO_PASS *const twopass,
                                         const FIRSTPASS_STATS *frame_stats) {
   const double sr_decay_rate = get_sr_decay_rate(twopass, frame_stats);
-  const double zero_motion_factor =
-      (0.95 * pow((frame_stats->pcnt_inter - frame_stats->pcnt_motion),
-                  twopass->zm_power_factor));
+  double zero_motion_factor =
+      twopass->zm_factor * DEFAULT_ZM_FACTOR *
+      (frame_stats->pcnt_inter - frame_stats->pcnt_motion);
+
+  // Clamp value to range 0.0 to 1.0
+  // This should happen anyway if input values are sensibly clamped but checked
+  // here just in case.
+  if (zero_motion_factor > 1.0)
+    zero_motion_factor = 1.0;
+  else if (zero_motion_factor < 0.0)
+    zero_motion_factor = 0.0;
 
   return VPXMAX(zero_motion_factor,
                 (sr_decay_rate + ((1.0 - sr_decay_rate) * zero_motion_factor)));
@@ -3501,7 +3509,7 @@ static void init_vizier_params(TWO_PASS *const twopass, int screen_area) {
     twopass->kf_frame_max_boost_first = KF_MAX_FRAME_BOOST;
     twopass->kf_frame_max_boost_subs = twopass->kf_frame_max_boost_first;
     twopass->kf_max_total_boost = MAX_KF_TOT_BOOST;
-    twopass->zm_power_factor = ZM_POWER_FACTOR;
+    twopass->zm_factor = 1.0;
   } else {
     // Vizer experimental parameters from training.
     // Later these will be set via the command line.
@@ -3517,7 +3525,7 @@ static void init_vizier_params(TWO_PASS *const twopass, int screen_area) {
       twopass->kf_frame_max_boost_first = 25.5;
       twopass->kf_frame_max_boost_subs = twopass->kf_frame_max_boost_first;
       twopass->kf_max_total_boost = MAX_KF_TOT_BOOST;
-      twopass->zm_power_factor = 2.93715229184991;
+      twopass->zm_factor = 1.0;
     } else if (screen_area <= 320 * 240) {
       twopass->active_wq_factor = 55.0;
       twopass->base_err_per_mb = 34525.33177195309;
@@ -3530,7 +3538,7 @@ static void init_vizier_params(TWO_PASS *const twopass, int screen_area) {
       twopass->kf_frame_max_boost_first = 185.0;
       twopass->kf_frame_max_boost_subs = twopass->kf_frame_max_boost_first;
       twopass->kf_max_total_boost = MAX_KF_TOT_BOOST;
-      twopass->zm_power_factor = 3.5299221493593413;
+      twopass->zm_factor = 1.0;
     } else if (screen_area <= 640 * 360) {
       twopass->active_wq_factor = 12.5;
       twopass->base_err_per_mb = 18823.978018028298;
@@ -3543,7 +3551,7 @@ static void init_vizier_params(TWO_PASS *const twopass, int screen_area) {
       twopass->kf_frame_max_boost_first = 224.5;
       twopass->kf_frame_max_boost_subs = twopass->kf_frame_max_boost_first;
       twopass->kf_max_total_boost = MAX_KF_TOT_BOOST;
-      twopass->zm_power_factor = 2.265742666649307;
+      twopass->zm_factor = 1.0;
     } else if (screen_area <= 854 * 480) {
       twopass->active_wq_factor = 51.5;
       twopass->base_err_per_mb = 33718.98307662595;
@@ -3556,7 +3564,7 @@ static void init_vizier_params(TWO_PASS *const twopass, int screen_area) {
       twopass->kf_frame_max_boost_first = 28.0;
       twopass->kf_frame_max_boost_subs = twopass->kf_frame_max_boost_first;
       twopass->kf_max_total_boost = MAX_KF_TOT_BOOST;
-      twopass->zm_power_factor = 3.552278528517416;
+      twopass->zm_factor = 1.0;
     } else if (screen_area <= 1280 * 720) {
       twopass->active_wq_factor = 41.5;
       twopass->base_err_per_mb = 29527.46375825401;
@@ -3569,7 +3577,7 @@ static void init_vizier_params(TWO_PASS *const twopass, int screen_area) {
       twopass->kf_frame_max_boost_first = 53.0;
       twopass->kf_frame_max_boost_subs = twopass->kf_frame_max_boost_first;
       twopass->kf_max_total_boost = MAX_KF_TOT_BOOST;
-      twopass->zm_power_factor = 2.568627575572356;
+      twopass->zm_factor = 1.0;
     } else {
       twopass->active_wq_factor = 31.0;
       twopass->base_err_per_mb = 34474.723463367416;
@@ -3582,7 +3590,7 @@ static void init_vizier_params(TWO_PASS *const twopass, int screen_area) {
       twopass->kf_frame_max_boost_first = 419.5;
       twopass->kf_frame_max_boost_subs = twopass->kf_frame_max_boost_first;
       twopass->kf_max_total_boost = MAX_KF_TOT_BOOST;
-      twopass->zm_power_factor = 5.5776463538431935;
+      twopass->zm_factor = 1.0;
     }
   }
 }
index 624fccd..8ec8a44 100644 (file)
@@ -234,7 +234,7 @@ typedef struct {
   int kf_max_total_boost;
   int gf_max_total_boost;
   double gf_frame_max_boost;
-  double zm_power_factor;
+  double zm_factor;
 } TWO_PASS;
 
 struct VP9_COMP;
index 7530850..94b1afb 100644 (file)
@@ -360,7 +360,7 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
   RANGE_CHECK(cfg, kf_max_total_boost.den, 1, 1000);
   RANGE_CHECK(cfg, gf_max_total_boost.den, 1, 1000);
   RANGE_CHECK(cfg, gf_frame_max_boost.den, 1, 1000);
-  RANGE_CHECK(cfg, zm_power_factor.den, 1, 1000);
+  RANGE_CHECK(cfg, zm_factor.den, 1, 1000);
 
   return VPX_CODEC_OK;
 }
@@ -681,8 +681,8 @@ static vpx_codec_err_t set_twopass_params_from_config(
                                           (double)cfg->gf_max_total_boost.den);
   cpi->twopass.gf_frame_max_boost =
       (double)cfg->gf_frame_max_boost.num / (double)cfg->gf_frame_max_boost.den;
-  cpi->twopass.zm_power_factor =
-      (double)cfg->zm_power_factor.num / (double)cfg->zm_power_factor.den;
+  cpi->twopass.zm_factor =
+      (double)cfg->zm_factor.num / (double)cfg->zm_factor.den;
 
   return VPX_CODEC_OK;
 }
@@ -1954,7 +1954,7 @@ static vpx_codec_enc_cfg_map_t encoder_usage_cfg_map[] = {
         { 0, 1 },  // kf_max_total_boost
         { 0, 1 },  // gf_max_total_boost
         { 0, 1 },  // gf_frame_max_boost
-        { 0, 1 },  // zm_power_factor
+        { 0, 1 },  // zm_factor
     } },
 };
 
index accc127..497051e 100644 (file)
@@ -776,7 +776,7 @@ typedef struct vpx_codec_enc_cfg {
    * Rate control parameters, set from external experiment results.
    *
    */
-  vpx_rational_t zm_power_factor;
+  vpx_rational_t zm_factor;
 } vpx_codec_enc_cfg_t; /**< alias for struct vpx_codec_enc_cfg */
 
 /*!\brief  vp9 svc extra configure parameters
index 3c04c64..874dddb 100644 (file)
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -310,7 +310,7 @@ static const arg_def_t gf_max_total_boost =
     ARG_DEF(NULL, "gf-max-total-boost", 1, "Golden frame max total boost");
 static const arg_def_t gf_frame_max_boost =
     ARG_DEF(NULL, "gf-frame-max-boost", 1, "Golden frame max boost");
-static const arg_def_t zm_power_factor =
+static const arg_def_t zm_factor =
     ARG_DEF(NULL, "zm-power-factor", 1, "Zero motion power factor");
 static const arg_def_t *vizier_rc_args[] = { &active_wq_factor,
                                              &base_err_per_mb,
@@ -323,7 +323,7 @@ static const arg_def_t *vizier_rc_args[] = { &active_wq_factor,
                                              &kf_max_total_boost,
                                              &gf_max_total_boost,
                                              &gf_frame_max_boost,
-                                             &zm_power_factor,
+                                             &zm_factor,
                                              NULL };
 #endif
 
@@ -1048,8 +1048,8 @@ static int parse_stream_params(struct VpxEncoderConfig *global,
       config->cfg.gf_max_total_boost = arg_parse_rational(&arg);
     } else if (arg_match(&arg, &gf_frame_max_boost, argi)) {
       config->cfg.gf_frame_max_boost = arg_parse_rational(&arg);
-    } else if (arg_match(&arg, &zm_power_factor, argi)) {
-      config->cfg.zm_power_factor = arg_parse_rational(&arg);
+    } else if (arg_match(&arg, &zm_factor, argi)) {
+      config->cfg.zm_factor = arg_parse_rational(&arg);
 #endif
 #if CONFIG_VP9_HIGHBITDEPTH
     } else if (arg_match(&arg, &test16bitinternalarg, argi)) {