Make gm_get_motion_vector respect allow_high_precision_mv
This fixes a rare encode/decode mismatch due to inconsistent
rounding of NEARMV/NEARESTMV vs. ZEROMV motion vectors when both
global motion and ref-mv are enabled.
Change-Id: Ia2bbaf63020f5ce7762e027f9bf835fd96797bec
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index 05dc0fa..838c9af 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -1230,11 +1230,13 @@
}
case ZEROMV: {
#if CONFIG_GLOBAL_MOTION
- mv[0].as_int =
- gm_get_motion_vector(&cm->global_motion[ref_frame[0]]).as_int;
+ mv[0].as_int = gm_get_motion_vector(&cm->global_motion[ref_frame[0]],
+ cm->allow_high_precision_mv)
+ .as_int;
if (is_compound)
- mv[1].as_int =
- gm_get_motion_vector(&cm->global_motion[ref_frame[1]]).as_int;
+ mv[1].as_int = gm_get_motion_vector(&cm->global_motion[ref_frame[1]],
+ cm->allow_high_precision_mv)
+ .as_int;
#else
mv[0].as_int = 0;
if (is_compound) mv[1].as_int = 0;
@@ -1479,14 +1481,29 @@
if (xd->ref_mv_count[ref_frame] < 2) {
MV_REFERENCE_FRAME rf[2];
+ int_mv zeromv[2];
av1_set_ref_frame(rf, ref_frame);
+#if CONFIG_GLOBAL_MOTION
+ zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[rf[0]],
+ cm->allow_high_precision_mv)
+ .as_int;
+ zeromv[1].as_int = (rf[1] != NONE)
+ ? gm_get_motion_vector(&cm->global_motion[rf[1]],
+ cm->allow_high_precision_mv)
+ .as_int
+ : 0;
+#else
+ zeromv[0].as_int = zeromv[1].as_int = 0;
+#endif
for (ref = 0; ref < 2; ++ref) {
lower_mv_precision(&ref_mvs[rf[ref]][0].as_mv, allow_hp);
lower_mv_precision(&ref_mvs[rf[ref]][1].as_mv, allow_hp);
}
- if (ref_mvs[rf[0]][0].as_int != 0 || ref_mvs[rf[0]][1].as_int != 0 ||
- ref_mvs[rf[1]][0].as_int != 0 || ref_mvs[rf[1]][1].as_int != 0)
+ if (ref_mvs[rf[0]][0].as_int != zeromv[0].as_int ||
+ ref_mvs[rf[0]][1].as_int != zeromv[0].as_int ||
+ ref_mvs[rf[1]][0].as_int != zeromv[1].as_int ||
+ ref_mvs[rf[1]][1].as_int != zeromv[1].as_int)
inter_mode_ctx[ref_frame] &= ~(1 << ALL_ZERO_FLAG_OFFSET);
}
}