blob: 981076d27b687a4f6985b85298fa02d057eded1c [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * 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 Xuc27fc142016-08-22 16:08:15 -070010 */
11
Yaowu Xuf883b422016-08-30 14:01:10 -070012#ifndef AV1_COMMON_MV_H_
13#define AV1_COMMON_MV_H_
Yaowu Xuc27fc142016-08-22 16:08:15 -070014
15#include "av1/common/common.h"
Sarah Parkerae7c4582017-02-28 16:30:30 -080016#include "av1/common/common_data.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070017#include "aom_dsp/aom_filter.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070018
19#ifdef __cplusplus
20extern "C" {
21#endif
22
23typedef struct mv {
24 int16_t row;
25 int16_t col;
26} MV;
27
28typedef union int_mv {
29 uint32_t as_int;
30 MV as_mv;
31} int_mv; /* facilitates faster equality tests and copies */
32
33typedef struct mv32 {
34 int32_t row;
35 int32_t col;
36} MV32;
37
Sarah Parkere5299862016-08-16 14:57:37 -070038#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
39// Bits of precision used for the model
Debargha Mukherjee3a50db42016-12-06 15:20:03 -080040#define WARPEDMODEL_PREC_BITS 16
41#define WARPEDMODEL_ROW3HOMO_PREC_BITS 16
Sarah Parkere5299862016-08-16 14:57:37 -070042
43// Bits of subpel precision for warped interpolation
44#define WARPEDPIXEL_PREC_BITS 6
45#define WARPEDPIXEL_PREC_SHIFTS (1 << WARPEDPIXEL_PREC_BITS)
46
47// Taps for ntap filter
48#define WARPEDPIXEL_FILTER_TAPS 6
49
50// Precision of filter taps
51#define WARPEDPIXEL_FILTER_BITS 7
52
53#define WARPEDDIFF_PREC_BITS (WARPEDMODEL_PREC_BITS - WARPEDPIXEL_PREC_BITS)
54
David Barkercf3d0b02016-11-10 10:14:49 +000055/* clang-format off */
Sarah Parkere5299862016-08-16 14:57:37 -070056typedef enum {
Debargha Mukherjee5dfa9302017-02-10 05:00:08 -080057 IDENTITY = 0, // identity transformation, 0-parameter
58 TRANSLATION = 1, // translational motion 2-parameter
59 ROTZOOM = 2, // simplified affine with rotation + zoom only, 4-parameter
60 AFFINE = 3, // affine, 6-parameter
61 HORTRAPEZOID = 4, // constrained homography, hor trapezoid, 6-parameter
62 VERTRAPEZOID = 5, // constrained homography, ver trapezoid, 6-parameter
63 HOMOGRAPHY = 6, // homography, 8-parameter
64 TRANS_TYPES = 7,
Sarah Parkere5299862016-08-16 14:57:37 -070065} TransformationType;
David Barkercf3d0b02016-11-10 10:14:49 +000066/* clang-format on */
67
Debargha Mukherjeeb0f6bd42016-12-02 09:19:39 -080068// Number of types used for global motion (must be >= 3 and <= TRANS_TYPES)
Debargha Mukherjee5dfa9302017-02-10 05:00:08 -080069// 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
David Barkercf3d0b02016-11-10 10:14:49 +000074#define GLOBAL_TRANS_TYPES 3
Sarah Parkere5299862016-08-16 14:57:37 -070075
76// number of parameters used by each transformation in TransformationTypes
Debargha Mukherjee5dfa9302017-02-10 05:00:08 -080077static const int trans_model_params[TRANS_TYPES] = { 0, 2, 4, 6, 6, 6, 8 };
Sarah Parkere5299862016-08-16 14:57:37 -070078
Debargha Mukherjee8db4c772016-11-07 12:54:21 -080079// The order of values in the wmmat matrix below is best described
80// by the homography:
Debargha Mukherjee5dfa9302017-02-10 05:00:08 -080081// [x' (m2 m3 m0 [x
82// z . y' = m4 m5 m1 * y
83// 1] m6 m7 1) 1]
Sarah Parkere5299862016-08-16 14:57:37 -070084typedef struct {
85 TransformationType wmtype;
David Barkercf3d0b02016-11-10 10:14:49 +000086 int32_t wmmat[8];
Sarah Parkere5299862016-08-16 14:57:37 -070087} WarpedMotionParams;
88#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
89
Yaowu Xuc27fc142016-08-22 16:08:15 -070090#if CONFIG_GLOBAL_MOTION
91// ALPHA here refers to parameters a and b in rotzoom model:
92// | a b|
93// |-b a|
94//
95// and a, b, c, d in affine model:
96// | a b|
97// | c d|
98//
99// Anything ending in PREC_BITS is the number of bits of precision
100// to maintain when converting from double to integer.
101//
102// The ABS parameters are used to create an upper and lower bound
103// for each parameter. In other words, after a parameter is integerized
104// it is clamped between -(1 << ABS_XXX_BITS) and (1 << ABS_XXX_BITS).
105//
106// XXX_PREC_DIFF and XXX_DECODE_FACTOR
107// are computed once here to prevent repetitive
108// computation on the decoder side. These are
109// to allow the global motion parameters to be encoded in a lower
110// precision than the warped model precision. This means that they
111// need to be changed to warped precision when they are decoded.
112//
113// XX_MIN, XX_MAX are also computed to avoid repeated computation
114
David Barker6c652782017-02-13 13:46:40 +0000115#define GM_TRANS_PREC_BITS 6
116#define GM_ABS_TRANS_BITS 12
Yaowu Xuc27fc142016-08-22 16:08:15 -0700117#define GM_TRANS_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_TRANS_PREC_BITS)
118#define GM_TRANS_DECODE_FACTOR (1 << GM_TRANS_PREC_DIFF)
119
Debargha Mukherjee3a50db42016-12-06 15:20:03 -0800120#define GM_ALPHA_PREC_BITS 15
121#define GM_ABS_ALPHA_BITS 12
Yaowu Xuc27fc142016-08-22 16:08:15 -0700122#define GM_ALPHA_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_ALPHA_PREC_BITS)
123#define GM_ALPHA_DECODE_FACTOR (1 << GM_ALPHA_PREC_DIFF)
124
Debargha Mukherjee3a50db42016-12-06 15:20:03 -0800125#define GM_ROW3HOMO_PREC_BITS 16
126#define GM_ABS_ROW3HOMO_BITS 11
Debargha Mukherjee8db4c772016-11-07 12:54:21 -0800127#define GM_ROW3HOMO_PREC_DIFF \
128 (WARPEDMODEL_ROW3HOMO_PREC_BITS - GM_ROW3HOMO_PREC_BITS)
129#define GM_ROW3HOMO_DECODE_FACTOR (1 << GM_ROW3HOMO_PREC_DIFF)
130
Yaowu Xuc27fc142016-08-22 16:08:15 -0700131#define GM_TRANS_MAX (1 << GM_ABS_TRANS_BITS)
132#define GM_ALPHA_MAX (1 << GM_ABS_ALPHA_BITS)
Debargha Mukherjee8db4c772016-11-07 12:54:21 -0800133#define GM_ROW3HOMO_MAX (1 << GM_ABS_ROW3HOMO_BITS)
134
Yaowu Xuc27fc142016-08-22 16:08:15 -0700135#define GM_TRANS_MIN -GM_TRANS_MAX
136#define GM_ALPHA_MIN -GM_ALPHA_MAX
Debargha Mukherjee8db4c772016-11-07 12:54:21 -0800137#define GM_ROW3HOMO_MIN -GM_ROW3HOMO_MAX
Yaowu Xuc27fc142016-08-22 16:08:15 -0700138
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -0800139// Maximum number of bits used for different models
Debargha Mukherjee9febfc12016-12-07 13:20:44 -0800140#define GM_IDENTITY_BITS 0
141#define GM_TRANSLATION_BITS ((GM_ABS_TRANS_BITS + 1) * 2)
142#define GM_ROTZOOM_BITS (GM_TRANSLATION_BITS + (GM_ABS_ALPHA_BITS + 1) * 2)
143#define GM_AFFINE_BITS (GM_ROTZOOM_BITS + (GM_ABS_ALPHA_BITS + 1) * 2)
144#define GM_HOMOGRAPHY_BITS (GM_AFFINE_BITS + (GM_ABS_ROW3HOMO_BITS + 1) * 2)
Debargha Mukherjee5dfa9302017-02-10 05:00:08 -0800145#define GM_HORTRAPEZOID_BITS \
146 (GM_AFFINE_BITS - GM_ABS_ALPHA_BITS + GM_ABS_ROW3HOMO_BITS)
147#define GM_VERTRAPEZOID_BITS \
148 (GM_AFFINE_BITS - GM_ABS_ALPHA_BITS + GM_ABS_ROW3HOMO_BITS)
Debargha Mukherjee9febfc12016-12-07 13:20:44 -0800149
Sarah Parkerae7c4582017-02-28 16:30:30 -0800150// Use global motion parameters for sub8x8 blocks
151#define GLOBAL_SUB8X8_USED 0
152
153static INLINE int block_center_x(int mi_col, BLOCK_SIZE bs) {
154 const int bw = block_size_wide[bs];
155 return mi_col * MI_SIZE + AOMMAX(bw, MI_SIZE) / 2;
156}
157
158static INLINE int block_center_y(int mi_row, BLOCK_SIZE bs) {
159 const int bh = block_size_high[bs];
160 return mi_row * MI_SIZE + AOMMAX(bh, MI_SIZE) / 2;
161}
162
Debargha Mukherjee5f305852016-11-03 15:47:21 -0700163// Convert a global motion translation vector (which may have more bits than a
164// regular motion vector) into a motion vector
David Barkercdcac6d2016-12-01 17:04:16 +0000165static INLINE int_mv gm_get_motion_vector(const WarpedMotionParams *gm,
Sarah Parkerae7c4582017-02-28 16:30:30 -0800166 int allow_hp, BLOCK_SIZE bsize,
167 int mi_col, int mi_row) {
168#if !GLOBAL_SUB8X8_USED
169 if (bsize < BLOCK_8X8) {
170 int_mv res_zero;
171 res_zero.as_mv.row = 0;
172 res_zero.as_mv.col = 0;
173 return res_zero;
174 }
175#endif
176
Debargha Mukherjee5f305852016-11-03 15:47:21 -0700177 int_mv res;
David Barker45390c12017-02-20 14:44:40 +0000178 const int32_t *mat = gm->wmmat;
Sarah Parkerae7c4582017-02-28 16:30:30 -0800179 const int x = block_center_x(mi_col, bsize);
180 const int y = block_center_y(mi_row, bsize);
David Barker45390c12017-02-20 14:44:40 +0000181 int xc, yc;
182 int shift = allow_hp ? WARPEDMODEL_PREC_BITS - 3 : WARPEDMODEL_PREC_BITS - 2;
183 int scale = allow_hp ? 0 : 1;
184
185 if (gm->wmtype == ROTZOOM) {
186 assert(gm->wmmat[5] == gm->wmmat[2]);
187 assert(gm->wmmat[4] == -gm->wmmat[3]);
188 }
189 xc = mat[2] * x + mat[3] * y + mat[0];
190 yc = mat[4] * x + mat[5] * y + mat[1];
191
Debargha Mukherjeef6dd3c62017-02-23 13:21:23 -0800192 if (gm->wmtype > AFFINE) {
193 const int Z =
194 mat[6] * x + mat[7] * y + (1 << WARPEDMODEL_ROW3HOMO_PREC_BITS);
195 xc <<= (WARPEDMODEL_ROW3HOMO_PREC_BITS - WARPEDMODEL_PREC_BITS);
196 yc <<= (WARPEDMODEL_ROW3HOMO_PREC_BITS - WARPEDMODEL_PREC_BITS);
197 xc = xc > 0 ? (xc + Z / 2) / Z : (xc - Z / 2) / Z;
198 yc = yc > 0 ? (yc + Z / 2) / Z : (yc - Z / 2) / Z;
199 }
200
David Barker45390c12017-02-20 14:44:40 +0000201 int tx = (ROUND_POWER_OF_TWO_SIGNED(xc, shift) << scale) - (x << 3);
202 int ty = (ROUND_POWER_OF_TWO_SIGNED(yc, shift) << scale) - (y << 3);
203
204 res.as_mv.row = ty;
205 res.as_mv.col = tx;
Debargha Mukherjee5f305852016-11-03 15:47:21 -0700206 return res;
207}
208
David Barkercf3d0b02016-11-10 10:14:49 +0000209static INLINE TransformationType get_gmtype(const WarpedMotionParams *gm) {
Debargha Mukherjee5dfa9302017-02-10 05:00:08 -0800210 if (gm->wmmat[6] != 0 || gm->wmmat[7] != 0) {
211 if (!gm->wmmat[6] && !gm->wmmat[4]) return HORTRAPEZOID;
212 if (!gm->wmmat[7] && !gm->wmmat[3]) return VERTRAPEZOID;
213 return HOMOGRAPHY;
214 }
David Barkercf3d0b02016-11-10 10:14:49 +0000215 if (gm->wmmat[5] == (1 << WARPEDMODEL_PREC_BITS) && !gm->wmmat[4] &&
216 gm->wmmat[2] == (1 << WARPEDMODEL_PREC_BITS) && !gm->wmmat[3]) {
217 return ((!gm->wmmat[1] && !gm->wmmat[0]) ? IDENTITY : TRANSLATION);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700218 }
David Barkercf3d0b02016-11-10 10:14:49 +0000219 if (gm->wmmat[2] == gm->wmmat[5] && gm->wmmat[3] == -gm->wmmat[4])
220 return ROTZOOM;
Debargha Mukherjee8db4c772016-11-07 12:54:21 -0800221 else
David Barkercf3d0b02016-11-10 10:14:49 +0000222 return AFFINE;
Debargha Mukherjee8db4c772016-11-07 12:54:21 -0800223}
224
Debargha Mukherjeee3e00792016-11-13 11:35:44 -0800225static INLINE void set_default_gmparams(WarpedMotionParams *wm) {
226 static const int32_t default_wm_mat[8] = {
Debargha Mukherjee8db4c772016-11-07 12:54:21 -0800227 0, 0, (1 << WARPEDMODEL_PREC_BITS), 0, 0, (1 << WARPEDMODEL_PREC_BITS), 0, 0
228 };
Debargha Mukherjeee3e00792016-11-13 11:35:44 -0800229 memcpy(wm->wmmat, default_wm_mat, sizeof(wm->wmmat));
230 wm->wmtype = IDENTITY;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700231}
232#endif // CONFIG_GLOBAL_MOTION
233
234#if CONFIG_REF_MV
235typedef struct candidate_mv {
236 int_mv this_mv;
237 int_mv comp_mv;
Jingning Han3f338832016-11-18 11:01:48 -0800238 uint8_t pred_diff[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700239 int weight;
240} CANDIDATE_MV;
241#endif
242
243static INLINE int is_zero_mv(const MV *mv) {
244 return *((const uint32_t *)mv) == 0;
245}
246
247static INLINE int is_equal_mv(const MV *a, const MV *b) {
248 return *((const uint32_t *)a) == *((const uint32_t *)b);
249}
250
251static INLINE void clamp_mv(MV *mv, int min_col, int max_col, int min_row,
252 int max_row) {
253 mv->col = clamp(mv->col, min_col, max_col);
254 mv->row = clamp(mv->row, min_row, max_row);
255}
256
257static INLINE int mv_has_subpel(const MV *mv) {
258 return (mv->row & SUBPEL_MASK) || (mv->col & SUBPEL_MASK);
259}
260#ifdef __cplusplus
261} // extern "C"
262#endif
263
Yaowu Xuf883b422016-08-30 14:01:10 -0700264#endif // AV1_COMMON_MV_H_