Simplify the ALL_ZERO_FLAG logic in av1_rd_pick_intra_mode_sb Since the CONFIG_EXT_INTER #if/#endif lines have been removed, it's a bit clearer what's going on here and this patch cleans up the code. Firstly, the patch pulls the cheap checks on best_mbmode.ref_frame out to the front of the block, so we needn't call gm_get_motion_vector at all for compound predictions. Next, second element of the zeromv array is never used, so we needn't compute it. Finally, the patch removes the calls to lower_mv_precision. These shouldn't be needed, but it's not exactly obvious why not so the patch adds some comments to gm_get_motion_vector to explain what's going on and adds an assertion to make sure they are true. It also adds a call to integer_mv_precision on the early return path of gm_get_motion_vector, correcting an apparent bug when CONFIG_AMVR is true. This patch shouldn't make any difference to encoder or decoder behaviour. Change-Id: I0b4a01063574d080bbf6d30187f4e1748c60939d
diff --git a/av1/common/mv.h b/av1/common/mv.h index 1412944..65f0f7e 100644 --- a/av1/common/mv.h +++ b/av1/common/mv.h
@@ -233,8 +233,13 @@ } } #endif -// Convert a global motion translation vector (which may have more bits than a -// regular motion vector) into a motion vector +// Convert a global motion vector into a motion vector at the centre of the +// given block. +// +// The resulting motion vector will have three fractional bits of precision. If +// allow_hp is zero, the bottom bit will always be zero. If CONFIG_AMVR and +// is_integer is true, the bottom three bits will be zero (so the motion vector +// represents an integer) static INLINE int_mv gm_get_motion_vector(const WarpedMotionParams *gm, int allow_hp, BLOCK_SIZE bsize, int mi_col, int mi_row, int block_idx @@ -249,8 +254,22 @@ int x, y, tx, ty; if (gm->wmtype == TRANSLATION) { + // All global motion vectors are stored with WARPEDMODEL_PREC_BITS (16) + // bits of fractional precision. The offset for a translation is stored in + // entries 0 and 1. For translations, all but the top three (two if + // cm->allow_high_precision_mv is false) fractional bits are always zero. + // + // After the right shifts, there are 3 fractional bits of precision. If + // allow_hp is false, the bottom bit is always zero (so we don't need a + // call to convert_to_trans_prec here) res.as_mv.row = gm->wmmat[0] >> GM_TRANS_ONLY_PREC_DIFF; res.as_mv.col = gm->wmmat[1] >> GM_TRANS_ONLY_PREC_DIFF; + assert(IMPLIES(1 & (res.as_mv.row | res.as_mv.col), allow_hp)); +#if CONFIG_AMVR + if (is_integer) { + integer_mv_precision(&res.as_mv); + } +#endif return res; } @@ -290,6 +309,7 @@ res.as_mv.row = ty; res.as_mv.col = tx; + #if CONFIG_AMVR if (is_integer) { integer_mv_precision(&res.as_mv);
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c index fadd930..401e50f 100644 --- a/av1/encoder/rdopt.c +++ b/av1/encoder/rdopt.c
@@ -11652,56 +11652,27 @@ best_mbmode.ref_mv_idx = 0; } - { + if (best_mbmode.ref_frame[0] > INTRA_FRAME && + best_mbmode.ref_frame[1] <= INTRA_FRAME) { 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]; + int_mv 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]], - cm->allow_high_precision_mv, - bsize, mi_col, mi_row, 0 + const MV_REFERENCE_FRAME ref = best_mbmode.ref_frame[0]; + zeromv.as_int = gm_get_motion_vector(&cm->global_motion[ref], + cm->allow_high_precision_mv, bsize, + mi_col, mi_row, 0 #if CONFIG_AMVR - , - cm->cur_frame_mv_precision_level + , + cm->cur_frame_mv_precision_level #endif - ) - .as_int; - zeromv[1].as_int = - (refs[1] != NONE_FRAME) - ? -#if CONFIG_AMVR - gm_get_motion_vector(&cm->global_motion[refs[1]], - cm->allow_high_precision_mv, bsize, mi_col, - mi_row, 0, cm->cur_frame_mv_precision_level) - .as_int - : 0; + ) + .as_int; #else - gm_get_motion_vector(&cm->global_motion[refs[1]], - cm->allow_high_precision_mv, bsize, mi_col, - mi_row, 0) - .as_int - : 0; -#endif - -#if CONFIG_AMVR - lower_mv_precision(&zeromv[0].as_mv, cm->allow_high_precision_mv, - cm->cur_frame_mv_precision_level); - lower_mv_precision(&zeromv[1].as_mv, cm->allow_high_precision_mv, - cm->cur_frame_mv_precision_level); -#else - lower_mv_precision(&zeromv[0].as_mv, cm->allow_high_precision_mv); - lower_mv_precision(&zeromv[1].as_mv, cm->allow_high_precision_mv); -#endif - -#else - zeromv[0].as_int = zeromv[1].as_int = 0; + zeromv.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 && - (best_mbmode.ref_frame[1] <= INTRA_FRAME)) { + if (best_mbmode.mv[0].as_int == zeromv.as_int) { best_mbmode.mode = ZEROMV; } }