Tune the decision on the GF group interval

The change is purely an encoder-side tuning, which constrains a GF
group interval to be either 8, or 12, or a number larger than 12
(maximum of 16). The change is under ext_refs.

This work has been part of the summer internship effort by chendixi@.

Further, this CL removes the experiment of flex_refs and merges it
into ext_refs, as flex_refs has been completely focused on the encoder
side optimization for ext_refs.

On Google test sets, above (stillness + interval enforcement) achieve
a coding gain in BDRate as follows, compared against the AV1 baseline
with all tools enabled by default (excluding ext-tx, global-motion,
and convolve-round for speed concern):

lowres: avg_psnr -0.193%; ovr_psnr -0.370%; ssim -0.332%
midres: avg_psnr -0.556%; ovr_psnr -0.680%; ssim -0.798%

Change-Id: Ia992d8ef0d82cc0ef2caba5eec9b26f0358e6bde
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index efad67a..8a3d9d3 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -602,10 +602,10 @@
   int sb_scanning_pass_idx;
 #endif  // CONFIG_SPEED_REFS
 
-#if CONFIG_FLEX_REFS
+#if CONFIG_EXT_REFS
   int extra_arf_allowed;
   int bwd_ref_allowed;
-#endif  // CONFIG_FLEX_REFS
+#endif  // CONFIG_EXT_REFS
 } AV1_COMP;
 
 void av1_initialize_enc(void);
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c
index 8b4c304..7240c45 100644
--- a/av1/encoder/firstpass.c
+++ b/av1/encoder/firstpass.c
@@ -456,7 +456,7 @@
   cpi->rc.frames_to_key = INT_MAX;
 }
 
-#if CONFIG_FLEX_REFS
+#if CONFIG_EXT_REFS
 static double raw_motion_error_stdev(int *raw_motion_err_list,
                                      int raw_motion_err_counts) {
   int64_t sum_raw_err = 0;
@@ -479,7 +479,7 @@
   raw_err_stdev = sqrt(raw_err_stdev / raw_motion_err_counts);
   return raw_err_stdev;
 }
-#endif  // CONFIG_FLEX_REFS
+#endif  // CONFIG_EXT_REFS
 
 #define UL_INTRA_THRESH 50
 #define INVALID_ROW -1
@@ -531,13 +531,13 @@
   od_adapt_ctx pvq_context;
 #endif
 
-#if CONFIG_FLEX_REFS
+#if CONFIG_EXT_REFS
   int *raw_motion_err_list;
   int raw_motion_err_counts = 0;
   CHECK_MEM_ERROR(
       cm, raw_motion_err_list,
       aom_calloc(cm->mb_rows * cm->mb_cols, sizeof(*raw_motion_err_list)));
-#endif  // CONFIG_FLEX_REFS
+#endif  // CONFIG_EXT_REFS
   // First pass code requires valid last and new frame buffers.
   assert(new_yv12 != NULL);
   assert(frame_is_intra_only(cm) || (lst_yv12 != NULL));
@@ -1000,9 +1000,9 @@
             }
           }
         }
-#if CONFIG_FLEX_REFS
+#if CONFIG_EXT_REFS
         raw_motion_err_list[raw_motion_err_counts++] = raw_motion_error;
-#endif  // CONFIG_FLEX_REFS
+#endif  // CONFIG_EXT_REFS
       } else {
         sr_coded_error += (int64_t)this_error;
       }
@@ -1025,10 +1025,12 @@
 
     aom_clear_system_state();
   }
-#if CONFIG_FLEX_REFS
+#if CONFIG_EXT_REFS
   const double raw_err_stdev =
       raw_motion_error_stdev(raw_motion_err_list, raw_motion_err_counts);
-#endif  // CONFIG_FLEX_REFS
+  aom_free(raw_motion_err_list);
+#endif  // CONFIG_EXT_REFS
+
 #if CONFIG_PVQ
 #if !CONFIG_ANS
   od_ec_enc_clear(&x->daala_enc.w.ec);
