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