Line data Source code
1 : /*
2 : * Copyright(c) 2019 Intel Corporation
3 : * SPDX - License - Identifier: BSD - 2 - Clause - Patent
4 : */
5 :
6 : #ifndef EbAdaptiveMotionVectorPrediction_h
7 : #define EbAdaptiveMotionVectorPrediction_h
8 :
9 : #include "EbUtility.h"
10 : #include "EbPictureControlSet.h"
11 : #include "EbCodingUnit.h"
12 : #include "EbPredictionUnit.h"
13 : #include "EbNeighborArrays.h"
14 : #include "EbMvMerge.h"
15 : #include "EbWarpedMotion.h"
16 :
17 : #ifdef __cplusplus
18 : extern "C" {
19 : #endif
20 :
21 : #define MV_BORDER (16 << 3) // Allow 16 pels in 1/8th pel units
22 :
23 : #define INTRABC_DELAY_PIXELS 256 // Delay of 256 pixels
24 : #define INTRABC_DELAY_SB64 (INTRABC_DELAY_PIXELS / 64)
25 :
26 : #define NELEMENTS(x) (int)(sizeof(x) / sizeof(x[0]))
27 :
28 : // Although we assign 32 bit integers, all the values are strictly under 14
29 : // bits.
30 : static int div_mult[32] = { 0, 16384, 8192, 5461, 4096, 3276, 2730, 2340,
31 : 2048, 1820, 1638, 1489, 1365, 1260, 1170, 1092,
32 : 1024, 963, 910, 862, 819, 780, 744, 712,
33 : 682, 655, 630, 606, 585, 564, 546, 528 };
34 :
35 : struct ModeDecisionContext;
36 : struct InterPredictionContext;
37 :
38 : extern EbErrorType clip_mv(
39 : uint32_t cu_origin_x,
40 : uint32_t cu_origin_y,
41 : int16_t *mv_x,
42 : int16_t *mv_y,
43 : uint32_t picture_width,
44 : uint32_t picture_height,
45 : uint32_t tb_size);
46 :
47 : void generate_av1_mvp_table(
48 : TileInfo *tile,
49 : struct ModeDecisionContext *context_ptr,
50 : CodingUnit *cu_ptr,
51 : const BlockGeom *blk_geom,
52 : uint16_t cu_origin_x,
53 : uint16_t cu_origin_y,
54 : MvReferenceFrame *ref_frames,
55 : uint32_t tot_refs,
56 : PictureControlSet *picture_control_set_ptr);
57 :
58 : void get_av1_mv_pred_drl(
59 : struct ModeDecisionContext *context_ptr,
60 : CodingUnit *cu_ptr,
61 : MvReferenceFrame ref_frame,
62 : uint8_t is_compound,
63 : PredictionMode mode,
64 : uint8_t drl_index,
65 : IntMv nearestmv[2],
66 : IntMv nearmv[2],
67 : IntMv ref_mv[2]);
68 :
69 : void enc_pass_av1_mv_pred(
70 : TileInfo *tile,
71 : struct ModeDecisionContext *md_context_ptr,
72 : CodingUnit *cu_ptr,
73 : const BlockGeom *blk_geom,
74 : uint16_t cu_origin_x,
75 : uint16_t cu_origin_y,
76 : PictureControlSet *picture_control_set_ptr,
77 : MvReferenceFrame ref_frame,
78 : uint8_t is_compound,
79 : PredictionMode mode,
80 : IntMv ref_mv[2]);
81 :
82 : void update_mi_map(
83 : struct ModeDecisionContext *context_ptr,
84 : CodingUnit *cu_ptr,
85 : uint32_t cu_origin_x,
86 : uint32_t cu_origin_y,
87 : const BlockGeom * blk_geom,
88 : const CodedUnitStats *cu_stats,
89 : PictureControlSet *picture_control_set_ptr);
90 :
91 : uint16_t wm_find_samples(
92 : CodingUnit *cu_ptr,
93 : const BlockGeom *blk_geom,
94 : uint16_t cu_origin_x,
95 : uint16_t cu_origin_y,
96 : MvReferenceFrame rf0,
97 : PictureControlSet *picture_control_set_ptr,
98 : int32_t *pts,
99 : int32_t *pts_inref);
100 :
101 : void wm_count_samples(
102 : CodingUnit *cu_ptr,
103 : const BlockGeom *blk_geom,
104 : uint16_t cu_origin_x,
105 : uint16_t cu_origin_y,
106 : uint8_t ref_frame_type,
107 : PictureControlSet *picture_control_set_ptr,
108 : uint16_t *num_samples);
109 :
110 : EbBool warped_motion_parameters(
111 : PictureControlSet *picture_control_set_ptr,
112 : CodingUnit *cu_ptr,
113 : MvUnit *mv_unit,
114 : const BlockGeom *blk_geom,
115 : uint16_t cu_origin_x,
116 : uint16_t cu_origin_y,
117 : uint8_t ref_frame_type,
118 : EbWarpedMotionParams *wm_params,
119 : uint16_t *num_samples);
120 :
121 78849925 : static INLINE EbBool is_motion_variation_allowed_bsize(const BlockSize bsize)
122 : {
123 78849925 : return (block_size_wide[bsize] >= 8 && block_size_high[bsize] >= 8);
124 : }
125 :
126 29163209 : static INLINE int is_neighbor_overlappable(const MbModeInfo *mbmi)
127 : {
128 29163209 : return /*is_intrabc_block(mbmi) ||*/ mbmi->block_mi.ref_frame[0] > INTRA_FRAME; // TODO: modify when add intra_bc
129 : }
130 :
131 32397244 : static INLINE EbBool has_overlappable_candidates(const CodingUnit *cu_ptr)
132 : {
133 32397244 : return (cu_ptr->prediction_unit_array[0].overlappable_neighbors[0] != 0
134 32397244 : || cu_ptr->prediction_unit_array[0].overlappable_neighbors[1] != 0);
135 : }
136 :
137 0 : static INLINE void integer_mv_precision(MV *mv) {
138 0 : int mod = (mv->row % 8);
139 0 : if (mod != 0) {
140 0 : mv->row -= mod;
141 0 : if (abs(mod) > 4) {
142 0 : if (mod > 0)
143 0 : mv->row += 8;
144 : else
145 0 : mv->row -= 8;
146 : }
147 : }
148 :
149 0 : mod = (mv->col % 8);
150 0 : if (mod != 0) {
151 0 : mv->col -= mod;
152 0 : if (abs(mod) > 4) {
153 0 : if (mod > 0)
154 0 : mv->col += 8;
155 : else
156 0 : mv->col -= 8;
157 : }
158 : }
159 0 : }
160 :
161 45827202 : static INLINE void lower_mv_precision(MV *mv, int allow_hp, int is_integer) {
162 45827202 : if (is_integer)
163 0 : integer_mv_precision(mv);
164 : else {
165 45827202 : if (!allow_hp) {
166 0 : if (mv->row & 1) mv->row += (mv->row > 0 ? -1 : 1);
167 0 : if (mv->col & 1) mv->col += (mv->col > 0 ? -1 : 1);
168 : }
169 : }
170 45827202 : }
171 :
172 46689562 : static INLINE void get_mv_projection(MV *output, MV ref, int num, int den) {
173 46689562 : den = AOMMIN(den, MAX_FRAME_DISTANCE);
174 46689562 : num = num > 0 ? AOMMIN(num, MAX_FRAME_DISTANCE)
175 46689562 : : AOMMAX(num, -MAX_FRAME_DISTANCE);
176 46689562 : const int mv_row =
177 46689562 : ROUND_POWER_OF_TWO_SIGNED(ref.row * num * div_mult[den], 14);
178 46689562 : const int mv_col =
179 46689562 : ROUND_POWER_OF_TWO_SIGNED(ref.col * num * div_mult[den], 14);
180 46689562 : const int clamp_max = MV_UPP - 1;
181 46689562 : const int clamp_min = MV_LOW + 1;
182 46689562 : output->row = (int16_t)clamp(mv_row, clamp_min, clamp_max);
183 46699303 : output->col = (int16_t)clamp(mv_col, clamp_min, clamp_max);
184 46694683 : }
185 :
186 65046211 : static INLINE PredictionMode compound_ref0_mode(PredictionMode mode) {
187 : static PredictionMode lut[] = {
188 : MB_MODE_COUNT, // DC_PRED
189 : MB_MODE_COUNT, // V_PRED
190 : MB_MODE_COUNT, // H_PRED
191 : MB_MODE_COUNT, // D45_PRED
192 : MB_MODE_COUNT, // D135_PRED
193 : MB_MODE_COUNT, // D113_PRED
194 : MB_MODE_COUNT, // D157_PRED
195 : MB_MODE_COUNT, // D203_PRED
196 : MB_MODE_COUNT, // D67_PRED
197 : MB_MODE_COUNT, // SMOOTH_PRED
198 : MB_MODE_COUNT, // SMOOTH_V_PRED
199 : MB_MODE_COUNT, // SMOOTH_H_PRED
200 : MB_MODE_COUNT, // PAETH_PRED
201 : MB_MODE_COUNT, // NEARESTMV
202 : MB_MODE_COUNT, // NEARMV
203 : MB_MODE_COUNT, // GLOBALMV
204 : MB_MODE_COUNT, // NEWMV
205 : NEARESTMV, // NEAREST_NEARESTMV
206 : NEARMV, // NEAR_NEARMV
207 : NEARESTMV, // NEAREST_NEWMV
208 : NEWMV, // NEW_NEARESTMV
209 : NEARMV, // NEAR_NEWMV
210 : NEWMV, // NEW_NEARMV
211 : GLOBALMV, // GLOBAL_GLOBALMV
212 : NEWMV, // NEW_NEWMV
213 : };
214 : assert(NELEMENTS(lut) == MB_MODE_COUNT);
215 65046211 : assert(is_inter_compound_mode(mode));
216 65047311 : return lut[mode];
217 : }
218 :
219 65046211 : static INLINE PredictionMode compound_ref1_mode(PredictionMode mode) {
220 : static PredictionMode lut[] = {
221 : MB_MODE_COUNT, // DC_PRED
222 : MB_MODE_COUNT, // V_PRED
223 : MB_MODE_COUNT, // H_PRED
224 : MB_MODE_COUNT, // D45_PRED
225 : MB_MODE_COUNT, // D135_PRED
226 : MB_MODE_COUNT, // D113_PRED
227 : MB_MODE_COUNT, // D157_PRED
228 : MB_MODE_COUNT, // D203_PRED
229 : MB_MODE_COUNT, // D67_PRED
230 : MB_MODE_COUNT, // SMOOTH_PRED
231 : MB_MODE_COUNT, // SMOOTH_V_PRED
232 : MB_MODE_COUNT, // SMOOTH_H_PRED
233 : MB_MODE_COUNT, // PAETH_PRED
234 : MB_MODE_COUNT, // NEARESTMV
235 : MB_MODE_COUNT, // NEARMV
236 : MB_MODE_COUNT, // GLOBALMV
237 : MB_MODE_COUNT, // NEWMV
238 : NEARESTMV, // NEAREST_NEARESTMV
239 : NEARMV, // NEAR_NEARMV
240 : NEWMV, // NEAREST_NEWMV
241 : NEARESTMV, // NEW_NEARESTMV
242 : NEWMV, // NEAR_NEWMV
243 : NEARMV, // NEW_NEARMV
244 : GLOBALMV, // GLOBAL_GLOBALMV
245 : NEWMV, // NEW_NEWMV
246 : };
247 : assert(NELEMENTS(lut) == MB_MODE_COUNT);
248 65046211 : assert(is_inter_compound_mode(mode));
249 65027511 : return lut[mode];
250 : }
251 :
252 11205001 : static INLINE int check_sb_border(const int mi_row, const int mi_col,
253 : const int row_offset, const int col_offset)
254 : {
255 11205001 : const int sb_mi_size = mi_size_wide[BLOCK_64X64];
256 11205001 : const int row = mi_row & (sb_mi_size - 1);
257 11205001 : const int col = mi_col & (sb_mi_size - 1);
258 :
259 11205001 : if (row + row_offset < 0 || row + row_offset >= sb_mi_size ||
260 9832241 : col + col_offset < 0 || col + col_offset >= sb_mi_size)
261 3600636 : return 0;
262 :
263 7604335 : return 1;
264 : }
265 :
266 54661489 : static INLINE int is_global_mv_block(
267 : const PredictionMode mode,
268 : const BlockSize bsize,
269 : TransformationType type)
270 : {
271 53531956 : return (mode == GLOBALMV || mode == GLOBAL_GLOBALMV)
272 7186232 : && type > TRANSLATION
273 109322978 : && is_motion_variation_allowed_bsize(bsize);
274 : }
275 :
276 479304132 : static INLINE void clamp_mv(MV *mv, int32_t min_col, int32_t max_col,
277 : int32_t min_row, int32_t max_row)
278 : {
279 479304132 : mv->col = (int16_t)clamp(mv->col, min_col, max_col);
280 478901642 : mv->row = (int16_t)clamp(mv->row, min_row, max_row);
281 478396642 : }
282 :
283 28000 : static INLINE int32_t is_mv_valid(const MV *mv) {
284 56000 : return mv->row > MV_LOW && mv->row < MV_UPP && mv->col > MV_LOW &&
285 28000 : mv->col < MV_UPP;
286 : }
287 :
288 : void eb_av1_count_overlappable_neighbors(
289 : const PictureControlSet *picture_control_set_ptr,
290 : CodingUnit *cu_ptr,
291 : const BlockSize bsize,
292 : int32_t mi_row,
293 : int32_t mi_col);
294 :
295 : void eb_av1_find_best_ref_mvs_from_stack(int allow_hp,
296 : CandidateMv ref_mv_stack[][MAX_REF_MV_STACK_SIZE],
297 : MacroBlockD * xd,
298 : MvReferenceFrame ref_frame,
299 : IntMv *nearest_mv, IntMv *near_mv,
300 : int is_integer);
301 : void av1_find_ref_dv(IntMv *ref_dv, const TileInfo *const tile,
302 : int mib_size, int mi_row, int mi_col);
303 : int av1_is_dv_valid(const MV dv,
304 : const MacroBlockD *xd, int mi_row, int mi_col,
305 : BlockSize bsize, int mib_size_log2);
306 : int is_inside_tile_boundary(TileInfo *tile, int16_t mvx, int16_t mvy, int mi_col, int mi_row, BlockSize bsize);
307 :
308 : IntMv gm_get_motion_vector_enc(
309 : const EbWarpedMotionParams *gm,
310 : int32_t allow_hp,
311 : BlockSize bsize,
312 : int32_t mi_col, int32_t mi_row,
313 : int32_t is_integer);
314 :
315 : #ifdef __cplusplus
316 : }
317 : #endif
318 : #endif // EbAdaptiveMotionVectorPrediction_h
|