Fix and re-enable the sf prune_nearest_near_mv_using_refmv_weight
This sf prunes NEARESTMV and NEARMV when the count of spatial
neighboring mvs is smaller than a threshold.
This sf was earlier disabled due to visual artifacts:
(https://aomedia-review.googlesource.com/c/aom/+/163241/).
This CL fixed and re-enabled the sf for speed >= 5 for 'GOOD'
encoding mode with the below improvements.
The pruning logic is enabled when,
- both the top and left neighboring blocks are available
- when a best inter prediction mode is already identified
for the current block
- screen content tools are disabled
The improvements mentioned above have reduced the quality
impact and visual artifacts.
For 'good' encoding mode,
Instruction Count BD-Rate Loss(%)
cpu-used Reduction(%) avg.psnr ovr.psnr ssim
5 0.809 0.0308 0.0305 0.0468
6 1.114 0.0505 0.0506 0.1004
STATS_CHANGED
BUG=b/245416468
Change-Id: I440cd27edce28ecb6742e06c6497bb3b44fc6c5f
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 4370621..ee7486d 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -1753,9 +1753,16 @@
// 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) {
+ const int8_t ref_frame_type, PREDICTION_MODE best_mode) {
if (this_mode != NEARESTMV && this_mode != NEARMV) return 0;
+ // Do not skip the mode if the current block has not yet obtained a valid
+ // inter mode.
+ if (!is_inter_mode(best_mode)) return 0;
+ const MACROBLOCKD *xd = &x->e_mbd;
+ // Do not skip the mode if both the top and left neighboring blocks are not
+ // available.
+ if (!xd->left_available || !xd->up_available) 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 =
@@ -5036,8 +5043,14 @@
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))
+ if (skip_nearest_near_mv_using_refmv_weight(
+ x, this_mode, ref_frame_type,
+ args->search_state->best_mbmode.mode)) {
+ // Ensure the mode is pruned only when the current block has obtained a
+ // valid inter mode.
+ assert(is_inter_mode(args->search_state->best_mbmode.mode));
return 1;
+ }
}
if (sf->rt_sf.prune_inter_modes_with_golden_ref &&
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c
index 1447f24..36bc645 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -593,6 +593,8 @@
cpi->ppi->gf_group.update_type[cpi->gf_frame_index] == INTNL_ARF_UPDATE;
const int is_lf_frame =
cpi->ppi->gf_group.update_type[cpi->gf_frame_index] == LF_UPDATE;
+ const int allow_screen_content_tools =
+ cm->features.allow_screen_content_tools;
if (is_480p_or_larger) {
sf->part_sf.use_square_partition_only_threshold = BLOCK_128X128;
@@ -813,6 +815,8 @@
if (!is_720p_or_larger) {
sf->inter_sf.mv_cost_upd_level = INTERNAL_COST_UPD_SBROW_SET;
+ sf->inter_sf.prune_nearest_near_mv_using_refmv_weight =
+ (boosted || allow_screen_content_tools) ? 0 : 1;
}
if (!is_480p_or_larger) {
@@ -832,6 +836,8 @@
sf->tx_sf.tx_type_search.winner_mode_tx_type_pruning = 4;
sf->inter_sf.prune_nearmv_using_neighbors = PRUNE_NEARMV_LEVEL3;
sf->inter_sf.prune_comp_ref_frames = 2;
+ sf->inter_sf.prune_nearest_near_mv_using_refmv_weight =
+ (boosted || allow_screen_content_tools) ? 0 : 1;
if (is_720p_or_larger) {
sf->part_sf.auto_max_partition_based_on_simple_motion = NOT_IN_USE;
} else if (is_480p_or_larger) {
diff --git a/av1/encoder/speed_features.h b/av1/encoder/speed_features.h
index 13b8903..6ce7e35 100644
--- a/av1/encoder/speed_features.h
+++ b/av1/encoder/speed_features.h
@@ -954,14 +954,9 @@
int prune_comp_using_best_single_mode_ref;
// Skip NEARESTMV and NEARMV using weight computed in ref mv list population
- // This speed feature sometimes leads to severe visual artifacts for
- // the overlay frame. It makes inter RD mode search skip NEARESTMV
- // and NEARMV, and no valid inter mode is evaluated when the NEWMV mode
- // is also early terminated due to the constraint that it does not handle
- // zero mv difference. In this cases, intra modes will be chosen, leading
- // to bad prediction and flickering artifacts.
- // Turn off this feature for now. Be careful to check visual quality if
- // anyone is going to turn it on.
+ //
+ // Pruning is enabled only when both the top and left neighbor blocks are
+ // available and when the current block already has a valid inter prediction.
int prune_nearest_near_mv_using_refmv_weight;
// Based on previous ref_mv_idx search result, prune the following search.