diff options
Diffstat (limited to 'third_party/aom/av1/common/mv.h')
-rw-r--r-- | third_party/aom/av1/common/mv.h | 83 |
1 files changed, 71 insertions, 12 deletions
diff --git a/third_party/aom/av1/common/mv.h b/third_party/aom/av1/common/mv.h index dabfc0ead..65f0f7eda 100644 --- a/third_party/aom/av1/common/mv.h +++ b/third_party/aom/av1/common/mv.h @@ -20,6 +20,8 @@ extern "C" { #endif +#define INVALID_MV 0x80008000 + typedef struct mv { int16_t row; int16_t col; @@ -88,10 +90,12 @@ typedef enum { // GLOBAL_TRANS_TYPES 7 - up to full homography #define GLOBAL_TRANS_TYPES 4 +#if GLOBAL_TRANS_TYPES > 4 // First bit indicates whether using identity or not // GLOBAL_TYPE_BITS=ceiling(log2(GLOBAL_TRANS_TYPES-1)) is the // number of bits needed to cover the remaining possibilities #define GLOBAL_TYPE_BITS (get_msb(2 * GLOBAL_TRANS_TYPES - 3)) +#endif // GLOBAL_TRANS_TYPES > 4 typedef struct { #if CONFIG_GLOBAL_MOTION @@ -116,14 +120,14 @@ typedef struct { int16_t alpha, beta, gamma, delta; } WarpedMotionParams; -static INLINE void set_default_warp_params(WarpedMotionParams *wm) { - static const int32_t default_wm_mat[8] = { - 0, 0, (1 << WARPEDMODEL_PREC_BITS), 0, 0, (1 << WARPEDMODEL_PREC_BITS), 0, 0 - }; - memset(wm, 0, sizeof(*wm)); - memcpy(wm->wmmat, default_wm_mat, sizeof(wm->wmmat)); - wm->wmtype = IDENTITY; -} +/* clang-format off */ +static const WarpedMotionParams default_warp_params = { + IDENTITY, + { 0, 0, (1 << WARPEDMODEL_PREC_BITS), 0, 0, (1 << WARPEDMODEL_PREC_BITS), 0, + 0 }, + 0, 0, 0, 0 +}; +/* clang-format on */ #endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION #if CONFIG_GLOBAL_MOTION @@ -202,21 +206,70 @@ static INLINE int convert_to_trans_prec(int allow_hp, int coor) { else return ROUND_POWER_OF_TWO_SIGNED(coor, WARPEDMODEL_PREC_BITS - 2) * 2; } +#if CONFIG_AMVR +static INLINE void integer_mv_precision(MV *mv) { + int mod = (mv->row % 8); + if (mod != 0) { + mv->row -= mod; + if (abs(mod) > 4) { + if (mod > 0) { + mv->row += 8; + } else { + mv->row -= 8; + } + } + } -// Convert a global motion translation vector (which may have more bits than a -// regular motion vector) into a motion vector + mod = (mv->col % 8); + if (mod != 0) { + mv->col -= mod; + if (abs(mod) > 4) { + if (mod > 0) { + mv->col += 8; + } else { + mv->col -= 8; + } + } + } +} +#endif +// 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) { + int mi_col, int mi_row, int block_idx +#if CONFIG_AMVR + , + int is_integer +#endif + ) { const int unify_bsize = CONFIG_CB4X4; int_mv res; const int32_t *mat = gm->wmmat; 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; } @@ -256,6 +309,12 @@ static INLINE int_mv gm_get_motion_vector(const WarpedMotionParams *gm, res.as_mv.row = ty; res.as_mv.col = tx; + +#if CONFIG_AMVR + if (is_integer) { + integer_mv_precision(&res.as_mv); + } +#endif return res; } |