Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1 | /* |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3 | * |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame] | 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. |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 10 | */ |
| 11 | |
James Zern | e1cbb13 | 2018-08-22 14:10:36 -0700 | [diff] [blame] | 12 | #ifndef AOM_AV1_ENCODER_MCOMP_H_ |
| 13 | #define AOM_AV1_ENCODER_MCOMP_H_ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 14 | |
| 15 | #include "av1/encoder/block.h" |
chiyotsai | 19a58ee | 2019-03-18 18:01:05 -0700 | [diff] [blame] | 16 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 17 | #include "aom_dsp/variance.h" |
| 18 | |
| 19 | #ifdef __cplusplus |
| 20 | extern "C" { |
| 21 | #endif |
| 22 | |
chiyotsai | e46cff7 | 2020-02-05 15:03:34 -0800 | [diff] [blame^] | 23 | // In this file, the following variables always have the same meaning: |
| 24 | // start_mv: the motion vector where we start the motion search |
| 25 | // ref_mv: the motion vector with respect to which we calculate the mv_cost |
| 26 | // best_mv: when it is not const, it is the destination where to store the |
| 27 | // best motion vector |
| 28 | // full_*: a prefix of full indicates that the mv is a FULLPEL_MV |
| 29 | // |
| 30 | // When a mv needs to both act as a fullpel_mv and subpel_mv, it is stored as an |
| 31 | // int_mv, which is a union of int, FULLPEL_MV, and MV |
| 32 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 33 | // The maximum number of steps in a step search given the largest |
| 34 | // allowed initial step |
Yunqing Wang | e25fdbb | 2018-03-16 16:36:32 -0700 | [diff] [blame] | 35 | #define MAX_MVSEARCH_STEPS 11 |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 36 | // Max full pel mv specified in the unit of full pixel |
Yunqing Wang | e25fdbb | 2018-03-16 16:36:32 -0700 | [diff] [blame] | 37 | // Enable the use of motion vector in range [-1023, 1023]. |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 38 | #define MAX_FULL_PEL_VAL ((1 << (MAX_MVSEARCH_STEPS - 1)) - 1) |
| 39 | // Maximum size of the first step in full pel units |
| 40 | #define MAX_FIRST_STEP (1 << (MAX_MVSEARCH_STEPS - 1)) |
| 41 | // Allowed motion vector pixel distance outside image border |
| 42 | // for Block_16x16 |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 43 | #define BORDER_MV_PIXELS_B16 (16 + AOM_INTERP_EXTEND) |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 44 | |
Deepa K G | d4febfb | 2018-08-14 11:33:51 +0530 | [diff] [blame] | 45 | #define SEARCH_RANGE_8P 3 |
| 46 | #define SEARCH_GRID_STRIDE_8P (2 * SEARCH_RANGE_8P + 1) |
| 47 | #define SEARCH_GRID_CENTER_8P \ |
| 48 | (SEARCH_RANGE_8P * SEARCH_GRID_STRIDE_8P + SEARCH_RANGE_8P) |
| 49 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 50 | // motion search site |
| 51 | typedef struct search_site { |
chiyotsai | e46cff7 | 2020-02-05 15:03:34 -0800 | [diff] [blame^] | 52 | FULLPEL_MV mv; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 53 | int offset; |
| 54 | } search_site; |
| 55 | |
| 56 | typedef struct search_site_config { |
Jingning Han | 969a8d4 | 2019-12-16 19:40:14 -0800 | [diff] [blame] | 57 | search_site ss[MAX_MVSEARCH_STEPS * 2][16 + 1]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 58 | int ss_count; |
Jingning Han | 969a8d4 | 2019-12-16 19:40:14 -0800 | [diff] [blame] | 59 | int searches_per_step[MAX_MVSEARCH_STEPS * 2]; |
| 60 | int radius[MAX_MVSEARCH_STEPS * 2]; |
chiyotsai | 836b69b | 2019-04-09 13:41:24 -0700 | [diff] [blame] | 61 | int stride; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 62 | } search_site_config; |
| 63 | |
Deepa K G | d4febfb | 2018-08-14 11:33:51 +0530 | [diff] [blame] | 64 | typedef struct { |
| 65 | MV coord; |
| 66 | int coord_offset; |
| 67 | } search_neighbors; |
| 68 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 69 | void av1_init_dsmotion_compensation(search_site_config *cfg, int stride); |
Jingning Han | 969a8d4 | 2019-12-16 19:40:14 -0800 | [diff] [blame] | 70 | void av1_init_motion_fpf(search_site_config *cfg, int stride); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 71 | void av1_init3smotion_compensation(search_site_config *cfg, int stride); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 72 | |
Alex Converse | 0fa0f42 | 2017-04-24 12:51:14 -0700 | [diff] [blame] | 73 | void av1_set_mv_search_range(MvLimits *mv_limits, const MV *mv); |
Yunqing Wang | 8e17342 | 2017-04-21 09:27:55 -0700 | [diff] [blame] | 74 | |
chiyotsai | e46cff7 | 2020-02-05 15:03:34 -0800 | [diff] [blame^] | 75 | int av1_mv_bit_cost(const MV *mv, const MV *ref_mv, const int *mvjcost, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 76 | int *mvcost[2], int weight); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 77 | |
| 78 | // Utility to compute variance + MV rate cost for a given MV |
chiyotsai | e46cff7 | 2020-02-05 15:03:34 -0800 | [diff] [blame^] | 79 | int av1_get_mvpred_var(const MACROBLOCK *x, const FULLPEL_MV *best_mv, |
| 80 | const MV *ref_mv, const aom_variance_fn_ptr_t *vfp, |
Jingning Han | d58f377 | 2019-12-05 15:52:36 -0800 | [diff] [blame] | 81 | int use_var); |
chiyotsai | e46cff7 | 2020-02-05 15:03:34 -0800 | [diff] [blame^] | 82 | int av1_get_mvpred_av_var(const MACROBLOCK *x, const FULLPEL_MV *best_mv, |
| 83 | const MV *ref_mv, const uint8_t *second_pred, |
Jingning Han | 7fb3967 | 2019-11-20 22:46:43 -0800 | [diff] [blame] | 84 | const aom_variance_fn_ptr_t *vfp, |
| 85 | const struct buf_2d *src, const struct buf_2d *pre, |
| 86 | int use_mvcost); |
chiyotsai | e46cff7 | 2020-02-05 15:03:34 -0800 | [diff] [blame^] | 87 | int av1_get_mvpred_mask_var(const MACROBLOCK *x, const FULLPEL_MV *best_mv, |
| 88 | const MV *ref_mv, const uint8_t *second_pred, |
David Barker | c155e01 | 2017-05-11 13:54:54 +0100 | [diff] [blame] | 89 | const uint8_t *mask, int mask_stride, |
| 90 | int invert_mask, const aom_variance_fn_ptr_t *vfp, |
Jingning Han | 7fb3967 | 2019-11-20 22:46:43 -0800 | [diff] [blame] | 91 | const struct buf_2d *src, const struct buf_2d *pre, |
David Barker | c155e01 | 2017-05-11 13:54:54 +0100 | [diff] [blame] | 92 | int use_mvcost); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 93 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 94 | struct AV1_COMP; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 95 | struct SPEED_FEATURES; |
| 96 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 97 | int av1_init_search_range(int size); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 98 | |
kyslov | 9de0d28 | 2019-02-27 16:14:08 -0800 | [diff] [blame] | 99 | unsigned int av1_int_pro_motion_estimation(const struct AV1_COMP *cpi, |
| 100 | MACROBLOCK *x, BLOCK_SIZE bsize, |
| 101 | int mi_row, int mi_col, |
| 102 | const MV *ref_mv); |
| 103 | |
Yunqing Wang | e25fdbb | 2018-03-16 16:36:32 -0700 | [diff] [blame] | 104 | // Runs sequence of diamond searches in smaller steps for RD. |
chiyotsai | e46cff7 | 2020-02-05 15:03:34 -0800 | [diff] [blame^] | 105 | int av1_hex_search(MACROBLOCK *x, FULLPEL_MV *start_mv, int search_param, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 106 | int sad_per_bit, int do_init_search, int *cost_list, |
| 107 | const aom_variance_fn_ptr_t *vfp, int use_mvcost, |
chiyotsai | e46cff7 | 2020-02-05 15:03:34 -0800 | [diff] [blame^] | 108 | const MV *ref_mv); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 109 | |
| 110 | typedef int(fractional_mv_step_fp)( |
Urvang Joshi | 52b6299 | 2018-02-02 14:43:07 -0800 | [diff] [blame] | 111 | MACROBLOCK *x, const AV1_COMMON *const cm, int mi_row, int mi_col, |
| 112 | const MV *ref_mv, int allow_hp, int error_per_bit, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 113 | const aom_variance_fn_ptr_t *vfp, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 114 | int forced_stop, // 0 - full, 1 - qtr only, 2 - half only |
| 115 | int iters_per_step, int *cost_list, int *mvjcost, int *mvcost[2], |
David Barker | c155e01 | 2017-05-11 13:54:54 +0100 | [diff] [blame] | 116 | int *distortion, unsigned int *sse1, const uint8_t *second_pred, |
Sebastien Alaiwan | 0bdea0d | 2017-10-02 15:15:05 +0200 | [diff] [blame] | 117 | const uint8_t *mask, int mask_stride, int invert_mask, int w, int h, |
Venkat | e846e2b | 2018-09-21 07:31:14 +0530 | [diff] [blame] | 118 | int use_accurate_subpel_search, const int do_reset_fractional_mv); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 119 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 120 | extern fractional_mv_step_fp av1_find_best_sub_pixel_tree; |
| 121 | extern fractional_mv_step_fp av1_find_best_sub_pixel_tree_pruned; |
| 122 | extern fractional_mv_step_fp av1_find_best_sub_pixel_tree_pruned_more; |
| 123 | extern fractional_mv_step_fp av1_find_best_sub_pixel_tree_pruned_evenmore; |
Yunqing Wang | ff4fa06 | 2017-04-21 10:56:08 -0700 | [diff] [blame] | 124 | extern fractional_mv_step_fp av1_return_max_sub_pixel_mv; |
| 125 | extern fractional_mv_step_fp av1_return_min_sub_pixel_mv; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 126 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 127 | int av1_refining_search_8p_c(MACROBLOCK *x, int error_per_bit, int search_range, |
| 128 | const aom_variance_fn_ptr_t *fn_ptr, |
David Barker | c155e01 | 2017-05-11 13:54:54 +0100 | [diff] [blame] | 129 | const uint8_t *mask, int mask_stride, |
chiyotsai | e46cff7 | 2020-02-05 15:03:34 -0800 | [diff] [blame^] | 130 | int invert_mask, const MV *ref_mv, |
Jingning Han | 03cbd6d | 2019-11-20 16:42:01 -0800 | [diff] [blame] | 131 | const uint8_t *second_pred, |
| 132 | const struct buf_2d *src, |
| 133 | const struct buf_2d *pre); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 134 | |
Jingning Han | aaa3467 | 2019-11-25 14:29:26 -0800 | [diff] [blame] | 135 | int av1_diamond_search_sad_c(MACROBLOCK *x, const search_site_config *cfg, |
chiyotsai | e46cff7 | 2020-02-05 15:03:34 -0800 | [diff] [blame^] | 136 | FULLPEL_MV *start_mv, FULLPEL_MV *best_mv, |
| 137 | int search_param, int sad_per_bit, int *num00, |
Jingning Han | aaa3467 | 2019-11-25 14:29:26 -0800 | [diff] [blame] | 138 | const aom_variance_fn_ptr_t *fn_ptr, |
chiyotsai | e46cff7 | 2020-02-05 15:03:34 -0800 | [diff] [blame^] | 139 | const MV *ref_mv, uint8_t *second_pred, |
Jingning Han | aaa3467 | 2019-11-25 14:29:26 -0800 | [diff] [blame] | 140 | uint8_t *mask, int mask_stride, int inv_mask); |
| 141 | |
RogerZhou | cc5d35d | 2017-08-07 22:20:15 -0700 | [diff] [blame] | 142 | int av1_full_pixel_search(const struct AV1_COMP *cpi, MACROBLOCK *x, |
chiyotsai | e46cff7 | 2020-02-05 15:03:34 -0800 | [diff] [blame^] | 143 | BLOCK_SIZE bsize, FULLPEL_MV *start_mv, |
| 144 | int step_param, int use_var, int method, |
| 145 | int run_mesh_search, int error_per_bit, |
| 146 | int *cost_list, const MV *ref_mv, int var_max, int rd, |
| 147 | int x_pos, int y_pos, int intra, |
Ranjit Kumar Tulabandu | 5e1f701 | 2019-10-18 19:01:46 +0530 | [diff] [blame] | 148 | const search_site_config *cfg, |
| 149 | int use_intrabc_mesh_pattern); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 150 | |
Peng Bin | 235d715 | 2018-09-03 16:40:46 +0800 | [diff] [blame] | 151 | int av1_obmc_full_pixel_search(const struct AV1_COMP *cpi, MACROBLOCK *x, |
chiyotsai | e46cff7 | 2020-02-05 15:03:34 -0800 | [diff] [blame^] | 152 | FULLPEL_MV *start_mv, int step_param, int sadpb, |
Peng Bin | 235d715 | 2018-09-03 16:40:46 +0800 | [diff] [blame] | 153 | int further_steps, int do_refine, |
| 154 | const aom_variance_fn_ptr_t *fn_ptr, |
chiyotsai | e46cff7 | 2020-02-05 15:03:34 -0800 | [diff] [blame^] | 155 | const MV *ref_mv, FULLPEL_MV *dst_mv, |
| 156 | int is_second, const search_site_config *cfg); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 157 | int av1_find_best_obmc_sub_pixel_tree_up( |
Urvang Joshi | 52b6299 | 2018-02-02 14:43:07 -0800 | [diff] [blame] | 158 | MACROBLOCK *x, const AV1_COMMON *const cm, int mi_row, int mi_col, |
| 159 | MV *bestmv, const MV *ref_mv, int allow_hp, int error_per_bit, |
| 160 | const aom_variance_fn_ptr_t *vfp, int forced_stop, int iters_per_step, |
| 161 | int *mvjcost, int *mvcost[2], int *distortion, unsigned int *sse1, |
| 162 | int is_second, int use_accurate_subpel_search); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 163 | |
Yunqing Wang | 68f3ccd | 2017-05-23 14:43:54 -0700 | [diff] [blame] | 164 | unsigned int av1_compute_motion_cost(const struct AV1_COMP *cpi, |
| 165 | MACROBLOCK *const x, BLOCK_SIZE bsize, |
Hui Su | b94cd5e | 2019-11-06 12:05:47 -0800 | [diff] [blame] | 166 | const MV *this_mv); |
Yunqing Wang | 1bc8286 | 2017-06-28 15:49:48 -0700 | [diff] [blame] | 167 | unsigned int av1_refine_warped_mv(const struct AV1_COMP *cpi, |
| 168 | MACROBLOCK *const x, BLOCK_SIZE bsize, |
Hui Su | b94cd5e | 2019-11-06 12:05:47 -0800 | [diff] [blame] | 169 | int *pts0, int *pts_inref0, |
| 170 | int total_samples); |
Peng Bin | 6e2ced6 | 2018-05-08 11:34:36 +0800 | [diff] [blame] | 171 | |
chiyotsai | 19a58ee | 2019-03-18 18:01:05 -0700 | [diff] [blame] | 172 | // Performs a motion search in SIMPLE_TRANSLATION mode using reference frame |
| 173 | // ref. Note that this sets the offset of mbmi, so we will need to reset it |
| 174 | // after calling this function. |
| 175 | void av1_simple_motion_search(struct AV1_COMP *const cpi, MACROBLOCK *x, |
| 176 | int mi_row, int mi_col, BLOCK_SIZE bsize, int ref, |
chiyotsai | e46cff7 | 2020-02-05 15:03:34 -0800 | [diff] [blame^] | 177 | FULLPEL_MV start_mv, int num_planes, |
| 178 | int use_subpixel); |
chiyotsai | 19a58ee | 2019-03-18 18:01:05 -0700 | [diff] [blame] | 179 | |
| 180 | // Performs a simple motion search to calculate the sse and var of the residue |
| 181 | void av1_simple_motion_sse_var(struct AV1_COMP *cpi, MACROBLOCK *x, int mi_row, |
| 182 | int mi_col, BLOCK_SIZE bsize, |
chiyotsai | e46cff7 | 2020-02-05 15:03:34 -0800 | [diff] [blame^] | 183 | const FULLPEL_MV start_mv, int use_subpixel, |
chiyotsai | 19a58ee | 2019-03-18 18:01:05 -0700 | [diff] [blame] | 184 | unsigned int *sse, unsigned int *var); |
| 185 | |
Venkat | e846e2b | 2018-09-21 07:31:14 +0530 | [diff] [blame] | 186 | static INLINE void av1_set_fractional_mv(int_mv *fractional_best_mv) { |
| 187 | for (int z = 0; z < 3; z++) { |
| 188 | fractional_best_mv[z].as_int = INVALID_MV; |
| 189 | } |
| 190 | } |
| 191 | |
Yunqing Wang | da21361 | 2019-06-12 08:47:03 -0700 | [diff] [blame] | 192 | static INLINE void set_subpel_mv_search_range(const MvLimits *mv_limits, |
| 193 | int *col_min, int *col_max, |
| 194 | int *row_min, int *row_max, |
| 195 | const MV *ref_mv) { |
| 196 | const int max_mv = MAX_FULL_PEL_VAL * 8; |
| 197 | const int minc = AOMMAX(mv_limits->col_min * 8, ref_mv->col - max_mv); |
| 198 | const int maxc = AOMMIN(mv_limits->col_max * 8, ref_mv->col + max_mv); |
| 199 | const int minr = AOMMAX(mv_limits->row_min * 8, ref_mv->row - max_mv); |
| 200 | const int maxr = AOMMIN(mv_limits->row_max * 8, ref_mv->row + max_mv); |
| 201 | |
| 202 | *col_min = AOMMAX(MV_LOW + 1, minc); |
| 203 | *col_max = AOMMIN(MV_UPP - 1, maxc); |
| 204 | *row_min = AOMMAX(MV_LOW + 1, minr); |
| 205 | *row_max = AOMMIN(MV_UPP - 1, maxr); |
| 206 | } |
| 207 | |
Peng Bin | 6e2ced6 | 2018-05-08 11:34:36 +0800 | [diff] [blame] | 208 | #ifdef __cplusplus |
| 209 | } // extern "C" |
| 210 | #endif |
| 211 | |
James Zern | e1cbb13 | 2018-08-22 14:10:36 -0700 | [diff] [blame] | 212 | #endif // AOM_AV1_ENCODER_MCOMP_H_ |