resize-refactor: Refactor 2-pass VBR resizing

Replaces resizing's table and index approach to frame sizes with
numerator and denominator integers in the AV1_COMP struct.

This approach is more flexible and will be simpler going forward as it
is much more similar to the 1-pass CBR approach that is also being
refactored. The intention is to merge both approaches and this is the
first step toward that.

Change-Id: I5733c0687390f8a8e2790dcddfa09fb08ab88376
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 35f9f20..c623bdc 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -2189,9 +2189,15 @@
   memset(cm->fc, 0, sizeof(*cm->fc));
   memset(cm->frame_contexts, 0, FRAME_CONTEXTS * sizeof(*cm->frame_contexts));
 
+  cpi->resize_pending = 0;
   cpi->resize_state = 0;
   cpi->resize_avg_qp = 0;
   cpi->resize_buffer_underflow = 0;
+  cpi->resize_scale_num = 16;
+  cpi->resize_scale_den = 16;
+  cpi->resize_next_scale_num = 16;
+  cpi->resize_next_scale_den = 16;
+
   cpi->common.buffer_pool = pool;
 
   init_config(cpi, oxcf);
@@ -3047,11 +3053,18 @@
   int scale = 0;
   assert(frame_is_kf_gf_arf(cpi));
 
-  if (rc->frame_size_selector == UNSCALED &&
+  if (cpi->resize_scale_num == cpi->resize_scale_den &&
       q >= rc->rf_level_maxq[gf_group->rf_level[gf_group->index]]) {
+    const int old_num = cpi->resize_scale_num;
+    --cpi->resize_scale_num;
+    if (cpi->resize_scale_num <= 0) {
+      cpi->resize_scale_num = old_num;
+      return 0;
+    }
     const int max_size_thresh =
-        (int)(rate_thresh_mult[SCALE_STEP1] *
+        (int)(av1_resize_rate_factor(cpi) *
               AOMMAX(rc->this_frame_target, rc->avg_frame_bandwidth));
+    cpi->resize_scale_num = old_num;
     scale = rc->projected_frame_size > max_size_thresh ? 1 : 0;
   }
   return scale;
@@ -4332,9 +4345,13 @@
 
         if (cpi->resize_pending == 1) {
           // Change in frame size so go back around the recode loop.
-          cpi->rc.frame_size_selector =
-              SCALE_STEP1 - cpi->rc.frame_size_selector;
-          cpi->rc.next_frame_size_selector = cpi->rc.frame_size_selector;
+          // 11/16 is close to the old 2/3, then goes back to 16/16.
+          cpi->resize_scale_num -= 5;
+          if (cpi->resize_scale_num < 8 || cpi->resize_scale_num > 16)
+            cpi->resize_scale_num = 16;
+          cpi->resize_scale_den = 16;
+          cpi->resize_next_scale_num = cpi->resize_scale_num;
+          cpi->resize_next_scale_den = cpi->resize_scale_den;
 
 #if CONFIG_INTERNAL_STATS
           ++cpi->tot_recode_hits;
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 4e7aef8..68808a7 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -629,6 +629,8 @@
   int resize_state;
   int resize_scale_num;
   int resize_scale_den;
+  int resize_next_scale_num;
+  int resize_next_scale_den;
   int resize_avg_qp;
   int resize_buffer_underflow;
   int resize_count;
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c
index e35a54e..109de34 100644
--- a/av1/encoder/firstpass.c
+++ b/av1/encoder/firstpass.c
@@ -1235,27 +1235,12 @@
   }
 }
 
-void av1_init_subsampling(AV1_COMP *cpi) {
-  const AV1_COMMON *const cm = &cpi->common;
-  RATE_CONTROL *const rc = &cpi->rc;
-  const int w = cm->width;
-  const int h = cm->height;
-  int i;
-
-  for (i = 0; i < FRAME_SCALE_STEPS; ++i) {
-    // Note: Frames with odd-sized dimensions may result from this scaling.
-    rc->frame_width[i] = (w * 16) / frame_scale_factor[i];
-    rc->frame_height[i] = (h * 16) / frame_scale_factor[i];
-  }
-
-  setup_rf_level_maxq(cpi);
-}
-
-void av1_calculate_coded_size(AV1_COMP *cpi, int *scaled_frame_width,
+void av1_calculate_coded_size(const AV1_COMP *cpi, int *scaled_frame_width,
                               int *scaled_frame_height) {
-  RATE_CONTROL *const rc = &cpi->rc;
-  *scaled_frame_width = rc->frame_width[rc->frame_size_selector];
-  *scaled_frame_height = rc->frame_height[rc->frame_size_selector];
+  *scaled_frame_width =
+      cpi->oxcf.width * cpi->resize_scale_num / cpi->resize_scale_den;
+  *scaled_frame_height =
+      cpi->oxcf.height * cpi->resize_scale_num / cpi->resize_scale_den;
 }
 
 void av1_init_second_pass(AV1_COMP *cpi) {
@@ -1316,7 +1301,7 @@
   twopass->last_kfgroup_zeromotion_pct = 100;
 
   if (oxcf->resize_mode != RESIZE_NONE) {
-    av1_init_subsampling(cpi);
+    setup_rf_level_maxq(cpi);
   }
 }
 
@@ -2300,7 +2285,8 @@
 
   if (oxcf->resize_mode == RESIZE_DYNAMIC) {
     // Default to starting GF groups at normal frame size.
-    cpi->rc.next_frame_size_selector = UNSCALED;
+    // TODO(afergs): Make a function for this
+    cpi->resize_next_scale_num = cpi->resize_next_scale_den;
   }
 }
 
@@ -2646,7 +2632,8 @@
 
   if (oxcf->resize_mode == RESIZE_DYNAMIC) {
     // Default to normal-sized frame on keyframes.
-    cpi->rc.next_frame_size_selector = UNSCALED;
+    // TODO(afergs): Make a function for this
+    cpi->resize_next_scale_num = cpi->resize_next_scale_den;
   }
 }
 
