Commit 37afe712 authored by Debargha Mukherjee's avatar Debargha Mukherjee
Browse files

Temporary mismatch fix for global motion

Related to all-zero handling.

Change-Id: I58070aabdcb7ef03ae587c26ffaff5c908db91a4
parent ed2a00f2
......@@ -499,8 +499,7 @@ static void find_mv_refs_idx(const AV1_COMMON *cm, const MACROBLOCKD *xd,
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 @@ Done:
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 @@ void av1_find_mv_refs(const AV1_COMMON *cm, const MACROBLOCKD *xd,
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 @@ void av1_find_mv_refs(const AV1_COMMON *cm, const MACROBLOCKD *xd,
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 @@ void av1_append_sub8x8_mvs_for_idx(const AV1_COMMON *cm, MACROBLOCKD *xd,
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 @@ void av1_append_sub8x8_mvs_for_idx(const AV1_COMMON *cm, MACROBLOCKD *xd,
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 @@ int findSamples(const AV1_COMMON *cm, MACROBLOCKD *xd, int mi_row, int mi_col,
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 @@ int findSamples(const AV1_COMMON *cm, MACROBLOCKD *xd, int mi_row, int mi_col,
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 @@ int findSamples(const AV1_COMMON *cm, MACROBLOCKD *xd, int mi_row, int mi_col,
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 @@ int findSamples(const AV1_COMMON *cm, MACROBLOCKD *xd, int mi_row, int mi_col,
} 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;
......
......@@ -1479,26 +1479,14 @@ static void read_inter_block_mode_info(AV1Decoder *const pbi,
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);
}
}
......
......@@ -8611,13 +8611,10 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
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 @@ PALETTE_EXIT:
}
#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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment