Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1 | /* |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3 | * |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 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. |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 10 | */ |
| 11 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 12 | #ifndef AV1_COMMON_MV_H_ |
| 13 | #define AV1_COMMON_MV_H_ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 14 | |
| 15 | #include "av1/common/common.h" |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 16 | #include "aom_dsp/aom_filter.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 17 | |
| 18 | #ifdef __cplusplus |
| 19 | extern "C" { |
| 20 | #endif |
| 21 | |
| 22 | typedef struct mv { |
| 23 | int16_t row; |
| 24 | int16_t col; |
| 25 | } MV; |
| 26 | |
| 27 | typedef union int_mv { |
| 28 | uint32_t as_int; |
| 29 | MV as_mv; |
| 30 | } int_mv; /* facilitates faster equality tests and copies */ |
| 31 | |
| 32 | typedef struct mv32 { |
| 33 | int32_t row; |
| 34 | int32_t col; |
| 35 | } MV32; |
| 36 | |
Sarah Parker | e529986 | 2016-08-16 14:57:37 -0700 | [diff] [blame] | 37 | #if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION |
| 38 | // Bits of precision used for the model |
Debargha Mukherjee | 3a50db4 | 2016-12-06 15:20:03 -0800 | [diff] [blame] | 39 | #define WARPEDMODEL_PREC_BITS 16 |
| 40 | #define WARPEDMODEL_ROW3HOMO_PREC_BITS 16 |
Sarah Parker | e529986 | 2016-08-16 14:57:37 -0700 | [diff] [blame] | 41 | |
| 42 | // Bits of subpel precision for warped interpolation |
| 43 | #define WARPEDPIXEL_PREC_BITS 6 |
| 44 | #define WARPEDPIXEL_PREC_SHIFTS (1 << WARPEDPIXEL_PREC_BITS) |
| 45 | |
| 46 | // Taps for ntap filter |
| 47 | #define WARPEDPIXEL_FILTER_TAPS 6 |
| 48 | |
| 49 | // Precision of filter taps |
| 50 | #define WARPEDPIXEL_FILTER_BITS 7 |
| 51 | |
| 52 | #define WARPEDDIFF_PREC_BITS (WARPEDMODEL_PREC_BITS - WARPEDPIXEL_PREC_BITS) |
| 53 | |
David Barker | cf3d0b0 | 2016-11-10 10:14:49 +0000 | [diff] [blame] | 54 | /* clang-format off */ |
Sarah Parker | e529986 | 2016-08-16 14:57:37 -0700 | [diff] [blame] | 55 | typedef enum { |
David Barker | cf3d0b0 | 2016-11-10 10:14:49 +0000 | [diff] [blame] | 56 | IDENTITY = 0, // identity transformation, 0-parameter |
| 57 | TRANSLATION = 1, // translational motion 2-parameter |
Debargha Mukherjee | b0f6bd4 | 2016-12-02 09:19:39 -0800 | [diff] [blame] | 58 | ROTZOOM = 2, // simplified affine with rotation + zoom only, 4-parameter |
David Barker | cf3d0b0 | 2016-11-10 10:14:49 +0000 | [diff] [blame] | 59 | AFFINE = 3, // affine, 6-parameter |
| 60 | HOMOGRAPHY = 4, // homography, 8-parameter |
| 61 | TRANS_TYPES = 5, |
Sarah Parker | e529986 | 2016-08-16 14:57:37 -0700 | [diff] [blame] | 62 | } TransformationType; |
David Barker | cf3d0b0 | 2016-11-10 10:14:49 +0000 | [diff] [blame] | 63 | /* clang-format on */ |
| 64 | |
Debargha Mukherjee | b0f6bd4 | 2016-12-02 09:19:39 -0800 | [diff] [blame] | 65 | // Number of types used for global motion (must be >= 3 and <= TRANS_TYPES) |
David Barker | cf3d0b0 | 2016-11-10 10:14:49 +0000 | [diff] [blame] | 66 | #define GLOBAL_TRANS_TYPES 3 |
Sarah Parker | e529986 | 2016-08-16 14:57:37 -0700 | [diff] [blame] | 67 | |
| 68 | // number of parameters used by each transformation in TransformationTypes |
David Barker | cf3d0b0 | 2016-11-10 10:14:49 +0000 | [diff] [blame] | 69 | static const int n_trans_model_params[TRANS_TYPES] = { 0, 2, 4, 6, 8 }; |
Sarah Parker | e529986 | 2016-08-16 14:57:37 -0700 | [diff] [blame] | 70 | |
Debargha Mukherjee | 8db4c77 | 2016-11-07 12:54:21 -0800 | [diff] [blame] | 71 | // The order of values in the wmmat matrix below is best described |
| 72 | // by the homography: |
| 73 | // [x' (m2 m3 m0 [x |
David Barker | cf3d0b0 | 2016-11-10 10:14:49 +0000 | [diff] [blame] | 74 | // y' = m4 m5 m1 * y |
Debargha Mukherjee | 8db4c77 | 2016-11-07 12:54:21 -0800 | [diff] [blame] | 75 | // 1] m6 m7 1) 1] |
Sarah Parker | e529986 | 2016-08-16 14:57:37 -0700 | [diff] [blame] | 76 | typedef struct { |
| 77 | TransformationType wmtype; |
David Barker | cf3d0b0 | 2016-11-10 10:14:49 +0000 | [diff] [blame] | 78 | int32_t wmmat[8]; |
Sarah Parker | e529986 | 2016-08-16 14:57:37 -0700 | [diff] [blame] | 79 | } WarpedMotionParams; |
| 80 | #endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION |
| 81 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 82 | #if CONFIG_GLOBAL_MOTION |
| 83 | // ALPHA here refers to parameters a and b in rotzoom model: |
| 84 | // | a b| |
| 85 | // |-b a| |
| 86 | // |
| 87 | // and a, b, c, d in affine model: |
| 88 | // | a b| |
| 89 | // | c d| |
| 90 | // |
| 91 | // Anything ending in PREC_BITS is the number of bits of precision |
| 92 | // to maintain when converting from double to integer. |
| 93 | // |
| 94 | // The ABS parameters are used to create an upper and lower bound |
| 95 | // for each parameter. In other words, after a parameter is integerized |
| 96 | // it is clamped between -(1 << ABS_XXX_BITS) and (1 << ABS_XXX_BITS). |
| 97 | // |
| 98 | // XXX_PREC_DIFF and XXX_DECODE_FACTOR |
| 99 | // are computed once here to prevent repetitive |
| 100 | // computation on the decoder side. These are |
| 101 | // to allow the global motion parameters to be encoded in a lower |
| 102 | // precision than the warped model precision. This means that they |
| 103 | // need to be changed to warped precision when they are decoded. |
| 104 | // |
| 105 | // XX_MIN, XX_MAX are also computed to avoid repeated computation |
| 106 | |
Debargha Mukherjee | 5f30585 | 2016-11-03 15:47:21 -0700 | [diff] [blame] | 107 | #define GM_TRANS_PREC_BITS 3 |
Debargha Mukherjee | 3a50db4 | 2016-12-06 15:20:03 -0800 | [diff] [blame] | 108 | #define GM_ABS_TRANS_BITS 9 |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 109 | #define GM_TRANS_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_TRANS_PREC_BITS) |
| 110 | #define GM_TRANS_DECODE_FACTOR (1 << GM_TRANS_PREC_DIFF) |
| 111 | |
Debargha Mukherjee | 3a50db4 | 2016-12-06 15:20:03 -0800 | [diff] [blame] | 112 | #define GM_ALPHA_PREC_BITS 15 |
| 113 | #define GM_ABS_ALPHA_BITS 12 |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 114 | #define GM_ALPHA_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_ALPHA_PREC_BITS) |
| 115 | #define GM_ALPHA_DECODE_FACTOR (1 << GM_ALPHA_PREC_DIFF) |
| 116 | |
Debargha Mukherjee | 3a50db4 | 2016-12-06 15:20:03 -0800 | [diff] [blame] | 117 | #define GM_ROW3HOMO_PREC_BITS 16 |
| 118 | #define GM_ABS_ROW3HOMO_BITS 11 |
Debargha Mukherjee | 8db4c77 | 2016-11-07 12:54:21 -0800 | [diff] [blame] | 119 | #define GM_ROW3HOMO_PREC_DIFF \ |
| 120 | (WARPEDMODEL_ROW3HOMO_PREC_BITS - GM_ROW3HOMO_PREC_BITS) |
| 121 | #define GM_ROW3HOMO_DECODE_FACTOR (1 << GM_ROW3HOMO_PREC_DIFF) |
| 122 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 123 | #define GM_TRANS_MAX (1 << GM_ABS_TRANS_BITS) |
| 124 | #define GM_ALPHA_MAX (1 << GM_ABS_ALPHA_BITS) |
Debargha Mukherjee | 8db4c77 | 2016-11-07 12:54:21 -0800 | [diff] [blame] | 125 | #define GM_ROW3HOMO_MAX (1 << GM_ABS_ROW3HOMO_BITS) |
| 126 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 127 | #define GM_TRANS_MIN -GM_TRANS_MAX |
| 128 | #define GM_ALPHA_MIN -GM_ALPHA_MAX |
Debargha Mukherjee | 8db4c77 | 2016-11-07 12:54:21 -0800 | [diff] [blame] | 129 | #define GM_ROW3HOMO_MIN -GM_ROW3HOMO_MAX |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 130 | |
Debargha Mukherjee | 9febfc1 | 2016-12-07 13:20:44 -0800 | [diff] [blame] | 131 | // Bits used for different models |
| 132 | #define GM_IDENTITY_BITS 0 |
| 133 | #define GM_TRANSLATION_BITS ((GM_ABS_TRANS_BITS + 1) * 2) |
| 134 | #define GM_ROTZOOM_BITS (GM_TRANSLATION_BITS + (GM_ABS_ALPHA_BITS + 1) * 2) |
| 135 | #define GM_AFFINE_BITS (GM_ROTZOOM_BITS + (GM_ABS_ALPHA_BITS + 1) * 2) |
| 136 | #define GM_HOMOGRAPHY_BITS (GM_AFFINE_BITS + (GM_ABS_ROW3HOMO_BITS + 1) * 2) |
| 137 | |
Debargha Mukherjee | 5f30585 | 2016-11-03 15:47:21 -0700 | [diff] [blame] | 138 | // Convert a global motion translation vector (which may have more bits than a |
| 139 | // regular motion vector) into a motion vector |
David Barker | cdcac6d | 2016-12-01 17:04:16 +0000 | [diff] [blame] | 140 | static INLINE int_mv gm_get_motion_vector(const WarpedMotionParams *gm, |
| 141 | int allow_hp) { |
Debargha Mukherjee | 5f30585 | 2016-11-03 15:47:21 -0700 | [diff] [blame] | 142 | int_mv res; |
David Barker | cdcac6d | 2016-12-01 17:04:16 +0000 | [diff] [blame] | 143 | res.as_mv.row = allow_hp ? (int16_t)ROUND_POWER_OF_TWO_SIGNED( |
| 144 | gm->wmmat[1], WARPEDMODEL_PREC_BITS - 3) |
| 145 | : (int16_t)ROUND_POWER_OF_TWO_SIGNED( |
| 146 | gm->wmmat[1], WARPEDMODEL_PREC_BITS - 2) * |
| 147 | 2; |
| 148 | res.as_mv.col = allow_hp ? (int16_t)ROUND_POWER_OF_TWO_SIGNED( |
| 149 | gm->wmmat[0], WARPEDMODEL_PREC_BITS - 3) |
| 150 | : (int16_t)ROUND_POWER_OF_TWO_SIGNED( |
| 151 | gm->wmmat[0], WARPEDMODEL_PREC_BITS - 2) * |
| 152 | 2; |
Debargha Mukherjee | 5f30585 | 2016-11-03 15:47:21 -0700 | [diff] [blame] | 153 | return res; |
| 154 | } |
| 155 | |
David Barker | cf3d0b0 | 2016-11-10 10:14:49 +0000 | [diff] [blame] | 156 | static INLINE TransformationType get_gmtype(const WarpedMotionParams *gm) { |
| 157 | // if (gm->wmmat[6] != 0 || gm->wmmat[7] != 0) return HOMOGRAPHY; |
| 158 | if (gm->wmmat[5] == (1 << WARPEDMODEL_PREC_BITS) && !gm->wmmat[4] && |
| 159 | gm->wmmat[2] == (1 << WARPEDMODEL_PREC_BITS) && !gm->wmmat[3]) { |
| 160 | return ((!gm->wmmat[1] && !gm->wmmat[0]) ? IDENTITY : TRANSLATION); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 161 | } |
David Barker | cf3d0b0 | 2016-11-10 10:14:49 +0000 | [diff] [blame] | 162 | if (gm->wmmat[2] == gm->wmmat[5] && gm->wmmat[3] == -gm->wmmat[4]) |
| 163 | return ROTZOOM; |
Debargha Mukherjee | 8db4c77 | 2016-11-07 12:54:21 -0800 | [diff] [blame] | 164 | else |
David Barker | cf3d0b0 | 2016-11-10 10:14:49 +0000 | [diff] [blame] | 165 | return AFFINE; |
Debargha Mukherjee | 8db4c77 | 2016-11-07 12:54:21 -0800 | [diff] [blame] | 166 | } |
| 167 | |
Debargha Mukherjee | e3e0079 | 2016-11-13 11:35:44 -0800 | [diff] [blame] | 168 | static INLINE void set_default_gmparams(WarpedMotionParams *wm) { |
| 169 | static const int32_t default_wm_mat[8] = { |
Debargha Mukherjee | 8db4c77 | 2016-11-07 12:54:21 -0800 | [diff] [blame] | 170 | 0, 0, (1 << WARPEDMODEL_PREC_BITS), 0, 0, (1 << WARPEDMODEL_PREC_BITS), 0, 0 |
| 171 | }; |
Debargha Mukherjee | e3e0079 | 2016-11-13 11:35:44 -0800 | [diff] [blame] | 172 | memcpy(wm->wmmat, default_wm_mat, sizeof(wm->wmmat)); |
| 173 | wm->wmtype = IDENTITY; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 174 | } |
| 175 | #endif // CONFIG_GLOBAL_MOTION |
| 176 | |
| 177 | #if CONFIG_REF_MV |
| 178 | typedef struct candidate_mv { |
| 179 | int_mv this_mv; |
| 180 | int_mv comp_mv; |
Jingning Han | 3f33883 | 2016-11-18 11:01:48 -0800 | [diff] [blame] | 181 | uint8_t pred_diff[2]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 182 | int weight; |
| 183 | } CANDIDATE_MV; |
| 184 | #endif |
| 185 | |
| 186 | static INLINE int is_zero_mv(const MV *mv) { |
| 187 | return *((const uint32_t *)mv) == 0; |
| 188 | } |
| 189 | |
| 190 | static INLINE int is_equal_mv(const MV *a, const MV *b) { |
| 191 | return *((const uint32_t *)a) == *((const uint32_t *)b); |
| 192 | } |
| 193 | |
| 194 | static INLINE void clamp_mv(MV *mv, int min_col, int max_col, int min_row, |
| 195 | int max_row) { |
| 196 | mv->col = clamp(mv->col, min_col, max_col); |
| 197 | mv->row = clamp(mv->row, min_row, max_row); |
| 198 | } |
| 199 | |
| 200 | static INLINE int mv_has_subpel(const MV *mv) { |
| 201 | return (mv->row & SUBPEL_MASK) || (mv->col & SUBPEL_MASK); |
| 202 | } |
| 203 | #ifdef __cplusplus |
| 204 | } // extern "C" |
| 205 | #endif |
| 206 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 207 | #endif // AV1_COMMON_MV_H_ |