blob: eb2024c8c054faade2e9ce4da0ffdc074f4bd9e4 [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
James Zerne1cbb132018-08-22 14:10:36 -070012#ifndef AOM_AV1_ENCODER_MCOMP_H_
13#define AOM_AV1_ENCODER_MCOMP_H_
Yaowu Xuc27fc142016-08-22 16:08:15 -070014
chiyotsai2ad959b2020-02-12 14:29:32 -080015#include "av1/common/mv.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070016#include "av1/encoder/block.h"
chiyotsai19a58ee2019-03-18 18:01:05 -070017
Yaowu Xuc27fc142016-08-22 16:08:15 -070018#include "aom_dsp/variance.h"
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
24// The maximum number of steps in a step search given the largest
25// allowed initial step
Yunqing Wange25fdbb2018-03-16 16:36:32 -070026#define MAX_MVSEARCH_STEPS 11
Yaowu Xuc27fc142016-08-22 16:08:15 -070027// Max full pel mv specified in the unit of full pixel
Yunqing Wange25fdbb2018-03-16 16:36:32 -070028// Enable the use of motion vector in range [-1023, 1023].
Yaowu Xuc27fc142016-08-22 16:08:15 -070029#define MAX_FULL_PEL_VAL ((1 << (MAX_MVSEARCH_STEPS - 1)) - 1)
30// Maximum size of the first step in full pel units
31#define MAX_FIRST_STEP (1 << (MAX_MVSEARCH_STEPS - 1))
Yaowu Xuc27fc142016-08-22 16:08:15 -070032
Deepa K Gd4febfb2018-08-14 11:33:51 +053033#define SEARCH_RANGE_8P 3
34#define SEARCH_GRID_STRIDE_8P (2 * SEARCH_RANGE_8P + 1)
35#define SEARCH_GRID_CENTER_8P \
36 (SEARCH_RANGE_8P * SEARCH_GRID_STRIDE_8P + SEARCH_RANGE_8P)
37
Yaowu Xuc27fc142016-08-22 16:08:15 -070038// motion search site
39typedef struct search_site {
chiyotsaie46cff72020-02-05 15:03:34 -080040 FULLPEL_MV mv;
Yaowu Xuc27fc142016-08-22 16:08:15 -070041 int offset;
42} search_site;
43
44typedef struct search_site_config {
Jingning Han969a8d42019-12-16 19:40:14 -080045 search_site ss[MAX_MVSEARCH_STEPS * 2][16 + 1];
Yaowu Xuc27fc142016-08-22 16:08:15 -070046 int ss_count;
Jingning Han969a8d42019-12-16 19:40:14 -080047 int searches_per_step[MAX_MVSEARCH_STEPS * 2];
48 int radius[MAX_MVSEARCH_STEPS * 2];
chiyotsai836b69b2019-04-09 13:41:24 -070049 int stride;
Yaowu Xuc27fc142016-08-22 16:08:15 -070050} search_site_config;
51
Deepa K Gd4febfb2018-08-14 11:33:51 +053052typedef struct {
chiyotsai9f664e32020-02-19 14:17:31 -080053 FULLPEL_MV coord;
Deepa K Gd4febfb2018-08-14 11:33:51 +053054 int coord_offset;
55} search_neighbors;
56
chiyotsai9f664e32020-02-19 14:17:31 -080057struct AV1_COMP;
58struct SPEED_FEATURES;
Yaowu Xuc27fc142016-08-22 16:08:15 -070059
chiyotsai9f664e32020-02-19 14:17:31 -080060// =============================================================================
61// Cost functions
62// =============================================================================
63typedef struct {
64 const MV *ref_mv;
chiyotsai2e42a662020-02-26 17:39:03 -080065 FULLPEL_MV full_ref_mv;
chiyotsai9f664e32020-02-19 14:17:31 -080066 const int *mvjcost;
67 const int *mvcost[2];
68 int error_per_bit;
chiyotsai2e42a662020-02-26 17:39:03 -080069 int sad_per_bit;
chiyotsai9f664e32020-02-19 14:17:31 -080070 MV_COST_TYPE mv_cost_type;
71} MV_COST_PARAMS;
Yunqing Wang8e173422017-04-21 09:27:55 -070072
chiyotsaie46cff72020-02-05 15:03:34 -080073int av1_mv_bit_cost(const MV *mv, const MV *ref_mv, const int *mvjcost,
Yaowu Xuf883b422016-08-30 14:01:10 -070074 int *mvcost[2], int weight);
Yaowu Xuc27fc142016-08-22 16:08:15 -070075
chiyotsaiff03e5b2020-02-10 15:47:14 -080076int av1_get_mvpred_sse(const MACROBLOCK *x, const FULLPEL_MV *best_mv,
77 const MV *ref_mv, const aom_variance_fn_ptr_t *vfp);
chiyotsaie46cff72020-02-05 15:03:34 -080078int av1_get_mvpred_var(const MACROBLOCK *x, const FULLPEL_MV *best_mv,
chiyotsaif1839b52020-02-10 16:10:36 -080079 const MV *ref_mv, const aom_variance_fn_ptr_t *vfp);
chiyotsai30a5bdf2020-04-06 14:28:59 -070080int av1_get_mvpred_compound_var(const MV_COST_PARAMS *ms_params,
81 const FULLPEL_MV best_mv,
82 const uint8_t *second_pred, const uint8_t *mask,
83 int mask_stride, int invert_mask,
84 const aom_variance_fn_ptr_t *vfp,
85 const struct buf_2d *src,
86 const struct buf_2d *pre);
Yaowu Xuc27fc142016-08-22 16:08:15 -070087
chiyotsai9f664e32020-02-19 14:17:31 -080088// =============================================================================
chiyotsai30a5bdf2020-04-06 14:28:59 -070089// Motion Search
chiyotsai9f664e32020-02-19 14:17:31 -080090// =============================================================================
chiyotsai94f4aca2020-03-20 12:54:47 -070091typedef struct {
92 // The reference buffer
93 const struct buf_2d *ref;
94
95 // The source and predictors/mask used by translational search
96 const struct buf_2d *src;
97 const uint8_t *second_pred;
98 const uint8_t *mask;
99 int mask_stride;
100 int inv_mask;
101
102 // The weighted source and mask used by OBMC
103 const int32_t *wsrc;
104 const int32_t *obmc_mask;
105} MSBuffers;
106
chiyotsai4d1b7d92020-04-07 13:56:22 -0700107static INLINE void av1_set_ms_compound_refs(MSBuffers *ms_buffers,
108 const uint8_t *second_pred,
109 const uint8_t *mask,
110 int mask_stride, int invert_mask) {
chiyotsai30a5bdf2020-04-06 14:28:59 -0700111 ms_buffers->second_pred = second_pred;
112 ms_buffers->mask = mask;
113 ms_buffers->mask_stride = mask_stride;
114 ms_buffers->inv_mask = invert_mask;
115}
116
117// =============================================================================
118// Fullpixel Motion Search
119// =============================================================================
120enum {
121 DIAMOND = 0,
122 NSTEP = 1,
123 HEX = 2,
124 BIGDIA = 3,
125 SQUARE = 4,
126 FAST_HEX = 5,
127 FAST_DIAMOND = 6
128} UENUM1BYTE(SEARCH_METHODS);
129
chiyotsai2e42a662020-02-26 17:39:03 -0800130// This struct holds fullpixel motion search parameters that should be constant
131// during the search
132typedef struct {
133 BLOCK_SIZE bsize;
134 const aom_variance_fn_ptr_t *vfp;
135
chiyotsai94f4aca2020-03-20 12:54:47 -0700136 MSBuffers ms_buffers;
137
chiyotsai2e42a662020-02-26 17:39:03 -0800138 SEARCH_METHODS search_method;
139 const search_site_config *search_sites;
140 FullMvLimits mv_limits;
141
142 int run_mesh_search; // Sets mesh search unless it got pruned by
143 // prune_mesh_search.
144 int prune_mesh_search; // Disables mesh search if the best_mv after a normal
145 // search if close to the start_mv.
146 int force_mesh_thresh; // Forces mesh search if the residue variance is
147 // higher than the threshold.
148 const struct MESH_PATTERN *mesh_patterns[2];
149
150 int is_intra_mode;
151
chiyotsai2e42a662020-02-26 17:39:03 -0800152 int fast_obmc_search;
153
154 // For calculating mv cost
155 MV_COST_PARAMS mv_cost_params;
156} FULLPEL_MOTION_SEARCH_PARAMS;
157
158void av1_make_default_fullpel_ms_params(FULLPEL_MOTION_SEARCH_PARAMS *ms_params,
159 const struct AV1_COMP *cpi,
160 const MACROBLOCK *x, BLOCK_SIZE bsize,
161 const MV *ref_mv,
162 const search_site_config *search_sites);
163
chiyotsai9f664e32020-02-19 14:17:31 -0800164// Sets up configs for fullpixel diamond search
165void av1_init_dsmotion_compensation(search_site_config *cfg, int stride);
166// Sets up configs for firstpass motion search
167void av1_init_motion_fpf(search_site_config *cfg, int stride);
168// Sets up configs for all other types of motion search
169void av1_init3smotion_compensation(search_site_config *cfg, int stride);
170
Yunqing Wang96640052020-02-25 18:59:47 -0800171// Set up limit values for MV components.
172// Mv beyond the range do not produce new/different prediction block.
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700173static INLINE void av1_set_mv_row_limits(
174 const CommonModeInfoParams *const mi_params, FullMvLimits *mv_limits,
175 int mi_row, int mi_height, int border) {
Yunqing Wang6a35bf92020-02-28 13:44:21 -0800176 const int min1 = -(mi_row * MI_SIZE + border - 2 * AOM_INTERP_EXTEND);
177 const int min2 = -(((mi_row + mi_height) * MI_SIZE) + 2 * AOM_INTERP_EXTEND);
178 mv_limits->row_min = AOMMAX(min1, min2);
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700179 const int max1 = (mi_params->mi_rows - mi_row - mi_height) * MI_SIZE +
180 border - 2 * AOM_INTERP_EXTEND;
181 const int max2 =
182 (mi_params->mi_rows - mi_row) * MI_SIZE + 2 * AOM_INTERP_EXTEND;
Yunqing Wang6a35bf92020-02-28 13:44:21 -0800183 mv_limits->row_max = AOMMIN(max1, max2);
184}
185
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700186static INLINE void av1_set_mv_col_limits(
187 const CommonModeInfoParams *const mi_params, FullMvLimits *mv_limits,
188 int mi_col, int mi_width, int border) {
Yunqing Wang6a35bf92020-02-28 13:44:21 -0800189 const int min1 = -(mi_col * MI_SIZE + border - 2 * AOM_INTERP_EXTEND);
190 const int min2 = -(((mi_col + mi_width) * MI_SIZE) + 2 * AOM_INTERP_EXTEND);
191 mv_limits->col_min = AOMMAX(min1, min2);
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700192 const int max1 = (mi_params->mi_cols - mi_col - mi_width) * MI_SIZE + border -
Yunqing Wang6a35bf92020-02-28 13:44:21 -0800193 2 * AOM_INTERP_EXTEND;
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700194 const int max2 =
195 (mi_params->mi_cols - mi_col) * MI_SIZE + 2 * AOM_INTERP_EXTEND;
Yunqing Wang6a35bf92020-02-28 13:44:21 -0800196 mv_limits->col_max = AOMMIN(max1, max2);
197}
198
Urvang Joshi9dc909d2020-03-23 16:07:02 -0700199static INLINE void av1_set_mv_limits(
200 const CommonModeInfoParams *const mi_params, FullMvLimits *mv_limits,
201 int mi_row, int mi_col, int mi_height, int mi_width, int border) {
202 av1_set_mv_row_limits(mi_params, mv_limits, mi_row, mi_height, border);
203 av1_set_mv_col_limits(mi_params, mv_limits, mi_col, mi_width, border);
Yunqing Wang96640052020-02-25 18:59:47 -0800204}
205
chiyotsai9f664e32020-02-19 14:17:31 -0800206void av1_set_mv_search_range(FullMvLimits *mv_limits, const MV *mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700207
Yaowu Xuf883b422016-08-30 14:01:10 -0700208int av1_init_search_range(int size);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700209
kyslov9de0d282019-02-27 16:14:08 -0800210unsigned int av1_int_pro_motion_estimation(const struct AV1_COMP *cpi,
211 MACROBLOCK *x, BLOCK_SIZE bsize,
212 int mi_row, int mi_col,
213 const MV *ref_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700214
chiyotsai30a5bdf2020-04-06 14:28:59 -0700215int av1_refining_search_8p_c(const FULLPEL_MOTION_SEARCH_PARAMS *ms_params,
216 const FULLPEL_MV start_mv, FULLPEL_MV *best_mv);
chiyotsai9f664e32020-02-19 14:17:31 -0800217
chiyotsai2e42a662020-02-26 17:39:03 -0800218int av1_full_pixel_search(const FULLPEL_MV start_mv,
219 const FULLPEL_MOTION_SEARCH_PARAMS *ms_params,
220 const int step_param, int *cost_list,
chiyotsai8bbdd412020-03-03 14:57:23 -0800221 FULLPEL_MV *best_mv, FULLPEL_MV *second_best_mv);
chiyotsai9f664e32020-02-19 14:17:31 -0800222
chiyotsai8bbdd412020-03-03 14:57:23 -0800223void av1_intrabc_hash_search(const struct AV1_COMP *cpi, MACROBLOCK *x,
224 BLOCK_SIZE bsize, const MV *ref_mv, int *bestsme,
225 FULLPEL_MV *best_mv);
226
chiyotsai94f4aca2020-03-20 12:54:47 -0700227int av1_obmc_full_pixel_search(const FULLPEL_MV start_mv,
chiyotsai2e42a662020-02-26 17:39:03 -0800228 const FULLPEL_MOTION_SEARCH_PARAMS *ms_params,
229 const int step_param, FULLPEL_MV *best_mv);
chiyotsai9f664e32020-02-19 14:17:31 -0800230
chiyotsai9f664e32020-02-19 14:17:31 -0800231static INLINE int av1_is_fullmv_in_range(const FullMvLimits *mv_limits,
232 FULLPEL_MV mv) {
233 return (mv.col >= mv_limits->col_min) && (mv.col <= mv_limits->col_max) &&
234 (mv.row >= mv_limits->row_min) && (mv.row <= mv_limits->row_max);
235}
236// =============================================================================
237// Subpixel Motion Search
238// =============================================================================
chiyotsai2aac3002020-02-13 17:02:01 -0800239enum {
240 EIGHTH_PEL,
241 QUARTER_PEL,
242 HALF_PEL,
243 FULL_PEL
244} UENUM1BYTE(SUBPEL_FORCE_STOP);
245
246typedef struct {
chiyotsai2aac3002020-02-13 17:02:01 -0800247 const aom_variance_fn_ptr_t *vfp;
248 SUBPEL_SEARCH_TYPE subpel_search_type;
chiyotsai5aa70752020-03-26 10:13:10 -0700249 // Source and reference buffers
250 MSBuffers ms_buffers;
chiyotsai2aac3002020-02-13 17:02:01 -0800251 int w, h;
chiyotsaia742e7d2020-02-14 17:27:58 -0800252} SUBPEL_SEARCH_VAR_PARAMS;
chiyotsai2aac3002020-02-13 17:02:01 -0800253
254// This struct holds subpixel motion search parameters that should be constant
255// during the search
256typedef struct {
257 // High level motion search settings
258 int allow_hp;
259 const int *cost_list;
260 SUBPEL_FORCE_STOP forced_stop;
261 int iters_per_step;
chiyotsai5aa70752020-03-26 10:13:10 -0700262 SubpelMvLimits mv_limits;
chiyotsai2aac3002020-02-13 17:02:01 -0800263
264 // For calculating mv cost
265 MV_COST_PARAMS mv_cost_params;
266
267 // Distortion calculation params
chiyotsaia742e7d2020-02-14 17:27:58 -0800268 SUBPEL_SEARCH_VAR_PARAMS var_params;
chiyotsai2aac3002020-02-13 17:02:01 -0800269} SUBPEL_MOTION_SEARCH_PARAMS;
270
chiyotsai083db972020-03-30 11:43:52 -0700271void av1_make_default_subpel_ms_params(SUBPEL_MOTION_SEARCH_PARAMS *ms_params,
272 const struct AV1_COMP *cpi,
273 const MACROBLOCK *x, BLOCK_SIZE bsize,
chiyotsai4d1b7d92020-04-07 13:56:22 -0700274 const MV *ref_mv, const int *cost_list);
chiyotsai2aac3002020-02-13 17:02:01 -0800275
chiyotsai5aa70752020-03-26 10:13:10 -0700276typedef int(fractional_mv_step_fp)(MACROBLOCKD *xd, const AV1_COMMON *const cm,
chiyotsai2aac3002020-02-13 17:02:01 -0800277 const SUBPEL_MOTION_SEARCH_PARAMS *ms_params,
Yaowu Xuf8b0e9b2020-03-31 13:14:38 -0700278 MV start_mv, MV *bestmv, int *distortion,
279 unsigned int *sse1,
chiyotsai5aa70752020-03-26 10:13:10 -0700280 int_mv *last_mv_search_list);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700281
Yaowu Xuf883b422016-08-30 14:01:10 -0700282extern fractional_mv_step_fp av1_find_best_sub_pixel_tree;
283extern fractional_mv_step_fp av1_find_best_sub_pixel_tree_pruned;
284extern fractional_mv_step_fp av1_find_best_sub_pixel_tree_pruned_more;
285extern fractional_mv_step_fp av1_find_best_sub_pixel_tree_pruned_evenmore;
Yunqing Wangff4fa062017-04-21 10:56:08 -0700286extern fractional_mv_step_fp av1_return_max_sub_pixel_mv;
287extern fractional_mv_step_fp av1_return_min_sub_pixel_mv;
chiyotsai2aac3002020-02-13 17:02:01 -0800288extern fractional_mv_step_fp av1_find_best_obmc_sub_pixel_tree_up;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700289
chiyotsai74da72b2020-04-07 13:45:40 -0700290unsigned int av1_refine_warped_mv(MACROBLOCKD *xd, const AV1_COMMON *const cm,
291 const SUBPEL_MOTION_SEARCH_PARAMS *ms_params,
292 BLOCK_SIZE bsize, const int *pts0,
293 const int *pts_inref0, int total_samples);
chiyotsai30a5bdf2020-04-06 14:28:59 -0700294
Venkate846e2b2018-09-21 07:31:14 +0530295static INLINE void av1_set_fractional_mv(int_mv *fractional_best_mv) {
296 for (int z = 0; z < 3; z++) {
297 fractional_best_mv[z].as_int = INVALID_MV;
298 }
299}
300
chiyotsai2ad959b2020-02-12 14:29:32 -0800301static INLINE void av1_set_subpel_mv_search_range(SubpelMvLimits *subpel_limits,
302 const FullMvLimits *mv_limits,
303 const MV *ref_mv) {
chiyotsai87bb8052020-02-12 16:56:33 -0800304 const int max_mv = GET_MV_SUBPEL(MAX_FULL_PEL_VAL);
305 const int minc =
306 AOMMAX(GET_MV_SUBPEL(mv_limits->col_min), ref_mv->col - max_mv);
307 const int maxc =
308 AOMMIN(GET_MV_SUBPEL(mv_limits->col_max), ref_mv->col + max_mv);
309 const int minr =
310 AOMMAX(GET_MV_SUBPEL(mv_limits->row_min), ref_mv->row - max_mv);
311 const int maxr =
312 AOMMIN(GET_MV_SUBPEL(mv_limits->row_max), ref_mv->row + max_mv);
Yunqing Wangda213612019-06-12 08:47:03 -0700313
chiyotsai2ad959b2020-02-12 14:29:32 -0800314 subpel_limits->col_min = AOMMAX(MV_LOW + 1, minc);
315 subpel_limits->col_max = AOMMIN(MV_UPP - 1, maxc);
316 subpel_limits->row_min = AOMMAX(MV_LOW + 1, minr);
317 subpel_limits->row_max = AOMMIN(MV_UPP - 1, maxr);
318}
319
chiyotsai2ad959b2020-02-12 14:29:32 -0800320static INLINE int av1_is_subpelmv_in_range(const SubpelMvLimits *mv_limits,
321 MV mv) {
322 return (mv.col >= mv_limits->col_min) && (mv.col <= mv_limits->col_max) &&
323 (mv.row >= mv_limits->row_min) && (mv.row <= mv_limits->row_max);
Yunqing Wangda213612019-06-12 08:47:03 -0700324}
325
Peng Bin6e2ced62018-05-08 11:34:36 +0800326#ifdef __cplusplus
327} // extern "C"
328#endif
329
James Zerne1cbb132018-08-22 14:10:36 -0700330#endif // AOM_AV1_ENCODER_MCOMP_H_