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;