Prune extended compound mode using ref frames of neighbor block
Introduced a speed feature to skip compound mode using reference
frames of above and left neighbor blocks. Pruning is applicable
for extended compound modes only.
This speed feature is enabled for speed 4 and above.
Encode Time BD-Rate Loss
cpu-used Reduction avg.psnr ovr.psnr ssim
4 5.192% 0.1617% 0.1592% 0.1053%
5 3.527% 0.1221% 0.1249% 0.0690%
STATS_CHANGED
Change-Id: I4bdcb4f20c2e417b813a6e53b90a52709f8bf3e9
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 45d6d4c..da9e068 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -4029,6 +4029,42 @@
return 0;
}
+// Check if ref frames of current block matches with given block.
+static INLINE void match_ref_frame(const MB_MODE_INFO *const mbmi,
+ const MV_REFERENCE_FRAME *ref_frames,
+ int *const is_ref_match) {
+ if (is_inter_block(mbmi)) {
+ is_ref_match[0] |= ref_frames[0] == mbmi->ref_frame[0];
+ is_ref_match[1] |= ref_frames[1] == mbmi->ref_frame[0];
+ if (has_second_ref(mbmi)) {
+ is_ref_match[0] |= ref_frames[0] == mbmi->ref_frame[1];
+ is_ref_match[1] |= ref_frames[1] == mbmi->ref_frame[1];
+ }
+ }
+}
+
+// Prune compound mode using ref frames of neighbor blocks.
+static INLINE int compound_skip_using_neighbor_refs(
+ MACROBLOCKD *const xd, const PREDICTION_MODE this_mode,
+ const MV_REFERENCE_FRAME *ref_frames) {
+ // Exclude non-extended compound modes from pruning
+ if (this_mode == NEAREST_NEARESTMV || this_mode == NEAR_NEARMV ||
+ this_mode == NEW_NEWMV || this_mode == GLOBAL_GLOBALMV)
+ return 0;
+
+ int is_ref_match[2] = { 0 }; // 0 - match for forward refs
+ // 1 - match for backward refs
+ // Check if ref frames of this block matches with left neighbor.
+ if (xd->left_available)
+ match_ref_frame(xd->left_mbmi, ref_frames, is_ref_match);
+
+ // Check if ref frames of this block matches with above neighbor.
+ if (xd->up_available)
+ match_ref_frame(xd->above_mbmi, ref_frames, is_ref_match);
+
+ return !(is_ref_match[0] && is_ref_match[1]);
+}
+
static int compare_int64(const void *a, const void *b) {
int64_t a64 = *((int64_t *)a);
int64_t b64 = *((int64_t *)b);
@@ -4277,6 +4313,11 @@
!in_single_ref_cutoff(ref_frame_rd, ref_frame, second_ref_frame)) {
return 1;
}
+
+ if (sf->inter_sf.prune_compound_using_neighbors && comp_pred) {
+ if (compound_skip_using_neighbor_refs(xd, this_mode, ref_frames)) return 1;
+ }
+
return 0;
}
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c
index 28af368..a45f665 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -514,6 +514,7 @@
(boosted || allow_screen_content_tools) ? 0 : 3;
sf->inter_sf.prune_inter_modes_based_on_tpl = boosted ? 0 : 2;
+ sf->inter_sf.prune_compound_using_neighbors = 1;
sf->inter_sf.disable_smooth_interintra = 1;
sf->interp_sf.cb_pred_filter_search = 1;
@@ -970,6 +971,7 @@
inter_sf->prune_single_motion_modes_by_simple_trans = 0;
inter_sf->inter_mode_rd_model_estimation = 0;
inter_sf->prune_compound_using_single_ref = 0;
+ inter_sf->prune_compound_using_neighbors = 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 96baf5d..e67f2bc 100644
--- a/av1/encoder/speed_features.h
+++ b/av1/encoder/speed_features.h
@@ -575,6 +575,10 @@
// the single reference modes, it is one of the two best performers.
int prune_compound_using_single_ref;
+ // Skip extended compound mode using ref frames of above and left neighbor
+ // blocks.
+ int prune_compound_using_neighbors;
+
// Based on previous ref_mv_idx search result, prune the following search.
int prune_ref_mv_idx_search;