diff --git a/av1/encoder/firstpass.h b/av1/encoder/firstpass.h
index db459cc..cb893d4 100644
--- a/av1/encoder/firstpass.h
+++ b/av1/encoder/firstpass.h
@@ -177,9 +177,8 @@
 // Post encode update of the rate control parameters for 2-pass
 void av1_twopass_postencode_update(struct AV1_COMP *cpi);
 
-void av1_init_subsampling(struct AV1_COMP *cpi);
-
-void av1_calculate_coded_size(struct AV1_COMP *cpi, int *scaled_frame_width,
+void av1_calculate_coded_size(const struct AV1_COMP *cpi,
+                              int *scaled_frame_width,
                               int *scaled_frame_height);
 
 #if CONFIG_EXT_REFS
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index 1f2ea36..8500b83 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -93,6 +93,11 @@
 static int kf_high = 5000;
 static int kf_low = 400;
 
+double av1_resize_rate_factor(const AV1_COMP *cpi) {
+  return (double)(cpi->resize_scale_den * cpi->resize_scale_den) /
+         (cpi->resize_scale_num * cpi->resize_scale_num);
+}
+
 // Functions to compute the active minq lookup table entries based on a
 // formulaic approach to facilitate easier adjustment of the Q tables.
 // The formulae were derived from computing a 3rd order polynomial best
@@ -384,7 +389,7 @@
     else
       rcf = rc->rate_correction_factors[INTER_NORMAL];
   }
-  rcf *= rcf_mult[rc->frame_size_selector];
+  rcf *= av1_resize_rate_factor(cpi);
   return fclamp(rcf, MIN_BPB_FACTOR, MAX_BPB_FACTOR);
 }
 
@@ -392,7 +397,7 @@
   RATE_CONTROL *const rc = &cpi->rc;
 
   // Normalize RCF to account for the size-dependent scaling factor.
-  factor /= rcf_mult[cpi->rc.frame_size_selector];
+  factor /= av1_resize_rate_factor(cpi);
 
   factor = fclamp(factor, MIN_BPB_FACTOR, MAX_BPB_FACTOR);
 
@@ -1076,7 +1081,8 @@
   }
 
   // Modify active_best_quality for downscaled normal frames.
-  if (rc->frame_size_selector != UNSCALED && !frame_is_kf_gf_arf(cpi)) {
+  if (cpi->resize_scale_num != cpi->resize_scale_den &&
+      !frame_is_kf_gf_arf(cpi)) {
     int qdelta = av1_compute_qdelta_by_rate(
         rc, cm->frame_type, active_best_quality, 2.0, cm->bit_depth);
     active_best_quality =
@@ -1160,9 +1166,9 @@
 
   // Modify frame size target when down-scaling.
   if (cpi->oxcf.resize_mode == RESIZE_DYNAMIC &&
-      rc->frame_size_selector != UNSCALED)
-    rc->this_frame_target = (int)(rc->this_frame_target *
-                                  rate_thresh_mult[rc->frame_size_selector]);
+      cpi->resize_scale_num != cpi->resize_scale_den)
+    rc->this_frame_target =
+        (int)(rc->this_frame_target * av1_resize_rate_factor(cpi));
 
   // Target rate per SB64 (including partial SB64s.
   rc->sb64_target_rate = (int)((int64_t)rc->this_frame_target * 64 * 64) /
@@ -1321,8 +1327,10 @@
   // Trigger the resizing of the next frame if it is scaled.
   if (oxcf->pass != 0) {
     cpi->resize_pending =
-        rc->next_frame_size_selector != rc->frame_size_selector;
-    rc->frame_size_selector = rc->next_frame_size_selector;
+        (cpi->resize_next_scale_num != cpi->resize_scale_num ||
+         cpi->resize_next_scale_den != cpi->resize_scale_den);
+    cpi->resize_scale_num = cpi->resize_next_scale_num;
+    cpi->resize_scale_den = cpi->resize_next_scale_den;
   }
 }
 
diff --git a/av1/encoder/ratectrl.h b/av1/encoder/ratectrl.h
index 93a9b49..61bb0c2 100644
--- a/av1/encoder/ratectrl.h
+++ b/av1/encoder/ratectrl.h
@@ -49,27 +49,6 @@
 } RATE_FACTOR_LEVEL;
 #endif  // CONFIG_EXT_REFS
 
-// Internal frame scaling level.
-typedef enum {
-  UNSCALED = 0,     // Frame is unscaled.
-  SCALE_STEP1 = 1,  // First-level down-scaling.
-  FRAME_SCALE_STEPS
-} FRAME_SCALE_LEVEL;
-
-// Frame dimensions multiplier wrt the native frame size, in 1/16ths,
-// specified for the scale-up case.
-// e.g. 24 => 16/24 = 2/3 of native size. The restriction to 1/16th is
-// intended to match the capabilities of the normative scaling filters,
-// giving precedence to the up-scaling accuracy.
-static const int frame_scale_factor[FRAME_SCALE_STEPS] = { 16, 24 };
-
-// Multiplier of the target rate to be used as threshold for triggering scaling.
-static const double rate_thresh_mult[FRAME_SCALE_STEPS] = { 1.0, 2.0 };
-
-// Scale dependent Rate Correction Factor multipliers. Compensates for the
-// greater number of bits per pixel generated in down-scaled frames.
-static const double rcf_mult[FRAME_SCALE_STEPS] = { 1.0, 2.0 };
-
 typedef struct {
   // Rate targetting variables
   int base_frame_target;  // A baseline frame target before adjustment
@@ -162,10 +141,6 @@
   int q_2_frame;
 
   // Auto frame-scaling variables.
-  FRAME_SCALE_LEVEL frame_size_selector;
-  FRAME_SCALE_LEVEL next_frame_size_selector;
-  int frame_width[FRAME_SCALE_STEPS];
-  int frame_height[FRAME_SCALE_STEPS];
   int rf_level_maxq[RATE_FACTOR_LEVELS];
 } RATE_CONTROL;
 
@@ -214,6 +189,10 @@
 void av1_rc_get_one_pass_vbr_params(struct AV1_COMP *cpi);
 void av1_rc_get_one_pass_cbr_params(struct AV1_COMP *cpi);
 
+// How many times less pixels there are to encode given the current scaling.
+// Temporary replacement for rcf_mult and rate_thresh_mult.
+double av1_resize_rate_factor(const struct AV1_COMP *cpi);
+
 // Post encode update of the rate control parameters based
 // on bytes used
 void av1_rc_postencode_update(struct AV1_COMP *cpi, uint64_t bytes_used);