@@ -1082,9 +1084,9 @@
     fps.intra_skip_pct = (double)intra_skip_count / num_mbs;
     fps.inactive_zone_rows = (double)image_data_start_row;
     fps.inactive_zone_cols = (double)0;  // TODO(paulwilkins): fix
-#if CONFIG_FLEX_REFS
+#if CONFIG_EXT_REFS
     fps.raw_error_stdev = raw_err_stdev;
-#endif  // CONFIG_FLEX_REFS
+#endif  // CONFIG_EXT_REFS
 
     if (mvcount > 0) {
       fps.MVr = (double)sum_mvr / mvcount;
@@ -1692,10 +1694,8 @@
   // (3) The bi-predictive group interval is strictly smaller than the
   //     golden group interval.
   const int is_bipred_enabled =
-#if CONFIG_FLEX_REFS
-      cpi->bwd_ref_allowed &&
-#endif
-      rc->source_alt_ref_pending && rc->bipred_group_interval &&
+      cpi->bwd_ref_allowed && rc->source_alt_ref_pending &&
+      rc->bipred_group_interval &&
       rc->bipred_group_interval <=
           (rc->baseline_gf_interval - rc->source_alt_ref_pending);
   int bipred_group_end = 0;
@@ -2086,10 +2086,10 @@
   const int is_key_frame = frame_is_intra_only(cm);
   const int arf_active_or_kf = is_key_frame || rc->source_alt_ref_active;
 
-#if CONFIG_FLEX_REFS
+#if CONFIG_EXT_REFS
   cpi->extra_arf_allowed = 1;
   cpi->bwd_ref_allowed = 1;
-#endif
+#endif  // CONFIG_EXT_REFS
 
   // Reset the GF group data structures unless this is a key
   // frame in which case it will already have been done.
@@ -2151,11 +2151,11 @@
     }
   }
 
-#if CONFIG_FLEX_REFS
+#if CONFIG_EXT_REFS
   double avg_sr_coded_error = 0;
   double avg_raw_err_stdev = 0;
   int non_zero_stdev_count = 0;
-#endif  // CONFIG_FLEX_REFS
+#endif  // CONFIG_EXT_REFS
 
   i = 0;
   while (i < rc->static_scene_max_gf_interval && i < rc->frames_to_key) {
@@ -2180,14 +2180,14 @@
     accumulate_frame_motion_stats(
         &next_frame, &this_frame_mv_in_out, &mv_in_out_accumulator,
         &abs_mv_in_out_accumulator, &mv_ratio_accumulator);
-#if CONFIG_FLEX_REFS
+#if CONFIG_EXT_REFS
     // sum up the metric values of current gf group
     avg_sr_coded_error += next_frame.sr_coded_error;
-    if (next_frame.raw_error_stdev) {
+    if (fabs(next_frame.raw_error_stdev) > 0.000001) {
       non_zero_stdev_count++;
       avg_raw_err_stdev += next_frame.raw_error_stdev;
     }
-#endif  // CONFIG_FLEX_REFS
+#endif  // CONFIG_EXT_REFS
 
     // Accumulate the effect of prediction quality decay.
     if (!flash_detected) {
@@ -2227,8 +2227,18 @@
              (abs_mv_in_out_accumulator > 3.0) ||
              (mv_in_out_accumulator < -2.0) ||
              ((boost_score - old_boost_score) < BOOST_BREAKOUT)))) {
-      boost_score = old_boost_score;
-      break;
+#if CONFIG_EXT_REFS
+      // If GF group interval is < 12, we force it to be 8. Otherwise,
+      // if it is >= 12, we keep it as is.
+      // NOTE: 'i' is 1 more than the GF group interval candidate that is being
+      //       checked.
+      if (i == (8 + 1) || i >= (12 + 1)) {
+#endif  // CONFIG_EXT_REFS
+        boost_score = old_boost_score;
+        break;
+#if CONFIG_EXT_REFS
+      }
+#endif  // CONFIG_EXT_REFS
     }
 
     *this_frame = next_frame;
@@ -2261,19 +2271,16 @@
   // Set the interval until the next gf.
   rc->baseline_gf_interval = i - (is_key_frame || rc->source_alt_ref_pending);
 #if CONFIG_EXT_REFS
