1 /*
2 * Copyright(c) 2019 Intel Corporation
3 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
4 *
5 * This source code is subject to the terms of the BSD 2 Clause License and
6 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
7 * was not distributed with this source code in the LICENSE file, you can
8 * obtain it at https://www.aomedia.org/license/software-license. If the Alliance for Open
9 * Media Patent License 1.0 was not distributed with this source code in the
10 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
11 */
12
13 #include <string.h>
14
15 #include "EbDefinitions.h"
16 #include "EbAdaptiveMotionVectorPrediction.h"
17 #include "EbSvtAv1.h"
18 #include "EbModeDecisionProcess.h"
19 #include "EbCommonUtils.h"
20 #include "EbEntropyCoding.h"
21
22 #define UNUSED_FUNC
23
24 /** ScaleMV
25 is used to scale the motion vector in AMVP process.
26 */
27 /*
28 static inline void scale_mv(
29 uint64_t current_pic_poc, // Iuput parameter, the POC of the current picture to be encoded.
30 uint64_t target_ref_pic_poc, // Iuput parameter, the POC of the reference picture where the inter coding is searching for.
31 uint64_t col_pu_pic_poc, // Iuput parameter, the POC of picture where the co-located PU is.
32 uint64_t col_pu_ref_pic_poc, // Iuput parameter, the POC of the reference picture where the MV of the co-located PU points to.
33 int16_t *mvx, // Output parameter,
34 int16_t *mvy) // Output parameter,
35 {
36 int16_t td = (int16_t)(col_pu_pic_poc - col_pu_ref_pic_poc);
37 int16_t tb = (int16_t)(current_pic_poc - target_ref_pic_poc);
38 int16_t scale_factor;
39 int16_t temp;
40
41 if (td != tb) {
42 tb = CLIP3(-128, 127, tb);
43 td = CLIP3(-128, 127, td);
44 temp = (int16_t)((0x4000 + ABS(td >> 1)) / td);
45 scale_factor = CLIP3(-4096, 4095, (tb * temp + 32) >> 6);
46
47 *mvx = CLIP3(-32768, 32767, (scale_factor * (*mvx) + 127 + (scale_factor * (*mvx) < 0)) >> 8);
48 *mvy = CLIP3(-32768, 32767, (scale_factor * (*mvy) + 127 + (scale_factor * (*mvy) < 0)) >> 8);
49 }
50
51 return;
52 }
53 */
54 static PartitionType from_shape_to_part[] = {PARTITION_NONE,
55 PARTITION_HORZ,
56 PARTITION_VERT,
57 PARTITION_HORZ_A,
58 PARTITION_HORZ_B,
59 PARTITION_VERT_A,
60 PARTITION_VERT_B,
61 PARTITION_HORZ_4,
62 PARTITION_VERT_4,
63 PARTITION_SPLIT};
64
65 #define MVREF_ROWS 3
66 #define MVREF_COLS 3
67
have_newmv_in_inter_mode(PredictionMode mode)68 static int32_t have_newmv_in_inter_mode(PredictionMode mode) {
69 return (mode == NEWMV || mode == NEW_NEWMV || mode == NEAREST_NEWMV || mode == NEW_NEARESTMV ||
70 mode == NEAR_NEWMV || mode == NEW_NEARMV);
71 }
72
73 typedef struct position {
74 int32_t row;
75 int32_t col;
76 } Position;
77
78 // clang-format on
79
get_sub_block_mv(const ModeInfo * candidate,int32_t which_mv,int32_t search_col)80 static INLINE IntMv get_sub_block_mv(const ModeInfo *candidate, int32_t which_mv,
81 int32_t search_col) {
82 (void)search_col;
83 return candidate->mbmi.block_mi.mv[which_mv];
84 }
is_inside(const TileInfo * const tile,int32_t mi_col,int32_t mi_row,const Position * mi_pos)85 static INLINE int32_t is_inside(const TileInfo *const tile, int32_t mi_col, int32_t mi_row,
86 const Position *mi_pos) {
87 return !(mi_row + mi_pos->row < tile->mi_row_start ||
88 mi_col + mi_pos->col < tile->mi_col_start ||
89 mi_row + mi_pos->row >= tile->mi_row_end || mi_col + mi_pos->col >= tile->mi_col_end);
90 }
91
clamp_mv_ref(MV * mv,int32_t bw,int32_t bh,const MacroBlockD * xd)92 static INLINE void clamp_mv_ref(MV *mv, int32_t bw, int32_t bh, const MacroBlockD *xd) {
93 clamp_mv(mv,
94 xd->mb_to_left_edge - bw * 8 - MV_BORDER,
95 xd->mb_to_right_edge + bw * 8 + MV_BORDER,
96 xd->mb_to_top_edge - bh * 8 - MV_BORDER,
97 xd->mb_to_bottom_edge + bh * 8 + MV_BORDER);
98 }
99
add_ref_mv_candidate(const ModeInfo * const candidate_mi,const MbModeInfo * const candidate,const MvReferenceFrame rf[2],uint8_t refmv_counts[MODE_CTX_REF_FRAMES],uint8_t ref_match_counts[MODE_CTX_REF_FRAMES],uint8_t newmv_counts[MODE_CTX_REF_FRAMES],CandidateMv ref_mv_stacks[][MAX_REF_MV_STACK_SIZE],int32_t len,IntMv * gm_mv_candidates,const EbWarpedMotionParams * gm_params,int32_t col,int32_t weight)100 static void add_ref_mv_candidate(const ModeInfo *const candidate_mi,
101 const MbModeInfo *const candidate, const MvReferenceFrame rf[2],
102 uint8_t refmv_counts[MODE_CTX_REF_FRAMES],
103 uint8_t ref_match_counts[MODE_CTX_REF_FRAMES],
104 uint8_t newmv_counts[MODE_CTX_REF_FRAMES],
105 CandidateMv ref_mv_stacks[][MAX_REF_MV_STACK_SIZE], int32_t len,
106 IntMv *gm_mv_candidates, const EbWarpedMotionParams *gm_params,
107 int32_t col, int32_t weight) {
108 if (!is_inter_block(&candidate->block_mi))
109 return; // for intrabc
110 assert(weight % 2 == 0);
111
112 if (rf[1] == NONE_FRAME) {
113 uint8_t * refmv_count = &refmv_counts[rf[0]];
114 uint8_t * ref_match_count = &ref_match_counts[rf[0]];
115 uint8_t * newmv_count = &newmv_counts[rf[0]];
116 CandidateMv *ref_mv_stack = ref_mv_stacks[rf[0]];
117 (void)ref_match_count;
118
119 // single reference frame
120 for (int32_t ref = 0; ref < 2; ++ref) {
121 if (candidate->block_mi.ref_frame[ref] == rf[0]) {
122 IntMv this_refmv;
123 if (is_global_mv_block(candidate->block_mi.mode,
124 candidate->block_mi.sb_type,
125 gm_params[rf[0]].wmtype))
126 this_refmv = gm_mv_candidates[0];
127 else
128 this_refmv = get_sub_block_mv(candidate_mi, ref, col);
129 int32_t index;
130 for (index = 0; index < *refmv_count; ++index)
131 if (ref_mv_stack[index].this_mv.as_int == this_refmv.as_int)
132 break;
133
134 if (index < *refmv_count)
135 ref_mv_stack[index].weight += weight * len;
136
137 // Add a new item to the list.
138 if (index == *refmv_count && *refmv_count < MAX_REF_MV_STACK_SIZE) {
139 ref_mv_stack[index].this_mv = this_refmv;
140 ref_mv_stack[index].weight = weight * len;
141 ++(*refmv_count);
142 }
143 if (have_newmv_in_inter_mode(candidate->block_mi.mode))
144 ++*newmv_count;
145 ++*ref_match_count;
146 }
147 }
148 } else {
149 MvReferenceFrame ref_frame = av1_ref_frame_type(rf);
150 uint8_t * refmv_count = &refmv_counts[ref_frame];
151 uint8_t * ref_match_count = &ref_match_counts[ref_frame];
152 uint8_t * newmv_count = &newmv_counts[ref_frame];
153 CandidateMv * ref_mv_stack = ref_mv_stacks[ref_frame];
154 (void)ref_match_count;
155
156 // compound reference frame
157 if (candidate->block_mi.ref_frame[0] == rf[0] &&
158 candidate->block_mi.ref_frame[1] == rf[1]) {
159 IntMv this_refmv[2];
160
161 for (int32_t ref = 0; ref < 2; ++ref) {
162 if (is_global_mv_block(candidate->block_mi.mode,
163 candidate->block_mi.sb_type,
164 gm_params[rf[ref]].wmtype))
165 this_refmv[ref] = gm_mv_candidates[ref];
166 else
167 this_refmv[ref] = get_sub_block_mv(candidate_mi, ref, col);
168 }
169 int32_t index;
170 for (index = 0; index < *refmv_count; ++index)
171 if ((ref_mv_stack[index].this_mv.as_int == this_refmv[0].as_int) &&
172 (ref_mv_stack[index].comp_mv.as_int == this_refmv[1].as_int))
173 break;
174
175 if (index < *refmv_count)
176 ref_mv_stack[index].weight += weight * len;
177
178 // Add a new item to the list.
179 if (index == *refmv_count && *refmv_count < MAX_REF_MV_STACK_SIZE) {
180 ref_mv_stack[index].this_mv = this_refmv[0];
181 ref_mv_stack[index].comp_mv = this_refmv[1];
182 ref_mv_stack[index].weight = weight * len;
183 ++(*refmv_count);
184 }
185 if (have_newmv_in_inter_mode(candidate->block_mi.mode))
186 ++*newmv_count;
187 ++*ref_match_count;
188 }
189 }
190 }
191
scan_row_mbmi(const Av1Common * cm,const MacroBlockD * xd,int32_t mi_row,int32_t mi_col,const MvReferenceFrame rf[2],int32_t row_offset,CandidateMv ref_mv_stack[][MAX_REF_MV_STACK_SIZE],uint8_t refmv_count[MODE_CTX_REF_FRAMES],uint8_t ref_match_count[MODE_CTX_REF_FRAMES],uint8_t newmv_count[MODE_CTX_REF_FRAMES],IntMv * gm_mv_candidates,const EbWarpedMotionParams * gm_params,int32_t max_row_offset,int32_t * processed_rows)192 static void scan_row_mbmi(const Av1Common *cm, const MacroBlockD *xd, int32_t mi_row,
193 int32_t mi_col, const MvReferenceFrame rf[2], int32_t row_offset,
194 CandidateMv ref_mv_stack[][MAX_REF_MV_STACK_SIZE],
195 uint8_t refmv_count[MODE_CTX_REF_FRAMES],
196 uint8_t ref_match_count[MODE_CTX_REF_FRAMES],
197 uint8_t newmv_count[MODE_CTX_REF_FRAMES], IntMv *gm_mv_candidates,
198 const EbWarpedMotionParams *gm_params, int32_t max_row_offset,
199 int32_t *processed_rows) {
200 int32_t end_mi = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
201 end_mi = AOMMIN(end_mi, mi_size_wide[BLOCK_64X64]);
202 const int32_t n8_w_8 = mi_size_wide[BLOCK_8X8];
203 const int32_t n8_w_16 = mi_size_wide[BLOCK_16X16];
204 int32_t i;
205 int32_t col_offset = 0;
206 const int32_t shift = 0;
207 if (abs(row_offset) > 1) {
208 col_offset = 1;
209 if (mi_col & 0x01 && xd->n8_w < n8_w_8)
210 --col_offset;
211 }
212 const int32_t use_step_16 = (xd->n8_w >= 16);
213 ModeInfo **const candidate_mi0 = xd->mi + row_offset * xd->mi_stride;
214 (void)mi_row;
215
216 for (i = 0; i < end_mi;) {
217 const ModeInfo *const candidate_mi = candidate_mi0[col_offset + i];
218 const MbModeInfo *const candidate = &candidate_mi->mbmi;
219 const int32_t candidate_bsize = candidate->block_mi.sb_type;
220 assert(candidate_bsize < BlockSizeS_ALL);
221 const int32_t n8_w = mi_size_wide[candidate_bsize];
222 int32_t len = AOMMIN(xd->n8_w, n8_w);
223 if (use_step_16)
224 len = AOMMAX(n8_w_16, len);
225 else if (abs(row_offset) > 1)
226 len = AOMMAX(len, n8_w_8);
227
228 int32_t weight = 2;
229 if (xd->n8_w >= n8_w_8 && xd->n8_w <= n8_w) {
230 int32_t inc = AOMMIN(-max_row_offset + row_offset + 1, mi_size_high[candidate_bsize]);
231 // Obtain range used in weight calculation.
232 weight = AOMMAX(weight, (inc << shift));
233 // Update processed rows.
234 *processed_rows = inc - row_offset - 1;
235 }
236
237 add_ref_mv_candidate(candidate_mi,
238 candidate,
239 rf,
240 refmv_count,
241 ref_match_count,
242 newmv_count,
243 ref_mv_stack,
244 len,
245 gm_mv_candidates,
246 gm_params,
247 col_offset + i,
248 weight);
249
250 i += len;
251 }
252 }
253
scan_col_mbmi(const Av1Common * cm,const MacroBlockD * xd,int32_t mi_row,int32_t mi_col,const MvReferenceFrame rf[2],int32_t col_offset,CandidateMv ref_mv_stack[][MAX_REF_MV_STACK_SIZE],uint8_t refmv_count[MODE_CTX_REF_FRAMES],uint8_t ref_match_count[MODE_CTX_REF_FRAMES],uint8_t newmv_count[MODE_CTX_REF_FRAMES],IntMv * gm_mv_candidates,const EbWarpedMotionParams * gm_params,int32_t max_col_offset,int32_t * processed_cols)254 static void scan_col_mbmi(const Av1Common *cm, const MacroBlockD *xd, int32_t mi_row,
255 int32_t mi_col, const MvReferenceFrame rf[2], int32_t col_offset,
256 CandidateMv ref_mv_stack[][MAX_REF_MV_STACK_SIZE],
257 uint8_t refmv_count[MODE_CTX_REF_FRAMES],
258 uint8_t ref_match_count[MODE_CTX_REF_FRAMES],
259 uint8_t newmv_count[MODE_CTX_REF_FRAMES], IntMv *gm_mv_candidates,
260 const EbWarpedMotionParams *gm_params, int32_t max_col_offset,
261 int32_t *processed_cols) {
262 int32_t end_mi = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
263 end_mi = AOMMIN(end_mi, mi_size_high[BLOCK_64X64]);
264 const int32_t n8_h_8 = mi_size_high[BLOCK_8X8];
265 const int32_t n8_h_16 = mi_size_high[BLOCK_16X16];
266 int32_t i;
267 int32_t row_offset = 0;
268 const int32_t shift = 0;
269 if (abs(col_offset) > 1) {
270 row_offset = 1;
271 if (mi_row & 0x01 && xd->n8_h < n8_h_8)
272 --row_offset;
273 }
274 const int32_t use_step_16 = (xd->n8_h >= 16);
275 (void)mi_col;
276
277 for (i = 0; i < end_mi;) {
278 const ModeInfo *const candidate_mi = xd->mi[(row_offset + i) * xd->mi_stride + col_offset];
279 const MbModeInfo *const candidate = &candidate_mi->mbmi;
280 const int32_t candidate_bsize = candidate->block_mi.sb_type;
281 assert(candidate_bsize < BlockSizeS_ALL);
282 const int32_t n8_h = mi_size_high[candidate_bsize];
283 int32_t len = AOMMIN(xd->n8_h, n8_h);
284 if (use_step_16)
285 len = AOMMAX(n8_h_16, len);
286 else if (abs(col_offset) > 1)
287 len = AOMMAX(len, n8_h_8);
288
289 int32_t weight = 2;
290 if (xd->n8_h >= n8_h_8 && xd->n8_h <= n8_h) {
291 int32_t inc = AOMMIN(-max_col_offset + col_offset + 1, mi_size_wide[candidate_bsize]);
292 // Obtain range used in weight calculation.
293 weight = AOMMAX(weight, (inc << shift));
294 // Update processed cols.
295 *processed_cols = inc - col_offset - 1;
296 }
297
298 add_ref_mv_candidate(candidate_mi,
299 candidate,
300 rf,
301 refmv_count,
302 ref_match_count,
303 newmv_count,
304 ref_mv_stack,
305 len,
306 gm_mv_candidates,
307 gm_params,
308 col_offset,
309 weight);
310
311 i += len;
312 }
313 }
314
scan_blk_mbmi(const MacroBlockD * xd,const int32_t mi_row,const int32_t mi_col,const MvReferenceFrame rf[2],int32_t row_offset,int32_t col_offset,CandidateMv ref_mv_stack[][MAX_REF_MV_STACK_SIZE],uint8_t ref_match_count[MODE_CTX_REF_FRAMES],uint8_t newmv_count[MODE_CTX_REF_FRAMES],IntMv * gm_mv_candidates,const EbWarpedMotionParams * gm_params,uint8_t refmv_count[MODE_CTX_REF_FRAMES])315 static void scan_blk_mbmi(const MacroBlockD *xd, const int32_t mi_row, const int32_t mi_col,
316 const MvReferenceFrame rf[2], int32_t row_offset, int32_t col_offset,
317 CandidateMv ref_mv_stack[][MAX_REF_MV_STACK_SIZE],
318 uint8_t ref_match_count[MODE_CTX_REF_FRAMES],
319 uint8_t newmv_count[MODE_CTX_REF_FRAMES], IntMv *gm_mv_candidates,
320 const EbWarpedMotionParams *gm_params,
321 uint8_t refmv_count[MODE_CTX_REF_FRAMES]) {
322 const TileInfo *const tile = &xd->tile;
323 Position mi_pos;
324
325 mi_pos.row = row_offset;
326 mi_pos.col = col_offset;
327
328 if (is_inside(tile, mi_col, mi_row, &mi_pos)) {
329 const ModeInfo *const candidate_mi = xd->mi[mi_pos.row * xd->mi_stride + mi_pos.col];
330 const MbModeInfo *const candidate = &candidate_mi->mbmi;
331 const int32_t len = mi_size_wide[BLOCK_8X8];
332
333 add_ref_mv_candidate(candidate_mi,
334 candidate,
335 rf,
336 refmv_count,
337 ref_match_count,
338 newmv_count,
339 ref_mv_stack,
340 len,
341 gm_mv_candidates,
342 gm_params,
343 mi_pos.col,
344 2);
345 } // Analyze a single 8x8 block motion information.
346 }
347
has_top_right(const Av1Common * cm,const BlockSize sb_size,const MacroBlockD * xd,int32_t mi_row,int32_t mi_col,int32_t bs)348 static int32_t has_top_right(const Av1Common *cm, const BlockSize sb_size, const MacroBlockD *xd,
349 int32_t mi_row, int32_t mi_col, int32_t bs) {
350 (void)xd;
351 (void)cm;
352 const int32_t sb_mi_size = mi_size_wide[sb_size];
353 const int32_t mask_row = mi_row & (sb_mi_size - 1);
354 const int32_t mask_col = mi_col & (sb_mi_size - 1);
355
356 if (bs > mi_size_wide[BLOCK_64X64])
357 return 0;
358
359 // In a split partition all apart from the bottom right has a top right
360 int32_t has_tr = !((mask_row & bs) && (mask_col & bs));
361
362 // bs > 0 and bs is a power of 2
363 assert(bs > 0 && !(bs & (bs - 1)));
364
365 // For each 4x4 group of blocks, when the bottom right is decoded the blocks
366 // to the right have not been decoded therefore the bottom right does
367 // not have a top right
368 while (bs < sb_mi_size) {
369 if (mask_col & bs) {
370 if ((mask_col & (2 * bs)) && (mask_row & (2 * bs))) {
371 has_tr = 0;
372 break;
373 }
374 } else
375 break;
376 bs <<= 1;
377 }
378
379 // The left hand of two vertical rectangles always has a top right (as the
380 // block above will have been decoded)
381 if (xd->n8_w < xd->n8_h)
382 if (!xd->is_sec_rect)
383 has_tr = 1;
384
385 // The bottom of two horizontal rectangles never has a top right (as the block
386 // to the right won't have been decoded)
387 if (xd->n8_w > xd->n8_h)
388 if (xd->is_sec_rect)
389 has_tr = 0;
390
391 // The bottom left square of a Vertical A (in the old format) does
392 // not have a top right as it is decoded before the right hand
393 // rectangle of the partition
394 if (xd->mi[0]->mbmi.block_mi.partition == PARTITION_VERT_A) {
395 if (xd->n8_w == xd->n8_h)
396 if (mask_row & bs)
397 has_tr = 0;
398 }
399
400 return has_tr;
401 }
find_valid_row_offset(const TileInfo * const tile,int32_t mi_row,int32_t row_offset)402 static INLINE int32_t find_valid_row_offset(const TileInfo *const tile, int32_t mi_row,
403 int32_t row_offset) {
404 return clamp(row_offset, tile->mi_row_start - mi_row, tile->mi_row_end - mi_row - 1);
405 }
406
find_valid_col_offset(const TileInfo * const tile,int32_t mi_col,int32_t col_offset)407 static INLINE int32_t find_valid_col_offset(const TileInfo *const tile, int32_t mi_col,
408 int32_t col_offset) {
409 return clamp(col_offset, tile->mi_col_start - mi_col, tile->mi_col_end - mi_col - 1);
410 }
get_relative_dist(const OrderHintInfo * oh,int a,int b)411 static INLINE int get_relative_dist(const OrderHintInfo *oh, int a, int b) {
412 if (!oh->enable_order_hint)
413 return 0;
414
415 const int bits = oh->order_hint_bits;
416
417 assert(bits >= 1);
418 assert(a >= 0 && a < (1 << bits));
419 assert(b >= 0 && b < (1 << bits));
420
421 int diff = a - b;
422 const int m = 1 << (bits - 1);
423 diff = (diff & (m - 1)) - (diff & m);
424 return diff;
425 }
add_tpl_ref_mv(const Av1Common * cm,PictureControlSet * pcs_ptr,const MacroBlockD * xd,int mi_row,int mi_col,MvReferenceFrame ref_frame,int blk_row,int blk_col,IntMv * gm_mv_candidates,uint8_t * const refmv_count,uint8_t two_symetric_refs,IntMv * mv_ref0,int cur_offset_0,int cur_offset_1,CandidateMv ref_mv_stack[MAX_REF_MV_STACK_SIZE],int16_t * mode_context)426 static int add_tpl_ref_mv(const Av1Common *cm, PictureControlSet *pcs_ptr, const MacroBlockD *xd,
427 int mi_row, int mi_col, MvReferenceFrame ref_frame, int blk_row,
428 int blk_col, IntMv *gm_mv_candidates, uint8_t *const refmv_count,
429 uint8_t two_symetric_refs, IntMv *mv_ref0,
430 int cur_offset_0, int cur_offset_1,
431
432 CandidateMv ref_mv_stack[MAX_REF_MV_STACK_SIZE], int16_t *mode_context) {
433 Position mi_pos;
434 mi_pos.row = (mi_row & 0x01) ? blk_row : blk_row + 1;
435 mi_pos.col = (mi_col & 0x01) ? blk_col : blk_col + 1;
436
437 if (!is_inside(&xd->tile, mi_col, mi_row, &mi_pos))
438 return 0;
439
440 const TPL_MV_REF *prev_frame_mvs = pcs_ptr->tpl_mvs +
441 ((mi_row + mi_pos.row) >> 1) * (cm->mi_stride >> 1) + ((mi_col + mi_pos.col) >> 1);
442 if (prev_frame_mvs->mfmv0.as_int == INVALID_MV)
443 return 0;
444
445 const uint16_t weight_unit = 1;
446 int idx;
447
448 IntMv this_refmv;
449
450
451 if (two_symetric_refs) {
452 if (ref_frame == LAST_FRAME) {
453
454 get_mv_projection(&this_refmv.as_mv,
455 prev_frame_mvs->mfmv0.as_mv,
456 cur_offset_0,
457 prev_frame_mvs->ref_frame_offset);
458 lower_mv_precision(
459 &this_refmv.as_mv, pcs_ptr->parent_pcs_ptr->frm_hdr.allow_high_precision_mv, 0);
460 //store for future use
461 (*mv_ref0) = this_refmv;
462 }
463 else {
464 if (ref_frame == BWDREF_FRAME) {
465 this_refmv.as_mv.row = -mv_ref0->as_mv.row;
466 this_refmv.as_mv.col = -mv_ref0->as_mv.col;
467 }
468 else {
469 this_refmv.as_mv = (*mv_ref0).as_mv;
470 }
471 }
472 }
473 else {
474
475 get_mv_projection(&this_refmv.as_mv,
476 prev_frame_mvs->mfmv0.as_mv,
477 cur_offset_0,
478 prev_frame_mvs->ref_frame_offset);
479 lower_mv_precision(
480 &this_refmv.as_mv, pcs_ptr->parent_pcs_ptr->frm_hdr.allow_high_precision_mv, 0);
481
482 }
483
484
485
486
487 //single ref case could be detected by ref_frame
488 if (ref_frame < LAST_BWD_FRAME) {
489 if (blk_row == 0 && blk_col == 0) {
490 if (abs(this_refmv.as_mv.row - gm_mv_candidates[0].as_mv.row) >= 16 ||
491 abs(this_refmv.as_mv.col - gm_mv_candidates[0].as_mv.col) >= 16)
492 mode_context[ref_frame] |= (1 << GLOBALMV_OFFSET);
493 }
494
495 for (idx = 0; idx < *refmv_count; ++idx)
496 if (this_refmv.as_int == ref_mv_stack[idx].this_mv.as_int)
497 break;
498
499 if (idx < *refmv_count)
500 ref_mv_stack[idx].weight += 2 * weight_unit;
501
502 if (idx == *refmv_count && *refmv_count < MAX_REF_MV_STACK_SIZE) {
503 ref_mv_stack[idx].this_mv.as_int = this_refmv.as_int;
504 ref_mv_stack[idx].weight = 2 * weight_unit;
505 ++(*refmv_count);
506 }
507 } else {
508 // Process compound inter mode
509 IntMv comp_refmv;
510 if (two_symetric_refs) {
511 comp_refmv.as_mv.row = -mv_ref0->as_mv.row;
512 comp_refmv.as_mv.col = -mv_ref0->as_mv.col;
513 }
514 else {
515 get_mv_projection(&comp_refmv.as_mv,
516 prev_frame_mvs->mfmv0.as_mv,
517 cur_offset_1,
518 prev_frame_mvs->ref_frame_offset);
519 lower_mv_precision(
520 &comp_refmv.as_mv, pcs_ptr->parent_pcs_ptr->frm_hdr.allow_high_precision_mv, 0);
521 }
522
523
524 if (blk_row == 0 && blk_col == 0) {
525 if (abs(this_refmv.as_mv.row - gm_mv_candidates[0].as_mv.row) >= 16 ||
526 abs(this_refmv.as_mv.col - gm_mv_candidates[0].as_mv.col) >= 16 ||
527 abs(comp_refmv.as_mv.row - gm_mv_candidates[1].as_mv.row) >= 16 ||
528 abs(comp_refmv.as_mv.col - gm_mv_candidates[1].as_mv.col) >= 16)
529 mode_context[ref_frame] |= (1 << GLOBALMV_OFFSET);
530 }
531
532 for (idx = 0; idx < *refmv_count; ++idx) {
533 if (this_refmv.as_int == ref_mv_stack[idx].this_mv.as_int &&
534 comp_refmv.as_int == ref_mv_stack[idx].comp_mv.as_int)
535 break;
536 }
537
538 if (idx < *refmv_count)
539 ref_mv_stack[idx].weight += 2 * weight_unit;
540
541 if (idx == *refmv_count && *refmv_count < MAX_REF_MV_STACK_SIZE) {
542 ref_mv_stack[idx].this_mv.as_int = this_refmv.as_int;
543 ref_mv_stack[idx].comp_mv.as_int = comp_refmv.as_int;
544 ref_mv_stack[idx].weight = 2 * weight_unit;
545 ++(*refmv_count);
546 }
547 }
548
549 return 1;
550 }
551
setup_ref_mv_list(PictureControlSet * pcs_ptr,const Av1Common * cm,const MacroBlockD * xd,MvReferenceFrame ref_frame,uint8_t refmv_count[MODE_CTX_REF_FRAMES],CandidateMv ref_mv_stack[][MAX_REF_MV_STACK_SIZE],IntMv mv_ref_list[][MAX_MV_REF_CANDIDATES],IntMv * gm_mv_candidates,const EbWarpedMotionParams * gm_params,int32_t mi_row,int32_t mi_col,ModeDecisionContext * ctx,uint8_t symteric_refs,IntMv * mv_ref0,int16_t * mode_context)552 void setup_ref_mv_list(PictureControlSet *pcs_ptr, const Av1Common *cm, const MacroBlockD *xd,
553 MvReferenceFrame ref_frame, uint8_t refmv_count[MODE_CTX_REF_FRAMES],
554 CandidateMv ref_mv_stack[][MAX_REF_MV_STACK_SIZE],
555 IntMv mv_ref_list[][MAX_MV_REF_CANDIDATES], IntMv *gm_mv_candidates,
556 const EbWarpedMotionParams *gm_params, int32_t mi_row, int32_t mi_col,
557 ModeDecisionContext *ctx,
558 uint8_t symteric_refs,
559 IntMv *mv_ref0,
560 int16_t *mode_context) {
561 const int32_t bs = AOMMAX(xd->n8_w, xd->n8_h);
562 const int32_t has_tr = has_top_right(
563 cm,
564 ((SequenceControlSet *)pcs_ptr->scs_wrapper_ptr->object_ptr)->seq_header.sb_size,
565 xd,
566 mi_row,
567 mi_col,
568 bs);
569 MvReferenceFrame rf[2];
570
571 const TileInfo *const tile = &xd->tile;
572 int32_t max_row_offset = 0, max_col_offset = 0;
573 const int32_t row_adj = (xd->n8_h < mi_size_high[BLOCK_8X8]) && (mi_row & 0x01);
574 const int32_t col_adj = (xd->n8_w < mi_size_wide[BLOCK_8X8]) && (mi_col & 0x01);
575 int32_t processed_rows = 0;
576 int32_t processed_cols = 0;
577
578 av1_set_ref_frame(rf, ref_frame);
579 mode_context[ref_frame] = 0;
580 refmv_count[ref_frame] = 0;
581
582 // Find valid maximum row/col offset.
583 if (xd->up_available) {
584 max_row_offset = -(MVREF_ROWS << 1) + row_adj;
585
586 if (xd->n8_h < mi_size_high[BLOCK_8X8])
587 max_row_offset = -(2 << 1) + row_adj;
588
589 max_row_offset = find_valid_row_offset(tile, mi_row, max_row_offset);
590 }
591
592 if (xd->left_available) {
593 max_col_offset = -(MVREF_COLS << 1) + col_adj;
594
595 if (xd->n8_w < mi_size_wide[BLOCK_8X8])
596 max_col_offset = -(2 << 1) + col_adj;
597
598 max_col_offset = find_valid_col_offset(tile, mi_col, max_col_offset);
599 }
600
601 uint8_t ref_match_count[MODE_CTX_REF_FRAMES];
602 uint8_t col_match_count[MODE_CTX_REF_FRAMES];
603 uint8_t row_match_count[MODE_CTX_REF_FRAMES];
604 uint8_t newmv_count[MODE_CTX_REF_FRAMES] ;
605
606 ref_match_count[ref_frame] = 0;
607 col_match_count[ref_frame] = 0;
608 row_match_count[ref_frame] = 0;
609 newmv_count[ref_frame] = 0;
610
611 //CHKN------------- ROW-1
612
613 // Scan the first above row mode info. row_offset = -1;
614 if (abs(max_row_offset) >= 1)
615 scan_row_mbmi(cm,
616 xd,
617 mi_row,
618 mi_col,
619 rf,
620 -1,
621 ref_mv_stack,
622 refmv_count,
623 row_match_count,
624 newmv_count,
625 gm_mv_candidates,
626 gm_params,
627 max_row_offset,
628 &processed_rows);
629
630 //CHKN------------- COL-1
631 // Scan the first left column mode info. col_offset = -1;
632 if (abs(max_col_offset) >= 1)
633 scan_col_mbmi(cm,
634 xd,
635 mi_row,
636 mi_col,
637 rf,
638 -1,
639 ref_mv_stack,
640 refmv_count,
641 col_match_count,
642 newmv_count,
643 gm_mv_candidates,
644 gm_params,
645 max_col_offset,
646 &processed_cols);
647
648 //CHKN------------- TOP-RIGHT
649
650 // Check top-right boundary
651 if (has_tr)
652 scan_blk_mbmi(xd,
653 mi_row,
654 mi_col,
655 rf,
656 -1,
657 xd->n8_w,
658 ref_mv_stack,
659 row_match_count,
660 newmv_count,
661 gm_mv_candidates,
662 gm_params,
663 refmv_count);
664
665 uint8_t nearest_match[MODE_CTX_REF_FRAMES];
666 uint8_t nearest_refmv_count[MODE_CTX_REF_FRAMES];
667
668 nearest_match[ref_frame] = (row_match_count[ref_frame] > 0) + (col_match_count[ref_frame] > 0);
669 nearest_refmv_count[ref_frame] = refmv_count[ref_frame];
670
671 for (int32_t idx = 0; idx < nearest_refmv_count[ref_frame]; ++idx)
672 ref_mv_stack[ref_frame][idx].weight += REF_CAT_LEVEL;
673
674 //CHKN MFMV - get canididates from reference frames- orderHint has to be on, in order to scale the vectors.
675 if (pcs_ptr->parent_pcs_ptr->frm_hdr.use_ref_frame_mvs) {
676 int is_available = 0;
677
678
679 int blk_row_end ,blk_col_end,step_w, step_h , allow_extension;
680 if (ctx->sb64_sq_no4xn_geom) {
681 blk_row_end = xd->n4_w;
682 blk_col_end = xd->n4_w;
683 step_w = (xd->n4_w >= MI_SIZE_W_64X64) ? MI_SIZE_W_16X16 : MI_SIZE_W_8X8;
684 step_h = step_w;
685 allow_extension = (xd->n4_w >= MI_SIZE_W_8X8) && (xd->n4_w < MI_SIZE_W_64X64);
686 }
687 else {
688 blk_row_end = AOMMIN(xd->n4_h, mi_size_high[BLOCK_64X64]);
689 blk_col_end = AOMMIN(xd->n4_w, mi_size_wide[BLOCK_64X64]);
690 allow_extension = (xd->n4_h >= mi_size_high[BLOCK_8X8]) &&
691 (xd->n4_h < mi_size_high[BLOCK_64X64]) && (xd->n4_w >= mi_size_wide[BLOCK_8X8]) &&
692 (xd->n4_w < mi_size_wide[BLOCK_64X64]);
693 step_h = (xd->n4_h >= mi_size_high[BLOCK_64X64]) ? mi_size_high[BLOCK_16X16]
694 : mi_size_high[BLOCK_8X8];
695 step_w = (xd->n4_w >= mi_size_wide[BLOCK_64X64]) ? mi_size_wide[BLOCK_16X16]
696 : mi_size_high[BLOCK_8X8];
697 }
698
699
700 int cur_offset_0;
701 int cur_offset_1 = 0;
702 uint8_t list_idx0, list_idx1, ref_idx_l0, ref_idx_l1;
703 list_idx0 = get_list_idx(rf[0]);
704 ref_idx_l0 = get_ref_frame_idx(rf[0]);
705 if (rf[1] == NONE_FRAME) {
706 list_idx1 = get_list_idx(rf[0]);
707 ref_idx_l1 = get_ref_frame_idx(rf[0]);
708 }
709 else {
710 list_idx1 = get_list_idx(rf[1]);
711 ref_idx_l1 = get_ref_frame_idx(rf[1]);
712 }
713
714 const int cur_frame_index = pcs_ptr->parent_pcs_ptr->cur_order_hint;
715 EbReferenceObject *buf_0 = (EbReferenceObject *)pcs_ptr->ref_pic_ptr_array[list_idx0][ref_idx_l0]->object_ptr;
716 const int frame0_index = buf_0->order_hint;
717 cur_offset_0 = get_relative_dist(
718 &pcs_ptr->parent_pcs_ptr->scs_ptr->seq_header.order_hint_info,
719 cur_frame_index,
720 frame0_index);
721 if (rf[1] != NONE_FRAME) {
722 EbReferenceObject *buf_1 = (EbReferenceObject *)pcs_ptr->ref_pic_ptr_array[list_idx1][ref_idx_l1]->object_ptr;
723 const int frame1_index = buf_1->order_hint;
724 cur_offset_1 = get_relative_dist(
725 &pcs_ptr->parent_pcs_ptr->scs_ptr->seq_header.order_hint_info,
726 cur_frame_index,
727 frame1_index);
728 }
729
730
731 for (int blk_row = 0; blk_row < blk_row_end; blk_row += step_h) {
732 for (int blk_col = 0; blk_col < blk_col_end; blk_col += step_w) {
733 int ret = add_tpl_ref_mv(cm,
734 pcs_ptr,
735 xd,
736 mi_row,
737 mi_col,
738 ref_frame,
739 blk_row,
740 blk_col,
741 gm_mv_candidates,
742 &refmv_count[ref_frame],
743 symteric_refs,
744 mv_ref0,
745 cur_offset_0, cur_offset_1,
746 ref_mv_stack[ref_frame],
747
748 mode_context);
749 if (blk_row == 0 && blk_col == 0)
750 is_available = ret;
751
752 mv_ref0++;
753
754 }
755 }
756
757 if (is_available == 0)
758 mode_context[ref_frame] |= (1 << GLOBALMV_OFFSET);
759
760
761 if (allow_extension) {
762
763 int voffset, hoffset;
764 if (ctx->sb64_sq_no4xn_geom) {
765 voffset = xd->n4_h;
766 hoffset = voffset;
767 }
768 else {
769 voffset = AOMMAX(mi_size_high[BLOCK_8X8], xd->n4_h);
770 hoffset = AOMMAX(mi_size_wide[BLOCK_8X8], xd->n4_w);
771 }
772
773 const int tpl_sample_pos[3][2] = {
774 {voffset, -2},
775 {voffset, hoffset},
776 {voffset - 2, hoffset},
777 };
778 for (int i = 0; i < 3; ++i) {
779 const int blk_row = tpl_sample_pos[i][0];
780 const int blk_col = tpl_sample_pos[i][1];
781
782 if (!check_sb_border(mi_row, mi_col, blk_row, blk_col))
783 continue;
784 add_tpl_ref_mv(cm,
785 pcs_ptr,
786 xd,
787 mi_row,
788 mi_col,
789 ref_frame,
790 blk_row,
791 blk_col,
792 gm_mv_candidates,
793 &refmv_count[ref_frame],
794 symteric_refs,
795 mv_ref0,
796 cur_offset_0, cur_offset_1,
797 ref_mv_stack[ref_frame],
798
799 mode_context);
800
801 mv_ref0++;
802
803 }
804
805 }
806
807 }
808
809 //CHKN------------- TOP-LEFT
810 uint8_t dummy_newmv_count[MODE_CTX_REF_FRAMES] ;
811 dummy_newmv_count[ref_frame] = 0;
812
813 // Scan the second outer area.
814 scan_blk_mbmi(xd,
815 mi_row,
816 mi_col,
817 rf,
818 -1,
819 -1,
820 ref_mv_stack,
821 row_match_count,
822 dummy_newmv_count,
823 gm_mv_candidates,
824 gm_params,
825 refmv_count);
826
827 //CHKN------------- ROW-3 COL-3 ROW-5 COL-5
828 for (int32_t idx = 2; idx <= MVREF_ROWS; ++idx) {
829 const int32_t row_offset = -(idx << 1) + 1 + row_adj;
830 const int32_t col_offset = -(idx << 1) + 1 + col_adj;
831
832 if (abs(row_offset) <= abs(max_row_offset) && abs(row_offset) > processed_rows)
833 scan_row_mbmi(cm,
834 xd,
835 mi_row,
836 mi_col,
837 rf,
838 row_offset,
839 ref_mv_stack,
840 refmv_count,
841 row_match_count,
842 dummy_newmv_count,
843 gm_mv_candidates,
844 gm_params,
845 max_row_offset,
846 &processed_rows);
847
848 if (abs(col_offset) <= abs(max_col_offset) && abs(col_offset) > processed_cols)
849 scan_col_mbmi(cm,
850 xd,
851 mi_row,
852 mi_col,
853 rf,
854 col_offset,
855 ref_mv_stack,
856 refmv_count,
857 col_match_count,
858 dummy_newmv_count,
859 gm_mv_candidates,
860 gm_params,
861 max_col_offset,
862 &processed_cols);
863 }
864
865 //---------- Mode Context Derivation based on 3 counters -------------
866 ref_match_count[ref_frame] = (row_match_count[ref_frame] > 0) +
867 (col_match_count[ref_frame] > 0);
868
869 switch (nearest_match[ref_frame]) {
870 case 0:
871 mode_context[ref_frame] |= 0;
872 if (ref_match_count[ref_frame] >= 1)
873 mode_context[ref_frame] |= 1;
874 if (ref_match_count[ref_frame] == 1)
875 mode_context[ref_frame] |= (1 << REFMV_OFFSET);
876 else if (ref_match_count[ref_frame] >= 2)
877 mode_context[ref_frame] |= (2 << REFMV_OFFSET);
878 break;
879 case 1:
880 mode_context[ref_frame] |= (newmv_count[ref_frame] > 0) ? 2 : 3;
881 if (ref_match_count[ref_frame] == 1)
882 mode_context[ref_frame] |= (3 << REFMV_OFFSET);
883 else if (ref_match_count[ref_frame] >= 2)
884 mode_context[ref_frame] |= (4 << REFMV_OFFSET);
885 break;
886 case 2:
887 default:
888 if (newmv_count[ref_frame] >= 1)
889 mode_context[ref_frame] |= 4;
890 else
891 mode_context[ref_frame] |= 5;
892
893 mode_context[ref_frame] |= (5 << REFMV_OFFSET);
894 break;
895 }
896 //---------- Mode Context Derivation based on 3 counters -------------
897
898 // Rank the likelihood and assign nearest and near mvs.
899 int32_t len = nearest_refmv_count[ref_frame];
900 while (len > 0) {
901 int32_t nr_len = 0;
902 for (int32_t idx = 1; idx < len; ++idx) {
903 if (ref_mv_stack[ref_frame][idx - 1].weight < ref_mv_stack[ref_frame][idx].weight) {
904 CandidateMv tmp_mv = ref_mv_stack[ref_frame][idx - 1];
905 ref_mv_stack[ref_frame][idx - 1] = ref_mv_stack[ref_frame][idx];
906 ref_mv_stack[ref_frame][idx] = tmp_mv;
907 nr_len = idx;
908 }
909 }
910 len = nr_len;
911 }
912
913 len = refmv_count[ref_frame];
914 while (len > nearest_refmv_count[ref_frame]) {
915 int32_t nr_len = nearest_refmv_count[ref_frame];
916 for (int32_t idx = nearest_refmv_count[ref_frame] + 1; idx < len; ++idx) {
917 if (ref_mv_stack[ref_frame][idx - 1].weight < ref_mv_stack[ref_frame][idx].weight) {
918 CandidateMv tmp_mv = ref_mv_stack[ref_frame][idx - 1];
919 ref_mv_stack[ref_frame][idx - 1] = ref_mv_stack[ref_frame][idx];
920 ref_mv_stack[ref_frame][idx] = tmp_mv;
921 nr_len = idx;
922 }
923 }
924 len = nr_len;
925 }
926
927 //CHKN finish the Tables.
928
929 if (rf[1] > NONE_FRAME) {
930 //CHKN we get here only when refMVCount=0 or 1
931
932 if (refmv_count[ref_frame] < 2) {
933 IntMv ref_id[2][2], ref_diff[2][2];
934 int32_t ref_id_count[2] = {0}, ref_diff_count[2] = {0};
935
936 int32_t mi_width = AOMMIN(mi_size_wide[BLOCK_64X64], xd->n8_w);
937 mi_width = AOMMIN(mi_width, cm->mi_cols - mi_col);
938 int32_t mi_height = AOMMIN(mi_size_high[BLOCK_64X64], xd->n8_h);
939 mi_height = AOMMIN(mi_height, cm->mi_rows - mi_row);
940 int32_t mi_size = AOMMIN(mi_width, mi_height);
941
942 //CHKN scan ROW=-1 again but with more relaxed constraints
943 for (int32_t idx = 0; abs(max_row_offset) >= 1 && idx < mi_size;) {
944 const ModeInfo *const candidate_mi = xd->mi[-xd->mi_stride + idx];
945 const MbModeInfo *const candidate = &candidate_mi->mbmi;
946 const int32_t candidate_bsize = candidate->block_mi.sb_type;
947
948 for (int32_t rf_idx = 0; rf_idx < 2; ++rf_idx) {
949 MvReferenceFrame can_rf = candidate->block_mi.ref_frame[rf_idx];
950
951 for (int32_t cmp_idx = 0; cmp_idx < 2; ++cmp_idx) {
952 if (can_rf == rf[cmp_idx] && ref_id_count[cmp_idx] < 2) {
953 ref_id[cmp_idx][ref_id_count[cmp_idx]] = candidate->block_mi.mv[rf_idx];
954 ++ref_id_count[cmp_idx];
955 } else if (can_rf > INTRA_FRAME && ref_diff_count[cmp_idx] < 2) {
956 IntMv this_mv = candidate->block_mi.mv[rf_idx];
957 if (cm->ref_frame_sign_bias[can_rf] !=
958 cm->ref_frame_sign_bias[rf[cmp_idx]]) {
959 this_mv.as_mv.row = -this_mv.as_mv.row;
960 this_mv.as_mv.col = -this_mv.as_mv.col;
961 }
962 ref_diff[cmp_idx][ref_diff_count[cmp_idx]] = this_mv;
963 ++ref_diff_count[cmp_idx];
964 }
965 }
966 }
967 idx += mi_size_wide[candidate_bsize];
968 }
969
970 //CHKN scan COL=-1 again but with more relaxed constraints
971 for (int32_t idx = 0; abs(max_col_offset) >= 1 && idx < mi_size;) {
972 const ModeInfo *const candidate_mi = xd->mi[idx * xd->mi_stride - 1];
973 const MbModeInfo *const candidate = &candidate_mi->mbmi;
974 const int32_t candidate_bsize = candidate->block_mi.sb_type;
975
976 for (int32_t rf_idx = 0; rf_idx < 2; ++rf_idx) {
977 MvReferenceFrame can_rf = candidate->block_mi.ref_frame[rf_idx];
978
979 for (int32_t cmp_idx = 0; cmp_idx < 2; ++cmp_idx) {
980 if (can_rf == rf[cmp_idx] && ref_id_count[cmp_idx] < 2) {
981 ref_id[cmp_idx][ref_id_count[cmp_idx]] = candidate->block_mi.mv[rf_idx];
982 ++ref_id_count[cmp_idx];
983 } else if (can_rf > INTRA_FRAME && ref_diff_count[cmp_idx] < 2) {
984 IntMv this_mv = candidate->block_mi.mv[rf_idx];
985 if (cm->ref_frame_sign_bias[can_rf] !=
986 cm->ref_frame_sign_bias[rf[cmp_idx]]) {
987 this_mv.as_mv.row = -this_mv.as_mv.row;
988 this_mv.as_mv.col = -this_mv.as_mv.col;
989 }
990 ref_diff[cmp_idx][ref_diff_count[cmp_idx]] = this_mv;
991 ++ref_diff_count[cmp_idx];
992 }
993 }
994 }
995 idx += mi_size_high[candidate_bsize];
996 }
997
998 // Build up the compound mv predictor
999 IntMv comp_list[MAX_MV_REF_CANDIDATES + 1][2];
1000
1001 for (int32_t idx = 0; idx < 2; ++idx) {
1002 int32_t comp_idx = 0;
1003 for (int32_t list_idx = 0;
1004 list_idx < ref_id_count[idx] && comp_idx < MAX_MV_REF_CANDIDATES;
1005 ++list_idx, ++comp_idx)
1006 comp_list[comp_idx][idx] = ref_id[idx][list_idx];
1007 for (int32_t list_idx = 0;
1008 list_idx < ref_diff_count[idx] && comp_idx < MAX_MV_REF_CANDIDATES;
1009 ++list_idx, ++comp_idx)
1010 comp_list[comp_idx][idx] = ref_diff[idx][list_idx];
1011 for (; comp_idx < MAX_MV_REF_CANDIDATES; ++comp_idx)
1012 comp_list[comp_idx][idx] = gm_mv_candidates[idx];
1013 }
1014
1015 //CHKN fill the stack, increment the counter
1016 if (refmv_count[ref_frame]) { //CHKN RefMvCount=1
1017 assert(refmv_count[ref_frame] == 1);
1018 if (comp_list[0][0].as_int == ref_mv_stack[ref_frame][0].this_mv.as_int &&
1019 comp_list[0][1].as_int == ref_mv_stack[ref_frame][0].comp_mv.as_int) {
1020 ref_mv_stack[ref_frame][refmv_count[ref_frame]].this_mv = comp_list[1][0];
1021 ref_mv_stack[ref_frame][refmv_count[ref_frame]].comp_mv = comp_list[1][1];
1022 } else {
1023 ref_mv_stack[ref_frame][refmv_count[ref_frame]].this_mv = comp_list[0][0];
1024 ref_mv_stack[ref_frame][refmv_count[ref_frame]].comp_mv = comp_list[0][1];
1025 }
1026 ref_mv_stack[ref_frame][refmv_count[ref_frame]].weight = 2;
1027 ++refmv_count[ref_frame];
1028 } else { //CHKN RefMvCount=0
1029 for (int32_t idx = 0; idx < MAX_MV_REF_CANDIDATES; ++idx) {
1030 ref_mv_stack[ref_frame][refmv_count[ref_frame]].this_mv = comp_list[idx][0];
1031 ref_mv_stack[ref_frame][refmv_count[ref_frame]].comp_mv = comp_list[idx][1];
1032 ref_mv_stack[ref_frame][refmv_count[ref_frame]].weight = 2;
1033 ++refmv_count[ref_frame];
1034 }
1035 }
1036 }
1037
1038 assert(refmv_count[ref_frame] >= 2);
1039
1040 for (int32_t idx = 0; idx < refmv_count[ref_frame]; ++idx) {
1041 clamp_mv_ref(&ref_mv_stack[ref_frame][idx].this_mv.as_mv,
1042 xd->n8_w << MI_SIZE_LOG2,
1043 xd->n8_h << MI_SIZE_LOG2,
1044 xd);
1045 clamp_mv_ref(&ref_mv_stack[ref_frame][idx].comp_mv.as_mv,
1046 xd->n8_w << MI_SIZE_LOG2,
1047 xd->n8_h << MI_SIZE_LOG2,
1048 xd);
1049 }
1050 } else {
1051 // Handle single reference frame extension
1052 int32_t mi_width = AOMMIN(mi_size_wide[BLOCK_64X64], xd->n8_w);
1053 mi_width = AOMMIN(mi_width, cm->mi_cols - mi_col);
1054 int32_t mi_height = AOMMIN(mi_size_high[BLOCK_64X64], xd->n8_h);
1055 mi_height = AOMMIN(mi_height, cm->mi_rows - mi_row);
1056 int32_t mi_size = AOMMIN(mi_width, mi_height);
1057
1058 //CHKn if count is still < 2, re-scan ROW=-1 with less constraints.
1059 // Order is already fixed. the added candidates are stored as we go at the bottom of the Stack.
1060 //CHKN TODO: confirm this could be avoided if we have already 2(DRL:OFF), or 4(DRL:ON) candidates
1061 for (int32_t idx = 0; abs(max_row_offset) >= 1 && idx < mi_size &&
1062 refmv_count[ref_frame] < MAX_MV_REF_CANDIDATES;) {
1063 const ModeInfo *const candidate_mi = xd->mi[-xd->mi_stride + idx];
1064 const MbModeInfo *const candidate = &candidate_mi->mbmi;
1065 const int32_t candidate_bsize = candidate->block_mi.sb_type;
1066
1067 for (int32_t rf_idx = 0; rf_idx < 2; ++rf_idx) {
1068 if (candidate->block_mi.ref_frame[rf_idx] > INTRA_FRAME) {
1069 IntMv this_mv = candidate->block_mi.mv[rf_idx];
1070 if (cm->ref_frame_sign_bias[candidate->block_mi.ref_frame[rf_idx]] !=
1071 cm->ref_frame_sign_bias[ref_frame]) {
1072 this_mv.as_mv.row = -this_mv.as_mv.row;
1073 this_mv.as_mv.col = -this_mv.as_mv.col;
1074 }
1075 int32_t stack_idx;
1076 for (stack_idx = 0; stack_idx < refmv_count[ref_frame]; ++stack_idx) {
1077 IntMv stack_mv = ref_mv_stack[ref_frame][stack_idx].this_mv;
1078 if (this_mv.as_int == stack_mv.as_int)
1079 break;
1080 }
1081
1082 if (stack_idx == refmv_count[ref_frame]) {
1083 ref_mv_stack[ref_frame][stack_idx].this_mv = this_mv;
1084
1085 ref_mv_stack[ref_frame][stack_idx].weight = 2;
1086 ++refmv_count[ref_frame];
1087 }
1088 }
1089 }
1090 idx += mi_size_wide[candidate_bsize];
1091 }
1092
1093 //CHKn if count is still < 2, re-scan COL=-1 with less constraints. the added candidates are stored as we go at the bottom of the Stack.
1094 for (int32_t idx = 0; abs(max_col_offset) >= 1 && idx < mi_size &&
1095 refmv_count[ref_frame] < MAX_MV_REF_CANDIDATES;) {
1096 const ModeInfo *const candidate_mi = xd->mi[idx * xd->mi_stride - 1];
1097 const MbModeInfo *const candidate = &candidate_mi->mbmi;
1098 const int32_t candidate_bsize = candidate->block_mi.sb_type;
1099
1100 for (int32_t rf_idx = 0; rf_idx < 2; ++rf_idx) {
1101 if (candidate->block_mi.ref_frame[rf_idx] > INTRA_FRAME) {
1102 IntMv this_mv = candidate->block_mi.mv[rf_idx];
1103 if (cm->ref_frame_sign_bias[candidate->block_mi.ref_frame[rf_idx]] !=
1104 cm->ref_frame_sign_bias[ref_frame]) {
1105 this_mv.as_mv.row = -this_mv.as_mv.row;
1106 this_mv.as_mv.col = -this_mv.as_mv.col;
1107 }
1108 int32_t stack_idx;
1109 for (stack_idx = 0; stack_idx < refmv_count[ref_frame]; ++stack_idx) {
1110 IntMv stack_mv = ref_mv_stack[ref_frame][stack_idx].this_mv;
1111 if (this_mv.as_int == stack_mv.as_int)
1112 break;
1113 }
1114
1115 if (stack_idx == refmv_count[ref_frame]) {
1116 ref_mv_stack[ref_frame][stack_idx].this_mv = this_mv;
1117
1118 ref_mv_stack[ref_frame][stack_idx].weight = 2;
1119 ++refmv_count[ref_frame];
1120 }
1121 }
1122 }
1123 idx += mi_size_high[candidate_bsize];
1124 }
1125
1126 //CHKN THIS IS a Single Reference case
1127
1128 //CHKN if the stack has at least 2 cand, then copy the top 2 to the final mvp Table,
1129 // if the stack has less than 2, use Gm to fill the mvpTable.
1130 // the stack counter remains 0 or 1 in this case.
1131
1132 for (int32_t idx = refmv_count[ref_frame]; idx < MAX_MV_REF_CANDIDATES; ++idx)
1133 mv_ref_list[rf[0]][idx].as_int = gm_mv_candidates[0].as_int;
1134
1135 for (int32_t idx = 0; idx < refmv_count[ref_frame]; ++idx) {
1136 clamp_mv_ref(&ref_mv_stack[ref_frame][idx].this_mv.as_mv,
1137 xd->n8_w << MI_SIZE_LOG2,
1138 xd->n8_h << MI_SIZE_LOG2,
1139 xd);
1140 }
1141
1142 for (int32_t idx = 0; idx < AOMMIN(MAX_MV_REF_CANDIDATES, refmv_count[ref_frame]); ++idx) {
1143 mv_ref_list[rf[0]][idx].as_int = ref_mv_stack[ref_frame][idx].this_mv.as_int;
1144 }
1145 }
1146 (void)nearest_match;
1147 }
1148
block_center_x(int mi_col,BlockSize bs)1149 static INLINE int block_center_x(int mi_col, BlockSize bs) {
1150 const int bw = block_size_wide[bs];
1151 return mi_col * MI_SIZE + bw / 2 - 1;
1152 }
1153
block_center_y(int mi_row,BlockSize bs)1154 static INLINE int block_center_y(int mi_row, BlockSize bs) {
1155 const int bh = block_size_high[bs];
1156 return mi_row * MI_SIZE + bh / 2 - 1;
1157 }
1158
gm_get_motion_vector_enc(const EbWarpedMotionParams * gm,int32_t allow_hp,BlockSize bsize,int32_t mi_col,int32_t mi_row,int32_t is_integer)1159 IntMv gm_get_motion_vector_enc(const EbWarpedMotionParams *gm, int32_t allow_hp, BlockSize bsize,
1160 int32_t mi_col, int32_t mi_row, int32_t is_integer) {
1161 IntMv res;
1162
1163 if (gm->wmtype == IDENTITY) {
1164 res.as_int = 0;
1165 return res;
1166 }
1167
1168 const int32_t *mat = gm->wmmat;
1169 int x, y, tx, ty;
1170
1171 if (gm->wmtype == TRANSLATION) {
1172 // All global motion vectors are stored with WARPEDMODEL_PREC_BITS (16)
1173 // bits of fractional precision. The offset for a translation is stored in
1174 // entries 0 and 1. For translations, all but the top three (two if
1175 // cm->allow_high_precision_mv is false) fractional bits are always zero.
1176 //
1177 // After the right shifts, there are 3 fractional bits of precision. If
1178 // allow_hp is false, the bottom bit is always zero (so we don't need a
1179 // call to convert_to_trans_prec here)
1180 res.as_mv.row = gm->wmmat[0] >> GM_TRANS_ONLY_PREC_DIFF;
1181 res.as_mv.col = gm->wmmat[1] >> GM_TRANS_ONLY_PREC_DIFF;
1182 assert(IMPLIES(1 & (res.as_mv.row | res.as_mv.col), allow_hp));
1183 if (is_integer) {
1184 integer_mv_precision(&res.as_mv);
1185 }
1186 return res;
1187 }
1188
1189 x = block_center_x(mi_col, bsize);
1190 y = block_center_y(mi_row, bsize);
1191
1192 if (gm->wmtype == ROTZOOM) {
1193 assert(gm->wmmat[5] == gm->wmmat[2]);
1194 assert(gm->wmmat[4] == -gm->wmmat[3]);
1195 }
1196
1197 const int xc = (mat[2] - (1 << WARPEDMODEL_PREC_BITS)) * x + mat[3] * y + mat[0];
1198 const int yc = mat[4] * x + (mat[5] - (1 << WARPEDMODEL_PREC_BITS)) * y + mat[1];
1199 tx = convert_to_trans_prec(allow_hp, xc);
1200 ty = convert_to_trans_prec(allow_hp, yc);
1201
1202 res.as_mv.row = ty;
1203 res.as_mv.col = tx;
1204
1205 if (is_integer) {
1206 integer_mv_precision(&res.as_mv);
1207 }
1208 return res;
1209 }
init_xd(PictureControlSet * pcs_ptr,ModeDecisionContext * context_ptr)1210 void init_xd(PictureControlSet *pcs_ptr, ModeDecisionContext *context_ptr) {
1211 TileInfo *tile = &context_ptr->sb_ptr->tile_info;
1212
1213 int32_t mi_row = context_ptr->blk_origin_y >> MI_SIZE_LOG2;
1214 int32_t mi_col = context_ptr->blk_origin_x >> MI_SIZE_LOG2;
1215 Av1Common * cm = pcs_ptr->parent_pcs_ptr->av1_cm;
1216 MacroBlockD * xd = context_ptr->blk_ptr->av1xd;
1217 BlockSize bsize = context_ptr->blk_geom->bsize;
1218 const int32_t bw = mi_size_wide[bsize];
1219 const int32_t bh = mi_size_high[bsize];
1220
1221 xd->n4_w = context_ptr->blk_geom->bwidth >> MI_SIZE_LOG2;
1222 xd->n4_h = context_ptr->blk_geom->bheight >> MI_SIZE_LOG2;
1223
1224 xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8);
1225 xd->mb_to_bottom_edge = ((cm->mi_rows - bh - mi_row) * MI_SIZE) * 8;
1226 xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8);
1227 xd->mb_to_right_edge = ((cm->mi_cols - bw - mi_col) * MI_SIZE) * 8;
1228 xd->mi_row = -xd->mb_to_top_edge / (8 * MI_SIZE);
1229 xd->mi_col = -xd->mb_to_left_edge / (8 * MI_SIZE);
1230 xd->up_available = (mi_row > tile->mi_row_start);
1231 xd->left_available = (mi_col > tile->mi_col_start);
1232
1233 xd->n8_h = bh;
1234 xd->n8_w = bw;
1235 xd->is_sec_rect = 0;
1236 if (xd->n8_w < xd->n8_h) {
1237 // Only mark is_sec_rect as 1 for the last block.
1238 // For PARTITION_VERT_4, it would be (0, 0, 0, 1);
1239 // For other partitions, it would be (0, 1).
1240 if (!((mi_col + xd->n8_w) & (xd->n8_h - 1)))
1241 xd->is_sec_rect = 1;
1242 }
1243
1244 if (xd->n8_w > xd->n8_h)
1245 if (mi_row & (xd->n8_w - 1))
1246 xd->is_sec_rect = 1;
1247
1248 xd->tile.mi_col_start = tile->mi_col_start;
1249 xd->tile.mi_col_end = tile->mi_col_end;
1250 xd->tile.mi_row_start = tile->mi_row_start;
1251 xd->tile.mi_row_end = tile->mi_row_end;
1252
1253 xd->mi_stride = pcs_ptr->mi_stride;
1254 const int32_t offset = mi_row * xd->mi_stride + mi_col;
1255 pcs_ptr->mi_grid_base[offset] = pcs_ptr->mip + offset;
1256 xd->mi = pcs_ptr->mi_grid_base + offset;
1257
1258 //ModeInfo *mi_ptr = xd->mi[-(xd->mi_stride)]; /*&xd->mi[-xd->mi_stride]->mbmi*/
1259 xd->above_mbmi = (xd->up_available) ? &xd->mi[-(xd->mi_stride)]->mbmi : NULL;
1260 //mi_ptr = xd->mi[-1];
1261 xd->left_mbmi = (xd->left_available) ? &xd->mi[-1]->mbmi : NULL;
1262 if (!context_ptr->skip_intra) {
1263 const uint8_t ss_x = 1, ss_y = 1;
1264 xd->chroma_up_available = bh < 2 /*mi_size_wide[BLOCK_8X8]*/ ? (mi_row - 1) > xd->tile.mi_row_start : xd->up_available;
1265 xd->chroma_left_available = bw < 2 /*mi_size_high[BLOCK_8X8]*/ ? (mi_col - 1) > xd->tile.mi_col_start : xd->left_available;
1266
1267 const int chroma_ref = ((mi_row & 0x01) || !(bh & 0x01)) &&
1268 ((mi_col & 0x01) || !(bw & 0x01));
1269
1270 // To help calculate the "above" and "left" chroma blocks, note that the
1271 // current block may cover multiple luma blocks (eg, if partitioned into
1272 // 4x4 luma blocks).
1273 // First, find the top-left-most luma block covered by this chroma block
1274 int32_t base_mbmi_offset = -(mi_row & ss_y) * xd->mi_stride - (mi_col & ss_x);
1275
1276 // Then, we consider the luma region covered by the left or above 4x4 chroma
1277 // prediction. We want to point to the chroma reference block in that
1278 // region, which is the bottom-right-most mi unit.
1279 // This leads to the following offsets:
1280 xd->chroma_above_mbmi = (xd->chroma_up_available && chroma_ref)
1281 ? &xd->mi[base_mbmi_offset - xd->mi_stride + ss_x]->mbmi
1282 : NULL;
1283
1284 xd->chroma_left_mbmi = (xd->chroma_left_available && chroma_ref)
1285 ? &xd->mi[base_mbmi_offset + ss_y * xd->mi_stride - 1]->mbmi
1286 : NULL;
1287 }
1288 xd->mi[0]->mbmi.block_mi.partition = from_shape_to_part[context_ptr->blk_geom->shape];
1289 }
1290
generate_av1_mvp_table(ModeDecisionContext * context_ptr,BlkStruct * blk_ptr,const BlockGeom * blk_geom,uint16_t blk_origin_x,uint16_t blk_origin_y,MvReferenceFrame * ref_frames,uint32_t tot_refs,PictureControlSet * pcs_ptr)1291 void generate_av1_mvp_table(ModeDecisionContext *context_ptr, BlkStruct *blk_ptr,
1292 const BlockGeom *blk_geom, uint16_t blk_origin_x, uint16_t blk_origin_y,
1293 MvReferenceFrame *ref_frames, uint32_t tot_refs,
1294 PictureControlSet *pcs_ptr) {
1295 int32_t mi_row = blk_origin_y >> MI_SIZE_LOG2;
1296 int32_t mi_col = blk_origin_x >> MI_SIZE_LOG2;
1297 Av1Common * cm = pcs_ptr->parent_pcs_ptr->av1_cm;
1298 FrameHeader *frm_hdr = &pcs_ptr->parent_pcs_ptr->frm_hdr;
1299 MacroBlockD *xd = blk_ptr->av1xd;
1300 BlockSize bsize = blk_geom->bsize;
1301
1302 uint8_t symteric_refs = 0;
1303 IntMv mv_ref0[64];
1304 if (pcs_ptr->temporal_layer_index>0)
1305 if(tot_refs == 3 && ref_frames[0] == LAST_FRAME && ref_frames[1] == BWDREF_FRAME && ref_frames[2] == LAST_BWD_FRAME)
1306 symteric_refs = 1;
1307
1308 //128x128 OFF, 4xN OFF, SQ only
1309
1310
1311 uint32_t ref_it;
1312 for (ref_it = 0; ref_it < tot_refs; ++ref_it) {
1313 MvReferenceFrame ref_frame = ref_frames[ref_it];
1314
1315 xd->ref_mv_count[ref_frame] = 0;
1316 memset(context_ptr->md_local_blk_unit[blk_geom->blkidx_mds].ed_ref_mv_stack[ref_frame],
1317 0, sizeof(CandidateMv)*MAX_REF_MV_STACK_SIZE);
1318
1319
1320 MvReferenceFrame rf[2];
1321 av1_set_ref_frame(rf, ref_frame);
1322
1323 IntMv gm_mv[2];
1324
1325 if (ref_frame == INTRA_FRAME) {
1326 gm_mv[0].as_int = gm_mv[1].as_int = 0;
1327 } else {
1328 if (ref_frame < REF_FRAMES) {
1329 gm_mv[0] = gm_get_motion_vector_enc(
1330 &pcs_ptr->parent_pcs_ptr->global_motion[ref_frame],
1331 frm_hdr->allow_high_precision_mv,
1332 bsize,
1333 mi_col,
1334 mi_row,
1335 frm_hdr->force_integer_mv);
1336 gm_mv[1].as_int = 0;
1337 } else {
1338 gm_mv[0] = gm_get_motion_vector_enc(&pcs_ptr->parent_pcs_ptr->global_motion[rf[0]],
1339 frm_hdr->allow_high_precision_mv,
1340 bsize,
1341 mi_col,
1342 mi_row,
1343 frm_hdr->force_integer_mv);
1344 gm_mv[1] = gm_get_motion_vector_enc(&pcs_ptr->parent_pcs_ptr->global_motion[rf[1]],
1345 frm_hdr->allow_high_precision_mv,
1346 bsize,
1347 mi_col,
1348 mi_row,
1349 frm_hdr->force_integer_mv);
1350 }
1351 }
1352
1353 setup_ref_mv_list(pcs_ptr,
1354 cm,
1355 xd,
1356 ref_frame,
1357 xd->ref_mv_count,
1358 context_ptr->md_local_blk_unit[blk_geom->blkidx_mds].ed_ref_mv_stack,
1359 context_ptr->md_local_blk_unit[context_ptr->blk_geom->blkidx_mds].ref_mvs,
1360 gm_mv,
1361 pcs_ptr->parent_pcs_ptr->global_motion,
1362 mi_row,
1363 mi_col,
1364 context_ptr,
1365 symteric_refs,
1366 mv_ref0,
1367 blk_ptr->inter_mode_ctx);
1368 }
1369 }
get_av1_mv_pred_drl(ModeDecisionContext * context_ptr,BlkStruct * blk_ptr,MvReferenceFrame ref_frame,uint8_t is_compound,PredictionMode mode,uint8_t drl_index,IntMv nearestmv[2],IntMv nearmv[2],IntMv ref_mv[2])1370 void get_av1_mv_pred_drl(ModeDecisionContext *context_ptr, BlkStruct *blk_ptr,
1371 MvReferenceFrame ref_frame, uint8_t is_compound, PredictionMode mode,
1372 uint8_t drl_index, //valid value of drl_index
1373 IntMv nearestmv[2], IntMv nearmv[2], IntMv ref_mv[2]) {
1374 MacroBlockD *xd = blk_ptr->av1xd;
1375
1376 if (!is_compound && mode != GLOBALMV) {
1377 //av1_find_best_ref_mvs(allow_hp, ref_mvs[mbmi->ref_frame[0]], &nearestmv[0], &nearmv[0], cm->cur_frame_force_integer_mv);
1378 nearestmv[0] =
1379 context_ptr->md_local_blk_unit[context_ptr->blk_geom->blkidx_mds].ref_mvs[ref_frame][0];
1380 nearmv[0] =
1381 context_ptr->md_local_blk_unit[context_ptr->blk_geom->blkidx_mds].ref_mvs[ref_frame][1];
1382 }
1383
1384 if (is_compound && mode != GLOBAL_GLOBALMV) {
1385 int32_t ref_mv_idx = drl_index + 1;
1386 nearestmv[0] =
1387 context_ptr->md_local_blk_unit[blk_ptr->mds_idx].ed_ref_mv_stack[ref_frame][0].this_mv;
1388 nearestmv[1] =
1389 context_ptr->md_local_blk_unit[blk_ptr->mds_idx].ed_ref_mv_stack[ref_frame][0].comp_mv;
1390 nearmv[0] = context_ptr->md_local_blk_unit[blk_ptr->mds_idx]
1391 .ed_ref_mv_stack[ref_frame][ref_mv_idx]
1392 .this_mv;
1393 nearmv[1] = context_ptr->md_local_blk_unit[blk_ptr->mds_idx]
1394 .ed_ref_mv_stack[ref_frame][ref_mv_idx]
1395 .comp_mv;
1396 } else if (drl_index > 0 && mode == NEARMV) {
1397 assert((1 + drl_index) < MAX_REF_MV_STACK_SIZE);
1398 IntMv cur_mv = context_ptr->md_local_blk_unit[blk_ptr->mds_idx]
1399 .ed_ref_mv_stack[ref_frame][1 + drl_index]
1400 .this_mv;
1401 nearmv[0] = cur_mv;
1402 }
1403
1404 ref_mv[0] = nearestmv[0];
1405 ref_mv[1] = nearestmv[1];
1406
1407 if (is_compound) {
1408 int32_t ref_mv_idx = drl_index;
1409 // Special case: NEAR_NEWMV and NEW_NEARMV modes use
1410 // 1 + mbmi->ref_mv_idx (like NEARMV) instead of
1411 // mbmi->ref_mv_idx (like NEWMV)
1412 if (mode == NEAR_NEWMV || mode == NEW_NEARMV)
1413 ref_mv_idx = 1 + drl_index;
1414
1415 if (compound_ref0_mode(mode) == NEWMV)
1416 ref_mv[0] = context_ptr->md_local_blk_unit[blk_ptr->mds_idx]
1417 .ed_ref_mv_stack[ref_frame][ref_mv_idx]
1418 .this_mv;
1419
1420 if (compound_ref1_mode(mode) == NEWMV)
1421 ref_mv[1] = context_ptr->md_local_blk_unit[blk_ptr->mds_idx]
1422 .ed_ref_mv_stack[ref_frame][ref_mv_idx]
1423 .comp_mv;
1424 } else {
1425 if (mode == NEWMV) {
1426 if (xd->ref_mv_count[ref_frame] > 1)
1427 ref_mv[0] = context_ptr->md_local_blk_unit[blk_ptr->mds_idx]
1428 .ed_ref_mv_stack[ref_frame][drl_index]
1429 .this_mv;
1430 }
1431 }
1432 }
update_mi_map_skip_settings(BlkStruct * blk_ptr)1433 void update_mi_map_skip_settings(BlkStruct *blk_ptr) {
1434
1435 // Update only the data in the top left block of the partition, because all other mi_blocks
1436 // point to the top left mi block of the partition
1437 blk_ptr->av1xd->mi[0]->mbmi.block_mi.skip = blk_ptr->block_has_coeff ? EB_FALSE : EB_TRUE;
1438 blk_ptr->av1xd->mi[0]->mbmi.block_mi.skip_mode = (int8_t)blk_ptr->skip_flag;
1439 }
update_mi_map(BlkStruct * blk_ptr,uint32_t blk_origin_x,uint32_t blk_origin_y,const BlockGeom * blk_geom,uint8_t avail_blk_flag,PictureControlSet * pcs_ptr)1440 void update_mi_map(BlkStruct* blk_ptr, uint32_t blk_origin_x, uint32_t blk_origin_y,
1441 const BlockGeom* blk_geom, uint8_t avail_blk_flag, PictureControlSet* pcs_ptr) {
1442 uint32_t mi_stride = pcs_ptr->mi_stride;
1443 int32_t mi_row = blk_origin_y >> MI_SIZE_LOG2;
1444 int32_t mi_col = blk_origin_x >> MI_SIZE_LOG2;
1445
1446 const int32_t offset = mi_row * mi_stride + mi_col;
1447 // Reset the mi_grid (needs to be done here in case it was changed for NSQ blocks during MD - init_xd())
1448 pcs_ptr->mi_grid_base[offset] = pcs_ptr->mip + offset;
1449 ModeInfo * mi_ptr = *(pcs_ptr->mi_grid_base + offset);
1450 MvReferenceFrame rf[2] = {0, 0};
1451 if (avail_blk_flag)
1452 av1_set_ref_frame(rf, blk_ptr->prediction_unit_array->ref_frame_type);
1453
1454 uint8_t mi_x, mi_y;
1455
1456 for (mi_y = 0; mi_y < (blk_geom->bheight >> MI_SIZE_LOG2); mi_y++) {
1457 for (mi_x = 0; mi_x < (blk_geom->bwidth >> MI_SIZE_LOG2); mi_x++) {
1458
1459 const int32_t mi_idx = mi_x + mi_y * mi_stride;
1460 if (mi_idx != 0) {
1461 pcs_ptr->mi_grid_base[offset + mi_idx] = pcs_ptr->mi_grid_base[offset];
1462 continue;
1463 }
1464 MbModeInfo* mbmi = &mi_ptr[mi_idx].mbmi;
1465 BlockModeInfo* block_mi = &mi_ptr[mi_idx].mbmi.block_mi;
1466 // copy mbmi data
1467 mbmi->tx_size = (avail_blk_flag && blk_ptr->prediction_mode_flag == INTRA_MODE && blk_ptr->pred_mode == INTRA_MODE_4x4)
1468 ? 0 :
1469 blk_geom->txsize[blk_ptr->tx_depth][0]; // inherit tx_size from 1st transform block;
1470 mbmi->tx_depth = blk_ptr->tx_depth;
1471 mbmi->comp_group_idx = blk_ptr->comp_group_idx;
1472 if (pcs_ptr->parent_pcs_ptr->frm_hdr.allow_screen_content_tools)
1473 svt_memcpy(&mbmi->palette_mode_info,
1474 &blk_ptr->palette_info.pmi,
1475 sizeof(PaletteModeInfo));
1476
1477 // The data copied into each mi block is the same; therefore, copy the data from the blk_ptr only for the first block_mi
1478 // then use memcpy to copy the first block_mi into the rest (more efficient than assignments from blk_ptr). All data that
1479 // is used from block_mi should be updated here.
1480 if (mi_idx == 0){
1481 block_mi->sb_type = (avail_blk_flag && blk_ptr->prediction_mode_flag == INTRA_MODE && blk_ptr->pred_mode == INTRA_MODE_4x4) ? BLOCK_4X4 : blk_geom->bsize;
1482 block_mi->mode = blk_ptr->pred_mode;
1483 block_mi->skip = (avail_blk_flag && blk_ptr->block_has_coeff) ? EB_FALSE : EB_TRUE;
1484 block_mi->partition = from_shape_to_part[blk_geom->shape];
1485 block_mi->skip_mode = (int8_t)blk_ptr->skip_flag;
1486 block_mi->segment_id = blk_ptr->segment_id;
1487 block_mi->seg_id_predicted = blk_ptr->seg_id_predicted;
1488 block_mi->uv_mode = blk_ptr->prediction_unit_array->intra_chroma_mode;
1489 block_mi->use_intrabc = blk_ptr->use_intrabc;
1490 block_mi->ref_frame[0] = rf[0];
1491 block_mi->ref_frame[1] = (avail_blk_flag && blk_ptr->is_interintra_used) ? INTRA_FRAME : rf[1];
1492
1493 if (avail_blk_flag) {
1494 if (blk_ptr->prediction_unit_array->inter_pred_direction_index ==
1495 UNI_PRED_LIST_0) {
1496 block_mi->mv[0].as_mv.col =
1497 blk_ptr->prediction_unit_array->mv[0].x;
1498 block_mi->mv[0].as_mv.row =
1499 blk_ptr->prediction_unit_array->mv[0].y;
1500 }
1501 else if (blk_ptr->prediction_unit_array->inter_pred_direction_index ==
1502 UNI_PRED_LIST_1) {
1503 block_mi->mv[0].as_mv.col =
1504 blk_ptr->prediction_unit_array->mv[1].x;
1505 block_mi->mv[0].as_mv.row =
1506 blk_ptr->prediction_unit_array->mv[1].y;
1507 }
1508 else {
1509 block_mi->mv[0].as_mv.col =
1510 blk_ptr->prediction_unit_array->mv[0].x;
1511 block_mi->mv[0].as_mv.row =
1512 blk_ptr->prediction_unit_array->mv[0].y;
1513 block_mi->mv[1].as_mv.col =
1514 blk_ptr->prediction_unit_array->mv[1].x;
1515 block_mi->mv[1].as_mv.row =
1516 blk_ptr->prediction_unit_array->mv[1].y;
1517 }
1518 }
1519
1520 block_mi->ref_mv_idx = blk_ptr->drl_index;
1521
1522 block_mi->interintra_mode_params.interintra_mode = blk_ptr->interintra_mode;
1523 block_mi->interintra_mode_params.wedge_interintra = blk_ptr->use_wedge_interintra;
1524 block_mi->interintra_mode_params.interintra_wedge_index = blk_ptr->interintra_wedge_index;
1525
1526 block_mi->motion_mode = blk_ptr->prediction_unit_array[0].motion_mode;
1527 block_mi->compound_idx = blk_ptr->compound_idx;
1528 block_mi->interp_filters = blk_ptr->interp_filters;
1529 block_mi->cfl_alpha_idx = blk_ptr->prediction_unit_array->cfl_alpha_idx;
1530 block_mi->cfl_alpha_signs = blk_ptr->prediction_unit_array->cfl_alpha_signs;
1531 block_mi->angle_delta[PLANE_TYPE_Y] = blk_ptr->prediction_unit_array[0].angle_delta[PLANE_TYPE_Y];
1532 block_mi->angle_delta[PLANE_TYPE_UV] = blk_ptr->prediction_unit_array[0].angle_delta[PLANE_TYPE_UV];
1533 }
1534 else {
1535 BlockModeInfo* block_mi_idx0 = &mi_ptr[0].mbmi.block_mi;
1536 svt_memcpy(block_mi, block_mi_idx0, sizeof(BlockModeInfo));
1537 }
1538 }
1539 }
1540 }
record_samples(MbModeInfo * mbmi,int * pts,int * pts_inref,int row_offset,int sign_r,int col_offset,int sign_c)1541 static INLINE void record_samples(MbModeInfo *mbmi, int *pts, int *pts_inref, int row_offset,
1542 int sign_r, int col_offset, int sign_c) {
1543 uint8_t bw = block_size_wide[mbmi->block_mi.sb_type];
1544 uint8_t bh = block_size_high[mbmi->block_mi.sb_type];
1545 int x = col_offset * MI_SIZE + sign_c * AOMMAX(bw, MI_SIZE) / 2 - 1;
1546 int y = row_offset * MI_SIZE + sign_r * AOMMAX(bh, MI_SIZE) / 2 - 1;
1547
1548 pts[0] = (x * 8);
1549 pts[1] = (y * 8);
1550 pts_inref[0] = (x * 8) + mbmi->block_mi.mv[0].as_mv.col;
1551 pts_inref[1] = (y * 8) + mbmi->block_mi.mv[0].as_mv.row;
1552 }
1553
1554 // Note: Samples returned are at 1/8-pel precision
1555 // Sample are the neighbor block center point's coordinates relative to the
1556 // left-top pixel of current block.
av1_find_samples(const Av1Common * cm,const BlockSize sb_size,MacroBlockD * xd,int mi_row,int mi_col,MvReferenceFrame rf0,int * pts,int * pts_inref)1557 int av1_find_samples(const Av1Common *cm, const BlockSize sb_size, MacroBlockD *xd, int mi_row,
1558 int mi_col, MvReferenceFrame rf0, int *pts, int *pts_inref) {
1559 int up_available = xd->up_available;
1560 int left_available = xd->left_available;
1561 int i, mi_step = 1, np = 0;
1562
1563 const TileInfo *const tile = &xd->tile;
1564 int do_tl = 1;
1565 int do_tr = 1;
1566
1567 // scan the nearest above rows
1568 if (up_available) {
1569 int mi_row_offset = -1;
1570 MbModeInfo *mbmi = &xd->mi[mi_row_offset * xd->mi_stride]->mbmi;
1571 uint8_t n4_w = mi_size_wide[mbmi->block_mi.sb_type];
1572
1573 if (xd->n4_w <= n4_w) {
1574 // Handle "current block width <= above block width" case.
1575 int col_offset = -mi_col % n4_w;
1576
1577 if (col_offset < 0)
1578 do_tl = 0;
1579 if (col_offset + n4_w > xd->n4_w)
1580 do_tr = 0;
1581
1582 if (mbmi->block_mi.ref_frame[0] == rf0 && mbmi->block_mi.ref_frame[1] == NONE_FRAME) {
1583 record_samples(mbmi, pts, pts_inref, 0, -1, col_offset, 1);
1584 pts += 2;
1585 pts_inref += 2;
1586 np++;
1587 if (np >= LEAST_SQUARES_SAMPLES_MAX)
1588 return LEAST_SQUARES_SAMPLES_MAX;
1589 }
1590 } else {
1591 // Handle "current block width > above block width" case.
1592 for (i = 0; i < AOMMIN(xd->n4_w, cm->mi_cols - mi_col); i += mi_step) {
1593 int mi_col_offset = i;
1594 mbmi = &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
1595 n4_w = mi_size_wide[mbmi->block_mi.sb_type];
1596 mi_step = AOMMIN(xd->n4_w, n4_w);
1597
1598 if (mbmi->block_mi.ref_frame[0] == rf0 &&
1599 mbmi->block_mi.ref_frame[1] == NONE_FRAME) {
1600 record_samples(mbmi, pts, pts_inref, 0, -1, i, 1);
1601 pts += 2;
1602 pts_inref += 2;
1603 np++;
1604 if (np >= LEAST_SQUARES_SAMPLES_MAX)
1605 return LEAST_SQUARES_SAMPLES_MAX;
1606 }
1607 }
1608 }
1609 }
1610
1611 // scan the nearest left columns
1612 if (left_available) {
1613 int mi_col_offset = -1;
1614 MbModeInfo *mbmi = &xd->mi[mi_col_offset]->mbmi;
1615 uint8_t n4_h = mi_size_high[mbmi->block_mi.sb_type];
1616
1617 if (xd->n4_h <= n4_h) {
1618 // Handle "current block height <= above block height" case.
1619 int row_offset = -mi_row % n4_h;
1620 if (row_offset < 0)
1621 do_tl = 0;
1622
1623 if (mbmi->block_mi.ref_frame[0] == rf0 && mbmi->block_mi.ref_frame[1] == NONE_FRAME) {
1624 record_samples(mbmi, pts, pts_inref, row_offset, 1, 0, -1);
1625 pts += 2;
1626 pts_inref += 2;
1627 np++;
1628 if (np >= LEAST_SQUARES_SAMPLES_MAX)
1629 return LEAST_SQUARES_SAMPLES_MAX;
1630 }
1631 } else {
1632 // Handle "current block height > above block height" case.
1633 for (i = 0; i < AOMMIN(xd->n4_h, cm->mi_rows - mi_row); i += mi_step) {
1634 int mi_row_offset = i;
1635 mbmi = &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
1636 n4_h = mi_size_high[mbmi->block_mi.sb_type];
1637 mi_step = AOMMIN(xd->n4_h, n4_h);
1638
1639 if (mbmi->block_mi.ref_frame[0] == rf0 &&
1640 mbmi->block_mi.ref_frame[1] == NONE_FRAME) {
1641 record_samples(mbmi, pts, pts_inref, i, 1, 0, -1);
1642 pts += 2;
1643 pts_inref += 2;
1644 np++;
1645 if (np >= LEAST_SQUARES_SAMPLES_MAX)
1646 return LEAST_SQUARES_SAMPLES_MAX;
1647 }
1648 }
1649 }
1650 }
1651
1652 // Top-left block
1653 if (do_tl && left_available && up_available) {
1654 int mi_row_offset = -1;
1655 int mi_col_offset = -1;
1656 MbModeInfo *mbmi = &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
1657
1658 if (mbmi->block_mi.ref_frame[0] == rf0 && mbmi->block_mi.ref_frame[1] == NONE_FRAME) {
1659 record_samples(mbmi, pts, pts_inref, 0, -1, 0, -1);
1660 pts += 2;
1661 pts_inref += 2;
1662 np++;
1663 if (np >= LEAST_SQUARES_SAMPLES_MAX)
1664 return LEAST_SQUARES_SAMPLES_MAX;
1665 }
1666 }
1667
1668 // Top-right block
1669 if (do_tr && has_top_right(cm, sb_size, xd, mi_row, mi_col, AOMMAX(xd->n4_w, xd->n4_h))) {
1670 Position trb_pos = {-1, xd->n4_w};
1671
1672 if (is_inside(tile, mi_col, mi_row, &trb_pos)) {
1673 int mi_row_offset = -1;
1674 int mi_col_offset = xd->n4_w;
1675
1676 MbModeInfo *mbmi = &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
1677
1678 if (mbmi->block_mi.ref_frame[0] == rf0 && mbmi->block_mi.ref_frame[1] == NONE_FRAME) {
1679 record_samples(mbmi, pts, pts_inref, 0, -1, xd->n4_w, 1);
1680 np++;
1681 if (np >= LEAST_SQUARES_SAMPLES_MAX)
1682 return LEAST_SQUARES_SAMPLES_MAX;
1683 }
1684 }
1685 }
1686
1687 return np;
1688 }
1689
wm_count_samples(BlkStruct * blk_ptr,const BlockSize sb_size,const BlockGeom * blk_geom,uint16_t blk_origin_x,uint16_t blk_origin_y,uint8_t ref_frame_type,PictureControlSet * pcs_ptr,uint16_t * num_samples)1690 void wm_count_samples(BlkStruct *blk_ptr, const BlockSize sb_size, const BlockGeom *blk_geom,
1691 uint16_t blk_origin_x, uint16_t blk_origin_y, uint8_t ref_frame_type,
1692 PictureControlSet *pcs_ptr, uint16_t *num_samples) {
1693 Av1Common * cm = pcs_ptr->parent_pcs_ptr->av1_cm;
1694 MacroBlockD *xd = blk_ptr->av1xd;
1695
1696 int32_t mi_row = blk_origin_y >> MI_SIZE_LOG2;
1697 int32_t mi_col = blk_origin_x >> MI_SIZE_LOG2;
1698
1699 xd->n4_w = blk_geom->bwidth >> MI_SIZE_LOG2;
1700 xd->n4_h = blk_geom->bheight >> MI_SIZE_LOG2;
1701
1702 int up_available = xd->up_available;
1703 int left_available = xd->left_available;
1704 int i, mi_step = 1, np = 0;
1705
1706 const TileInfo *const tile = &xd->tile;
1707 int do_tl = 1;
1708 int do_tr = 1;
1709
1710 MvReferenceFrame rf[2];
1711 av1_set_ref_frame(rf, ref_frame_type);
1712
1713 if (up_available) {
1714 int mi_row_offset = -1;
1715 MbModeInfo *mbmi = &xd->mi[mi_row_offset * xd->mi_stride]->mbmi;
1716 uint8_t n4_w = mi_size_wide[mbmi->block_mi.sb_type];
1717
1718 if (xd->n4_w <= n4_w) {
1719 int col_offset = -mi_col % n4_w;
1720 if (col_offset < 0)
1721 do_tl = 0;
1722 if (col_offset + n4_w > xd->n4_w)
1723 do_tr = 0;
1724
1725 if (mbmi->block_mi.ref_frame[0] == rf[0] && mbmi->block_mi.ref_frame[1] == NONE_FRAME) {
1726 np++;
1727 if (np >= LEAST_SQUARES_SAMPLES_MAX) {
1728 *num_samples = LEAST_SQUARES_SAMPLES_MAX;
1729 return;
1730 }
1731 }
1732 } else {
1733 for (i = 0; i < AOMMIN(xd->n4_w, cm->mi_cols - mi_col); i += mi_step) {
1734 int mi_col_offset = i;
1735 mbmi = &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
1736 n4_w = mi_size_wide[mbmi->block_mi.sb_type];
1737 mi_step = AOMMIN(xd->n4_w, n4_w);
1738
1739 if (mbmi->block_mi.ref_frame[0] == rf[0] &&
1740 mbmi->block_mi.ref_frame[1] == NONE_FRAME) {
1741 np++;
1742 if (np >= LEAST_SQUARES_SAMPLES_MAX) {
1743 *num_samples = LEAST_SQUARES_SAMPLES_MAX;
1744 return;
1745 }
1746 }
1747 }
1748 }
1749 }
1750
1751 if (left_available) {
1752 int mi_col_offset = -1;
1753 MbModeInfo *mbmi = &xd->mi[mi_col_offset]->mbmi;
1754 uint8_t n4_h = mi_size_high[mbmi->block_mi.sb_type];
1755 if (xd->n4_h <= n4_h) {
1756 int row_offset = -mi_row % n4_h;
1757 if (row_offset < 0)
1758 do_tl = 0;
1759 if (mbmi->block_mi.ref_frame[0] == rf[0] && mbmi->block_mi.ref_frame[1] == NONE_FRAME) {
1760 np++;
1761 if (np >= LEAST_SQUARES_SAMPLES_MAX) {
1762 *num_samples = LEAST_SQUARES_SAMPLES_MAX;
1763 return;
1764 }
1765 }
1766 } else {
1767 for (i = 0; i < AOMMIN(xd->n4_h, cm->mi_rows - mi_row); i += mi_step) {
1768 int mi_row_offset = i;
1769 mbmi = &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
1770 n4_h = mi_size_high[mbmi->block_mi.sb_type];
1771 mi_step = AOMMIN(xd->n4_h, n4_h);
1772
1773 if (mbmi->block_mi.ref_frame[0] == rf[0] &&
1774 mbmi->block_mi.ref_frame[1] == NONE_FRAME) {
1775 np++;
1776 if (np >= LEAST_SQUARES_SAMPLES_MAX) {
1777 *num_samples = LEAST_SQUARES_SAMPLES_MAX;
1778 return;
1779 }
1780 }
1781 }
1782 }
1783 }
1784
1785 if (do_tl && left_available && up_available) {
1786 int mi_row_offset = -1;
1787 int mi_col_offset = -1;
1788 MbModeInfo *mbmi = &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
1789 if (mbmi->block_mi.ref_frame[0] == rf[0] && mbmi->block_mi.ref_frame[1] == NONE_FRAME) {
1790 np++;
1791 if (np >= LEAST_SQUARES_SAMPLES_MAX) {
1792 *num_samples = LEAST_SQUARES_SAMPLES_MAX;
1793 return;
1794 }
1795 }
1796 }
1797
1798 if (do_tr && has_top_right(cm, sb_size, xd, mi_row, mi_col, AOMMAX(xd->n4_w, xd->n4_h))) {
1799 Position trb_pos = {-1, xd->n4_w};
1800 if (is_inside(tile, mi_col, mi_row, &trb_pos)) {
1801 int mi_row_offset = -1;
1802 int mi_col_offset = xd->n4_w;
1803 MbModeInfo *mbmi = &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
1804
1805 if (mbmi->block_mi.ref_frame[0] == rf[0] && mbmi->block_mi.ref_frame[1] == NONE_FRAME) {
1806 np++;
1807 if (np >= LEAST_SQUARES_SAMPLES_MAX) {
1808 *num_samples = LEAST_SQUARES_SAMPLES_MAX;
1809 return;
1810 }
1811 }
1812 }
1813 }
1814 *num_samples = np;
1815 }
1816
wm_find_samples(BlkStruct * blk_ptr,const BlockGeom * blk_geom,uint16_t blk_origin_x,uint16_t blk_origin_y,MvReferenceFrame rf0,PictureControlSet * pcs_ptr,int32_t * pts,int32_t * pts_inref)1817 uint16_t wm_find_samples(BlkStruct *blk_ptr, const BlockGeom *blk_geom, uint16_t blk_origin_x,
1818 uint16_t blk_origin_y, MvReferenceFrame rf0, PictureControlSet *pcs_ptr,
1819 int32_t *pts, int32_t *pts_inref) {
1820 Av1Common * cm = pcs_ptr->parent_pcs_ptr->av1_cm;
1821 MacroBlockD *xd = blk_ptr->av1xd;
1822
1823 int32_t mi_row = blk_origin_y >> MI_SIZE_LOG2;
1824 int32_t mi_col = blk_origin_x >> MI_SIZE_LOG2;
1825
1826 xd->n4_w = blk_geom->bwidth >> MI_SIZE_LOG2;
1827 xd->n4_h = blk_geom->bheight >> MI_SIZE_LOG2;
1828
1829 return (uint16_t)av1_find_samples(
1830 cm,
1831 ((SequenceControlSet *)pcs_ptr->scs_wrapper_ptr->object_ptr)->seq_header.sb_size,
1832 xd,
1833 mi_row,
1834 mi_col,
1835 rf0,
1836 pts,
1837 pts_inref);
1838 }
1839
warped_motion_parameters(PictureControlSet * pcs_ptr,BlkStruct * blk_ptr,MvUnit * mv_unit,const BlockGeom * blk_geom,uint16_t blk_origin_x,uint16_t blk_origin_y,uint8_t ref_frame_type,EbWarpedMotionParams * wm_params,uint16_t * num_samples)1840 EbBool warped_motion_parameters(PictureControlSet *pcs_ptr, BlkStruct *blk_ptr, MvUnit *mv_unit,
1841 const BlockGeom *blk_geom, uint16_t blk_origin_x,
1842 uint16_t blk_origin_y, uint8_t ref_frame_type,
1843 EbWarpedMotionParams *wm_params, uint16_t *num_samples) {
1844 MacroBlockD *xd = blk_ptr->av1xd;
1845 BlockSize bsize = blk_geom->bsize;
1846 EbBool apply_wm = EB_FALSE;
1847
1848 int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
1849 int32_t mi_row = blk_origin_y >> MI_SIZE_LOG2;
1850 int32_t mi_col = blk_origin_x >> MI_SIZE_LOG2;
1851 xd->n4_w = blk_geom->bwidth >> MI_SIZE_LOG2;
1852 xd->n4_h = blk_geom->bheight >> MI_SIZE_LOG2;
1853
1854 *num_samples = 0;
1855 if (blk_geom->bwidth < 8 || blk_geom->bheight < 8)
1856 return apply_wm;
1857
1858 MvReferenceFrame rf[2];
1859 av1_set_ref_frame(rf, ref_frame_type);
1860
1861 uint16_t nsamples = wm_find_samples(
1862 blk_ptr, blk_geom, blk_origin_x, blk_origin_y, rf[0], pcs_ptr, pts, pts_inref);
1863
1864 if (nsamples == 0)
1865 return apply_wm;
1866
1867 MV mv;
1868 mv.col = mv_unit->mv[mv_unit->pred_direction % BI_PRED].x;
1869 mv.row = mv_unit->mv[mv_unit->pred_direction % BI_PRED].y;
1870 if (nsamples > 1)
1871 nsamples = select_samples(&mv, pts, pts_inref, nsamples, bsize);
1872 *num_samples = nsamples;
1873
1874 apply_wm = !svt_find_projection(
1875 (int)nsamples, pts, pts_inref, bsize, mv.row, mv.col, wm_params, (int)mi_row, (int)mi_col);
1876
1877 return apply_wm;
1878 }
1879
1880 //foreach_overlappable_nb_above
count_overlappable_nb_above(const Av1Common * cm,MacroBlockD * xd,int32_t mi_col,int nb_max)1881 int count_overlappable_nb_above(const Av1Common *cm, MacroBlockD *xd, int32_t mi_col, int nb_max) {
1882 int nb_count = 0;
1883 if (!xd->up_available)
1884 return nb_count;
1885
1886 // prev_row_mi points into the mi array, starting at the beginning of the
1887 // previous row.
1888 ModeInfo **prev_row_mi = xd->mi - mi_col - 1 * xd->mi_stride;
1889 const int end_col = MIN(mi_col + xd->n4_w, cm->mi_cols);
1890 uint8_t mi_step;
1891
1892 for (int above_mi_col = mi_col; above_mi_col < end_col && nb_count < nb_max;
1893 above_mi_col += mi_step) {
1894 ModeInfo **above_mi = prev_row_mi + above_mi_col;
1895 mi_step = MIN(mi_size_wide[above_mi[0]->mbmi.block_mi.sb_type], mi_size_wide[BLOCK_64X64]);
1896
1897 // If we're considering a block with width 4, it should be treated as
1898 // half of a pair of blocks with chroma information in the second. Move
1899 // above_mi_col back to the start of the pair if needed, set above_mbmi
1900 // to point at the block with chroma information, and set mi_step to 2 to
1901 // step over the entire pair at the end of the iteration.
1902 if (mi_step == 1) {
1903 above_mi_col &= ~1;
1904 above_mi = prev_row_mi + above_mi_col + 1;
1905 mi_step = 2;
1906 }
1907 if (is_neighbor_overlappable(&(*above_mi)->mbmi))
1908 ++nb_count;
1909 }
1910
1911 return nb_count;
1912 }
1913
count_overlappable_nb_left(const Av1Common * cm,MacroBlockD * xd,int32_t mi_row,int nb_max)1914 int count_overlappable_nb_left(const Av1Common *cm, MacroBlockD *xd, int32_t mi_row, int nb_max) {
1915 int nb_count = 0;
1916 if (!xd->left_available)
1917 return nb_count;
1918
1919 // prev_col_mi points into the mi array, starting at the top of the
1920 // previous column
1921 ModeInfo **prev_col_mi = xd->mi - 1 - mi_row * xd->mi_stride;
1922 const int end_row = MIN(mi_row + xd->n4_h, cm->mi_rows);
1923 uint8_t mi_step;
1924
1925 for (int left_mi_row = mi_row; left_mi_row < end_row && nb_count < nb_max;
1926 left_mi_row += mi_step) {
1927 ModeInfo **left_mi = prev_col_mi + left_mi_row * xd->mi_stride;
1928 mi_step = MIN(mi_size_high[left_mi[0]->mbmi.block_mi.sb_type], mi_size_high[BLOCK_64X64]);
1929 if (mi_step == 1) {
1930 left_mi_row &= ~1;
1931 left_mi = prev_col_mi + (left_mi_row + 1) * xd->mi_stride;
1932 mi_step = 2;
1933 }
1934
1935 if (is_neighbor_overlappable(&(*left_mi)->mbmi))
1936 ++nb_count;
1937 }
1938
1939 return nb_count;
1940 }
1941
svt_av1_count_overlappable_neighbors(const PictureControlSet * pcs_ptr,BlkStruct * blk_ptr,const BlockSize bsize,int32_t mi_row,int32_t mi_col)1942 void svt_av1_count_overlappable_neighbors(const PictureControlSet *pcs_ptr, BlkStruct *blk_ptr,
1943 const BlockSize bsize, int32_t mi_row, int32_t mi_col) {
1944 Av1Common * cm = pcs_ptr->parent_pcs_ptr->av1_cm;
1945 MacroBlockD *xd = blk_ptr->av1xd;
1946 blk_ptr->prediction_unit_array[0].overlappable_neighbors[0] = 0;
1947 blk_ptr->prediction_unit_array[0].overlappable_neighbors[1] = 0;
1948
1949 if (!is_motion_variation_allowed_bsize(bsize))
1950 return;
1951
1952 blk_ptr->prediction_unit_array[0].overlappable_neighbors[0] = count_overlappable_nb_above(
1953 cm, xd, mi_col, MAX_SIGNED_VALUE);
1954
1955 blk_ptr->prediction_unit_array[0].overlappable_neighbors[1] = count_overlappable_nb_left(
1956 cm, xd, mi_row, MAX_SIGNED_VALUE);
1957 }
1958
av1_is_dv_valid(const MV dv,const MacroBlockD * xd,int mi_row,int mi_col,BlockSize bsize,int mib_size_log2)1959 int av1_is_dv_valid(const MV dv, const MacroBlockD *xd, int mi_row, int mi_col, BlockSize bsize,
1960 int mib_size_log2) {
1961 const int bw = block_size_wide[bsize];
1962 const int bh = block_size_high[bsize];
1963 const int scale_px_to_mv = 8;
1964 // Disallow subpixel for now
1965 // SUBPEL_MASK is not the correct scale
1966 if (((dv.row & (scale_px_to_mv - 1)) || (dv.col & (scale_px_to_mv - 1))))
1967 return 0;
1968
1969 const TileInfo *const tile = &xd->tile;
1970 // Is the source top-left inside the current tile?
1971 const int src_top_edge = mi_row * MI_SIZE * scale_px_to_mv + dv.row;
1972 const int tile_top_edge = tile->mi_row_start * MI_SIZE * scale_px_to_mv;
1973 if (src_top_edge < tile_top_edge)
1974 return 0;
1975 const int src_left_edge = mi_col * MI_SIZE * scale_px_to_mv + dv.col;
1976 const int tile_left_edge = tile->mi_col_start * MI_SIZE * scale_px_to_mv;
1977 if (src_left_edge < tile_left_edge)
1978 return 0;
1979 // Is the bottom right inside the current tile?
1980 const int src_bottom_edge = (mi_row * MI_SIZE + bh) * scale_px_to_mv + dv.row;
1981 const int tile_bottom_edge = tile->mi_row_end * MI_SIZE * scale_px_to_mv;
1982 if (src_bottom_edge > tile_bottom_edge)
1983 return 0;
1984 const int src_right_edge = (mi_col * MI_SIZE + bw) * scale_px_to_mv + dv.col;
1985 const int tile_right_edge = tile->mi_col_end * MI_SIZE * scale_px_to_mv;
1986 if (src_right_edge > tile_right_edge)
1987 return 0;
1988
1989 // Special case for sub 8x8 chroma cases, to prevent referring to chroma
1990 // pixels outside current tile.
1991 for (int plane = 1; plane < 3 /* av1_num_planes(cm)*/; ++plane) {
1992 //const struct MacroBlockDPlane *const pd = &xd->plane[plane];
1993
1994 if (is_chroma_reference(mi_row, mi_col, bsize, 1, 1/* pd->subsampling_x,
1995 pd->subsampling_y*/)) {
1996 if (bw < 8 /*&& pd->subsampling_x*/)
1997 if (src_left_edge < tile_left_edge + 4 * scale_px_to_mv)
1998 return 0;
1999 if (bh < 8 /* && pd->subsampling_y*/)
2000 if (src_top_edge < tile_top_edge + 4 * scale_px_to_mv)
2001 return 0;
2002 }
2003 }
2004
2005 // Is the bottom right within an already coded SB? Also consider additional
2006 // constraints to facilitate HW decoder.
2007 const int max_mib_size = 1 << mib_size_log2;
2008 const int active_sb_row = mi_row >> mib_size_log2;
2009 const int active_sb64_col = (mi_col * MI_SIZE) >> 6;
2010 const int sb_size = max_mib_size * MI_SIZE;
2011 const int src_sb_row = ((src_bottom_edge >> 3) - 1) / sb_size;
2012 const int src_sb64_col = ((src_right_edge >> 3) - 1) >> 6;
2013 const int total_sb64_per_row = ((tile->mi_col_end - tile->mi_col_start - 1) >> 4) + 1;
2014 const int active_sb64 = active_sb_row * total_sb64_per_row + active_sb64_col;
2015 const int src_sb64 = src_sb_row * total_sb64_per_row + src_sb64_col;
2016 if (src_sb64 >= active_sb64 - INTRABC_DELAY_SB64)
2017 return 0;
2018
2019 // Wavefront constraint: use only top left area of frame for reference.
2020 const int gradient = 1 + INTRABC_DELAY_SB64 + (sb_size > 64);
2021 const int wf_offset = gradient * (active_sb_row - src_sb_row);
2022 if (src_sb_row > active_sb_row ||
2023 src_sb64_col >= active_sb64_col - INTRABC_DELAY_SB64 + wf_offset)
2024 return 0;
2025
2026 //add a SW-Wavefront constraint
2027 if (sb_size == 64) {
2028 if (src_sb64_col > active_sb64_col + (active_sb_row - src_sb_row))
2029 return 0;
2030 } else {
2031 const int src_sb128_col = ((src_right_edge >> 3) - 1) >> 7;
2032 const int active_sb128_col = (mi_col * MI_SIZE) >> 7;
2033
2034 if (src_sb128_col > active_sb128_col + (active_sb_row - src_sb_row))
2035 return 0;
2036 }
2037
2038 return 1;
2039 }
2040
is_inside_tile_boundary(TileInfo * tile,int16_t mvx,int16_t mvy,int mi_col,int mi_row,BlockSize bsize)2041 int is_inside_tile_boundary(TileInfo *tile, int16_t mvx, int16_t mvy, int mi_col, int mi_row,
2042 BlockSize bsize) {
2043 const int bw = block_size_wide[bsize];
2044 const int bh = block_size_high[bsize];
2045 const int scale_px_to_mv = 8;
2046 const int src_top_edge = mi_row * MI_SIZE * scale_px_to_mv + mvy;
2047 const int tile_top_edge = tile->mi_row_start * MI_SIZE * scale_px_to_mv;
2048 if (src_top_edge < tile_top_edge)
2049 return 0;
2050 const int src_left_edge = mi_col * MI_SIZE * scale_px_to_mv + mvx;
2051 const int tile_left_edge = tile->mi_col_start * MI_SIZE * scale_px_to_mv;
2052 if (src_left_edge < tile_left_edge)
2053 return 0;
2054 // Is the bottom right inside the current tile?
2055 const int src_bottom_edge = (mi_row * MI_SIZE + bh) * scale_px_to_mv + mvy;
2056 const int tile_bottom_edge = tile->mi_row_end * MI_SIZE * scale_px_to_mv;
2057 if (src_bottom_edge > tile_bottom_edge)
2058 return 0;
2059 const int src_right_edge = (mi_col * MI_SIZE + bw) * scale_px_to_mv + mvx;
2060 const int tile_right_edge = tile->mi_col_end * MI_SIZE * scale_px_to_mv;
2061 if (src_right_edge > tile_right_edge)
2062 return 0;
2063
2064 return 1;
2065 }
2066
svt_av1_get_ref_mv_from_stack(int ref_idx,const MvReferenceFrame * ref_frame,int ref_mv_idx,CandidateMv ref_mv_stack[][MAX_REF_MV_STACK_SIZE],MacroBlockD * xd)2067 IntMv svt_av1_get_ref_mv_from_stack(int ref_idx, const MvReferenceFrame *ref_frame, int ref_mv_idx,
2068 CandidateMv ref_mv_stack[][MAX_REF_MV_STACK_SIZE],
2069 MacroBlockD *xd
2070 /*const MB_MODE_INFO_EXT *mbmi_ext*/) {
2071 const int8_t ref_frame_type = av1_ref_frame_type(ref_frame);
2072 const CandidateMv *curr_ref_mv_stack =
2073 /*mbmi_ext->*/ ref_mv_stack[ref_frame_type];
2074 IntMv ref_mv;
2075 ref_mv.as_int = INVALID_MV;
2076
2077 if (ref_frame[1] > INTRA_FRAME) {
2078 if (ref_idx == 0)
2079 ref_mv = curr_ref_mv_stack[ref_mv_idx].this_mv;
2080 else {
2081 assert(ref_idx == 1);
2082 ref_mv = curr_ref_mv_stack[ref_mv_idx].comp_mv;
2083 }
2084 } else {
2085 assert(ref_idx == 0);
2086 if (ref_mv_idx < /*mbmi_ext->*/ xd->ref_mv_count[ref_frame_type])
2087 ref_mv = curr_ref_mv_stack[ref_mv_idx].this_mv;
2088 else {
2089 //CHKN got this from decoder read_intrabc_info global_mvs[ref_frame].as_int = INVALID_MV;
2090 ref_mv.as_int = INVALID_MV; // mbmi_ext->global_mvs[ref_frame_type];
2091 }
2092 }
2093 return ref_mv;
2094 }
2095
svt_av1_find_best_ref_mvs_from_stack(int allow_hp,CandidateMv ref_mv_stack[][MAX_REF_MV_STACK_SIZE],MacroBlockD * xd,MvReferenceFrame ref_frame,IntMv * nearest_mv,IntMv * near_mv,int is_integer)2096 void svt_av1_find_best_ref_mvs_from_stack(int allow_hp,
2097 //const MB_MODE_INFO_EXT *mbmi_ext,
2098 CandidateMv ref_mv_stack[][MAX_REF_MV_STACK_SIZE],
2099 MacroBlockD *xd, MvReferenceFrame ref_frame,
2100 IntMv *nearest_mv, IntMv *near_mv, int is_integer) {
2101 const int ref_idx = 0;
2102 MvReferenceFrame ref_frames[2] = {ref_frame, NONE_FRAME};
2103 *nearest_mv = svt_av1_get_ref_mv_from_stack(
2104 ref_idx, ref_frames, 0, ref_mv_stack /*mbmi_ext*/, xd);
2105 lower_mv_precision(&nearest_mv->as_mv, allow_hp, is_integer);
2106 *near_mv = svt_av1_get_ref_mv_from_stack(ref_idx, ref_frames, 1, ref_mv_stack /*mbmi_ext*/, xd);
2107 lower_mv_precision(&near_mv->as_mv, allow_hp, is_integer);
2108 }
2109