RTC: Disable compound modes based on variance

This commit introduces speed feature skip_compound_based_on_var that
skips all compound modes if the best single mode prediction has low
residual variance.

Furthermore, this commit also disables the sad_based_comp_prune speed
feature on speed 9, 10 as variance of best mode outperforms the SAD
of zeromv on last frame. Note that the speed feature is disabled by
inserting a 0 into the conditional. This is because there are other
speed features that relies on the stats collected by
sad_based_comp_prune. This will be corrected in a later commit.

Performance:
| SPD_SET | TESTSET  | AVG_PSNR | OVR_PSNR |  SSIM   | ENC_T |
|---------|----------|----------|----------|---------|-------|
|    7    |   rtc    | +0.035%  | +0.219%  | +0.252% | -0.3% |
|---------|----------|----------|----------|---------|-------|
|    8    |   rtc    | +0.026%  | +0.027%  | +0.137% | -0.3% |
|---------|----------|----------|----------|---------|-------|
|    9    |   rtc    | -0.169%  | -0.060%  | +0.253% | -0.3% |
|---------|----------|----------|----------|---------|-------|
|   10    |   rtc    | -0.007%  | -0.018%  | +0.140% | -0.2% |

The larger PSNR loss on speed 7 is caused by thaloundeskmtgvga.y4m.

STATS_CHANGED

Change-Id: I7f663ddbf316fe75f5827ee0a8367ca50d691b0c
diff --git a/av1/encoder/nonrd_pickmode.c b/av1/encoder/nonrd_pickmode.c
index 5c3f1c4..b11b30a 100644
--- a/av1/encoder/nonrd_pickmode.c
+++ b/av1/encoder/nonrd_pickmode.c
@@ -2636,6 +2636,27 @@
   return 0;
 }
 
+// Prune compound mode if the single mode variance is lower than a fixed
+// percentage of the median value.
+static bool skip_comp_based_on_var(
+    const unsigned int (*single_vars)[REF_FRAMES], BLOCK_SIZE bsize) {
+  unsigned int best_var = UINT_MAX;
+  for (int cur_mode_idx = 0; cur_mode_idx < RTC_INTER_MODES; cur_mode_idx++) {
+    for (int ref_idx = 0; ref_idx < REF_FRAMES; ref_idx++) {
+      best_var = AOMMIN(best_var, single_vars[cur_mode_idx][ref_idx]);
+    }
+  }
+  const unsigned int thresh_64 = (unsigned int)(0.57356805f * 8659);
+  const unsigned int thresh_32 = (unsigned int)(0.23964763f * 4281);
+
+  if (bsize == BLOCK_64X64) {
+    return best_var < thresh_64;
+  } else if (bsize == BLOCK_32X32) {
+    return best_var < thresh_32;
+  }
+  return false;
+}
+
 static AOM_FORCE_INLINE void fill_single_inter_mode_costs(
     int (*single_inter_mode_costs)[REF_FRAMES], const int num_inter_modes,
     const REF_MODE *ref_mode_set, const ModeCosts *mode_costs,
@@ -2941,7 +2962,10 @@
   }
 
   // Skip compound mode based on sad
-  if (tot_num_comp_modes && cpi->sf.rt_sf.sad_based_comp_prune &&
+  // Temporarily disable this with a 0 flag. Currently we cannot simply turn off
+  // cpi->sf.rt_sf.sad_based_comp_prune as it causes unexpected stats changed.
+  // TODO(chiyotsai@google.com): Figure remove the 0 from the conditional.
+  if (0 && tot_num_comp_modes && cpi->sf.rt_sf.sad_based_comp_prune &&
       bsize >= BLOCK_64X64 && cpi->src_sad_blk_64x64 &&
       skip_comp_based_on_sad(cpi, x, mi_row, mi_col, bsize)) {
     tot_num_comp_modes = 0;
@@ -3003,6 +3027,13 @@
   MV_REFERENCE_FRAME last_comp_ref_frame = NONE_FRAME;
 
   for (int idx = 0; idx < num_inter_modes + tot_num_comp_modes; ++idx) {
+    // If we are at the first compound mode, and the single modes already
+    // perform well, then end the search.
+    if (cpi->sf.rt_sf.skip_compound_based_on_var && idx == num_inter_modes &&
+        skip_comp_based_on_var(vars, bsize)) {
+      break;
+    }
+
     const struct segmentation *const seg = &cm->seg;
 
     int rate_mv = 0;
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c
index 5f3a949..b9411ab 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -1672,6 +1672,7 @@
     sf->rt_sf.var_part_based_on_qidx = 3;
     sf->rt_sf.prune_compoundmode_with_singlecompound_var = true;
     sf->rt_sf.prune_compoundmode_with_singlemode_var = true;
+    sf->rt_sf.skip_compound_based_on_var = true;
   }
 
   if (speed >= 8) {
@@ -2053,6 +2054,7 @@
   rt_sf->check_only_zero_zeromv_on_large_blocks = false;
   rt_sf->disable_cdf_update_non_reference_frame = false;
   rt_sf->prune_compoundmode_with_singlemode_var = false;
+  rt_sf->skip_compound_based_on_var = false;
   rt_sf->top_right_sync_wait_in_mis = false;
 }
 
diff --git a/av1/encoder/speed_features.h b/av1/encoder/speed_features.h
index 3d50d1c..fad0774 100644
--- a/av1/encoder/speed_features.h
+++ b/av1/encoder/speed_features.h
@@ -1602,6 +1602,10 @@
   // Prune compound modes if the single modes variances do not perform well.
   bool prune_compoundmode_with_singlemode_var;
 
+  // Skip searching all compound mode if the variance of single_mode residue is
+  // sufficiently low.
+  bool skip_compound_based_on_var;
+
   // In multi-threaded encoding, enable top right dependency wait of threads at
   // mi level.
   bool top_right_sync_wait_in_mis;