Temporary mismatch fix for global motion
Related to all-zero handling.
Change-Id: I58070aabdcb7ef03ae587c26ffaff5c908db91a4
diff --git a/av1/common/mvref_common.c b/av1/common/mvref_common.c
index 542ec5c..6f6fe90 100644
--- a/av1/common/mvref_common.c
+++ b/av1/common/mvref_common.c
@@ -499,8 +499,7 @@
MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
int_mv *mv_ref_list, int block, int mi_row,
int mi_col, find_mv_refs_sync sync,
- void *const data, int16_t *mode_context,
- int_mv zeromv) {
+ void *const data, int16_t *mode_context) {
const int *ref_sign_bias = cm->ref_frame_sign_bias;
int i, refmv_count = 0;
#if !CONFIG_REF_MV
@@ -662,7 +661,7 @@
if (mode_context)
mode_context[ref_frame] = counter_to_context[context_counter];
for (i = refmv_count; i < MAX_MV_REF_CANDIDATES; ++i)
- mv_ref_list[i].as_int = zeromv.as_int;
+ mv_ref_list[i].as_int = 0;
}
#if CONFIG_EXT_INTER
@@ -746,12 +745,8 @@
int_mv *mv_ref_list, int mi_row, int mi_col,
find_mv_refs_sync sync, void *const data,
int16_t *mode_context) {
- int_mv zeromv[2];
#if CONFIG_REF_MV
- int idx, all_zero = 1;
-#endif
-#if CONFIG_GLOBAL_MOTION
- MV_REFERENCE_FRAME rf[2];
+ int all_zero = 1;
#endif
#if CONFIG_EXT_INTER
av1_update_mv_context(xd, mi, ref_frame, mv_ref_list, -1, mi_row, mi_col,
@@ -761,54 +756,47 @@
mode_context);
#endif // CONFIG_REF_MV
#endif // CONFIG_EXT_INTER
-
-#if CONFIG_GLOBAL_MOTION
- av1_set_ref_frame(rf, ref_frame);
- zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[rf[0]]).as_int;
- zeromv[1].as_int =
- (rf[1] != NONE) ? gm_get_motion_vector(&cm->global_motion[rf[1]]).as_int
- : 0;
-#else
- zeromv[0].as_int = zeromv[1].as_int = 0;
-#endif
-
#if CONFIG_REF_MV
if (ref_frame <= ALTREF_FRAME)
-#endif // CONFIG_REF_MV
find_mv_refs_idx(cm, xd, mi, ref_frame, mv_ref_list, -1, mi_row, mi_col,
- sync, data, mode_context, zeromv[0]);
+ sync, data, mode_context);
+#else
+ find_mv_refs_idx(cm, xd, mi, ref_frame, mv_ref_list, -1, mi_row, mi_col, sync,
+ data, mode_context);
+#endif // CONFIG_REF_MV
#if CONFIG_REF_MV
setup_ref_mv_list(cm, xd, ref_frame, ref_mv_count, ref_mv_stack, mv_ref_list,
-1, mi_row, mi_col, mode_context);
- /* Note: If global motion is enabled, then we want to set the ALL_ZERO flag
- iff all of the MVs we could generate with NEARMV/NEARESTMV are equivalent
- to the global motion vector.
- Note: For the following to work properly, the encoder can't throw away
- any global motion models after calling this function, even if they are
- unused. Instead we rely on the recode loop: If any non-IDENTITY model
- is unused, the whole frame will be re-encoded without it.
- The problem is that, otherwise, we can end up in the following situation:
- * Encoder has a global motion model with nonzero translational part,
- and all candidate MVs are zero. So the ALL_ZERO flag is unset.
- * Encoder throws away global motion because it is never used.
- * Decoder sees that there is no global motion and all candidate MVs are
- zero, so sets the ALL_ZERO flag.
- * This leads to an encode/decode mismatch.
- */
+
if (*ref_mv_count >= 2) {
+ int idx;
for (idx = 0; idx < AOMMIN(3, *ref_mv_count); ++idx) {
- if (ref_mv_stack[idx].this_mv.as_int != zeromv[0].as_int) all_zero = 0;
+ if (ref_mv_stack[idx].this_mv.as_int != 0) all_zero = 0;
if (ref_frame > ALTREF_FRAME)
- if (ref_mv_stack[idx].comp_mv.as_int != zeromv[1].as_int) all_zero = 0;
+ if (ref_mv_stack[idx].comp_mv.as_int != 0) all_zero = 0;
}
} else if (ref_frame <= ALTREF_FRAME) {
+ int idx;
for (idx = 0; idx < MAX_MV_REF_CANDIDATES; ++idx)
- if (mv_ref_list[idx].as_int != zeromv[0].as_int) all_zero = 0;
+ if (mv_ref_list[idx].as_int != 0) all_zero = 0;
}
+#if CONFIG_GLOBAL_MOTION
+ if (all_zero) {
+ MV_REFERENCE_FRAME rf[2];
+ av1_set_ref_frame(rf, ref_frame);
+
+ if (gm_get_motion_vector(&cm->global_motion[rf[0]]).as_int != 0) {
+ all_zero = 0;
+ } else if (rf[1] != NONE &&
+ gm_get_motion_vector(&cm->global_motion[rf[1]]).as_int != 0) {
+ all_zero = 0;
+ }
+ }
+#endif // CONFIG_GLOBAL_MOTION
if (all_zero) mode_context[ref_frame] |= (1 << ALL_ZERO_FLAG_OFFSET);
-#endif
+#endif // CONFIG_REF_MV
}
void av1_find_best_ref_mvs(int allow_hp, int_mv *mvlist, int_mv *nearest_mv,
@@ -838,7 +826,6 @@
MODE_INFO *const mi = xd->mi[0];
b_mode_info *bmi = mi->bmi;
int n;
- int_mv zeromv;
#if CONFIG_REF_MV
CANDIDATE_MV tmp_mv;
uint8_t idx;
@@ -849,13 +836,8 @@
assert(MAX_MV_REF_CANDIDATES == 2);
-#if CONFIG_GLOBAL_MOTION
- zeromv.as_int = gm_get_motion_vector(&cm->global_motion[ref]).as_int;
-#else
- zeromv.as_int = 0;
-#endif
find_mv_refs_idx(cm, xd, mi, mi->mbmi.ref_frame[ref], mv_list, block, mi_row,
- mi_col, NULL, NULL, NULL, zeromv);
+ mi_col, NULL, NULL, NULL);
#if CONFIG_REF_MV
scan_blk_mbmi(cm, xd, mi_row, mi_col, block, rf, -1, 0, ref_mv_stack,
@@ -940,8 +922,8 @@
mi_step = AOMMIN(xd->n8_w, num_8x8_blocks_wide_lookup[mbmi->sb_type]);
if (mbmi->ref_frame[0] == ref_frame && mbmi->ref_frame[1] == NONE) {
- int bw = block_size_wide[mbmi->sb_type];
- int bh = block_size_high[mbmi->sb_type];
+ int bw = num_4x4_blocks_wide_lookup[mbmi->sb_type] * 4;
+ int bh = num_4x4_blocks_high_lookup[mbmi->sb_type] * 4;
int mv_row = mbmi->mv[0].as_mv.row;
int mv_col = mbmi->mv[0].as_mv.col;
int cr_offset = -AOMMAX(bh, 8) / 2 - 1;
@@ -995,8 +977,8 @@
mi_step = AOMMIN(xd->n8_h, num_8x8_blocks_high_lookup[mbmi->sb_type]);
if (mbmi->ref_frame[0] == ref_frame && mbmi->ref_frame[1] == NONE) {
- int bw = block_size_wide[mbmi->sb_type];
- int bh = block_size_high[mbmi->sb_type];
+ int bw = num_4x4_blocks_wide_lookup[mbmi->sb_type] * 4;
+ int bh = num_4x4_blocks_high_lookup[mbmi->sb_type] * 4;
int mv_row = mbmi->mv[0].as_mv.row;
int mv_col = mbmi->mv[0].as_mv.col;
int cr_offset = i * 8 + AOMMAX(bh, 8) / 2 - 1;
@@ -1046,8 +1028,8 @@
MB_MODE_INFO *mbmi = &mi->mbmi;
if (mbmi->ref_frame[0] == ref_frame && mbmi->ref_frame[1] == NONE) {
- int bw = block_size_wide[mbmi->sb_type];
- int bh = block_size_high[mbmi->sb_type];
+ int bw = num_4x4_blocks_wide_lookup[mbmi->sb_type] * 4;
+ int bh = num_4x4_blocks_high_lookup[mbmi->sb_type] * 4;
int mv_row = mbmi->mv[0].as_mv.row;
int mv_col = mbmi->mv[0].as_mv.col;
int cr_offset = -AOMMAX(bh, 8) / 2 - 1;
@@ -1096,8 +1078,8 @@
} else {
MODE_INFO *mi = xd->mi[0];
MB_MODE_INFO *mbmi = &mi->mbmi;
- int bw = block_size_wide[mbmi->sb_type];
- int bh = block_size_high[mbmi->sb_type];
+ int bw = num_4x4_blocks_wide_lookup[mbmi->sb_type] * 4;
+ int bh = num_4x4_blocks_high_lookup[mbmi->sb_type] * 4;
int mv_row = mbmi->mv[0].as_mv.row;
int mv_col = mbmi->mv[0].as_mv.col;
int cr_offset = AOMMAX(bh, 8) / 2 - 1;
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index 826d30d..101ed3e 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -1479,26 +1479,14 @@
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]]).as_int;
- zeromv[1].as_int =
- (rf[1] != NONE)
- ? gm_get_motion_vector(&cm->global_motion[rf[1]]).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 != 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)
+ 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)
inter_mode_ctx[ref_frame] &= ~(1 << ALL_ZERO_FLAG_OFFSET);
}
}
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 98c5455..0f5db59 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -8611,13 +8611,10 @@
if (mbmi_ext->ref_mv_count[ref_frame] < 2) {
MV_REFERENCE_FRAME rf[2];
av1_set_ref_frame(rf, ref_frame);
- if (mbmi_ext->ref_mvs[rf[0]][0].as_int !=
- frame_mv[ZEROMV][rf[0]].as_int ||
- mbmi_ext->ref_mvs[rf[0]][1].as_int !=
- frame_mv[ZEROMV][rf[0]].as_int ||
- mbmi_ext->ref_mvs[rf[1]][0].as_int !=
- frame_mv[ZEROMV][rf[1]].as_int ||
- mbmi_ext->ref_mvs[rf[1]][1].as_int != frame_mv[ZEROMV][rf[1]].as_int)
+ if (mbmi_ext->ref_mvs[rf[0]][0].as_int != 0 ||
+ mbmi_ext->ref_mvs[rf[0]][1].as_int != 0 ||
+ mbmi_ext->ref_mvs[rf[1]][0].as_int != 0 ||
+ mbmi_ext->ref_mvs[rf[1]][1].as_int != 0)
mbmi_ext->mode_context[ref_frame] &= ~(1 << ALL_ZERO_FLAG_OFFSET);
}
}
@@ -9972,34 +9969,27 @@
}
#if CONFIG_REF_MV
- {
+ if (best_mbmode.ref_frame[0] > INTRA_FRAME && best_mbmode.mv[0].as_int == 0 &&
+#if CONFIG_EXT_INTER
+ (best_mbmode.ref_frame[1] <= INTRA_FRAME)
+#else
+ (best_mbmode.ref_frame[1] == NONE || best_mbmode.mv[1].as_int == 0)
+#endif // CONFIG_EXT_INTER
+ ) {
int8_t ref_frame_type = av1_ref_frame_type(best_mbmode.ref_frame);
int16_t mode_ctx = mbmi_ext->mode_context[ref_frame_type];
+
if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) {
- int_mv zeromv[2];
+ best_mbmode.mode = ZEROMV;
#if CONFIG_GLOBAL_MOTION
- const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
- best_mbmode.ref_frame[1] };
- zeromv[0].as_int =
- gm_get_motion_vector(&cm->global_motion[refs[0]]).as_int;
- zeromv[1].as_int =
- gm_get_motion_vector(&cm->global_motion[refs[1]]).as_int;
- lower_mv_precision(&zeromv[0].as_mv, cm->allow_high_precision_mv);
- lower_mv_precision(&zeromv[1].as_mv, cm->allow_high_precision_mv);
-#else
- zeromv[0].as_int = zeromv[1].as_int = 0;
-#endif // CONFIG_GLOBAL_MOTION
- if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
- best_mbmode.mv[0].as_int == zeromv[0].as_int &&
-#if CONFIG_EXT_INTER
- (best_mbmode.ref_frame[1] <= INTRA_FRAME)
-#else
- (best_mbmode.ref_frame[1] == NONE ||
- best_mbmode.mv[1].as_int == zeromv[1].as_int)
-#endif // CONFIG_EXT_INTER
- ) {
- best_mbmode.mode = ZEROMV;
- }
+ best_mbmode.mv[0].as_int =
+ gm_get_motion_vector(&cm->global_motion[best_mbmode.ref_frame[0]])
+ .as_int;
+ if (best_mbmode.ref_frame[1] != NONE)
+ best_mbmode.mv[1].as_int =
+ gm_get_motion_vector(&cm->global_motion[best_mbmode.ref_frame[1]])
+ .as_int;
+#endif
}
}
#endif