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