-#if CONFIG_FLEX_REFS
   const int num_mbs = (cpi->oxcf.resize_mode != RESIZE_NONE) ? cpi->initial_mbs
                                                              : cpi->common.MBs;
   if (i) avg_sr_coded_error /= i;
   if (non_zero_stdev_count) avg_raw_err_stdev /= non_zero_stdev_count;
 
-  // Disable extra alter refs and backward ref for "still" gf group
-  // zero_motion_accumulator indicates the minimum percentage of (0, 0) motion
-  // in gf group
-  // avg_sr_coded_error indicates the average of the sse per pixel of each frame
-  // in gf group
-  // avg_raw_err_stdev indicates the average of the standard deviation of (0, 0)
-  // motion error per block of each frame in gf group
+  // Disable extra altrefs and backward refs for "still" gf group:
+  //   zero_motion_accumulator: minimum percentage of (0,0) motion;
+  //   avg_sr_coded_error:      average of the SSE per pixel of each frame;
+  //   avg_raw_err_stdev:       average of the standard deviation of (0,0)
+  //                            motion error per block of each frame.
   assert(num_mbs > 0);
   const int disable_bwd_extarf =
       (zero_motion_accumulator > MIN_ZERO_MOTION &&
@@ -2282,13 +2289,13 @@
 
   if (disable_bwd_extarf) cpi->extra_arf_allowed = cpi->bwd_ref_allowed = 0;
 
-  if (!cpi->extra_arf_allowed)
+  if (!cpi->extra_arf_allowed) {
     cpi->num_extra_arfs = 0;
-  else
-#endif  // CONFIG_FLEX_REFS
+  } else {
     // Compute how many extra alt_refs we can have
     cpi->num_extra_arfs = get_number_of_extra_arfs(rc->baseline_gf_interval,
                                                    rc->source_alt_ref_pending);
+  }
   // Currently at maximum two extra ARFs' are allowed
   assert(cpi->num_extra_arfs <= MAX_EXT_ARFS);
 #endif  // CONFIG_EXT_REFS
diff --git a/av1/encoder/firstpass.h b/av1/encoder/firstpass.h
index 3b7c2b5..1c077f4 100644
--- a/av1/encoder/firstpass.h
+++ b/av1/encoder/firstpass.h
@@ -50,14 +50,12 @@
 //       overflow.
 #define MAX_EXT_ARFS 2
 #define MIN_EXT_ARF_INTERVAL 4
-#endif  // CONFIG_EXT_REFS
 
-#if CONFIG_FLEX_REFS
 #define MIN_ZERO_MOTION 0.95
 #define MAX_SR_CODED_ERROR 40
 #define MAX_RAW_ERR_VAR 2000
 #define MIN_MV_IN_OUT 0.4
-#endif  // CONFIG_FLEX_REFS
+#endif  // CONFIG_EXT_REFS
 
 #define VLOW_MOTION_THRESHOLD 950
 
@@ -84,10 +82,10 @@
   double new_mv_count;
   double duration;
   double count;
-#if CONFIG_FLEX_REFS
-  // standard deviation for (0, 0) motion prediction error
+#if CONFIG_EXT_REFS
+  // Standard deviation for (0,0) motion prediction error
   double raw_error_stdev;
-#endif  // CONFIG_FLEX_REFS
+#endif  // CONFIG_EXT_REFS
 } FIRSTPASS_STATS;
 
 typedef enum {
diff --git a/configure b/configure
index e85dc1e..30b9b76 100755
--- a/configure
+++ b/configure
@@ -268,7 +268,6 @@
     altref2
     speed_refs
     gf_groups
-    flex_refs
     global_motion
     new_quant
     supertx
@@ -561,7 +560,6 @@
     enabled ext_comp_refs && enable_feature ext_refs
     enabled ext_comp_refs && enable_feature one_sided_compound
     enabled altref2 && enable_feature ext_refs
-    enabled altref2 && enable_feature flex_refs
     enabled rect_tx_ext && enable_feature rect_tx
     enabled cfl && enable_feature smooth_hv
     enabled cdef_singlepass && enable_feature cdef