tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

mcomp.h (15152B)


      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_ENCODER_MCOMP_H_
     13 #define AOM_AV1_ENCODER_MCOMP_H_
     14 
     15 #include "av1/common/mv.h"
     16 #include "av1/encoder/block.h"
     17 #include "av1/encoder/rd.h"
     18 
     19 #include "aom_dsp/variance.h"
     20 
     21 #ifdef __cplusplus
     22 extern "C" {
     23 #endif
     24 
     25 struct AV1_COMP;
     26 struct SPEED_FEATURES;
     27 
     28 // =============================================================================
     29 //  Cost functions
     30 // =============================================================================
     31 
     32 enum {
     33  MV_COST_ENTROPY,    // Use the entropy rate of the mv as the cost
     34  MV_COST_L1_LOWRES,  // Use the l1 norm of the mv as the cost (<480p)
     35  MV_COST_L1_MIDRES,  // Use the l1 norm of the mv as the cost (>=480p)
     36  MV_COST_L1_HDRES,   // Use the l1 norm of the mv as the cost (>=720p)
     37  MV_COST_NONE        // Use 0 as as cost irrespective of the current mv
     38 } UENUM1BYTE(MV_COST_TYPE);
     39 
     40 typedef struct {
     41  // The reference mv used to compute the mv cost
     42  const MV *ref_mv;
     43  FULLPEL_MV full_ref_mv;
     44  MV_COST_TYPE mv_cost_type;
     45  const int *mvjcost;
     46  const int *mvcost[2];
     47  int error_per_bit;
     48  // A multiplier used to convert rate to sad cost
     49  int sad_per_bit;
     50 } MV_COST_PARAMS;
     51 
     52 int av1_mv_bit_cost(const MV *mv, const MV *ref_mv, const int *mvjcost,
     53                    int *const mvcost[2], int weight);
     54 
     55 int av1_get_mvpred_sse(const MV_COST_PARAMS *mv_cost_params,
     56                       const FULLPEL_MV best_mv,
     57                       const aom_variance_fn_ptr_t *vfp,
     58                       const struct buf_2d *src, const struct buf_2d *pre);
     59 
     60 // =============================================================================
     61 //  Motion Search
     62 // =============================================================================
     63 typedef struct {
     64  // The reference buffer
     65  const struct buf_2d *ref;
     66 
     67  // The source and predictors/mask used by translational search
     68  const struct buf_2d *src;
     69  const uint8_t *second_pred;
     70  const uint8_t *mask;
     71  int mask_stride;
     72  int inv_mask;
     73 
     74  // The weighted source and mask used by OBMC
     75  const int32_t *wsrc;
     76  const int32_t *obmc_mask;
     77 } MSBuffers;
     78 
     79 static inline void av1_set_ms_compound_refs(MSBuffers *ms_buffers,
     80                                            const uint8_t *second_pred,
     81                                            const uint8_t *mask,
     82                                            int mask_stride, int invert_mask) {
     83  ms_buffers->second_pred = second_pred;
     84  ms_buffers->mask = mask;
     85  ms_buffers->mask_stride = mask_stride;
     86  ms_buffers->inv_mask = invert_mask;
     87 }
     88 
     89 // =============================================================================
     90 //  Fullpixel Motion Search
     91 // =============================================================================
     92 // This struct holds fullpixel motion search parameters that should be constant
     93 // during the search
     94 typedef struct {
     95  BLOCK_SIZE bsize;
     96  // A function pointer to the simd function for fast computation
     97  const aom_variance_fn_ptr_t *vfp;
     98 
     99  MSBuffers ms_buffers;
    100 
    101  // WARNING: search_method should be regarded as a private variable and should
    102  // not be modified directly so it is in sync with search_sites. To modify it,
    103  // use av1_set_mv_search_method.
    104  SEARCH_METHODS search_method;
    105  const search_site_config *search_sites;
    106  FullMvLimits mv_limits;
    107 
    108  int run_mesh_search;    // Sets mesh search unless it got pruned by
    109                          // prune_mesh_search.
    110  int prune_mesh_search;  // Disables mesh search if the best_mv after a normal
    111                          // search if close to the start_mv.
    112  int mesh_search_mv_diff_threshold;  // mv diff threshold to enable
    113                                      // prune_mesh_search
    114  int force_mesh_thresh;  // Forces mesh search if the residue variance is
    115                          // higher than the threshold.
    116  const struct MESH_PATTERN *mesh_patterns[2];
    117 
    118  // Use maximum search interval of 4 if true. This helps motion search to find
    119  // the best motion vector for screen content types.
    120  int fine_search_interval;
    121 
    122  int is_intra_mode;
    123 
    124  int fast_obmc_search;
    125 
    126  // For calculating mv cost
    127  MV_COST_PARAMS mv_cost_params;
    128 
    129  // Stores the function used to compute the sad. This can be different from the
    130  // sdf in vfp (e.g. downsampled sad and not sad) to allow speed up.
    131  aom_sad_fn_t sdf;
    132  aom_sad_multi_d_fn_t sdx4df;
    133  aom_sad_multi_d_fn_t sdx3df;
    134 } FULLPEL_MOTION_SEARCH_PARAMS;
    135 
    136 typedef struct {
    137  int err_cost;
    138  unsigned int distortion;
    139  unsigned int sse;
    140 } FULLPEL_MV_STATS;
    141 
    142 void av1_init_obmc_buffer(OBMCBuffer *obmc_buffer);
    143 
    144 void av1_make_default_fullpel_ms_params(
    145    FULLPEL_MOTION_SEARCH_PARAMS *ms_params, const struct AV1_COMP *cpi,
    146    MACROBLOCK *x, BLOCK_SIZE bsize, const MV *ref_mv, FULLPEL_MV start_mv,
    147    const search_site_config search_sites[NUM_DISTINCT_SEARCH_METHODS],
    148    SEARCH_METHODS search_method, int fine_search_interval);
    149 
    150 /*! Sets the \ref FULLPEL_MOTION_SEARCH_PARAMS to intra mode. */
    151 void av1_set_ms_to_intra_mode(FULLPEL_MOTION_SEARCH_PARAMS *ms_params,
    152                              const IntraBCMVCosts *dv_costs);
    153 
    154 // Sets up configs for firstpass motion search.
    155 void av1_init_motion_fpf(search_site_config *cfg, int stride);
    156 
    157 /*! Function pointer to search site config initialization of different search
    158 * method functions. */
    159 typedef void (*av1_init_search_site_config)(search_site_config *cfg, int stride,
    160                                            int level);
    161 
    162 /*! Array of function pointers used to set the motion search config. */
    163 extern const av1_init_search_site_config
    164    av1_init_motion_compensation[NUM_DISTINCT_SEARCH_METHODS];
    165 
    166 // Array to inform which all search methods are having
    167 // same candidates and different in number of search steps.
    168 static const SEARCH_METHODS search_method_lookup[NUM_SEARCH_METHODS] = {
    169  DIAMOND,          // DIAMOND
    170  NSTEP,            // NSTEP
    171  NSTEP_8PT,        // NSTEP_8PT
    172  CLAMPED_DIAMOND,  // CLAMPED_DIAMOND
    173  HEX,              // HEX
    174  BIGDIA,           // BIGDIA
    175  SQUARE,           // SQUARE
    176  HEX,              // FAST_HEX
    177  BIGDIA,           // FAST_DIAMOND
    178  BIGDIA,           // FAST_BIGDIA
    179  BIGDIA            // VFAST_DIAMOND
    180 };
    181 
    182 // Reinitialize the search site config.
    183 static inline void av1_refresh_search_site_config(
    184    search_site_config *ss_cfg_buf, SEARCH_METHODS search_method,
    185    const int ref_stride) {
    186  const int level =
    187      search_method == NSTEP_8PT || search_method == CLAMPED_DIAMOND;
    188  search_method = search_method_lookup[search_method];
    189  av1_init_motion_compensation[search_method](&ss_cfg_buf[search_method],
    190                                              ref_stride, level);
    191 }
    192 
    193 // Mv beyond the range do not produce new/different prediction block.
    194 static inline void av1_set_mv_search_method(
    195    FULLPEL_MOTION_SEARCH_PARAMS *ms_params,
    196    const search_site_config search_sites[NUM_DISTINCT_SEARCH_METHODS],
    197    SEARCH_METHODS search_method) {
    198  ms_params->search_method = search_method;
    199  ms_params->search_sites =
    200      &search_sites[search_method_lookup[ms_params->search_method]];
    201 }
    202 
    203 // Set up limit values for MV components.
    204 // Mv beyond the range do not produce new/different prediction block.
    205 static inline void av1_set_mv_row_limits(
    206    const CommonModeInfoParams *const mi_params, FullMvLimits *mv_limits,
    207    int mi_row, int mi_height, int border) {
    208  const int min1 = -(mi_row * MI_SIZE + border - 2 * AOM_INTERP_EXTEND);
    209  const int min2 = -(((mi_row + mi_height) * MI_SIZE) + 2 * AOM_INTERP_EXTEND);
    210  mv_limits->row_min = AOMMAX(min1, min2);
    211  const int max1 = (mi_params->mi_rows - mi_row - mi_height) * MI_SIZE +
    212                   border - 2 * AOM_INTERP_EXTEND;
    213  const int max2 =
    214      (mi_params->mi_rows - mi_row) * MI_SIZE + 2 * AOM_INTERP_EXTEND;
    215  mv_limits->row_max = AOMMIN(max1, max2);
    216 }
    217 
    218 static inline void av1_set_mv_col_limits(
    219    const CommonModeInfoParams *const mi_params, FullMvLimits *mv_limits,
    220    int mi_col, int mi_width, int border) {
    221  const int min1 = -(mi_col * MI_SIZE + border - 2 * AOM_INTERP_EXTEND);
    222  const int min2 = -(((mi_col + mi_width) * MI_SIZE) + 2 * AOM_INTERP_EXTEND);
    223  mv_limits->col_min = AOMMAX(min1, min2);
    224  const int max1 = (mi_params->mi_cols - mi_col - mi_width) * MI_SIZE + border -
    225                   2 * AOM_INTERP_EXTEND;
    226  const int max2 =
    227      (mi_params->mi_cols - mi_col) * MI_SIZE + 2 * AOM_INTERP_EXTEND;
    228  mv_limits->col_max = AOMMIN(max1, max2);
    229 }
    230 
    231 static inline void av1_set_mv_limits(
    232    const CommonModeInfoParams *const mi_params, FullMvLimits *mv_limits,
    233    int mi_row, int mi_col, int mi_height, int mi_width, int border) {
    234  av1_set_mv_row_limits(mi_params, mv_limits, mi_row, mi_height, border);
    235  av1_set_mv_col_limits(mi_params, mv_limits, mi_col, mi_width, border);
    236 }
    237 
    238 void av1_set_mv_search_range(FullMvLimits *mv_limits, const MV *mv);
    239 
    240 int av1_init_search_range(int size);
    241 
    242 int av1_vector_match(const int16_t *ref, const int16_t *src, int bwl,
    243                     int search_size, int full_search, int *sad);
    244 
    245 unsigned int av1_int_pro_motion_estimation(
    246    const struct AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize, int mi_row,
    247    int mi_col, const MV *ref_mv, unsigned int *y_sad_zero,
    248    int me_search_size_col, int me_search_size_row);
    249 
    250 int av1_refining_search_8p_c(const FULLPEL_MOTION_SEARCH_PARAMS *ms_params,
    251                             const FULLPEL_MV start_mv, FULLPEL_MV *best_mv);
    252 
    253 int av1_full_pixel_search(const FULLPEL_MV start_mv,
    254                          const FULLPEL_MOTION_SEARCH_PARAMS *ms_params,
    255                          const int step_param, int *cost_list,
    256                          FULLPEL_MV *best_mv, FULLPEL_MV_STATS *best_mv_stats,
    257                          FULLPEL_MV *second_best_mv);
    258 
    259 int av1_intrabc_hash_search(const struct AV1_COMP *cpi, const MACROBLOCKD *xd,
    260                            const FULLPEL_MOTION_SEARCH_PARAMS *ms_params,
    261                            IntraBCHashInfo *intrabc_hash_info,
    262                            FULLPEL_MV *best_mv);
    263 
    264 int av1_obmc_full_pixel_search(const FULLPEL_MV start_mv,
    265                               const FULLPEL_MOTION_SEARCH_PARAMS *ms_params,
    266                               const int step_param, FULLPEL_MV *best_mv);
    267 
    268 static inline int av1_is_fullmv_in_range(const FullMvLimits *mv_limits,
    269                                         FULLPEL_MV mv) {
    270  return (mv.col >= mv_limits->col_min) && (mv.col <= mv_limits->col_max) &&
    271         (mv.row >= mv_limits->row_min) && (mv.row <= mv_limits->row_max);
    272 }
    273 // =============================================================================
    274 //  Subpixel Motion Search
    275 // =============================================================================
    276 enum {
    277  EIGHTH_PEL,
    278  QUARTER_PEL,
    279  HALF_PEL,
    280  FULL_PEL
    281 } UENUM1BYTE(SUBPEL_FORCE_STOP);
    282 
    283 typedef struct {
    284  const aom_variance_fn_ptr_t *vfp;
    285  SUBPEL_SEARCH_TYPE subpel_search_type;
    286  // Source and reference buffers
    287  MSBuffers ms_buffers;
    288  int w, h;
    289 } SUBPEL_SEARCH_VAR_PARAMS;
    290 
    291 // This struct holds subpixel motion search parameters that should be constant
    292 // during the search
    293 typedef struct {
    294  // High level motion search settings
    295  int allow_hp;
    296  const int *cost_list;
    297  SUBPEL_FORCE_STOP forced_stop;
    298  int iters_per_step;
    299  SubpelMvLimits mv_limits;
    300 
    301  // For calculating mv cost
    302  MV_COST_PARAMS mv_cost_params;
    303 
    304  // Distortion calculation params
    305  SUBPEL_SEARCH_VAR_PARAMS var_params;
    306 } SUBPEL_MOTION_SEARCH_PARAMS;
    307 
    308 void av1_make_default_subpel_ms_params(SUBPEL_MOTION_SEARCH_PARAMS *ms_params,
    309                                       const struct AV1_COMP *cpi,
    310                                       const MACROBLOCK *x, BLOCK_SIZE bsize,
    311                                       const MV *ref_mv, const int *cost_list);
    312 
    313 typedef int(fractional_mv_step_fp)(MACROBLOCKD *xd, const AV1_COMMON *const cm,
    314                                   const SUBPEL_MOTION_SEARCH_PARAMS *ms_params,
    315                                   MV start_mv,
    316                                   const FULLPEL_MV_STATS *start_mv_stats,
    317                                   MV *bestmv, int *distortion,
    318                                   unsigned int *sse1,
    319                                   int_mv *last_mv_search_list);
    320 
    321 extern fractional_mv_step_fp av1_find_best_sub_pixel_tree;
    322 extern fractional_mv_step_fp av1_find_best_sub_pixel_tree_pruned;
    323 extern fractional_mv_step_fp av1_find_best_sub_pixel_tree_pruned_more;
    324 extern fractional_mv_step_fp av1_return_max_sub_pixel_mv;
    325 extern fractional_mv_step_fp av1_return_min_sub_pixel_mv;
    326 extern fractional_mv_step_fp av1_find_best_obmc_sub_pixel_tree_up;
    327 
    328 unsigned int av1_refine_warped_mv(MACROBLOCKD *xd, const AV1_COMMON *const cm,
    329                                  const SUBPEL_MOTION_SEARCH_PARAMS *ms_params,
    330                                  BLOCK_SIZE bsize, const int *pts0,
    331                                  const int *pts_inref0, int total_samples,
    332                                  WARP_SEARCH_METHOD search_method,
    333                                  int num_iterations);
    334 
    335 static inline void av1_set_fractional_mv(int_mv *fractional_best_mv) {
    336  for (int z = 0; z < 3; z++) {
    337    fractional_best_mv[z].as_int = INVALID_MV;
    338  }
    339 }
    340 
    341 static inline void av1_set_subpel_mv_search_range(SubpelMvLimits *subpel_limits,
    342                                                  const FullMvLimits *mv_limits,
    343                                                  const MV *ref_mv) {
    344  const int max_mv = GET_MV_SUBPEL(MAX_FULL_PEL_VAL);
    345  int minc = AOMMAX(GET_MV_SUBPEL(mv_limits->col_min), ref_mv->col - max_mv);
    346  int maxc = AOMMIN(GET_MV_SUBPEL(mv_limits->col_max), ref_mv->col + max_mv);
    347  int minr = AOMMAX(GET_MV_SUBPEL(mv_limits->row_min), ref_mv->row - max_mv);
    348  int maxr = AOMMIN(GET_MV_SUBPEL(mv_limits->row_max), ref_mv->row + max_mv);
    349 
    350  maxc = AOMMAX(minc, maxc);
    351  maxr = AOMMAX(minr, maxr);
    352 
    353  subpel_limits->col_min = AOMMAX(MV_LOW + 1, minc);
    354  subpel_limits->col_max = AOMMIN(MV_UPP - 1, maxc);
    355  subpel_limits->row_min = AOMMAX(MV_LOW + 1, minr);
    356  subpel_limits->row_max = AOMMIN(MV_UPP - 1, maxr);
    357 }
    358 
    359 static inline int av1_is_subpelmv_in_range(const SubpelMvLimits *mv_limits,
    360                                           MV mv) {
    361  return (mv.col >= mv_limits->col_min) && (mv.col <= mv_limits->col_max) &&
    362         (mv.row >= mv_limits->row_min) && (mv.row <= mv_limits->row_max);
    363 }
    364 
    365 static inline int get_offset_from_fullmv(const FULLPEL_MV *mv, int stride) {
    366  return mv->row * stride + mv->col;
    367 }
    368 
    369 static inline const uint8_t *get_buf_from_fullmv(const struct buf_2d *buf,
    370                                                 const FULLPEL_MV *mv) {
    371  return &buf->buf[get_offset_from_fullmv(mv, buf->stride)];
    372 }
    373 
    374 #ifdef __cplusplus
    375 }  // extern "C"
    376 #endif
    377 
    378 #endif  // AOM_AV1_ENCODER_MCOMP_H_