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