Change gm_get_motion_vector Since gm_get_motion_vector is trying to give a motion vector for "the frame as a whole", it makes more sense for it to calculate the motion of the *center* of the block rather than the top-left corner of the frame. In theory, this change should also help the encoder make better decisions on when to use global motion. It avoids an issue where, early in the frame, NEARESTMV looks like a good way to use the global motion vector *without* paying the rate cost applied to the first few global motion blocks in each frame. This seems to lead to a better overall result. Change-Id: Ia5c6259ceb8b4ff3d00a5d553e1d18bdb802da59
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c index 39cb2cc..fc21bc4 100644 --- a/av1/decoder/decodemv.c +++ b/av1/decoder/decodemv.c
@@ -1271,8 +1271,9 @@ PREDICTION_MODE mode, MV_REFERENCE_FRAME ref_frame[2], int block, int_mv mv[2], int_mv ref_mv[2], - int_mv nearest_mv[2], int_mv near_mv[2], - int is_compound, int allow_hp, aom_reader *r) { + int_mv nearest_mv[2], int_mv near_mv[2], int mi_row, + int mi_col, int is_compound, int allow_hp, + aom_reader *r) { int i; int ret = 1; #if CONFIG_EC_ADAPT @@ -1295,6 +1296,8 @@ #endif // CONFIG_REF_MV (void)ref_frame; (void)cm; + (void)mi_row; + (void)mi_col; switch (mode) { #if CONFIG_EXT_INTER @@ -1350,11 +1353,15 @@ case ZEROMV: { #if CONFIG_GLOBAL_MOTION mv[0].as_int = gm_get_motion_vector(&cm->global_motion[ref_frame[0]], - cm->allow_high_precision_mv) + cm->allow_high_precision_mv, + mi_col * MI_SIZE + MI_SIZE / 2, + mi_row * MI_SIZE + MI_SIZE / 2) .as_int; if (is_compound) mv[1].as_int = gm_get_motion_vector(&cm->global_motion[ref_frame[1]], - cm->allow_high_precision_mv) + cm->allow_high_precision_mv, + mi_col * MI_SIZE + MI_SIZE / 2, + mi_row * MI_SIZE + MI_SIZE / 2) .as_int; #else mv[0].as_int = 0; @@ -1503,10 +1510,14 @@ assert(is_compound); #if CONFIG_GLOBAL_MOTION mv[0].as_int = gm_get_motion_vector(&cm->global_motion[ref_frame[0]], - cm->allow_high_precision_mv) + cm->allow_high_precision_mv, + mi_col * MI_SIZE + MI_SIZE / 2, + mi_row * MI_SIZE + MI_SIZE / 2) .as_int; mv[1].as_int = gm_get_motion_vector(&cm->global_motion[ref_frame[1]], - cm->allow_high_precision_mv) + cm->allow_high_precision_mv, + mi_col * MI_SIZE + MI_SIZE / 2, + mi_row * MI_SIZE + MI_SIZE / 2) .as_int; #else mv[0].as_int = 0; @@ -1613,13 +1624,18 @@ 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) + cm->allow_high_precision_mv, + mi_col * MI_SIZE + MI_SIZE / 2, + mi_row * MI_SIZE + MI_SIZE / 2) .as_int; - zeromv[1].as_int = (rf[1] != NONE_FRAME) - ? gm_get_motion_vector(&cm->global_motion[rf[1]], - cm->allow_high_precision_mv) - .as_int - : 0; + zeromv[1].as_int = + (rf[1] != NONE_FRAME) + ? gm_get_motion_vector(&cm->global_motion[rf[1]], + cm->allow_high_precision_mv, + mi_col * MI_SIZE + MI_SIZE / 2, + mi_row * MI_SIZE + MI_SIZE / 2) + .as_int + : 0; #else zeromv[0].as_int = zeromv[1].as_int = 0; #endif @@ -1843,7 +1859,8 @@ #else ref_mv_s8, #endif // CONFIG_EXT_INTER - nearest_sub8x8, near_sub8x8, is_compound, allow_hp, r)) { + nearest_sub8x8, near_sub8x8, mi_row, mi_col, is_compound, + allow_hp, r)) { xd->corrupted |= 1; break; }; @@ -1892,7 +1909,7 @@ #else ref_mv, #endif // CONFIG_EXT_INTER - nearestmv, nearmv, is_compound, allow_hp, r); + nearestmv, nearmv, mi_row, mi_col, is_compound, allow_hp, r); } #if CONFIG_EXT_INTER