Check for best_pred_mv_sad in selective_ref_frames
Currently, selective_ref_frames might remove ALTREF2 and BWDREF even
though pred_mv_sad suggests that they might be good references. In this
scenario, mode_skip_mask, which is based on pred_mv_sad, might also
remove ALTREF2 and BWDREF, leading to an infinite loop inside
rd_pick_partition.
This commit adds an additional check in prune_ref_by_selective_ref_frame
so that a reference will not disabled if it has the best pred_mv_sad.
This did not affect the quality/speed on speed <= 3.
Performance:
SPEED_SET | TESTSET | AVG_PSNR | OVR_PSNR | SSIM | SPD
-----------+---------+----------+----------+---------+-------
| LOWRES | -0.186% | -0.197% | -0.228% | -0.2%
4 | MIDRES | -0.167% | -0.150% | -0.232% | -0.2%
| HDRES | -0.094% | -0.098% | -0.090% | -0.1%
-----------+---------+----------+----------+---------+-------
| LOWRES | -0.179% | -0.188% | -0.243% | -0.3%
5 | MIDRES | -0.157% | -0.162% | -0.232% | -0.3%
| HDRES | -0.097% | -0.090% | -0.083% | -0.3%
-----------+---------+----------+----------+---------+-------
| LOWRES | -0.116% | -0.127% | -0.131% | -0.5%
6 | MIDRES | -0.075% | -0.079% | -0.090% | -0.4%
| HDRES | -0.093% | -0.095% | -0.085% | -0.3%
STATS_CHANGED
BUG=aomedia:2969
Change-Id: I76036a72875b867ef538683a27111a78850d2864
diff --git a/av1/encoder/rdopt.h b/av1/encoder/rdopt.h
index df080b0..362da7b 100644
--- a/av1/encoder/rdopt.h
+++ b/av1/encoder/rdopt.h
@@ -272,8 +272,16 @@
int ref_frame_list[2] = { LAST3_FRAME, LAST2_FRAME };
if (x != NULL) {
- if (x->tpl_keep_ref_frame[LAST3_FRAME]) ref_frame_list[0] = NONE_FRAME;
- if (x->tpl_keep_ref_frame[LAST2_FRAME]) ref_frame_list[1] = NONE_FRAME;
+ // Disable pruning if either tpl suggests that we keep the frame or
+ // the pred_mv gives us the best sad
+ if (x->tpl_keep_ref_frame[LAST3_FRAME] ||
+ x->pred_mv_sad[LAST3_FRAME] == x->best_pred_mv_sad) {
+ ref_frame_list[0] = NONE_FRAME;
+ }
+ if (x->tpl_keep_ref_frame[LAST2_FRAME] ||
+ x->pred_mv_sad[LAST2_FRAME] == x->best_pred_mv_sad) {
+ ref_frame_list[1] = NONE_FRAME;
+ }
}
if (prune_ref(ref_frame, ref_display_order_hint,
@@ -286,8 +294,16 @@
int ref_frame_list[2] = { ALTREF2_FRAME, BWDREF_FRAME };
if (x != NULL) {
- if (x->tpl_keep_ref_frame[ALTREF2_FRAME]) ref_frame_list[0] = NONE_FRAME;
- if (x->tpl_keep_ref_frame[BWDREF_FRAME]) ref_frame_list[1] = NONE_FRAME;
+ // Disable pruning if either tpl suggests that we keep the frame or
+ // the pred_mv gives us the best sad
+ if (x->tpl_keep_ref_frame[ALTREF2_FRAME] ||
+ x->pred_mv_sad[ALTREF2_FRAME] == x->best_pred_mv_sad) {
+ ref_frame_list[0] = NONE_FRAME;
+ }
+ if (x->tpl_keep_ref_frame[BWDREF_FRAME] ||
+ x->pred_mv_sad[BWDREF_FRAME] == x->best_pred_mv_sad) {
+ ref_frame_list[1] = NONE_FRAME;
+ }
}
if (prune_ref(ref_frame, ref_display_order_hint,