LCOV - code coverage report
Current view: top level - third_party/aom/av1/common - mv.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 70 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 9 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 AV1_COMMON_MV_H_
      13             : #define 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             : typedef struct mv {
      24             :   int16_t row;
      25             :   int16_t col;
      26             : } MV;
      27             : 
      28             : typedef union int_mv {
      29             :   uint32_t as_int;
      30             :   MV as_mv;
      31             : } int_mv; /* facilitates faster equality tests and copies */
      32             : 
      33             : typedef struct mv32 {
      34             :   int32_t row;
      35             :   int32_t col;
      36             : } MV32;
      37             : 
      38             : #if (CONFIG_WARPED_MOTION || CONFIG_MOTION_VAR) && CONFIG_GLOBAL_MOTION
      39             : #define SEPARATE_GLOBAL_MOTION 1
      40             : #endif  // (CONFIG_WARPED_MOTION || CONFIG_MOTION_VAR) && CONFIG_GLOBAL_MOTION
      41             : #if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
      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_DIAGAFFINE_CLAMP (1 << (WARPEDMODEL_PREC_BITS + 1))
      48             : #define WARPEDMODEL_NONDIAGAFFINE_CLAMP (1 << (WARPEDMODEL_PREC_BITS - 1))
      49             : #define WARPEDMODEL_ROW3HOMO_CLAMP (1 << (WARPEDMODEL_PREC_BITS - 1))
      50             : 
      51             : // Bits of subpel precision for warped interpolation
      52             : #define WARPEDPIXEL_PREC_BITS 6
      53             : #define WARPEDPIXEL_PREC_SHIFTS (1 << WARPEDPIXEL_PREC_BITS)
      54             : 
      55             : // Taps for ntap filter
      56             : #define WARPEDPIXEL_FILTER_TAPS 6
      57             : 
      58             : // Precision of filter taps
      59             : #define WARPEDPIXEL_FILTER_BITS 7
      60             : 
      61             : #define WARP_PARAM_REDUCE_BITS 6
      62             : 
      63             : // Precision bits reduction after horizontal shear
      64             : #define HORSHEAR_REDUCE_PREC_BITS 5
      65             : #define VERSHEAR_REDUCE_PREC_BITS \
      66             :   (2 * WARPEDPIXEL_FILTER_BITS - HORSHEAR_REDUCE_PREC_BITS)
      67             : 
      68             : #define WARPEDDIFF_PREC_BITS (WARPEDMODEL_PREC_BITS - WARPEDPIXEL_PREC_BITS)
      69             : 
      70             : /* clang-format off */
      71             : typedef enum {
      72             :   IDENTITY = 0,      // identity transformation, 0-parameter
      73             :   TRANSLATION = 1,   // translational motion 2-parameter
      74             :   ROTZOOM = 2,       // simplified affine with rotation + zoom only, 4-parameter
      75             :   AFFINE = 3,        // affine, 6-parameter
      76             :   HORTRAPEZOID = 4,  // constrained homography, hor trapezoid, 6-parameter
      77             :   VERTRAPEZOID = 5,  // constrained homography, ver trapezoid, 6-parameter
      78             :   HOMOGRAPHY = 6,    // homography, 8-parameter
      79             :   TRANS_TYPES = 7,
      80             : } TransformationType;
      81             : /* clang-format on */
      82             : 
      83             : // Number of types used for global motion (must be >= 3 and <= TRANS_TYPES)
      84             : // The following can be useful:
      85             : // GLOBAL_TRANS_TYPES 3 - up to rotation-zoom
      86             : // GLOBAL_TRANS_TYPES 4 - up to affine
      87             : // GLOBAL_TRANS_TYPES 6 - up to hor/ver trapezoids
      88             : // GLOBAL_TRANS_TYPES 7 - up to full homography
      89             : #define GLOBAL_TRANS_TYPES 4
      90             : 
      91             : typedef struct {
      92             : #if CONFIG_GLOBAL_MOTION
      93             :   int global_warp_allowed;
      94             : #endif  // CONFIG_GLOBAL_MOTION
      95             : #if CONFIG_WARPED_MOTION
      96             :   int local_warp_allowed;
      97             : #endif  // CONFIG_WARPED_MOTION
      98             : } WarpTypesAllowed;
      99             : 
     100             : // number of parameters used by each transformation in TransformationTypes
     101             : static const int trans_model_params[TRANS_TYPES] = { 0, 2, 4, 6, 6, 6, 8 };
     102             : 
     103             : // The order of values in the wmmat matrix below is best described
     104             : // by the homography:
     105             : //      [x'     (m2 m3 m0   [x
     106             : //  z .  y'  =   m4 m5 m1 *  y
     107             : //       1]      m6 m7 1)    1]
     108             : typedef struct {
     109             :   TransformationType wmtype;
     110             :   int32_t wmmat[8];
     111             :   int16_t alpha, beta, gamma, delta;
     112             : } WarpedMotionParams;
     113             : 
     114           0 : static INLINE void set_default_warp_params(WarpedMotionParams *wm) {
     115             :   static const int32_t default_wm_mat[8] = {
     116             :     0, 0, (1 << WARPEDMODEL_PREC_BITS), 0, 0, (1 << WARPEDMODEL_PREC_BITS), 0, 0
     117             :   };
     118           0 :   memset(wm, 0, sizeof(*wm));
     119           0 :   memcpy(wm->wmmat, default_wm_mat, sizeof(wm->wmmat));
     120           0 :   wm->wmtype = IDENTITY;
     121           0 : }
     122             : #endif  // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
     123             : 
     124             : #if CONFIG_GLOBAL_MOTION
     125             : // The following constants describe the various precisions
     126             : // of different parameters in the global motion experiment.
     127             : //
     128             : // Given the general homography:
     129             : //      [x'     (a  b  c   [x
     130             : //  z .  y'  =   d  e  f *  y
     131             : //       1]      g  h  i)    1]
     132             : //
     133             : // Constants using the name ALPHA here are related to parameters
     134             : // a, b, d, e. Constants using the name TRANS are related
     135             : // to parameters c and f.
     136             : //
     137             : // Anything ending in PREC_BITS is the number of bits of precision
     138             : // to maintain when converting from double to integer.
     139             : //
     140             : // The ABS parameters are used to create an upper and lower bound
     141             : // for each parameter. In other words, after a parameter is integerized
     142             : // it is clamped between -(1 << ABS_XXX_BITS) and (1 << ABS_XXX_BITS).
     143             : //
     144             : // XXX_PREC_DIFF and XXX_DECODE_FACTOR
     145             : // are computed once here to prevent repetitive
     146             : // computation on the decoder side. These are
     147             : // to allow the global motion parameters to be encoded in a lower
     148             : // precision than the warped model precision. This means that they
     149             : // need to be changed to warped precision when they are decoded.
     150             : //
     151             : // XX_MIN, XX_MAX are also computed to avoid repeated computation
     152             : 
     153             : #define SUBEXPFIN_K 3
     154             : #define GM_TRANS_PREC_BITS 6
     155             : #define GM_ABS_TRANS_BITS 12
     156             : #define GM_ABS_TRANS_ONLY_BITS (GM_ABS_TRANS_BITS - GM_TRANS_PREC_BITS + 3)
     157             : #define GM_TRANS_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_TRANS_PREC_BITS)
     158             : #define GM_TRANS_ONLY_PREC_DIFF (WARPEDMODEL_PREC_BITS - 3)
     159             : #define GM_TRANS_DECODE_FACTOR (1 << GM_TRANS_PREC_DIFF)
     160             : #define GM_TRANS_ONLY_DECODE_FACTOR (1 << GM_TRANS_ONLY_PREC_DIFF)
     161             : 
     162             : #define GM_ALPHA_PREC_BITS 15
     163             : #define GM_ABS_ALPHA_BITS 12
     164             : #define GM_ALPHA_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_ALPHA_PREC_BITS)
     165             : #define GM_ALPHA_DECODE_FACTOR (1 << GM_ALPHA_PREC_DIFF)
     166             : 
     167             : #define GM_ROW3HOMO_PREC_BITS 16
     168             : #define GM_ABS_ROW3HOMO_BITS 11
     169             : #define GM_ROW3HOMO_PREC_DIFF \
     170             :   (WARPEDMODEL_ROW3HOMO_PREC_BITS - GM_ROW3HOMO_PREC_BITS)
     171             : #define GM_ROW3HOMO_DECODE_FACTOR (1 << GM_ROW3HOMO_PREC_DIFF)
     172             : 
     173             : #define GM_TRANS_MAX (1 << GM_ABS_TRANS_BITS)
     174             : #define GM_ALPHA_MAX (1 << GM_ABS_ALPHA_BITS)
     175             : #define GM_ROW3HOMO_MAX (1 << GM_ABS_ROW3HOMO_BITS)
     176             : 
     177             : #define GM_TRANS_MIN -GM_TRANS_MAX
     178             : #define GM_ALPHA_MIN -GM_ALPHA_MAX
     179             : #define GM_ROW3HOMO_MIN -GM_ROW3HOMO_MAX
     180             : 
     181             : // Use global motion parameters for sub8x8 blocks
     182             : #define GLOBAL_SUB8X8_USED 0
     183             : 
     184           0 : static INLINE int block_center_x(int mi_col, BLOCK_SIZE bs) {
     185           0 :   const int bw = block_size_wide[bs];
     186           0 :   return mi_col * MI_SIZE + bw / 2 - 1;
     187             : }
     188             : 
     189           0 : static INLINE int block_center_y(int mi_row, BLOCK_SIZE bs) {
     190           0 :   const int bh = block_size_high[bs];
     191           0 :   return mi_row * MI_SIZE + bh / 2 - 1;
     192             : }
     193             : 
     194           0 : static INLINE int convert_to_trans_prec(int allow_hp, int coor) {
     195           0 :   if (allow_hp)
     196           0 :     return ROUND_POWER_OF_TWO_SIGNED(coor, WARPEDMODEL_PREC_BITS - 3);
     197             :   else
     198           0 :     return ROUND_POWER_OF_TWO_SIGNED(coor, WARPEDMODEL_PREC_BITS - 2) * 2;
     199             : }
     200             : 
     201             : // Convert a global motion translation vector (which may have more bits than a
     202             : // regular motion vector) into a motion vector
     203           0 : static INLINE int_mv gm_get_motion_vector(const WarpedMotionParams *gm,
     204             :                                           int allow_hp, BLOCK_SIZE bsize,
     205             :                                           int mi_col, int mi_row,
     206             :                                           int block_idx) {
     207           0 :   const int unify_bsize = CONFIG_CB4X4;
     208             :   int_mv res;
     209           0 :   const int32_t *mat = gm->wmmat;
     210             :   int x, y, tx, ty;
     211             : 
     212           0 :   if (gm->wmtype == TRANSLATION) {
     213           0 :     res.as_mv.row = gm->wmmat[0] >> GM_TRANS_ONLY_PREC_DIFF;
     214           0 :     res.as_mv.col = gm->wmmat[1] >> GM_TRANS_ONLY_PREC_DIFF;
     215           0 :     return res;
     216             :   }
     217             : 
     218           0 :   if (bsize >= BLOCK_8X8 || unify_bsize) {
     219           0 :     x = block_center_x(mi_col, bsize);
     220           0 :     y = block_center_y(mi_row, bsize);
     221             :   } else {
     222           0 :     x = block_center_x(mi_col, bsize);
     223           0 :     y = block_center_y(mi_row, bsize);
     224           0 :     x += (block_idx & 1) * MI_SIZE / 2;
     225           0 :     y += (block_idx & 2) * MI_SIZE / 4;
     226             :   }
     227             : 
     228           0 :   if (gm->wmtype == ROTZOOM) {
     229           0 :     assert(gm->wmmat[5] == gm->wmmat[2]);
     230           0 :     assert(gm->wmmat[4] == -gm->wmmat[3]);
     231             :   }
     232           0 :   if (gm->wmtype > AFFINE) {
     233           0 :     int xc = (int)((int64_t)mat[2] * x + (int64_t)mat[3] * y + mat[0]);
     234           0 :     int yc = (int)((int64_t)mat[4] * x + (int64_t)mat[5] * y + mat[1]);
     235           0 :     const int Z = (int)((int64_t)mat[6] * x + (int64_t)mat[7] * y +
     236             :                         (1 << WARPEDMODEL_ROW3HOMO_PREC_BITS));
     237           0 :     xc *= 1 << (WARPEDMODEL_ROW3HOMO_PREC_BITS - WARPEDMODEL_PREC_BITS);
     238           0 :     yc *= 1 << (WARPEDMODEL_ROW3HOMO_PREC_BITS - WARPEDMODEL_PREC_BITS);
     239           0 :     xc = (int)(xc > 0 ? ((int64_t)xc + Z / 2) / Z : ((int64_t)xc - Z / 2) / Z);
     240           0 :     yc = (int)(yc > 0 ? ((int64_t)yc + Z / 2) / Z : ((int64_t)yc - Z / 2) / Z);
     241           0 :     tx = convert_to_trans_prec(allow_hp, xc) - (x << 3);
     242           0 :     ty = convert_to_trans_prec(allow_hp, yc) - (y << 3);
     243             :   } else {
     244           0 :     const int xc =
     245           0 :         (mat[2] - (1 << WARPEDMODEL_PREC_BITS)) * x + mat[3] * y + mat[0];
     246           0 :     const int yc =
     247           0 :         mat[4] * x + (mat[5] - (1 << WARPEDMODEL_PREC_BITS)) * y + mat[1];
     248           0 :     tx = convert_to_trans_prec(allow_hp, xc);
     249           0 :     ty = convert_to_trans_prec(allow_hp, yc);
     250             :   }
     251             : 
     252           0 :   res.as_mv.row = ty;
     253           0 :   res.as_mv.col = tx;
     254           0 :   return res;
     255             : }
     256             : 
     257           0 : static INLINE TransformationType get_gmtype(const WarpedMotionParams *gm) {
     258           0 :   if (gm->wmmat[6] != 0 || gm->wmmat[7] != 0) {
     259           0 :     if (!gm->wmmat[6] && !gm->wmmat[4]) return HORTRAPEZOID;
     260           0 :     if (!gm->wmmat[7] && !gm->wmmat[3]) return VERTRAPEZOID;
     261           0 :     return HOMOGRAPHY;
     262             :   }
     263           0 :   if (gm->wmmat[5] == (1 << WARPEDMODEL_PREC_BITS) && !gm->wmmat[4] &&
     264           0 :       gm->wmmat[2] == (1 << WARPEDMODEL_PREC_BITS) && !gm->wmmat[3]) {
     265           0 :     return ((!gm->wmmat[1] && !gm->wmmat[0]) ? IDENTITY : TRANSLATION);
     266             :   }
     267           0 :   if (gm->wmmat[2] == gm->wmmat[5] && gm->wmmat[3] == -gm->wmmat[4])
     268           0 :     return ROTZOOM;
     269             :   else
     270           0 :     return AFFINE;
     271             : }
     272             : #endif  // CONFIG_GLOBAL_MOTION
     273             : 
     274             : typedef struct candidate_mv {
     275             :   int_mv this_mv;
     276             :   int_mv comp_mv;
     277             :   uint8_t pred_diff[2];
     278             :   int weight;
     279             : } CANDIDATE_MV;
     280             : 
     281           0 : static INLINE int is_zero_mv(const MV *mv) {
     282           0 :   return *((const uint32_t *)mv) == 0;
     283             : }
     284             : 
     285           0 : static INLINE int is_equal_mv(const MV *a, const MV *b) {
     286           0 :   return *((const uint32_t *)a) == *((const uint32_t *)b);
     287             : }
     288             : 
     289           0 : static INLINE void clamp_mv(MV *mv, int min_col, int max_col, int min_row,
     290             :                             int max_row) {
     291           0 :   mv->col = clamp(mv->col, min_col, max_col);
     292           0 :   mv->row = clamp(mv->row, min_row, max_row);
     293           0 : }
     294             : 
     295             : static INLINE int mv_has_subpel(const MV *mv) {
     296             :   return (mv->row & SUBPEL_MASK) || (mv->col & SUBPEL_MASK);
     297             : }
     298             : #ifdef __cplusplus
     299             : }  // extern "C"
     300             : #endif
     301             : 
     302             : #endif  // AV1_COMMON_MV_H_

Generated by: LCOV version 1.13