1 /* 2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved 3 * 4 * This source code is subject to the terms of the BSD 2 Clause License and 5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License 6 * was not distributed with this source code in the LICENSE file, you can 7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open 8 * Media Patent License 1.0 was not distributed with this source code in the 9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent. 10 */ 11 12 #ifndef AOM_AV1_COMMON_MV_H_ 13 #define AOM_AV1_COMMON_MV_H_ 14 15 #include "av1/common/common.h" 16 #include "av1/common/common_data.h" 17 #include "aom_dsp/aom_filter.h" 18 19 #ifdef __cplusplus 20 extern "C" { 21 #endif 22 23 #define INVALID_MV 0x80008000 24 25 typedef struct mv { 26 int16_t row; 27 int16_t col; 28 } MV; 29 30 static const MV kZeroMv = { 0, 0 }; 31 32 typedef union int_mv { 33 uint32_t as_int; 34 MV as_mv; 35 } int_mv; /* facilitates faster equality tests and copies */ 36 37 typedef struct mv32 { 38 int32_t row; 39 int32_t col; 40 } MV32; 41 42 // Bits of precision used for the model 43 #define WARPEDMODEL_PREC_BITS 16 44 #define WARPEDMODEL_ROW3HOMO_PREC_BITS 16 45 46 #define WARPEDMODEL_TRANS_CLAMP (128 << WARPEDMODEL_PREC_BITS) 47 #define WARPEDMODEL_NONDIAGAFFINE_CLAMP (1 << (WARPEDMODEL_PREC_BITS - 3)) 48 #define WARPEDMODEL_ROW3HOMO_CLAMP (1 << (WARPEDMODEL_PREC_BITS - 2)) 49 50 // Bits of subpel precision for warped interpolation 51 #define WARPEDPIXEL_PREC_BITS 6 52 #define WARPEDPIXEL_PREC_SHIFTS (1 << WARPEDPIXEL_PREC_BITS) 53 54 #define WARP_PARAM_REDUCE_BITS 6 55 56 #define WARPEDDIFF_PREC_BITS (WARPEDMODEL_PREC_BITS - WARPEDPIXEL_PREC_BITS) 57 58 /* clang-format off */ 59 enum { 60 IDENTITY = 0, // identity transformation, 0-parameter 61 TRANSLATION = 1, // translational motion 2-parameter 62 ROTZOOM = 2, // simplified affine with rotation + zoom only, 4-parameter 63 AFFINE = 3, // affine, 6-parameter 64 TRANS_TYPES, 65 } UENUM1BYTE(TransformationType); 66 /* clang-format on */ 67 68 // Number of types used for global motion (must be >= 3 and <= TRANS_TYPES) 69 // The following can be useful: 70 // GLOBAL_TRANS_TYPES 3 - up to rotation-zoom 71 // GLOBAL_TRANS_TYPES 4 - up to affine 72 // GLOBAL_TRANS_TYPES 6 - up to hor/ver trapezoids 73 // GLOBAL_TRANS_TYPES 7 - up to full homography 74 #define GLOBAL_TRANS_TYPES 4 75 76 typedef struct { 77 int global_warp_allowed; 78 int local_warp_allowed; 79 } WarpTypesAllowed; 80 81 // number of parameters used by each transformation in TransformationTypes 82 static const int trans_model_params[TRANS_TYPES] = { 0, 2, 4, 6 }; 83 84 // The order of values in the wmmat matrix below is best described 85 // by the homography: 86 // [x' (m2 m3 m0 [x 87 // z . y' = m4 m5 m1 * y 88 // 1] m6 m7 1) 1] 89 typedef struct { 90 int32_t wmmat[8]; 91 int16_t alpha, beta, gamma, delta; 92 TransformationType wmtype; 93 int8_t invalid; 94 } WarpedMotionParams; 95 96 /* clang-format off */ 97 static const WarpedMotionParams default_warp_params = { 98 { 0, 0, (1 << WARPEDMODEL_PREC_BITS), 0, 0, (1 << WARPEDMODEL_PREC_BITS), 0, 99 0 }, 100 0, 0, 0, 0, 101 IDENTITY, 102 0, 103 }; 104 /* clang-format on */ 105 106 // The following constants describe the various precisions 107 // of different parameters in the global motion experiment. 108 // 109 // Given the general homography: 110 // [x' (a b c [x 111 // z . y' = d e f * y 112 // 1] g h i) 1] 113 // 114 // Constants using the name ALPHA here are related to parameters 115 // a, b, d, e. Constants using the name TRANS are related 116 // to parameters c and f. 117 // 118 // Anything ending in PREC_BITS is the number of bits of precision 119 // to maintain when converting from double to integer. 120 // 121 // The ABS parameters are used to create an upper and lower bound 122 // for each parameter. In other words, after a parameter is integerized 123 // it is clamped between -(1 << ABS_XXX_BITS) and (1 << ABS_XXX_BITS). 124 // 125 // XXX_PREC_DIFF and XXX_DECODE_FACTOR 126 // are computed once here to prevent repetitive 127 // computation on the decoder side. These are 128 // to allow the global motion parameters to be encoded in a lower 129 // precision than the warped model precision. This means that they 130 // need to be changed to warped precision when they are decoded. 131 // 132 // XX_MIN, XX_MAX are also computed to avoid repeated computation 133 134 #define SUBEXPFIN_K 3 135 #define GM_TRANS_PREC_BITS 6 136 #define GM_ABS_TRANS_BITS 12 137 #define GM_ABS_TRANS_ONLY_BITS (GM_ABS_TRANS_BITS - GM_TRANS_PREC_BITS + 3) 138 #define GM_TRANS_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_TRANS_PREC_BITS) 139 #define GM_TRANS_ONLY_PREC_DIFF (WARPEDMODEL_PREC_BITS - 3) 140 #define GM_TRANS_DECODE_FACTOR (1 << GM_TRANS_PREC_DIFF) 141 #define GM_TRANS_ONLY_DECODE_FACTOR (1 << GM_TRANS_ONLY_PREC_DIFF) 142 143 #define GM_ALPHA_PREC_BITS 15 144 #define GM_ABS_ALPHA_BITS 12 145 #define GM_ALPHA_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_ALPHA_PREC_BITS) 146 #define GM_ALPHA_DECODE_FACTOR (1 << GM_ALPHA_PREC_DIFF) 147 148 #define GM_ROW3HOMO_PREC_BITS 16 149 #define GM_ABS_ROW3HOMO_BITS 11 150 #define GM_ROW3HOMO_PREC_DIFF \ 151 (WARPEDMODEL_ROW3HOMO_PREC_BITS - GM_ROW3HOMO_PREC_BITS) 152 #define GM_ROW3HOMO_DECODE_FACTOR (1 << GM_ROW3HOMO_PREC_DIFF) 153 154 #define GM_TRANS_MAX (1 << GM_ABS_TRANS_BITS) 155 #define GM_ALPHA_MAX (1 << GM_ABS_ALPHA_BITS) 156 #define GM_ROW3HOMO_MAX (1 << GM_ABS_ROW3HOMO_BITS) 157 158 #define GM_TRANS_MIN -GM_TRANS_MAX 159 #define GM_ALPHA_MIN -GM_ALPHA_MAX 160 #define GM_ROW3HOMO_MIN -GM_ROW3HOMO_MAX 161 162 static INLINE int block_center_x(int mi_col, BLOCK_SIZE bs) { 163 const int bw = block_size_wide[bs]; 164 return mi_col * MI_SIZE + bw / 2 - 1; 165 } 166 167 static INLINE int block_center_y(int mi_row, BLOCK_SIZE bs) { 168 const int bh = block_size_high[bs]; 169 return mi_row * MI_SIZE + bh / 2 - 1; 170 } 171 172 static INLINE int convert_to_trans_prec(int allow_hp, int coor) { 173 if (allow_hp) 174 return ROUND_POWER_OF_TWO_SIGNED(coor, WARPEDMODEL_PREC_BITS - 3); 175 else 176 return ROUND_POWER_OF_TWO_SIGNED(coor, WARPEDMODEL_PREC_BITS - 2) * 2; 177 } 178 static INLINE void integer_mv_precision(MV *mv) { 179 int mod = (mv->row % 8); 180 if (mod != 0) { 181 mv->row -= mod; 182 if (abs(mod) > 4) { 183 if (mod > 0) { 184 mv->row += 8; 185 } else { 186 mv->row -= 8; 187 } 188 } 189 } 190 191 mod = (mv->col % 8); 192 if (mod != 0) { 193 mv->col -= mod; 194 if (abs(mod) > 4) { 195 if (mod > 0) { 196 mv->col += 8; 197 } else { 198 mv->col -= 8; 199 } 200 } 201 } 202 } 203 // Convert a global motion vector into a motion vector at the centre of the 204 // given block. 205 // 206 // The resulting motion vector will have three fractional bits of precision. If 207 // allow_hp is zero, the bottom bit will always be zero. If CONFIG_AMVR and 208 // is_integer is true, the bottom three bits will be zero (so the motion vector 209 // represents an integer) 210 static INLINE int_mv gm_get_motion_vector(const WarpedMotionParams *gm, 211 int allow_hp, BLOCK_SIZE bsize, 212 int mi_col, int mi_row, 213 int is_integer) { 214 int_mv res; 215 216 if (gm->wmtype == IDENTITY) { 217 res.as_int = 0; 218 return res; 219 } 220 221 const int32_t *mat = gm->wmmat; 222 int x, y, tx, ty; 223 224 if (gm->wmtype == TRANSLATION) { 225 // All global motion vectors are stored with WARPEDMODEL_PREC_BITS (16) 226 // bits of fractional precision. The offset for a translation is stored in 227 // entries 0 and 1. For translations, all but the top three (two if 228 // cm->allow_high_precision_mv is false) fractional bits are always zero. 229 // 230 // After the right shifts, there are 3 fractional bits of precision. If 231 // allow_hp is false, the bottom bit is always zero (so we don't need a 232 // call to convert_to_trans_prec here) 233 res.as_mv.row = gm->wmmat[0] >> GM_TRANS_ONLY_PREC_DIFF; 234 res.as_mv.col = gm->wmmat[1] >> GM_TRANS_ONLY_PREC_DIFF; 235 assert(IMPLIES(1 & (res.as_mv.row | res.as_mv.col), allow_hp)); 236 if (is_integer) { 237 integer_mv_precision(&res.as_mv); 238 } 239 return res; 240 } 241 242 x = block_center_x(mi_col, bsize); 243 y = block_center_y(mi_row, bsize); 244 245 if (gm->wmtype == ROTZOOM) { 246 assert(gm->wmmat[5] == gm->wmmat[2]); 247 assert(gm->wmmat[4] == -gm->wmmat[3]); 248 } 249 250 const int xc = 251 (mat[2] - (1 << WARPEDMODEL_PREC_BITS)) * x + mat[3] * y + mat[0]; 252 const int yc = 253 mat[4] * x + (mat[5] - (1 << WARPEDMODEL_PREC_BITS)) * y + mat[1]; 254 tx = convert_to_trans_prec(allow_hp, xc); 255 ty = convert_to_trans_prec(allow_hp, yc); 256 257 res.as_mv.row = ty; 258 res.as_mv.col = tx; 259 260 if (is_integer) { 261 integer_mv_precision(&res.as_mv); 262 } 263 return res; 264 } 265 266 static INLINE TransformationType get_wmtype(const WarpedMotionParams *gm) { 267 if (gm->wmmat[5] == (1 << WARPEDMODEL_PREC_BITS) && !gm->wmmat[4] && 268 gm->wmmat[2] == (1 << WARPEDMODEL_PREC_BITS) && !gm->wmmat[3]) { 269 return ((!gm->wmmat[1] && !gm->wmmat[0]) ? IDENTITY : TRANSLATION); 270 } 271 if (gm->wmmat[2] == gm->wmmat[5] && gm->wmmat[3] == -gm->wmmat[4]) 272 return ROTZOOM; 273 else 274 return AFFINE; 275 } 276 277 typedef struct candidate_mv { 278 int_mv this_mv; 279 int_mv comp_mv; 280 int weight; 281 } CANDIDATE_MV; 282 283 static INLINE int is_zero_mv(const MV *mv) { 284 return *((const uint32_t *)mv) == 0; 285 } 286 287 static INLINE int is_equal_mv(const MV *a, const MV *b) { 288 return *((const uint32_t *)a) == *((const uint32_t *)b); 289 } 290 291 static INLINE void clamp_mv(MV *mv, int min_col, int max_col, int min_row, 292 int max_row) { 293 mv->col = clamp(mv->col, min_col, max_col); 294 mv->row = clamp(mv->row, min_row, max_row); 295 } 296 297 #ifdef __cplusplus 298 } // extern "C" 299 #endif 300 301 #endif // AOM_AV1_COMMON_MV_H_ 302