Add speed feature to prune NEAREST,NEAR MV based on ref mv weight

This CL introduces a speed feature to prune NEARESTMV, NEARMV
modes using mv weight computed in ref mv list population. This
SF is enabled for speed 4 and above.

          Instruction Count      BD-Rate Loss(%)
cpu-used    Reduction(%)    avg.psnr    ovr.psnr    ssim
    4         1.350          0.0575      0.0420    0.1236
    5         0.868          0.0454      0.0501    0.1089
    6         0.498         -0.0244     -0.0256   -0.0245

STATS_CHANGED

Change-Id: I1cde168b062b340846fe015b7dc54a3c0cb1384f
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index ef0fe75..a4c29a6 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -1735,6 +1735,40 @@
   return 1;
 }
 
+// Skip NEARESTMV and NEARMV modes based on refmv weight computed in ref mv list
+// population
+static INLINE int skip_nearest_near_mv_using_refmv_weight(
+    const MACROBLOCK *const x, const PREDICTION_MODE this_mode,
+    const int8_t ref_frame_type) {
+  if (this_mode != NEARESTMV && this_mode != NEARMV) return 0;
+
+  const MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
+  const uint16_t *const ref_mv_weight = mbmi_ext->weight[ref_frame_type];
+  const int ref_mv_count =
+      AOMMIN(MAX_REF_MV_SEARCH, mbmi_ext->ref_mv_count[ref_frame_type]);
+
+  if (ref_mv_count == 0) return 0;
+  // If ref mv list has atleast one nearest candidate do not prune NEARESTMV
+  if (this_mode == NEARESTMV && ref_mv_weight[0] >= REF_CAT_LEVEL) return 0;
+
+  // Count number of ref mvs populated from nearest candidates
+  int nearest_refmv_count = 0;
+  for (int ref_mv_idx = 0; ref_mv_idx < ref_mv_count; ref_mv_idx++) {
+    if (ref_mv_weight[ref_mv_idx] >= REF_CAT_LEVEL) nearest_refmv_count++;
+  }
+
+  // nearest_refmv_count indicates the closeness of block motion characteristics
+  // with respect its spatial neighbor. Lower value of nearest_refmv_count
+  // means less correlation with its spatial neighbors. Hence less possibility
+  // for NEARESTMV and NEARMV modes becoming the best mode since these modes
+  // work well for blocks that shares similar motion characteristics with its
+  // neighbor. Thus, when nearest_refmv_count is less w.r.t ref_mv_count prune
+  // the mode.
+  const int prune_thresh = 1 + (ref_mv_count >= 2);
+  if (nearest_refmv_count < prune_thresh) return 1;
+  return 0;
+}
+
 // This function update the non-new mv for the current prediction mode
 static INLINE int build_cur_mv(int_mv *cur_mv, PREDICTION_MODE this_mode,
                                const AV1_COMMON *cm, const MACROBLOCK *x,
@@ -4726,6 +4760,12 @@
       return 1;
   }
 
+  if (sf->inter_sf.prune_nearest_near_mv_using_refmv_weight && !comp_pred) {
+    const int8_t ref_frame_type = av1_ref_frame_type(ref_frames);
+    if (skip_nearest_near_mv_using_refmv_weight(x, this_mode, ref_frame_type))
+      return 1;
+  }
+
   return 0;
 }
 
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c
index f0537a1..7aae149 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -1058,6 +1058,7 @@
     sf->inter_sf.prune_ext_comp_using_neighbors = 2;
     sf->inter_sf.prune_obmc_prob_thresh = INT_MAX;
     sf->inter_sf.disable_interinter_wedge_var_thresh = UINT_MAX;
+    sf->inter_sf.prune_nearest_near_mv_using_refmv_weight = boosted ? 0 : 1;
 
     sf->interp_sf.cb_pred_filter_search = 1;
     sf->interp_sf.skip_sharp_interp_filter_search = 1;
@@ -1677,6 +1678,7 @@
   inter_sf->prune_ext_comp_using_neighbors = 0;
   inter_sf->skip_ext_comp_nearmv_mode = 0;
   inter_sf->prune_comp_using_best_single_mode_ref = 0;
+  inter_sf->prune_nearest_near_mv_using_refmv_weight = 0;
   inter_sf->disable_onesided_comp = 0;
   inter_sf->prune_mode_search_simple_translation = 0;
   inter_sf->prune_comp_type_by_comp_avg = 0;
diff --git a/av1/encoder/speed_features.h b/av1/encoder/speed_features.h
index 241f985..0b4b2fc 100644
--- a/av1/encoder/speed_features.h
+++ b/av1/encoder/speed_features.h
@@ -820,6 +820,9 @@
   // 2 : prune extended compound mode (high aggressiveness)
   int prune_comp_using_best_single_mode_ref;
 
+  // Skip NEARESTMV and NEARMV using weight computed in ref mv list population
+  int prune_nearest_near_mv_using_refmv_weight;
+
   // Based on previous ref_mv_idx search result, prune the following search.
   int prune_ref_mv_idx_search;