Skip NEW_MV when new_mv is same as ref
The BDRate is moreorless neutral, but the encoding gets about 0.5%
faster.
STATS_CHANGED
Change-Id: I66c1c6f01d79c5cebfe9c1a2707e414f94885bba
diff --git a/av1/encoder/encodemv.c b/av1/encoder/encodemv.c
index 43b7237..a101c9c 100644
--- a/av1/encoder/encodemv.c
+++ b/av1/encoder/encodemv.c
@@ -195,6 +195,8 @@
nmv_context *mvctx, int usehp) {
const MV diff = { mv->row - ref->row, mv->col - ref->col };
const MV_JOINT_TYPE j = av1_get_mv_joint(&diff);
+ // If the mv_diff is zero, then we should have used near or nearest instead.
+ assert(j != MV_JOINT_ZERO);
if (cpi->common.cur_frame_force_integer_mv) {
usehp = MV_SUBPEL_NONE;
}
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index e203037..5118fc0 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -10258,6 +10258,32 @@
if (ret < 0) continue;
}
+ // If we are searching newmv and the mv is the same as refmv, skip the
+ // current mode
+ if (this_mode == NEW_NEWMV) {
+ const int_mv ref_mv_0 = av1_get_ref_mv(x, 0);
+ const int_mv ref_mv_1 = av1_get_ref_mv(x, 1);
+ if (mbmi->mv[0].as_int == ref_mv_0.as_int ||
+ mbmi->mv[1].as_int == ref_mv_1.as_int) {
+ continue;
+ }
+ } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
+ const int_mv ref_mv_1 = av1_get_ref_mv(x, 1);
+ if (mbmi->mv[1].as_int == ref_mv_1.as_int) {
+ continue;
+ }
+ } else if (this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV) {
+ const int_mv ref_mv_0 = av1_get_ref_mv(x, 0);
+ if (mbmi->mv[0].as_int == ref_mv_0.as_int) {
+ continue;
+ }
+ } else if (this_mode == NEWMV) {
+ const int_mv ref_mv_0 = av1_get_ref_mv(x, 0);
+ if (mbmi->mv[0].as_int == ref_mv_0.as_int) {
+ continue;
+ }
+ }
+
x->skip = 0;
rd_stats->dist = 0;
rd_stats->sse = 0;
@@ -11286,8 +11312,11 @@
break;
} else {
// If the cost is less than current best result, make this
- // the best and update corresponding variables
- if (best_mbmi.ref_mv_idx == i) {
+ // the best and update corresponding variables unless the
+ // best_mv is the same as ref_mv. In this case we skip and
+ // rely on NEAR(EST)MV instead
+ if (best_mbmi.ref_mv_idx == i &&
+ mode_info[i].mv.as_int != ref_mv.as_int) {
assert(best_rd != INT64_MAX);
best_mbmi.ref_mv_idx = ref_mv_idx;
motion_mode_cand->rate_mv = this_rate_mv;