shithub: libvpx

Download patch

ref: 90c1cc651592f2dbad517ceb65dc0c0fef3d0dbc
parent: 04086a30664d2a3e89d6a6e4e1c18f1a82c8f958
parent: b5e754a840511c9956c033561955745a184495cb
author: Paul Wilkins <paulwilkins@google.com>
date: Fri Mar 19 15:44:38 EDT 2021

Merge "Change SR_diff calculation and representation"

--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -58,7 +58,6 @@
 #define INTRA_PART 0.005
 #define DEFAULT_DECAY_LIMIT 0.75
 #define LOW_SR_DIFF_TRHESH 0.1
-#define SR_DIFF_MAX 128.0
 #define LOW_CODED_ERR_PER_MB 10.0
 #define NCOUNT_FRAME_II_THRESH 6.0
 #define BASELINE_ERR_PER_MB 12500.0
@@ -1833,17 +1832,21 @@
   twopass->arnr_strength_adjustment = 0;
 }
 
-static double get_sr_decay_rate(const FRAME_INFO *frame_info,
-                                const TWO_PASS *const twopass,
+/* This function considers how the quality of prediction may be deteriorating
+ * with distance. It comapres 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
+ * 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;
-  const double motion_amplitude_part =
-      frame->pcnt_motion *
-      ((frame->mvc_abs + frame->mvr_abs) /
-       (frame_info->frame_height + frame_info->frame_width));
 
   modified_pct_inter = frame->pcnt_inter;
   if ((frame->coded_error > LOW_CODED_ERR_PER_MB) &&
@@ -1855,9 +1858,9 @@
   modified_pcnt_intra = 100 * (1.0 - modified_pct_inter);
 
   if ((sr_diff > LOW_SR_DIFF_TRHESH)) {
-    sr_diff = VPXMIN(sr_diff, SR_DIFF_MAX);
-    sr_decay = 1.0 - (twopass->sr_diff_part * sr_diff) - motion_amplitude_part -
-               (INTRA_PART * modified_pcnt_intra);
+    double sr_diff_part =
+        twopass->sr_diff_factor * ((sr_diff * 0.25) / frame->intra_error);
+    sr_decay = 1.0 - sr_diff_part - (INTRA_PART * modified_pcnt_intra);
   }
   return VPXMAX(sr_decay, twopass->sr_default_decay_limit);
 }
@@ -1864,20 +1867,17 @@
 
 // This function gives an estimate of how badly we believe the prediction
 // quality is decaying from frame to frame.
-static double get_zero_motion_factor(const FRAME_INFO *frame_info,
-                                     const TWO_PASS *const twopass,
+static double get_zero_motion_factor(const TWO_PASS *const twopass,
                                      const FIRSTPASS_STATS *frame_stats) {
   const double zero_motion_pct =
       frame_stats->pcnt_inter - frame_stats->pcnt_motion;
-  double sr_decay = get_sr_decay_rate(frame_info, twopass, frame_stats);
+  double sr_decay = get_sr_decay_rate(twopass, frame_stats);
   return VPXMIN(sr_decay, zero_motion_pct);
 }
 
-static double get_prediction_decay_rate(const FRAME_INFO *frame_info,
-                                        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(frame_info, twopass, 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));
@@ -2066,8 +2066,7 @@
 
     // Accumulate the effect of prediction quality decay.
     if (!flash_detected) {
-      decay_accumulator *=
-          get_prediction_decay_rate(frame_info, twopass, this_frame);
+      decay_accumulator *= get_prediction_decay_rate(twopass, this_frame);
       decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR
                               ? MIN_DECAY_FACTOR
                               : decay_accumulator;
@@ -2107,8 +2106,7 @@
 
     // Cumulative effect of prediction quality decay.
     if (!flash_detected) {
-      decay_accumulator *=
-          get_prediction_decay_rate(frame_info, twopass, this_frame);
+      decay_accumulator *= get_prediction_decay_rate(twopass, this_frame);
       decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR
                               ? MIN_DECAY_FACTOR
                               : decay_accumulator;
@@ -2606,16 +2604,14 @@
 
     // Monitor for static sections.
     if ((rc->frames_since_key + gop_coding_frames - 1) > 1) {
-      zero_motion_accumulator =
-          VPXMIN(zero_motion_accumulator,
-                 get_zero_motion_factor(frame_info, twopass, next_frame));
+      zero_motion_accumulator = VPXMIN(
+          zero_motion_accumulator, get_zero_motion_factor(twopass, next_frame));
     }
 
     // Accumulate the effect of prediction quality decay.
     if (!flash_detected) {
       double last_loop_decay_rate = loop_decay_rate;
-      loop_decay_rate =
-          get_prediction_decay_rate(frame_info, twopass, next_frame);
+      loop_decay_rate = get_prediction_decay_rate(twopass, next_frame);
 
       // Break clause to detect very still sections after motion. For example,
       // a static image after a fade or other transition.
@@ -3181,7 +3177,6 @@
 #define KF_ABS_ZOOM_THRESH 6.0
 
 int vp9_get_frames_to_next_key(const VP9EncoderConfig *oxcf,
-                               const FRAME_INFO *frame_info,
                                const TWO_PASS *const twopass, int kf_show_idx,
                                int min_gf_interval) {
   const FIRST_PASS_INFO *first_pass_info = &twopass->first_pass_info;
@@ -3211,8 +3206,7 @@
           break;
 
         // How fast is the prediction quality decaying?
-        loop_decay_rate =
-            get_prediction_decay_rate(frame_info, twopass, next_frame);
+        loop_decay_rate = get_prediction_decay_rate(twopass, next_frame);
 
         // We want to know something about the recent past... rather than
         // as used elsewhere where we are concerned with decay in prediction
@@ -3298,8 +3292,8 @@
   kf_mod_err = calc_norm_frame_score(oxcf, frame_info, keyframe_stats,
                                      mean_mod_score, av_err);
 
-  rc->frames_to_key = vp9_get_frames_to_next_key(
-      oxcf, frame_info, twopass, kf_show_idx, rc->min_gf_interval);
+  rc->frames_to_key = vp9_get_frames_to_next_key(oxcf, twopass, kf_show_idx,
+                                                 rc->min_gf_interval);
 
   // If there is a max kf interval set by the user we must obey it.
   // We already breakout of the loop above at 2x max.
@@ -3379,9 +3373,9 @@
       // Monitor for static sections.
       // First frame in kf group the second ref indicator is invalid.
       if (i > 0) {
-        zero_motion_accumulator = VPXMIN(
-            zero_motion_accumulator,
-            get_zero_motion_factor(&cpi->frame_info, twopass, &next_frame));
+        zero_motion_accumulator =
+            VPXMIN(zero_motion_accumulator,
+                   get_zero_motion_factor(twopass, &next_frame));
       } else {
         zero_motion_accumulator =
             next_frame.pcnt_inter - next_frame.pcnt_motion;
@@ -3493,7 +3487,7 @@
     twopass->active_wq_factor = AV_WQ_FACTOR;
     twopass->base_err_per_mb = BASELINE_ERR_PER_MB;
     twopass->sr_default_decay_limit = DEFAULT_DECAY_LIMIT;
-    twopass->sr_diff_part = SR_DIFF_PART;
+    twopass->sr_diff_factor = 1.0;
     twopass->gf_frame_max_boost = GF_MAX_FRAME_BOOST;
     twopass->gf_max_total_boost = MAX_GF_BOOST;
     if (screen_area < 1280 * 720) {
@@ -3515,7 +3509,7 @@
       twopass->active_wq_factor = 46.0;
       twopass->base_err_per_mb = 37597.399760969536;
       twopass->sr_default_decay_limit = 0.3905639800962774;
-      twopass->sr_diff_part = 0.009599023654146284;
+      twopass->sr_diff_factor = 6.4;
       twopass->gf_frame_max_boost = 87.27362648627846;
       twopass->gf_max_total_boost = MAX_GF_BOOST;
       twopass->kf_err_per_mb = 1854.8255436877148;
@@ -3528,7 +3522,7 @@
       twopass->active_wq_factor = 55.0;
       twopass->base_err_per_mb = 34525.33177195309;
       twopass->sr_default_decay_limit = 0.23901360046804604;
-      twopass->sr_diff_part = 0.008581014394766773;
+      twopass->sr_diff_factor = 5.73;
       twopass->gf_frame_max_boost = 127.34978204980285;
       twopass->gf_max_total_boost = MAX_GF_BOOST;
       twopass->kf_err_per_mb = 723.8337508755031;
@@ -3541,7 +3535,7 @@
       twopass->active_wq_factor = 12.5;
       twopass->base_err_per_mb = 18823.978018028298;
       twopass->sr_default_decay_limit = 0.6043527690301296;
-      twopass->sr_diff_part = 0.00343296783885544;
+      twopass->sr_diff_factor = 2.28;
       twopass->gf_frame_max_boost = 75.17672317013668;
       twopass->gf_max_total_boost = MAX_GF_BOOST;
       twopass->kf_err_per_mb = 422.2871502380377;
@@ -3554,7 +3548,7 @@
       twopass->active_wq_factor = 51.5;
       twopass->base_err_per_mb = 33718.98307662595;
       twopass->sr_default_decay_limit = 0.33633414970713393;
-      twopass->sr_diff_part = 0.00868988716928333;
+      twopass->sr_diff_factor = 5.8;
       twopass->gf_frame_max_boost = 85.2868528581522;
       twopass->gf_max_total_boost = MAX_GF_BOOST;
       twopass->kf_err_per_mb = 1513.4883914008383;
@@ -3567,7 +3561,7 @@
       twopass->active_wq_factor = 41.5;
       twopass->base_err_per_mb = 29527.46375825401;
       twopass->sr_default_decay_limit = 0.5009117586299728;
-      twopass->sr_diff_part = 0.005007364627260114;
+      twopass->sr_diff_factor = 3.33;
       twopass->gf_frame_max_boost = 81.00472969483079;
       twopass->gf_max_total_boost = MAX_GF_BOOST;
       twopass->kf_err_per_mb = 998.6342911785146;
@@ -3580,7 +3574,7 @@
       twopass->active_wq_factor = 31.0;
       twopass->base_err_per_mb = 34474.723463367416;
       twopass->sr_default_decay_limit = 0.23346886902707745;
-      twopass->sr_diff_part = 0.011431716637966029;
+      twopass->sr_diff_factor = 7.6;
       twopass->gf_frame_max_boost = 213.2940230360479;
       twopass->gf_max_total_boost = MAX_GF_BOOST;
       twopass->kf_err_per_mb = 35931.25734431429;
@@ -3873,9 +3867,8 @@
 
   *first_is_key_frame = 0;
   if (rc.frames_to_key == 0) {
-    rc.frames_to_key =
-        vp9_get_frames_to_next_key(&cpi->oxcf, &cpi->frame_info, twopass,
-                                   *first_show_idx, rc.min_gf_interval);
+    rc.frames_to_key = vp9_get_frames_to_next_key(
+        &cpi->oxcf, twopass, *first_show_idx, rc.min_gf_interval);
     rc.frames_since_key = 0;
     *first_is_key_frame = 1;
   }
@@ -3939,8 +3932,8 @@
     int use_alt_ref;
     int first_is_key_frame = 0;
     if (rc.frames_to_key == 0) {
-      rc.frames_to_key = vp9_get_frames_to_next_key(
-          oxcf, frame_info, twopass, show_idx, rc.min_gf_interval);
+      rc.frames_to_key = vp9_get_frames_to_next_key(oxcf, twopass, show_idx,
+                                                    rc.min_gf_interval);
       rc.frames_since_key = 0;
       first_is_key_frame = 1;
     }
@@ -3961,7 +3954,6 @@
 }
 
 void vp9_get_key_frame_map(const VP9EncoderConfig *oxcf,
-                           const FRAME_INFO *frame_info,
                            const TWO_PASS *const twopass, int *key_frame_map) {
   int show_idx = 0;
   RATE_CONTROL rc;
@@ -3975,8 +3967,8 @@
   while (show_idx < first_pass_info->num_frames) {
     int key_frame_group_size;
     key_frame_map[show_idx] = 1;
-    key_frame_group_size = vp9_get_frames_to_next_key(
-        oxcf, frame_info, twopass, show_idx, rc.min_gf_interval);
+    key_frame_group_size =
+        vp9_get_frames_to_next_key(oxcf, twopass, show_idx, rc.min_gf_interval);
     assert(key_frame_group_size > 0);
     show_idx += key_frame_group_size;
   }
--- a/vp9/encoder/vp9_firstpass.h
+++ b/vp9/encoder/vp9_firstpass.h
@@ -226,7 +226,7 @@
   double active_wq_factor;
   double base_err_per_mb;
   double sr_default_decay_limit;
-  double sr_diff_part;
+  double sr_diff_factor;
   double kf_err_per_mb;
   double kf_frame_min_boost;
   double kf_frame_max_boost_first;  // Max for first kf in a chunk.
@@ -262,7 +262,6 @@
 
 struct VP9EncoderConfig;
 int vp9_get_frames_to_next_key(const struct VP9EncoderConfig *oxcf,
-                               const FRAME_INFO *frame_info,
                                const TWO_PASS *const twopass, int kf_show_idx,
                                int min_gf_interval);
 #if CONFIG_RATE_CTRL
@@ -311,7 +310,6 @@
  * number of show frames in the video.
  */
 void vp9_get_key_frame_map(const struct VP9EncoderConfig *oxcf,
-                           const FRAME_INFO *frame_info,
                            const FIRST_PASS_INFO *first_pass_info,
                            int *key_frame_map);
 #endif  // CONFIG_RATE_CTRL
--- a/vp9/encoder/vp9_rd.c
+++ b/vp9/encoder/vp9_rd.c
@@ -201,14 +201,60 @@
 // Later this function will use passed in command line values.
 void vp9_init_rd_parameters(VP9_COMP *cpi) {
   RD_CONTROL *const rdc = &cpi->rd_ctrl;
-  unsigned int screen_area = (cpi->common.width * cpi->common.height);
 
   // Make sure this function is floating point safe.
   vpx_clear_system_state();
 
   rdc->rd_mult_q_sq_key_high_qp = 7.5;  // No defined Vizer values yet
-  if (1) {
-    // Non/pre-Vizer defaults
+
+  if (0) {
+    unsigned int screen_area = (cpi->common.width * cpi->common.height);
+
+    if (screen_area <= 176 * 144) {
+      rdc->rd_mult_q_sq_inter_low_qp = 4.0718581295922025;
+      rdc->rd_mult_q_sq_inter_mid_qp = 4.031435609256739;
+      rdc->rd_mult_q_sq_inter_high_qp = 4.295745965132044;
+      rdc->rd_mult_q_sq_key_ultralow_qp = 4.290774097327333;
+      rdc->rd_mult_q_sq_key_low_qp = 5.7037775720838155;
+      rdc->rd_mult_q_sq_key_mid_qp = 4.72424015517201;
+    } else if (screen_area <= 320 * 240) {
+      rdc->rd_mult_q_sq_inter_low_qp = 4.506676356706102;
+      rdc->rd_mult_q_sq_inter_mid_qp = 4.489349899621181;
+      rdc->rd_mult_q_sq_inter_high_qp = 4.388244213131458;
+      rdc->rd_mult_q_sq_key_ultralow_qp = 4.217074424696166;
+      rdc->rd_mult_q_sq_key_low_qp = 4.497000582319771;
+      rdc->rd_mult_q_sq_key_mid_qp = 4.2825894884789735;
+    } else if (screen_area <= 640 * 360) {
+      rdc->rd_mult_q_sq_inter_low_qp = 4.730644123689013;
+      rdc->rd_mult_q_sq_inter_mid_qp = 4.314589509578551;
+      rdc->rd_mult_q_sq_inter_high_qp = 4.3702861603380025;
+      rdc->rd_mult_q_sq_key_ultralow_qp = 4.576902541873747;
+      rdc->rd_mult_q_sq_key_low_qp = 6.068652999601526;
+      rdc->rd_mult_q_sq_key_mid_qp = 4.817707474077241;
+    } else if (screen_area <= 854 * 480) {
+      rdc->rd_mult_q_sq_inter_low_qp = 4.811470143416073;
+      rdc->rd_mult_q_sq_inter_mid_qp = 4.621618127750201;
+      rdc->rd_mult_q_sq_inter_high_qp = 3.969083125219539;
+      rdc->rd_mult_q_sq_key_ultralow_qp = 4.9854544277222566;
+      rdc->rd_mult_q_sq_key_low_qp = 5.073157238799473;
+      rdc->rd_mult_q_sq_key_mid_qp = 5.7587672849242635;
+    } else if (screen_area <= 1280 * 720) {
+      rdc->rd_mult_q_sq_inter_low_qp = 5.119381136011107;
+      rdc->rd_mult_q_sq_inter_mid_qp = 4.518613675766538;
+      rdc->rd_mult_q_sq_inter_high_qp = 4.410712348825541;
+      rdc->rd_mult_q_sq_key_ultralow_qp = 3.9468491666607326;
+      rdc->rd_mult_q_sq_key_low_qp = 5.848703119971484;
+      rdc->rd_mult_q_sq_key_mid_qp = 5.368947246228739;
+    } else {
+      rdc->rd_mult_q_sq_inter_low_qp = 6.00569815296199;
+      rdc->rd_mult_q_sq_inter_mid_qp = 3.932565684947023;
+      rdc->rd_mult_q_sq_inter_high_qp = 3.2141187537667797;
+      rdc->rd_mult_q_sq_key_ultralow_qp = 4.399795006320089;
+      rdc->rd_mult_q_sq_key_low_qp = 10.582906599488298;
+      rdc->rd_mult_q_sq_key_mid_qp = 6.274162346360692;
+    }
+  } else {
+    // For now force defaults unless testing
     rdc->rd_mult_q_sq_inter_low_qp = 4.0;
     rdc->rd_mult_q_sq_inter_mid_qp = 4.5;
     rdc->rd_mult_q_sq_inter_high_qp = 3.0;
@@ -215,48 +261,6 @@
     rdc->rd_mult_q_sq_key_ultralow_qp = 4.0;
     rdc->rd_mult_q_sq_key_low_qp = 3.5;
     rdc->rd_mult_q_sq_key_mid_qp = 4.5;
-  } else if (screen_area <= 176 * 144) {
-    rdc->rd_mult_q_sq_inter_low_qp = 4.0718581295922025;
-    rdc->rd_mult_q_sq_inter_mid_qp = 4.031435609256739;
-    rdc->rd_mult_q_sq_inter_high_qp = 4.295745965132044;
-    rdc->rd_mult_q_sq_key_ultralow_qp = 4.290774097327333;
-    rdc->rd_mult_q_sq_key_low_qp = 5.7037775720838155;
-    rdc->rd_mult_q_sq_key_mid_qp = 4.72424015517201;
-  } else if (screen_area <= 320 * 240) {
-    rdc->rd_mult_q_sq_inter_low_qp = 4.506676356706102;
-    rdc->rd_mult_q_sq_inter_mid_qp = 4.489349899621181;
-    rdc->rd_mult_q_sq_inter_high_qp = 4.388244213131458;
-    rdc->rd_mult_q_sq_key_ultralow_qp = 4.217074424696166;
-    rdc->rd_mult_q_sq_key_low_qp = 4.497000582319771;
-    rdc->rd_mult_q_sq_key_mid_qp = 4.2825894884789735;
-  } else if (screen_area <= 640 * 360) {
-    rdc->rd_mult_q_sq_inter_low_qp = 4.730644123689013;
-    rdc->rd_mult_q_sq_inter_mid_qp = 4.314589509578551;
-    rdc->rd_mult_q_sq_inter_high_qp = 4.3702861603380025;
-    rdc->rd_mult_q_sq_key_ultralow_qp = 4.576902541873747;
-    rdc->rd_mult_q_sq_key_low_qp = 6.068652999601526;
-    rdc->rd_mult_q_sq_key_mid_qp = 4.817707474077241;
-  } else if (screen_area <= 854 * 480) {
-    rdc->rd_mult_q_sq_inter_low_qp = 4.811470143416073;
-    rdc->rd_mult_q_sq_inter_mid_qp = 4.621618127750201;
-    rdc->rd_mult_q_sq_inter_high_qp = 3.969083125219539;
-    rdc->rd_mult_q_sq_key_ultralow_qp = 4.9854544277222566;
-    rdc->rd_mult_q_sq_key_low_qp = 5.073157238799473;
-    rdc->rd_mult_q_sq_key_mid_qp = 5.7587672849242635;
-  } else if (screen_area <= 1280 * 720) {
-    rdc->rd_mult_q_sq_inter_low_qp = 5.119381136011107;
-    rdc->rd_mult_q_sq_inter_mid_qp = 4.518613675766538;
-    rdc->rd_mult_q_sq_inter_high_qp = 4.410712348825541;
-    rdc->rd_mult_q_sq_key_ultralow_qp = 3.9468491666607326;
-    rdc->rd_mult_q_sq_key_low_qp = 5.848703119971484;
-    rdc->rd_mult_q_sq_key_mid_qp = 5.368947246228739;
-  } else {
-    rdc->rd_mult_q_sq_inter_low_qp = 6.00569815296199;
-    rdc->rd_mult_q_sq_inter_mid_qp = 3.932565684947023;
-    rdc->rd_mult_q_sq_inter_high_qp = 3.2141187537667797;
-    rdc->rd_mult_q_sq_key_ultralow_qp = 4.399795006320089;
-    rdc->rd_mult_q_sq_key_low_qp = 10.582906599488298;
-    rdc->rd_mult_q_sq_key_mid_qp = 6.274162346360692;
   }
 }