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_