1 /*
2  * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3  *
4  * This source code is subject to the terms of the BSD 2 Clause License and
5  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6  * was not distributed with this source code in the LICENSE file, you can
7  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8  * Media Patent License 1.0 was not distributed with this source code in the
9  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10  */
11 
12 #include "av1/common/mvref_common.h"
13 #if CONFIG_WARPED_MOTION
14 #include "av1/common/warped_motion.h"
15 #endif  // CONFIG_WARPED_MOTION
16 
17 #if CONFIG_GLOBAL_MOTION
18 #define USE_CUR_GM_REFMV 1
19 #endif  // CONFIG_GLOBAL_MOTION
20 
av1_copy_frame_mvs(const AV1_COMMON * const cm,MODE_INFO * mi,int mi_row,int mi_col,int x_mis,int y_mis)21 void av1_copy_frame_mvs(const AV1_COMMON *const cm, MODE_INFO *mi, int mi_row,
22                         int mi_col, int x_mis, int y_mis) {
23 #if CONFIG_TMV
24   const int frame_mvs_stride = ROUND_POWER_OF_TWO(cm->mi_cols, 1);
25   MV_REF *frame_mvs = cm->cur_frame->mvs +
26                       ((mi_row & 0xfffe) >> 1) * frame_mvs_stride +
27                       ((mi_col & 0xfffe) >> 1);
28   x_mis = ROUND_POWER_OF_TWO(x_mis, 1);
29   y_mis = ROUND_POWER_OF_TWO(y_mis, 1);
30 #else
31   const int frame_mvs_stride = cm->mi_cols;
32   MV_REF *frame_mvs = cm->cur_frame->mvs +
33                       (mi_row & 0xfffe) * frame_mvs_stride + (mi_col & 0xfffe);
34   x_mis = AOMMAX(x_mis, 2);
35   y_mis = AOMMAX(y_mis, 2);
36 #endif  // CONFIG_TMV
37   int w, h;
38 
39   for (h = 0; h < y_mis; h++) {
40     MV_REF *const frame_mv = frame_mvs + h * frame_mvs_stride;
41     for (w = 0; w < x_mis; w++) {
42       MV_REF *const mv = frame_mv + w;
43       mv->ref_frame[0] = mi->mbmi.ref_frame[0];
44       mv->ref_frame[1] = mi->mbmi.ref_frame[1];
45       mv->mv[0].as_int = mi->mbmi.mv[0].as_int;
46       mv->mv[1].as_int = mi->mbmi.mv[1].as_int;
47       // (TODO:yunqing) The following 2 lines won't be used and can be removed.
48       mv->pred_mv[0].as_int = mi->mbmi.pred_mv[0].as_int;
49       mv->pred_mv[1].as_int = mi->mbmi.pred_mv[1].as_int;
50     }
51   }
52 }
53 
add_ref_mv_candidate(const MODE_INFO * const candidate_mi,const MB_MODE_INFO * const candidate,const MV_REFERENCE_FRAME rf[2],uint8_t * refmv_count,CANDIDATE_MV * ref_mv_stack,const int use_hp,int len,int block,int_mv * gm_mv_candidates,const WarpedMotionParams * gm_params,int col,int weight,int is_integer)54 static uint8_t add_ref_mv_candidate(
55     const MODE_INFO *const candidate_mi, const MB_MODE_INFO *const candidate,
56     const MV_REFERENCE_FRAME rf[2], uint8_t *refmv_count,
57     CANDIDATE_MV *ref_mv_stack, const int use_hp, int len, int block,
58 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
59     int_mv *gm_mv_candidates, const WarpedMotionParams *gm_params,
60 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
61     int col, int weight
62 #if CONFIG_AMVR
63     ,
64     int is_integer
65 #endif
66     ) {
67   int index = 0, ref;
68   int newmv_count = 0;
69 #if CONFIG_CB4X4
70   const int unify_bsize = 1;
71 #else
72   const int unify_bsize = 0;
73 #endif
74   assert(weight % 2 == 0);
75 
76   if (rf[1] == NONE_FRAME) {
77     // single reference frame
78     for (ref = 0; ref < 2; ++ref) {
79       if (candidate->ref_frame[ref] == rf[0]) {
80         int_mv this_refmv;
81 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
82         if (is_global_mv_block(candidate_mi, block, gm_params[rf[0]].wmtype))
83           this_refmv = gm_mv_candidates[0];
84         else
85 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
86           this_refmv = get_sub_block_mv(candidate_mi, ref, col, block);
87 #if CONFIG_AMVR
88         lower_mv_precision(&this_refmv.as_mv, use_hp, is_integer);
89 #else
90         lower_mv_precision(&this_refmv.as_mv, use_hp);
91 #endif  // CONFIG_AMVR
92 
93         for (index = 0; index < *refmv_count; ++index)
94           if (ref_mv_stack[index].this_mv.as_int == this_refmv.as_int) break;
95 
96         if (index < *refmv_count) ref_mv_stack[index].weight += weight * len;
97 
98         // Add a new item to the list.
99         if (index == *refmv_count) {
100           ref_mv_stack[index].this_mv = this_refmv;
101           ref_mv_stack[index].pred_diff[0] = av1_get_pred_diff_ctx(
102               get_sub_block_pred_mv(candidate_mi, ref, col, block), this_refmv);
103           ref_mv_stack[index].weight = weight * len;
104           ++(*refmv_count);
105 
106           if (candidate->mode == NEWMV) ++newmv_count;
107         }
108 
109         if (candidate_mi->mbmi.sb_type < BLOCK_8X8 && block >= 0 &&
110             !unify_bsize) {
111           int alt_block = 3 - block;
112           this_refmv = get_sub_block_mv(candidate_mi, ref, col, alt_block);
113 #if CONFIG_AMVR
114           lower_mv_precision(&this_refmv.as_mv, use_hp, is_integer);
115 #else
116           lower_mv_precision(&this_refmv.as_mv, use_hp);
117 #endif
118           for (index = 0; index < *refmv_count; ++index)
119             if (ref_mv_stack[index].this_mv.as_int == this_refmv.as_int) break;
120 
121           if (index < *refmv_count) ref_mv_stack[index].weight += len;
122 
123           // Add a new item to the list.
124           if (index == *refmv_count) {
125             ref_mv_stack[index].this_mv = this_refmv;
126             ref_mv_stack[index].pred_diff[0] = av1_get_pred_diff_ctx(
127                 get_sub_block_pred_mv(candidate_mi, ref, col, alt_block),
128                 this_refmv);
129             ref_mv_stack[index].weight = len;
130             ++(*refmv_count);
131 
132             if (candidate->mode == NEWMV) ++newmv_count;
133           }
134         }
135       }
136     }
137   } else {
138     // compound reference frame
139     if (candidate->ref_frame[0] == rf[0] && candidate->ref_frame[1] == rf[1]) {
140       int_mv this_refmv[2];
141 
142       for (ref = 0; ref < 2; ++ref) {
143 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
144         if (is_global_mv_block(candidate_mi, block, gm_params[rf[ref]].wmtype))
145           this_refmv[ref] = gm_mv_candidates[ref];
146         else
147 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
148           this_refmv[ref] = get_sub_block_mv(candidate_mi, ref, col, block);
149 #if CONFIG_AMVR
150         lower_mv_precision(&this_refmv[ref].as_mv, use_hp, is_integer);
151 #else
152         lower_mv_precision(&this_refmv[ref].as_mv, use_hp);
153 #endif
154       }
155 
156       for (index = 0; index < *refmv_count; ++index)
157         if ((ref_mv_stack[index].this_mv.as_int == this_refmv[0].as_int) &&
158             (ref_mv_stack[index].comp_mv.as_int == this_refmv[1].as_int))
159           break;
160 
161       if (index < *refmv_count) ref_mv_stack[index].weight += weight * len;
162 
163       // Add a new item to the list.
164       if (index == *refmv_count) {
165         ref_mv_stack[index].this_mv = this_refmv[0];
166         ref_mv_stack[index].comp_mv = this_refmv[1];
167         ref_mv_stack[index].pred_diff[0] = av1_get_pred_diff_ctx(
168             get_sub_block_pred_mv(candidate_mi, 0, col, block), this_refmv[0]);
169         ref_mv_stack[index].pred_diff[1] = av1_get_pred_diff_ctx(
170             get_sub_block_pred_mv(candidate_mi, 1, col, block), this_refmv[1]);
171         ref_mv_stack[index].weight = weight * len;
172         ++(*refmv_count);
173 
174         if (candidate->mode == NEW_NEWMV) ++newmv_count;
175       }
176 
177       if (candidate_mi->mbmi.sb_type < BLOCK_8X8 && block >= 0 &&
178           !unify_bsize) {
179         int alt_block = 3 - block;
180         this_refmv[0] = get_sub_block_mv(candidate_mi, 0, col, alt_block);
181         this_refmv[1] = get_sub_block_mv(candidate_mi, 1, col, alt_block);
182 
183         for (ref = 0; ref < 2; ++ref) {
184 #if CONFIG_AMVR
185           lower_mv_precision(&this_refmv[ref].as_mv, use_hp, is_integer);
186 #else
187           lower_mv_precision(&this_refmv[ref].as_mv, use_hp);
188 #endif
189         }
190         for (index = 0; index < *refmv_count; ++index)
191           if (ref_mv_stack[index].this_mv.as_int == this_refmv[0].as_int &&
192               ref_mv_stack[index].comp_mv.as_int == this_refmv[1].as_int)
193             break;
194 
195         if (index < *refmv_count) ref_mv_stack[index].weight += len;
196 
197         // Add a new item to the list.
198         if (index == *refmv_count) {
199           ref_mv_stack[index].this_mv = this_refmv[0];
200           ref_mv_stack[index].comp_mv = this_refmv[1];
201           ref_mv_stack[index].pred_diff[0] = av1_get_pred_diff_ctx(
202               get_sub_block_pred_mv(candidate_mi, 0, col, block),
203               this_refmv[0]);
204           ref_mv_stack[index].pred_diff[0] = av1_get_pred_diff_ctx(
205               get_sub_block_pred_mv(candidate_mi, 1, col, block),
206               this_refmv[1]);
207           ref_mv_stack[index].weight = len;
208           ++(*refmv_count);
209 
210           if (candidate->mode == NEW_NEWMV) ++newmv_count;
211         }
212       }
213     }
214   }
215   return newmv_count;
216 }
217 
scan_row_mbmi(const AV1_COMMON * cm,const MACROBLOCKD * xd,const int mi_col,int block,const MV_REFERENCE_FRAME rf[2],int row_offset,CANDIDATE_MV * ref_mv_stack,uint8_t * refmv_count,int_mv * gm_mv_candidates,int max_row_offset,int * processed_rows)218 static uint8_t scan_row_mbmi(const AV1_COMMON *cm, const MACROBLOCKD *xd,
219                              const int mi_col, int block,
220                              const MV_REFERENCE_FRAME rf[2], int row_offset,
221                              CANDIDATE_MV *ref_mv_stack, uint8_t *refmv_count,
222 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
223                              int_mv *gm_mv_candidates,
224 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
225                              int max_row_offset, int *processed_rows) {
226   const int end_mi = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
227   const int n8_w_8 = mi_size_wide[BLOCK_8X8];
228   const int n8_w_16 = mi_size_wide[BLOCK_16X16];
229   int i;
230   uint8_t newmv_count = 0;
231   int col_offset = 0;
232 #if CONFIG_CB4X4
233   const int shift = 0;
234   // TODO(jingning): Revisit this part after cb4x4 is stable.
235   if (abs(row_offset) > 1) {
236     col_offset = 1;
237     if (mi_col & 0x01 && xd->n8_w < n8_w_8) --col_offset;
238   }
239   const int use_step_16 = (xd->n8_w >= 16);
240 #else
241   const int shift = 1;
242   const int use_step_16 = (xd->n8_w >= 8);
243 #endif
244   MODE_INFO **const candidate_mi0 = xd->mi + row_offset * xd->mi_stride;
245 
246   for (i = 0; i < end_mi && *refmv_count < MAX_REF_MV_STACK_SIZE;) {
247     const MODE_INFO *const candidate_mi = candidate_mi0[col_offset + i];
248     const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
249     const int candidate_bsize = candidate->sb_type;
250     const int n8_w = mi_size_wide[candidate_bsize];
251     int len = AOMMIN(xd->n8_w, n8_w);
252     if (use_step_16)
253       len = AOMMAX(n8_w_16, len);
254     else if (abs(row_offset) > 1)
255       len = AOMMAX(len, n8_w_8);
256 
257     int weight = 2;
258     if (xd->n8_w >= n8_w_8 && xd->n8_w <= n8_w) {
259       int inc = AOMMIN(-max_row_offset + row_offset + 1,
260                        mi_size_high[candidate_bsize]);
261       // Obtain range used in weight calculation.
262       weight = AOMMAX(weight, (inc << shift));
263       // Update processed rows.
264       *processed_rows = inc - row_offset - 1;
265     }
266 
267 #if CONFIG_AMVR
268     newmv_count += add_ref_mv_candidate(
269         candidate_mi, candidate, rf, refmv_count, ref_mv_stack,
270         cm->allow_high_precision_mv, len, block,
271 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
272         gm_mv_candidates, cm->global_motion,
273 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
274         col_offset + i, weight, cm->cur_frame_mv_precision_level);
275 #else
276     newmv_count += add_ref_mv_candidate(candidate_mi, candidate, rf,
277                                         refmv_count, ref_mv_stack,
278                                         cm->allow_high_precision_mv, len, block,
279 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
280                                         gm_mv_candidates, cm->global_motion,
281 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
282                                         col_offset + i, weight);
283 #endif
284 
285     i += len;
286   }
287 
288   return newmv_count;
289 }
290 
scan_col_mbmi(const AV1_COMMON * cm,const MACROBLOCKD * xd,const int mi_row,int block,const MV_REFERENCE_FRAME rf[2],int col_offset,CANDIDATE_MV * ref_mv_stack,uint8_t * refmv_count,int_mv * gm_mv_candidates,int max_col_offset,int * processed_cols)291 static uint8_t scan_col_mbmi(const AV1_COMMON *cm, const MACROBLOCKD *xd,
292                              const int mi_row, int block,
293                              const MV_REFERENCE_FRAME rf[2], int col_offset,
294                              CANDIDATE_MV *ref_mv_stack, uint8_t *refmv_count,
295 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
296                              int_mv *gm_mv_candidates,
297 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
298                              int max_col_offset, int *processed_cols) {
299   const int end_mi = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
300   const int n8_h_8 = mi_size_high[BLOCK_8X8];
301   const int n8_h_16 = mi_size_high[BLOCK_16X16];
302   int i;
303   uint8_t newmv_count = 0;
304   int row_offset = 0;
305 #if CONFIG_CB4X4
306   const int shift = 0;
307   if (abs(col_offset) > 1) {
308     row_offset = 1;
309     if (mi_row & 0x01 && xd->n8_h < n8_h_8) --row_offset;
310   }
311   const int use_step_16 = (xd->n8_h >= 16);
312 #else
313   const int shift = 1;
314   const int use_step_16 = (xd->n8_h >= 8);
315 #endif
316 
317   for (i = 0; i < end_mi && *refmv_count < MAX_REF_MV_STACK_SIZE;) {
318     const MODE_INFO *const candidate_mi =
319         xd->mi[(row_offset + i) * xd->mi_stride + col_offset];
320     const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
321     const int candidate_bsize = candidate->sb_type;
322     const int n8_h = mi_size_high[candidate_bsize];
323     int len = AOMMIN(xd->n8_h, n8_h);
324     if (use_step_16)
325       len = AOMMAX(n8_h_16, len);
326     else if (abs(col_offset) > 1)
327       len = AOMMAX(len, n8_h_8);
328 
329     int weight = 2;
330     if (xd->n8_h >= n8_h_8 && xd->n8_h <= n8_h) {
331       int inc = AOMMIN(-max_col_offset + col_offset + 1,
332                        mi_size_wide[candidate_bsize]);
333       // Obtain range used in weight calculation.
334       weight = AOMMAX(weight, (inc << shift));
335       // Update processed cols.
336       *processed_cols = inc - col_offset - 1;
337     }
338 
339 #if CONFIG_AMVR
340     newmv_count += add_ref_mv_candidate(
341         candidate_mi, candidate, rf, refmv_count, ref_mv_stack,
342         cm->allow_high_precision_mv, len, block,
343 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
344         gm_mv_candidates, cm->global_motion,
345 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
346         col_offset, weight, cm->cur_frame_mv_precision_level);
347 #else
348     newmv_count += add_ref_mv_candidate(candidate_mi, candidate, rf,
349                                         refmv_count, ref_mv_stack,
350                                         cm->allow_high_precision_mv, len, block,
351 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
352                                         gm_mv_candidates, cm->global_motion,
353 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
354                                         col_offset, weight);
355 #endif
356     i += len;
357   }
358 
359   return newmv_count;
360 }
361 
scan_blk_mbmi(const AV1_COMMON * cm,const MACROBLOCKD * xd,const int mi_row,const int mi_col,int block,const MV_REFERENCE_FRAME rf[2],int row_offset,int col_offset,CANDIDATE_MV * ref_mv_stack,int_mv * gm_mv_candidates,uint8_t * refmv_count)362 static uint8_t scan_blk_mbmi(const AV1_COMMON *cm, const MACROBLOCKD *xd,
363                              const int mi_row, const int mi_col, int block,
364                              const MV_REFERENCE_FRAME rf[2], int row_offset,
365                              int col_offset, CANDIDATE_MV *ref_mv_stack,
366 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
367                              int_mv *gm_mv_candidates,
368 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
369                              uint8_t *refmv_count) {
370   const TileInfo *const tile = &xd->tile;
371   POSITION mi_pos;
372   uint8_t newmv_count = 0;
373 
374   mi_pos.row = row_offset;
375   mi_pos.col = col_offset;
376 
377   if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm, &mi_pos) &&
378       *refmv_count < MAX_REF_MV_STACK_SIZE) {
379     const MODE_INFO *const candidate_mi =
380         xd->mi[mi_pos.row * xd->mi_stride + mi_pos.col];
381     const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
382     const int len = mi_size_wide[BLOCK_8X8];
383 
384 #if CONFIG_AMVR
385     newmv_count += add_ref_mv_candidate(
386         candidate_mi, candidate, rf, refmv_count, ref_mv_stack,
387         cm->allow_high_precision_mv, len, block,
388 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
389         gm_mv_candidates, cm->global_motion,
390 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
391         mi_pos.col, 2, cm->cur_frame_mv_precision_level);
392 #else
393     newmv_count += add_ref_mv_candidate(candidate_mi, candidate, rf,
394                                         refmv_count, ref_mv_stack,
395                                         cm->allow_high_precision_mv, len, block,
396 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
397                                         gm_mv_candidates, cm->global_motion,
398 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
399                                         mi_pos.col, 2);
400 #endif
401   }  // Analyze a single 8x8 block motion information.
402 
403   return newmv_count;
404 }
405 
has_top_right(const AV1_COMMON * cm,const MACROBLOCKD * xd,int mi_row,int mi_col,int bs)406 static int has_top_right(const AV1_COMMON *cm, const MACROBLOCKD *xd,
407                          int mi_row, int mi_col, int bs) {
408   const int sb_mi_size = mi_size_wide[cm->sb_size];
409   const int mask_row = mi_row & (sb_mi_size - 1);
410   const int mask_col = mi_col & (sb_mi_size - 1);
411 
412   // In a split partition all apart from the bottom right has a top right
413   int has_tr = !((mask_row & bs) && (mask_col & bs));
414 
415   // bs > 0 and bs is a power of 2
416   assert(bs > 0 && !(bs & (bs - 1)));
417 
418   // For each 4x4 group of blocks, when the bottom right is decoded the blocks
419   // to the right have not been decoded therefore the bottom right does
420   // not have a top right
421   while (bs < sb_mi_size) {
422     if (mask_col & bs) {
423       if ((mask_col & (2 * bs)) && (mask_row & (2 * bs))) {
424         has_tr = 0;
425         break;
426       }
427     } else {
428       break;
429     }
430     bs <<= 1;
431   }
432 
433   // The left hand of two vertical rectangles always has a top right (as the
434   // block above will have been decoded)
435   if (xd->n8_w < xd->n8_h)
436     if (!xd->is_sec_rect) has_tr = 1;
437 
438   // The bottom of two horizontal rectangles never has a top right (as the block
439   // to the right won't have been decoded)
440   if (xd->n8_w > xd->n8_h)
441     if (xd->is_sec_rect) has_tr = 0;
442 
443 #if CONFIG_EXT_PARTITION_TYPES && !CONFIG_EXT_PARTITION_TYPES_AB
444   // The bottom left square of a Vertical A (in the old format) does
445   // not have a top right as it is decoded before the right hand
446   // rectangle of the partition
447   if (xd->mi[0]->mbmi.partition == PARTITION_VERT_A)
448     if ((mask_row & bs) && !(mask_col & bs)) has_tr = 0;
449 #endif  // CONFIG_EXT_PARTITION_TYPES
450 
451   return has_tr;
452 }
453 
454 #if CONFIG_MFMV
check_sb_border(const AV1_COMMON * cm,const int mi_row,const int mi_col,const int row_offset,const int col_offset)455 static int check_sb_border(const AV1_COMMON *cm, const int mi_row,
456                            const int mi_col, const int row_offset,
457                            const int col_offset) {
458   const int sb_mi_size = mi_size_wide[cm->sb_size];
459   const int row = mi_row & (sb_mi_size - 1);
460   const int col = mi_col & (sb_mi_size - 1);
461 
462   if (row + row_offset < 0 || row + row_offset >= sb_mi_size ||
463       col + col_offset < 0 || col + col_offset >= sb_mi_size)
464     return 0;
465 
466   return 1;
467 }
468 
add_tpl_ref_mv(const AV1_COMMON * cm,const MV_REF * prev_frame_mvs_base,const MACROBLOCKD * xd,int mi_row,int mi_col,MV_REFERENCE_FRAME ref_frame,int blk_row,int blk_col,uint8_t * refmv_count,CANDIDATE_MV * ref_mv_stack,int16_t * mode_context)469 static int add_tpl_ref_mv(const AV1_COMMON *cm,
470                           const MV_REF *prev_frame_mvs_base,
471                           const MACROBLOCKD *xd, int mi_row, int mi_col,
472                           MV_REFERENCE_FRAME ref_frame, int blk_row,
473                           int blk_col, uint8_t *refmv_count,
474                           CANDIDATE_MV *ref_mv_stack, int16_t *mode_context) {
475   (void)prev_frame_mvs_base;
476   POSITION mi_pos;
477   int idx;
478   int coll_blk_count = 0;
479   const int weight_unit = 1;  // mi_size_wide[BLOCK_8X8];
480 
481 #if CONFIG_MV_COMPRESS
482   mi_pos.row = (mi_row & 0x01) ? blk_row : blk_row + 1;
483   mi_pos.col = (mi_col & 0x01) ? blk_col : blk_col + 1;
484 #else
485   mi_pos.row = blk_row;
486   mi_pos.col = blk_col;
487 #endif
488 
489   if (!is_inside(&xd->tile, mi_col, mi_row, cm->mi_rows, cm, &mi_pos))
490     return coll_blk_count;
491 
492   const TPL_MV_REF *prev_frame_mvs = cm->cur_frame->tpl_mvs +
493                                      (mi_row + mi_pos.row) * cm->mi_stride +
494                                      (mi_col + mi_pos.col);
495 
496   MV_REFERENCE_FRAME rf[2];
497   av1_set_ref_frame(rf, ref_frame);
498 
499   if (rf[1] == NONE_FRAME) {
500     for (int i = 0; i < MFMV_STACK_SIZE; ++i) {
501       if (prev_frame_mvs->mfmv[ref_frame - LAST_FRAME][i].as_int !=
502           INVALID_MV) {
503         int_mv this_refmv = prev_frame_mvs->mfmv[ref_frame - LAST_FRAME][i];
504         lower_mv_precision(&this_refmv.as_mv, cm->allow_high_precision_mv);
505 
506         if (blk_row == 0 && blk_col == 0)
507           if (abs(this_refmv.as_mv.row) >= 16 ||
508               abs(this_refmv.as_mv.col) >= 16)
509             mode_context[ref_frame] |= (1 << ZEROMV_OFFSET);
510 
511         for (idx = 0; idx < *refmv_count; ++idx)
512           if (abs(this_refmv.as_mv.row - ref_mv_stack[idx].this_mv.as_mv.row) <
513                   4 &&
514               abs(this_refmv.as_mv.col - ref_mv_stack[idx].this_mv.as_mv.col) <
515                   4)
516             break;
517 
518         if (idx < *refmv_count) ref_mv_stack[idx].weight += 2 * weight_unit;
519 
520         if (idx == *refmv_count && *refmv_count < MAX_REF_MV_STACK_SIZE) {
521           ref_mv_stack[idx].this_mv.as_int = this_refmv.as_int;
522           // TODO(jingning): Hard coded context number. Need to make it better
523           // sense.
524           ref_mv_stack[idx].pred_diff[0] = 1;
525           ref_mv_stack[idx].weight = 2 * weight_unit;
526           ++(*refmv_count);
527         }
528 
529         ++coll_blk_count;
530       }
531     }
532   } else {
533     // Process compound inter mode
534     for (int i = 0; i < MFMV_STACK_SIZE; ++i) {
535       if (prev_frame_mvs->mfmv[rf[0] - LAST_FRAME][i].as_int != INVALID_MV &&
536           prev_frame_mvs->mfmv[rf[1] - LAST_FRAME][i].as_int != INVALID_MV) {
537         int_mv this_refmv = prev_frame_mvs->mfmv[rf[0] - LAST_FRAME][i];
538         int_mv comp_refmv = prev_frame_mvs->mfmv[rf[1] - LAST_FRAME][i];
539         lower_mv_precision(&this_refmv.as_mv, cm->allow_high_precision_mv);
540         lower_mv_precision(&comp_refmv.as_mv, cm->allow_high_precision_mv);
541 
542         if (blk_row == 0 && blk_col == 0)
543           if (abs(this_refmv.as_mv.row) >= 16 ||
544               abs(this_refmv.as_mv.col) >= 16 ||
545               abs(comp_refmv.as_mv.row) >= 16 ||
546               abs(comp_refmv.as_mv.col) >= 16)
547             mode_context[ref_frame] |= (1 << ZEROMV_OFFSET);
548 
549         for (idx = 0; idx < *refmv_count; ++idx)
550           if (abs(this_refmv.as_mv.row - ref_mv_stack[idx].this_mv.as_mv.row) <
551                   4 &&
552               abs(this_refmv.as_mv.col - ref_mv_stack[idx].this_mv.as_mv.col) <
553                   4 &&
554               abs(comp_refmv.as_mv.row - ref_mv_stack[idx].comp_mv.as_mv.row) <
555                   4 &&
556               abs(comp_refmv.as_mv.col - ref_mv_stack[idx].comp_mv.as_mv.col) <
557                   4)
558             break;
559 
560         if (idx < *refmv_count) ref_mv_stack[idx].weight += 2 * weight_unit;
561 
562         if (idx == *refmv_count && *refmv_count < MAX_REF_MV_STACK_SIZE) {
563           ref_mv_stack[idx].this_mv.as_int = this_refmv.as_int;
564           ref_mv_stack[idx].comp_mv.as_int = comp_refmv.as_int;
565           // TODO(jingning): Hard coded context number. Need to make it better
566           // sense.
567           ref_mv_stack[idx].pred_diff[0] = 1;
568           ref_mv_stack[idx].pred_diff[1] = 1;
569           ref_mv_stack[idx].weight = 2 * weight_unit;
570           ++(*refmv_count);
571         }
572 
573         ++coll_blk_count;
574       }
575     }
576   }
577 
578   return coll_blk_count;
579 }
580 #else
add_col_ref_mv(const AV1_COMMON * cm,const MV_REF * prev_frame_mvs_base,int prev_frame_mvs_stride,const MACROBLOCKD * xd,int mi_row,int mi_col,MV_REFERENCE_FRAME ref_frame,int blk_row,int blk_col,uint8_t * refmv_count,CANDIDATE_MV * ref_mv_stack,int16_t * mode_context)581 static int add_col_ref_mv(const AV1_COMMON *cm,
582                           const MV_REF *prev_frame_mvs_base,
583                           int prev_frame_mvs_stride, const MACROBLOCKD *xd,
584                           int mi_row, int mi_col, MV_REFERENCE_FRAME ref_frame,
585                           int blk_row, int blk_col, uint8_t *refmv_count,
586                           CANDIDATE_MV *ref_mv_stack, int16_t *mode_context) {
587 #if CONFIG_TMV
588   const MV_REF *prev_frame_mvs = prev_frame_mvs_base +
589                                  ((blk_row + 1) >> 1) * prev_frame_mvs_stride +
590                                  ((blk_col + 1) >> 1);
591 #else
592   const MV_REF *prev_frame_mvs =
593       prev_frame_mvs_base + blk_row * prev_frame_mvs_stride + blk_col;
594 #endif
595   POSITION mi_pos;
596   int ref, idx;
597   int coll_blk_count = 0;
598   const int weight_unit = mi_size_wide[BLOCK_8X8];
599 
600 #if CONFIG_TMV
601   mi_pos.row = blk_row;
602   mi_pos.col = blk_col;
603 #else
604 #if CONFIG_MV_COMPRESS
605   mi_pos.row = (mi_row & 0x01) ? blk_row : blk_row + 1;
606   mi_pos.col = (mi_col & 0x01) ? blk_col : blk_col + 1;
607 #else
608   mi_pos.row = blk_row;
609   mi_pos.col = blk_col;
610 #endif
611 #endif  // CONFIG_TMV
612 
613   if (!is_inside(&xd->tile, mi_col, mi_row, cm->mi_rows, cm, &mi_pos))
614     return coll_blk_count;
615   for (ref = 0; ref < 2; ++ref) {
616     if (prev_frame_mvs->ref_frame[ref] == ref_frame) {
617       int_mv this_refmv = prev_frame_mvs->mv[ref];
618 #if CONFIG_AMVR
619       lower_mv_precision(&this_refmv.as_mv, cm->allow_high_precision_mv,
620                          cm->cur_frame_mv_precision_level);
621 #else
622       lower_mv_precision(&this_refmv.as_mv, cm->allow_high_precision_mv);
623 #endif
624 
625 #if CONFIG_OPT_REF_MV
626       if (blk_row == 0 && blk_col == 0)
627 #endif
628       {
629         if (abs(this_refmv.as_mv.row) >= 16 || abs(this_refmv.as_mv.col) >= 16)
630           mode_context[ref_frame] |= (1 << ZEROMV_OFFSET);
631       }
632 
633       for (idx = 0; idx < *refmv_count; ++idx)
634         if (this_refmv.as_int == ref_mv_stack[idx].this_mv.as_int) break;
635 
636       if (idx < *refmv_count) ref_mv_stack[idx].weight += 2 * weight_unit;
637 
638       if (idx == *refmv_count && *refmv_count < MAX_REF_MV_STACK_SIZE) {
639         ref_mv_stack[idx].this_mv.as_int = this_refmv.as_int;
640         ref_mv_stack[idx].pred_diff[0] =
641             av1_get_pred_diff_ctx(prev_frame_mvs->pred_mv[ref], this_refmv);
642         ref_mv_stack[idx].weight = 2 * weight_unit;
643         ++(*refmv_count);
644       }
645 
646       ++coll_blk_count;
647     }
648   }
649 
650   return coll_blk_count;
651 }
652 #endif
653 
setup_ref_mv_list(const AV1_COMMON * cm,const MACROBLOCKD * xd,MV_REFERENCE_FRAME ref_frame,uint8_t * refmv_count,CANDIDATE_MV * ref_mv_stack,int_mv * mv_ref_list,int_mv * gm_mv_candidates,int block,int mi_row,int mi_col,int16_t * mode_context)654 static void setup_ref_mv_list(const AV1_COMMON *cm, const MACROBLOCKD *xd,
655                               MV_REFERENCE_FRAME ref_frame,
656                               uint8_t *refmv_count, CANDIDATE_MV *ref_mv_stack,
657                               int_mv *mv_ref_list,
658 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
659                               int_mv *gm_mv_candidates,
660 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
661                               int block, int mi_row, int mi_col,
662                               int16_t *mode_context) {
663   int idx, nearest_refmv_count = 0;
664   uint8_t newmv_count = 0;
665   CANDIDATE_MV tmp_mv;
666   int len, nr_len;
667 
668 #if CONFIG_TMV
669   const int prev_frame_mvs_stride = ROUND_POWER_OF_TWO(cm->mi_cols, 1);
670   const int tmi_row = mi_row & 0xfffe;
671   const int tmi_col = mi_col & 0xfffe;
672   const MV_REF *const prev_frame_mvs_base =
673       cm->use_prev_frame_mvs
674           ? cm->prev_frame->mvs + (tmi_row >> 1) * prev_frame_mvs_stride +
675                 (tmi_col >> 1)
676           : NULL;
677 #else
678   const int prev_frame_mvs_stride = cm->mi_cols;
679 #if CONFIG_MV_COMPRESS
680   const MV_REF *const prev_frame_mvs_base =
681       cm->use_prev_frame_mvs
682           ? cm->prev_frame->mvs +
683                 (((mi_row >> 1) << 1) + 1) * prev_frame_mvs_stride +
684                 ((mi_col >> 1) << 1) + 1
685           : NULL;
686 #else
687   const MV_REF *const prev_frame_mvs_base =
688       cm->use_prev_frame_mvs
689           ? cm->prev_frame->mvs + mi_row * prev_frame_mvs_stride + mi_col
690           : NULL;
691 #endif
692 #endif  // CONFIG_TMV
693 
694   const int bs = AOMMAX(xd->n8_w, xd->n8_h);
695   const int has_tr = has_top_right(cm, xd, mi_row, mi_col, bs);
696   MV_REFERENCE_FRAME rf[2];
697 
698   const TileInfo *const tile = &xd->tile;
699   int max_row_offset = 0, max_col_offset = 0;
700 #if CONFIG_CB4X4
701   const int row_adj = (xd->n8_h < mi_size_high[BLOCK_8X8]) && (mi_row & 0x01);
702   const int col_adj = (xd->n8_w < mi_size_wide[BLOCK_8X8]) && (mi_col & 0x01);
703 #endif
704   int processed_rows = 0;
705   int processed_cols = 0;
706   int row_offset, col_offset;
707 
708   av1_set_ref_frame(rf, ref_frame);
709   mode_context[ref_frame] = 0;
710   *refmv_count = 0;
711 
712   // Find valid maximum row/col offset.
713   if (xd->up_available) {
714 #if CONFIG_CB4X4
715     max_row_offset = -(MVREF_ROWS << 1) + row_adj;
716 #else
717     max_row_offset = -MVREF_ROWS;
718 #endif
719     max_row_offset =
720         find_valid_row_offset(tile, mi_row, cm->mi_rows, cm, max_row_offset);
721   }
722 
723   if (xd->left_available) {
724 #if CONFIG_CB4X4
725     max_col_offset = -(MVREF_COLS << 1) + col_adj;
726 #else
727     max_col_offset = -MVREF_COLS;
728 #endif
729     max_col_offset = find_valid_col_offset(tile, mi_col, max_col_offset);
730   }
731 
732   // Scan the first above row mode info. row_offset = -1;
733   if (abs(max_row_offset) >= 1)
734     newmv_count +=
735         scan_row_mbmi(cm, xd, mi_col, block, rf, -1, ref_mv_stack, refmv_count,
736 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
737                       gm_mv_candidates,
738 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
739                       max_row_offset, &processed_rows);
740   // Scan the first left column mode info. col_offset = -1;
741   if (abs(max_col_offset) >= 1)
742     newmv_count +=
743         scan_col_mbmi(cm, xd, mi_row, block, rf, -1, ref_mv_stack, refmv_count,
744 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
745                       gm_mv_candidates,
746 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
747                       max_col_offset, &processed_cols);
748   // Check top-right boundary
749   if (has_tr)
750     newmv_count += scan_blk_mbmi(cm, xd, mi_row, mi_col, block, rf, -1,
751                                  xd->n8_w, ref_mv_stack,
752 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
753                                  gm_mv_candidates,
754 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
755                                  refmv_count);
756 
757   nearest_refmv_count = *refmv_count;
758 
759   for (idx = 0; idx < nearest_refmv_count; ++idx)
760     ref_mv_stack[idx].weight += REF_CAT_LEVEL;
761 
762 #if CONFIG_MFMV
763   int blk_row, blk_col;
764   int coll_blk_count = 0;
765   int voffset = AOMMAX(mi_size_high[BLOCK_8X8], xd->n8_h);
766   int hoffset = AOMMAX(mi_size_wide[BLOCK_8X8], xd->n8_w);
767 
768   int tpl_sample_pos[9][2] = {
769     { -2, hoffset }, { 0, hoffset },  { voffset, hoffset },
770     { voffset, 0 },  { voffset, -2 }, { voffset, -4 },
771     { -4, hoffset }, { voffset, 4 },  { 2, hoffset + 4 },
772   };
773   int i;
774 
775   for (blk_row = 0; blk_row < xd->n8_h; blk_row += mi_size_high[BLOCK_8X8]) {
776     for (blk_col = 0; blk_col < xd->n8_w; blk_col += mi_size_wide[BLOCK_8X8]) {
777       // (TODO: yunqing) prev_frame_mvs_base is not used here, tpl_mvs is used.
778       // Can be modified the same way.
779       int is_available = add_tpl_ref_mv(
780           cm, prev_frame_mvs_base, xd, mi_row, mi_col, ref_frame, blk_row,
781           blk_col, refmv_count, ref_mv_stack, mode_context);
782       if (blk_row == 0 && blk_col == 0) coll_blk_count = is_available;
783     }
784   }
785 
786   if (coll_blk_count == 0) mode_context[ref_frame] |= (1 << ZEROMV_OFFSET);
787 
788   for (i = 0; i < 9; ++i) {
789     blk_row = tpl_sample_pos[i][0];
790     blk_col = tpl_sample_pos[i][1];
791 
792     if (!check_sb_border(cm, mi_row, mi_col, blk_row, blk_col)) continue;
793     // (TODO: yunqing) prev_frame_mvs_base is not used here, tpl_mvs is used.
794     // Can be modified the same way.
795     coll_blk_count += add_tpl_ref_mv(cm, prev_frame_mvs_base, xd, mi_row,
796                                      mi_col, ref_frame, blk_row, blk_col,
797                                      refmv_count, ref_mv_stack, mode_context);
798   }
799 #else
800 #if CONFIG_TEMPMV_SIGNALING
801   if (cm->use_prev_frame_mvs && rf[1] == NONE_FRAME)
802 #else
803   if (prev_frame_mvs_base && cm->show_frame && cm->last_show_frame &&
804       rf[1] == NONE_FRAME)
805 #endif
806   {
807     int blk_row, blk_col;
808     int coll_blk_count = 0;
809 #if CONFIG_CB4X4
810     const int mi_step = (xd->n8_w == 1 || xd->n8_h == 1)
811                             ? mi_size_wide[BLOCK_8X8]
812                             : mi_size_wide[BLOCK_16X16];
813 #else
814     const int mi_step = mi_size_wide[BLOCK_16X16];
815 #endif
816 
817 #if CONFIG_TPL_MV
818     // Modified sample positions to be consistent with frame_mvs
819     // spatial resolution.
820     int tpl_sample_pos[5][2] = { { -1, xd->n8_w },
821                                  { 0, xd->n8_w },
822                                  { xd->n8_h, xd->n8_w },
823                                  { xd->n8_h, 0 },
824                                  { xd->n8_h, -1 } };
825     int i;
826 #endif
827 
828     for (blk_row = 0; blk_row < xd->n8_h; blk_row += mi_step) {
829       for (blk_col = 0; blk_col < xd->n8_w; blk_col += mi_step) {
830 #if CONFIG_TMV
831         int is_available =
832             add_col_ref_mv(cm, prev_frame_mvs_base, prev_frame_mvs_stride, xd,
833                            tmi_row, tmi_col, ref_frame, blk_row, blk_col,
834                            refmv_count, ref_mv_stack, mode_context);
835 #else
836         int is_available =
837             add_col_ref_mv(cm, prev_frame_mvs_base, prev_frame_mvs_stride, xd,
838                            mi_row, mi_col, ref_frame, blk_row, blk_col,
839                            refmv_count, ref_mv_stack, mode_context);
840 #endif  // CONFIG_TMV
841 #if CONFIG_OPT_REF_MV
842         if (blk_row == 0 && blk_col == 0) coll_blk_count = is_available;
843 #else
844         coll_blk_count += is_available;
845 #endif
846       }
847     }
848 
849 #if CONFIG_TPL_MV
850     for (i = 0; i < 5; ++i) {
851       blk_row = tpl_sample_pos[i][0];
852       blk_col = tpl_sample_pos[i][1];
853 #if CONFIG_TMV
854       coll_blk_count += add_col_ref_mv(
855           cm, prev_frame_mvs_base, prev_frame_mvs_stride, xd, tmi_row, tmi_col,
856           ref_frame, blk_row, blk_col, refmv_count, ref_mv_stack, mode_context);
857 #else
858       coll_blk_count += add_col_ref_mv(
859           cm, prev_frame_mvs_base, prev_frame_mvs_stride, xd, mi_row, mi_col,
860           ref_frame, blk_row, blk_col, refmv_count, ref_mv_stack, mode_context);
861 #endif  // CONFIG_TMV
862     }
863 #endif
864 
865     if (coll_blk_count == 0) mode_context[ref_frame] |= (1 << ZEROMV_OFFSET);
866   } else {
867     mode_context[ref_frame] |= (1 << ZEROMV_OFFSET);
868   }
869 #endif
870 
871   // Scan the second outer area.
872   scan_blk_mbmi(cm, xd, mi_row, mi_col, block, rf, -1, -1, ref_mv_stack,
873 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
874                 gm_mv_candidates,
875 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
876                 refmv_count);
877   for (idx = 2; idx <= MVREF_ROWS; ++idx) {
878 #if CONFIG_CB4X4
879     row_offset = -(idx << 1) + 1 + row_adj;
880     col_offset = -(idx << 1) + 1 + col_adj;
881 #else
882     row_offset = -idx;
883     col_offset = -idx;
884 #endif
885 
886     if (abs(row_offset) <= abs(max_row_offset) &&
887         abs(row_offset) > processed_rows)
888       scan_row_mbmi(cm, xd, mi_col, block, rf, row_offset, ref_mv_stack,
889                     refmv_count,
890 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
891                     gm_mv_candidates,
892 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
893                     max_row_offset, &processed_rows);
894 
895     if (abs(col_offset) <= abs(max_col_offset) &&
896         abs(col_offset) > processed_cols)
897       scan_col_mbmi(cm, xd, mi_row, block, rf, col_offset, ref_mv_stack,
898                     refmv_count,
899 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
900                     gm_mv_candidates,
901 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
902                     max_col_offset, &processed_cols);
903   }
904 
905 #if CONFIG_CB4X4
906   col_offset = -(MVREF_COLS << 1) + 1 + col_adj;
907 #else
908   col_offset = -MVREF_COLS;
909 #endif
910   if (abs(col_offset) <= abs(max_col_offset) &&
911       abs(col_offset) > processed_cols)
912     scan_col_mbmi(cm, xd, mi_row, block, rf, col_offset, ref_mv_stack,
913                   refmv_count,
914 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
915                   gm_mv_candidates,
916 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
917                   max_col_offset, &processed_cols);
918 
919   switch (nearest_refmv_count) {
920     case 0: mode_context[ref_frame] |= 0;
921 #if !CONFIG_OPT_REF_MV
922       if (*refmv_count >= 1) mode_context[ref_frame] |= 1;
923       if (*refmv_count == 1)
924         mode_context[ref_frame] |= (1 << REFMV_OFFSET);
925       else if (*refmv_count >= 2)
926         mode_context[ref_frame] |= (2 << REFMV_OFFSET);
927 #endif
928       break;
929     case 1: mode_context[ref_frame] |= (newmv_count > 0) ? 2 : 3;
930 #if CONFIG_OPT_REF_MV
931       mode_context[ref_frame] |= (3 << REFMV_OFFSET);
932 #else
933       if (*refmv_count == 1)
934         mode_context[ref_frame] |= (3 << REFMV_OFFSET);
935       else if (*refmv_count >= 2)
936         mode_context[ref_frame] |= (4 << REFMV_OFFSET);
937 #endif
938       break;
939 
940     case 2:
941     default:
942       if (newmv_count >= 2)
943         mode_context[ref_frame] |= 4;
944       else if (newmv_count == 1)
945         mode_context[ref_frame] |= 5;
946       else
947         mode_context[ref_frame] |= 6;
948 
949       mode_context[ref_frame] |= (5 << REFMV_OFFSET);
950       break;
951   }
952 
953   // Rank the likelihood and assign nearest and near mvs.
954   len = nearest_refmv_count;
955   while (len > 0) {
956     nr_len = 0;
957     for (idx = 1; idx < len; ++idx) {
958       if (ref_mv_stack[idx - 1].weight < ref_mv_stack[idx].weight) {
959         tmp_mv = ref_mv_stack[idx - 1];
960         ref_mv_stack[idx - 1] = ref_mv_stack[idx];
961         ref_mv_stack[idx] = tmp_mv;
962         nr_len = idx;
963       }
964     }
965     len = nr_len;
966   }
967 
968   len = *refmv_count;
969   while (len > nearest_refmv_count) {
970     nr_len = nearest_refmv_count;
971     for (idx = nearest_refmv_count + 1; idx < len; ++idx) {
972       if (ref_mv_stack[idx - 1].weight < ref_mv_stack[idx].weight) {
973         tmp_mv = ref_mv_stack[idx - 1];
974         ref_mv_stack[idx - 1] = ref_mv_stack[idx];
975         ref_mv_stack[idx] = tmp_mv;
976         nr_len = idx;
977       }
978     }
979     len = nr_len;
980   }
981 
982   if (rf[1] > NONE_FRAME) {
983     for (idx = 0; idx < *refmv_count; ++idx) {
984       clamp_mv_ref(&ref_mv_stack[idx].this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
985                    xd->n8_h << MI_SIZE_LOG2, xd);
986       clamp_mv_ref(&ref_mv_stack[idx].comp_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
987                    xd->n8_h << MI_SIZE_LOG2, xd);
988     }
989   } else {
990     for (idx = 0; idx < AOMMIN(MAX_MV_REF_CANDIDATES, *refmv_count); ++idx) {
991       mv_ref_list[idx].as_int = ref_mv_stack[idx].this_mv.as_int;
992       clamp_mv_ref(&mv_ref_list[idx].as_mv, xd->n8_w << MI_SIZE_LOG2,
993                    xd->n8_h << MI_SIZE_LOG2, xd);
994     }
995   }
996 }
997 
998 // This function searches the neighbourhood of a given MB/SB
999 // to try and find candidate reference vectors.
find_mv_refs_idx(const AV1_COMMON * cm,const MACROBLOCKD * xd,MODE_INFO * mi,MV_REFERENCE_FRAME ref_frame,int_mv * mv_ref_list,int block,int mi_row,int mi_col,find_mv_refs_sync sync,void * const data,int16_t * mode_context,int_mv zeromv)1000 static void find_mv_refs_idx(const AV1_COMMON *cm, const MACROBLOCKD *xd,
1001                              MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
1002                              int_mv *mv_ref_list, int block, int mi_row,
1003                              int mi_col, find_mv_refs_sync sync,
1004                              void *const data, int16_t *mode_context,
1005                              int_mv zeromv) {
1006   const int *ref_sign_bias = cm->ref_frame_sign_bias;
1007   const int sb_mi_size = mi_size_wide[cm->sb_size];
1008   int i, refmv_count = 0;
1009   int different_ref_found = 0;
1010   int context_counter = 0;
1011 
1012 #if CONFIG_TMV
1013   int tmi_row = mi_row & 0xfffe;
1014   int tmi_col = mi_col & 0xfffe;
1015   POSITION mi_pos = { 0, 0 };
1016   int inside = is_inside(&xd->tile, tmi_col, tmi_row, cm->mi_rows, cm, &mi_pos);
1017   const MV_REF *const prev_frame_mvs =
1018       cm->use_prev_frame_mvs && inside
1019           ? cm->prev_frame->mvs + (tmi_row >> 1) * ((cm->mi_cols + 1) >> 1) +
1020                 (tmi_col >> 1)
1021           : NULL;
1022 #else
1023 #if CONFIG_MV_COMPRESS
1024   const TileInfo *const tile_ = &xd->tile;
1025   int mi_row_end = tile_->mi_row_end;
1026   int mi_col_end = tile_->mi_col_end;
1027   const MV_REF *const prev_frame_mvs =
1028       cm->use_prev_frame_mvs
1029           ? cm->prev_frame->mvs +
1030                 AOMMIN(((mi_row >> 1) << 1) + 1 + (((xd->n8_h - 1) >> 1) << 1),
1031                        mi_row_end - 1) *
1032                     cm->mi_cols +
1033                 AOMMIN(((mi_col >> 1) << 1) + 1 + (((xd->n8_w - 1) >> 1) << 1),
1034                        mi_col_end - 1)
1035           : NULL;
1036 #else
1037   const MV_REF *const prev_frame_mvs =
1038       cm->use_prev_frame_mvs
1039           ? cm->prev_frame->mvs + mi_row * cm->mi_cols + mi_col
1040           : NULL;
1041 #endif
1042 #endif  // CONFIG_TMV
1043 
1044 #if CONFIG_INTRABC
1045   assert(IMPLIES(ref_frame == INTRA_FRAME, cm->use_prev_frame_mvs == 0));
1046 #endif
1047   const TileInfo *const tile = &xd->tile;
1048   const BLOCK_SIZE bsize = mi->mbmi.sb_type;
1049   const int bw = block_size_wide[AOMMAX(bsize, BLOCK_8X8)];
1050   const int bh = block_size_high[AOMMAX(bsize, BLOCK_8X8)];
1051   POSITION mv_ref_search[MVREF_NEIGHBOURS];
1052   const int num_8x8_blocks_wide = num_8x8_blocks_wide_lookup[bsize];
1053   const int num_8x8_blocks_high = num_8x8_blocks_high_lookup[bsize];
1054   mv_ref_search[0].row = num_8x8_blocks_high - 1;
1055   mv_ref_search[0].col = -1;
1056   mv_ref_search[1].row = -1;
1057   mv_ref_search[1].col = num_8x8_blocks_wide - 1;
1058   mv_ref_search[2].row = -1;
1059   mv_ref_search[2].col = (num_8x8_blocks_wide - 1) >> 1;
1060   mv_ref_search[3].row = (num_8x8_blocks_high - 1) >> 1;
1061   mv_ref_search[3].col = -1;
1062   mv_ref_search[4].row = -1;
1063   mv_ref_search[4].col = -1;
1064 #if CONFIG_EXT_PARTITION_TYPES
1065   if (num_8x8_blocks_wide == num_8x8_blocks_high) {
1066     mv_ref_search[5].row = -1;
1067     mv_ref_search[5].col = 0;
1068     mv_ref_search[6].row = 0;
1069     mv_ref_search[6].col = -1;
1070   } else {
1071     mv_ref_search[5].row = -1;
1072     mv_ref_search[5].col = num_8x8_blocks_wide;
1073     mv_ref_search[6].row = num_8x8_blocks_high;
1074     mv_ref_search[6].col = -1;
1075   }
1076 #else
1077   mv_ref_search[5].row = -1;
1078   mv_ref_search[5].col = num_8x8_blocks_wide;
1079   mv_ref_search[6].row = num_8x8_blocks_high;
1080   mv_ref_search[6].col = -1;
1081 #endif  // CONFIG_EXT_PARTITION_TYPES
1082   mv_ref_search[7].row = -1;
1083   mv_ref_search[7].col = -3;
1084   mv_ref_search[8].row = num_8x8_blocks_high - 1;
1085   mv_ref_search[8].col = -3;
1086 
1087 #if CONFIG_CB4X4
1088   for (i = 0; i < MVREF_NEIGHBOURS; ++i) {
1089     mv_ref_search[i].row *= 2;
1090     mv_ref_search[i].col *= 2;
1091   }
1092 #endif  // CONFIG_CB4X4
1093 
1094   // The nearest 2 blocks are treated differently
1095   // if the size < 8x8 we get the mv from the bmi substructure,
1096   // and we also need to keep a mode count.
1097   for (i = 0; i < 2; ++i) {
1098     const POSITION *const mv_ref = &mv_ref_search[i];
1099     if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm, mv_ref)) {
1100       const MODE_INFO *const candidate_mi =
1101           xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride];
1102       const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
1103       // Keep counts for entropy encoding.
1104       context_counter += mode_2_counter[candidate->mode];
1105       different_ref_found = 1;
1106 
1107       if (candidate->ref_frame[0] == ref_frame)
1108         ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 0, mv_ref->col, block),
1109                         refmv_count, mv_ref_list, bw, bh, xd, Done);
1110       else if (candidate->ref_frame[1] == ref_frame)
1111         ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 1, mv_ref->col, block),
1112                         refmv_count, mv_ref_list, bw, bh, xd, Done);
1113     }
1114   }
1115 
1116   // Check the rest of the neighbors in much the same way
1117   // as before except we don't need to keep track of sub blocks or
1118   // mode counts.
1119   for (; i < MVREF_NEIGHBOURS; ++i) {
1120     const POSITION *const mv_ref = &mv_ref_search[i];
1121     if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm, mv_ref)) {
1122       const MB_MODE_INFO *const candidate =
1123           !xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]
1124               ? NULL
1125               : &xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]->mbmi;
1126       if (candidate == NULL) continue;
1127       if ((mi_row & (sb_mi_size - 1)) + mv_ref->row >= sb_mi_size ||
1128           (mi_col & (sb_mi_size - 1)) + mv_ref->col >= sb_mi_size)
1129         continue;
1130       different_ref_found = 1;
1131 
1132       if (candidate->ref_frame[0] == ref_frame)
1133         ADD_MV_REF_LIST(candidate->mv[0], refmv_count, mv_ref_list, bw, bh, xd,
1134                         Done);
1135       else if (candidate->ref_frame[1] == ref_frame)
1136         ADD_MV_REF_LIST(candidate->mv[1], refmv_count, mv_ref_list, bw, bh, xd,
1137                         Done);
1138     }
1139   }
1140 
1141 // TODO(hkuang): Remove this sync after fixing pthread_cond_broadcast
1142 // on windows platform. The sync here is unncessary if use_perv_frame_mvs
1143 // is 0. But after removing it, there will be hang in the unit test on windows
1144 // due to several threads waiting for a thread's signal.
1145 #if defined(_WIN32) && !HAVE_PTHREAD_H
1146   if (cm->frame_parallel_decode && sync != NULL) {
1147     sync(data, mi_row);
1148   }
1149 #endif
1150 
1151   // Check the last frame's mode and mv info.
1152   if (cm->use_prev_frame_mvs) {
1153     // Synchronize here for frame parallel decode if sync function is provided.
1154     if (cm->frame_parallel_decode && sync != NULL) {
1155       sync(data, mi_row);
1156     }
1157 
1158     if (prev_frame_mvs->ref_frame[0] == ref_frame) {
1159       ADD_MV_REF_LIST(prev_frame_mvs->mv[0], refmv_count, mv_ref_list, bw, bh,
1160                       xd, Done);
1161     } else if (prev_frame_mvs->ref_frame[1] == ref_frame) {
1162       ADD_MV_REF_LIST(prev_frame_mvs->mv[1], refmv_count, mv_ref_list, bw, bh,
1163                       xd, Done);
1164     }
1165   }
1166 
1167   // Since we couldn't find 2 mvs from the same reference frame
1168   // go back through the neighbors and find motion vectors from
1169   // different reference frames.
1170   if (different_ref_found) {
1171     for (i = 0; i < MVREF_NEIGHBOURS; ++i) {
1172       const POSITION *mv_ref = &mv_ref_search[i];
1173       if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm, mv_ref)) {
1174         const MB_MODE_INFO *const candidate =
1175             !xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]
1176                 ? NULL
1177                 : &xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]->mbmi;
1178         if (candidate == NULL) continue;
1179         if ((mi_row & (sb_mi_size - 1)) + mv_ref->row >= sb_mi_size ||
1180             (mi_col & (sb_mi_size - 1)) + mv_ref->col >= sb_mi_size)
1181           continue;
1182 
1183         // If the candidate is INTRA we don't want to consider its mv.
1184         IF_DIFF_REF_FRAME_ADD_MV(candidate, ref_frame, ref_sign_bias,
1185                                  refmv_count, mv_ref_list, bw, bh, xd, Done);
1186       }
1187     }
1188   }
1189 
1190   // Since we still don't have a candidate we'll try the last frame.
1191   if (cm->use_prev_frame_mvs) {
1192     if (prev_frame_mvs->ref_frame[0] != ref_frame &&
1193         prev_frame_mvs->ref_frame[0] > INTRA_FRAME) {
1194       int_mv mv = prev_frame_mvs->mv[0];
1195       if (ref_sign_bias[prev_frame_mvs->ref_frame[0]] !=
1196           ref_sign_bias[ref_frame]) {
1197         mv.as_mv.row *= -1;
1198         mv.as_mv.col *= -1;
1199       }
1200       ADD_MV_REF_LIST(mv, refmv_count, mv_ref_list, bw, bh, xd, Done);
1201     }
1202 
1203     if (prev_frame_mvs->ref_frame[1] > INTRA_FRAME &&
1204         prev_frame_mvs->ref_frame[1] != ref_frame) {
1205       int_mv mv = prev_frame_mvs->mv[1];
1206       if (ref_sign_bias[prev_frame_mvs->ref_frame[1]] !=
1207           ref_sign_bias[ref_frame]) {
1208         mv.as_mv.row *= -1;
1209         mv.as_mv.col *= -1;
1210       }
1211       ADD_MV_REF_LIST(mv, refmv_count, mv_ref_list, bw, bh, xd, Done);
1212     }
1213   }
1214 
1215 Done:
1216   if (mode_context)
1217     mode_context[ref_frame] = counter_to_context[context_counter];
1218   for (i = refmv_count; i < MAX_MV_REF_CANDIDATES; ++i)
1219     mv_ref_list[i].as_int = zeromv.as_int;
1220 }
1221 
1222 // This function keeps a mode count for a given MB/SB
av1_update_mv_context(const AV1_COMMON * cm,const MACROBLOCKD * xd,MODE_INFO * mi,MV_REFERENCE_FRAME ref_frame,int_mv * mv_ref_list,int block,int mi_row,int mi_col,int16_t * mode_context)1223 void av1_update_mv_context(const AV1_COMMON *cm, const MACROBLOCKD *xd,
1224                            MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
1225                            int_mv *mv_ref_list, int block, int mi_row,
1226                            int mi_col, int16_t *mode_context) {
1227   int i, refmv_count = 0;
1228   int context_counter = 0;
1229   const int bw = block_size_wide[mi->mbmi.sb_type];
1230   const int bh = block_size_high[mi->mbmi.sb_type];
1231   const TileInfo *const tile = &xd->tile;
1232   POSITION mv_ref_search[2];
1233   const int num_8x8_blocks_wide = mi_size_wide[mi->mbmi.sb_type];
1234   const int num_8x8_blocks_high = mi_size_high[mi->mbmi.sb_type];
1235 
1236   mv_ref_search[0].row = num_8x8_blocks_high - 1;
1237   mv_ref_search[0].col = -1;
1238   mv_ref_search[1].row = -1;
1239   mv_ref_search[1].col = num_8x8_blocks_wide - 1;
1240 
1241   // Blank the reference vector list
1242   memset(mv_ref_list, 0, sizeof(*mv_ref_list) * MAX_MV_REF_CANDIDATES);
1243 
1244   // The nearest 2 blocks are examined only.
1245   // If the size < 8x8, we get the mv from the bmi substructure;
1246   for (i = 0; i < 2; ++i) {
1247     const POSITION *const mv_ref = &mv_ref_search[i];
1248     if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm, mv_ref)) {
1249       const MODE_INFO *const candidate_mi =
1250           xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride];
1251       const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
1252 
1253       // Keep counts for entropy encoding.
1254       context_counter += mode_2_counter[candidate->mode];
1255 
1256       if (candidate->ref_frame[0] == ref_frame) {
1257         ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 0, mv_ref->col, block),
1258                         refmv_count, mv_ref_list, bw, bh, xd, Done);
1259       } else if (candidate->ref_frame[1] == ref_frame) {
1260         ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 1, mv_ref->col, block),
1261                         refmv_count, mv_ref_list, bw, bh, xd, Done);
1262       }
1263     }
1264   }
1265 
1266 Done:
1267 
1268   if (mode_context)
1269     mode_context[ref_frame] = counter_to_context[context_counter];
1270 }
1271 
av1_find_mv_refs(const AV1_COMMON * cm,const MACROBLOCKD * xd,MODE_INFO * mi,MV_REFERENCE_FRAME ref_frame,uint8_t * ref_mv_count,CANDIDATE_MV * ref_mv_stack,int16_t * compound_mode_context,int_mv * mv_ref_list,int mi_row,int mi_col,find_mv_refs_sync sync,void * const data,int16_t * mode_context)1272 void av1_find_mv_refs(const AV1_COMMON *cm, const MACROBLOCKD *xd,
1273                       MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
1274                       uint8_t *ref_mv_count, CANDIDATE_MV *ref_mv_stack,
1275                       int16_t *compound_mode_context, int_mv *mv_ref_list,
1276                       int mi_row, int mi_col, find_mv_refs_sync sync,
1277                       void *const data, int16_t *mode_context) {
1278   int_mv zeromv[2];
1279 #if CONFIG_GLOBAL_MOTION
1280   BLOCK_SIZE bsize = mi->mbmi.sb_type;
1281 #endif  // CONFIG_GLOBAL_MOTION
1282   int idx, all_zero = 1;
1283 #if CONFIG_GLOBAL_MOTION
1284   MV_REFERENCE_FRAME rf[2];
1285 #endif  // CONFIG_GLOBAL_MOTION
1286 
1287   av1_update_mv_context(cm, xd, mi, ref_frame, mv_ref_list, -1, mi_row, mi_col,
1288                         compound_mode_context);
1289 
1290 #if CONFIG_GLOBAL_MOTION
1291   if (!CONFIG_INTRABC || ref_frame != INTRA_FRAME) {
1292     av1_set_ref_frame(rf, ref_frame);
1293     zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[rf[0]],
1294                                             cm->allow_high_precision_mv, bsize,
1295                                             mi_col, mi_row, 0
1296 #if CONFIG_AMVR
1297                                             ,
1298                                             cm->cur_frame_mv_precision_level
1299 #endif
1300                                             )
1301                            .as_int;
1302     zeromv[1].as_int =
1303         (rf[1] != NONE_FRAME)
1304             ? gm_get_motion_vector(&cm->global_motion[rf[1]],
1305                                    cm->allow_high_precision_mv, bsize, mi_col,
1306                                    mi_row, 0
1307 #if CONFIG_AMVR
1308                                    ,
1309                                    cm->cur_frame_mv_precision_level
1310 #endif
1311                                    )
1312                   .as_int
1313             : 0;
1314   } else {
1315     zeromv[0].as_int = zeromv[1].as_int = 0;
1316   }
1317 #else
1318   zeromv[0].as_int = zeromv[1].as_int = 0;
1319 #endif  // CONFIG_GLOBAL_MOTION
1320 
1321   if (ref_frame <= ALTREF_FRAME)
1322     find_mv_refs_idx(cm, xd, mi, ref_frame, mv_ref_list, -1, mi_row, mi_col,
1323                      sync, data, mode_context, zeromv[0]);
1324 
1325   setup_ref_mv_list(cm, xd, ref_frame, ref_mv_count, ref_mv_stack, mv_ref_list,
1326 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
1327                     zeromv,
1328 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
1329                     -1, mi_row, mi_col, mode_context);
1330   /* Note: If global motion is enabled, then we want to set the ALL_ZERO flag
1331      iff all of the MVs we could generate with NEARMV/NEARESTMV are equivalent
1332      to the global motion vector.
1333      Note: For the following to work properly, the encoder can't throw away
1334      any global motion models after calling this function, even if they are
1335      unused. Instead we rely on the recode loop: If any non-IDENTITY model
1336      is unused, the whole frame will be re-encoded without it.
1337      The problem is that, otherwise, we can end up in the following situation:
1338      * Encoder has a global motion model with nonzero translational part,
1339        and all candidate MVs are zero. So the ALL_ZERO flag is unset.
1340      * Encoder throws away global motion because it is never used.
1341      * Decoder sees that there is no global motion and all candidate MVs are
1342        zero, so sets the ALL_ZERO flag.
1343      * This leads to an encode/decode mismatch.
1344   */
1345   for (idx = 0; idx < AOMMIN(3, *ref_mv_count); ++idx) {
1346     if (ref_mv_stack[idx].this_mv.as_int != zeromv[0].as_int) all_zero = 0;
1347     if (ref_frame > ALTREF_FRAME)
1348       if (ref_mv_stack[idx].comp_mv.as_int != zeromv[1].as_int) all_zero = 0;
1349   }
1350   if (*ref_mv_count < 2 && ref_frame <= ALTREF_FRAME) {
1351     for (idx = 0; idx < MAX_MV_REF_CANDIDATES; ++idx)
1352       if (mv_ref_list[idx].as_int != zeromv[0].as_int) all_zero = 0;
1353   }
1354 
1355 #if !CONFIG_OPT_REF_MV
1356   if (all_zero) mode_context[ref_frame] |= (1 << ALL_ZERO_FLAG_OFFSET);
1357 #else
1358   (void)all_zero;
1359 #endif
1360 }
1361 
av1_find_best_ref_mvs(int allow_hp,int_mv * mvlist,int_mv * nearest_mv,int_mv * near_mv,int is_integer)1362 void av1_find_best_ref_mvs(int allow_hp, int_mv *mvlist, int_mv *nearest_mv,
1363                            int_mv *near_mv
1364 #if CONFIG_AMVR
1365                            ,
1366                            int is_integer
1367 #endif
1368                            ) {
1369   int i;
1370   // Make sure all the candidates are properly clamped etc
1371   for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
1372 #if CONFIG_AMVR
1373     lower_mv_precision(&mvlist[i].as_mv, allow_hp, is_integer);
1374 #else
1375     lower_mv_precision(&mvlist[i].as_mv, allow_hp);
1376 #endif
1377   }
1378   *nearest_mv = mvlist[0];
1379   *near_mv = mvlist[1];
1380 }
1381 
av1_append_sub8x8_mvs_for_idx(const AV1_COMMON * cm,MACROBLOCKD * xd,int block,int ref,int mi_row,int mi_col,CANDIDATE_MV * ref_mv_stack,uint8_t * ref_mv_count,int_mv * mv_list,int_mv * nearest_mv,int_mv * near_mv)1382 void av1_append_sub8x8_mvs_for_idx(const AV1_COMMON *cm, MACROBLOCKD *xd,
1383                                    int block, int ref, int mi_row, int mi_col,
1384                                    CANDIDATE_MV *ref_mv_stack,
1385                                    uint8_t *ref_mv_count, int_mv *mv_list,
1386                                    int_mv *nearest_mv, int_mv *near_mv) {
1387   MODE_INFO *const mi = xd->mi[0];
1388   b_mode_info *bmi = mi->bmi;
1389   int n;
1390   int_mv zeromv;
1391   CANDIDATE_MV tmp_mv;
1392   uint8_t idx;
1393   uint8_t above_count = 0, left_count = 0;
1394   MV_REFERENCE_FRAME rf[2] = { mi->mbmi.ref_frame[ref], NONE_FRAME };
1395   *ref_mv_count = 0;
1396 
1397   assert(MAX_MV_REF_CANDIDATES == 2);
1398 
1399 #if CONFIG_GLOBAL_MOTION
1400   zeromv.as_int = gm_get_motion_vector(&cm->global_motion[rf[0]],
1401                                        cm->allow_high_precision_mv,
1402                                        mi->mbmi.sb_type, mi_col, mi_row, block
1403 #if CONFIG_AMVR
1404                                        ,
1405                                        cm->cur_frame_mv_precision_level
1406 #endif
1407                                        )
1408                       .as_int;
1409 #else
1410   zeromv.as_int = 0;
1411 #endif
1412   find_mv_refs_idx(cm, xd, mi, mi->mbmi.ref_frame[ref], mv_list, block, mi_row,
1413                    mi_col, NULL, NULL, NULL, zeromv);
1414 
1415   scan_blk_mbmi(cm, xd, mi_row, mi_col, block, rf, -1, 0, ref_mv_stack,
1416 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
1417                 &zeromv,
1418 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
1419                 ref_mv_count);
1420   above_count = *ref_mv_count;
1421 
1422   scan_blk_mbmi(cm, xd, mi_row, mi_col, block, rf, 0, -1, ref_mv_stack,
1423 #if CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
1424                 &zeromv,
1425 #endif  // CONFIG_GLOBAL_MOTION && USE_CUR_GM_REFMV
1426                 ref_mv_count);
1427   left_count = *ref_mv_count - above_count;
1428 
1429   if (above_count > 1 && left_count > 0) {
1430     tmp_mv = ref_mv_stack[1];
1431     ref_mv_stack[1] = ref_mv_stack[above_count];
1432     ref_mv_stack[above_count] = tmp_mv;
1433   }
1434 
1435   for (idx = 0; idx < *ref_mv_count; ++idx)
1436     clamp_mv_ref(&ref_mv_stack[idx].this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
1437                  xd->n8_h << MI_SIZE_LOG2, xd);
1438 
1439   for (idx = 0; idx < AOMMIN(MAX_MV_REF_CANDIDATES, *ref_mv_count); ++idx)
1440     mv_list[idx].as_int = ref_mv_stack[idx].this_mv.as_int;
1441 
1442   near_mv->as_int = 0;
1443   switch (block) {
1444     case 0:
1445       nearest_mv->as_int = mv_list[0].as_int;
1446       near_mv->as_int = mv_list[1].as_int;
1447       break;
1448     case 1:
1449     case 2:
1450       nearest_mv->as_int = bmi[0].as_mv[ref].as_int;
1451       for (n = 0; n < MAX_MV_REF_CANDIDATES; ++n)
1452         if (nearest_mv->as_int != mv_list[n].as_int) {
1453           near_mv->as_int = mv_list[n].as_int;
1454           break;
1455         }
1456       break;
1457     case 3: {
1458       int_mv candidates[2 + MAX_MV_REF_CANDIDATES];
1459       candidates[0] = bmi[1].as_mv[ref];
1460       candidates[1] = bmi[0].as_mv[ref];
1461       candidates[2] = mv_list[0];
1462       candidates[3] = mv_list[1];
1463 
1464       nearest_mv->as_int = bmi[2].as_mv[ref].as_int;
1465       for (n = 0; n < 2 + MAX_MV_REF_CANDIDATES; ++n)
1466         if (nearest_mv->as_int != candidates[n].as_int) {
1467           near_mv->as_int = candidates[n].as_int;
1468           break;
1469         }
1470       break;
1471     }
1472     default: assert(0 && "Invalid block index.");
1473   }
1474 }
1475 
1476 #if CONFIG_FRAME_MARKER
av1_setup_frame_buf_refs(AV1_COMMON * cm)1477 void av1_setup_frame_buf_refs(AV1_COMMON *cm) {
1478   cm->cur_frame->cur_frame_offset = cm->frame_offset;
1479   int alt_buf_idx = cm->frame_refs[ALTREF_FRAME - LAST_FRAME].idx;
1480   int lst_buf_idx = cm->frame_refs[LAST_FRAME - LAST_FRAME].idx;
1481   int gld_buf_idx = cm->frame_refs[GOLDEN_FRAME - LAST_FRAME].idx;
1482 
1483 #if CONFIG_EXT_REFS
1484   int lst2_buf_idx = cm->frame_refs[LAST2_FRAME - LAST_FRAME].idx;
1485   int lst3_buf_idx = cm->frame_refs[LAST3_FRAME - LAST_FRAME].idx;
1486   int bwd_buf_idx = cm->frame_refs[BWDREF_FRAME - LAST_FRAME].idx;
1487   int alt2_buf_idx = cm->frame_refs[ALTREF2_FRAME - LAST_FRAME].idx;
1488 #endif
1489 
1490   if (alt_buf_idx >= 0)
1491     cm->cur_frame->alt_frame_offset =
1492         cm->buffer_pool->frame_bufs[alt_buf_idx].cur_frame_offset;
1493 
1494   if (lst_buf_idx >= 0)
1495     cm->cur_frame->lst_frame_offset =
1496         cm->buffer_pool->frame_bufs[lst_buf_idx].cur_frame_offset;
1497 
1498   if (gld_buf_idx >= 0)
1499     cm->cur_frame->gld_frame_offset =
1500         cm->buffer_pool->frame_bufs[gld_buf_idx].cur_frame_offset;
1501 
1502 #if CONFIG_EXT_REFS
1503   if (lst2_buf_idx >= 0)
1504     cm->cur_frame->lst2_frame_offset =
1505         cm->buffer_pool->frame_bufs[lst2_buf_idx].cur_frame_offset;
1506 
1507   if (lst3_buf_idx >= 0)
1508     cm->cur_frame->lst3_frame_offset =
1509         cm->buffer_pool->frame_bufs[lst3_buf_idx].cur_frame_offset;
1510 
1511   if (bwd_buf_idx >= 0)
1512     cm->cur_frame->bwd_frame_offset =
1513         cm->buffer_pool->frame_bufs[bwd_buf_idx].cur_frame_offset;
1514 
1515   if (alt2_buf_idx >= 0)
1516     cm->cur_frame->alt2_frame_offset =
1517         cm->buffer_pool->frame_bufs[alt2_buf_idx].cur_frame_offset;
1518 #endif
1519 }
1520 
1521 #if CONFIG_FRAME_SIGN_BIAS
av1_setup_frame_sign_bias(AV1_COMMON * cm)1522 void av1_setup_frame_sign_bias(AV1_COMMON *cm) {
1523   MV_REFERENCE_FRAME ref_frame;
1524   for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
1525     const int buf_idx = cm->frame_refs[ref_frame - LAST_FRAME].idx;
1526     if (buf_idx != INVALID_IDX) {
1527       const int ref_frame_offset =
1528           cm->buffer_pool->frame_bufs[buf_idx].cur_frame_offset;
1529       cm->ref_frame_sign_bias[ref_frame] =
1530           (ref_frame_offset <= (int)cm->frame_offset) ? 0 : 1;
1531     } else {
1532       cm->ref_frame_sign_bias[ref_frame] = 0;
1533     }
1534   }
1535 }
1536 #endif  // CONFIG_FRAME_SIGN_BIAS
1537 #endif  // CONFIG_FRAME_MARKER
1538 
1539 #if CONFIG_MFMV
1540 // Although we assign 32 bit integers, all the values are strictly under 14
1541 // bits.
1542 static int div_mult[32] = {
1543   0,    16384, 8192, 5461, 4096, 3276, 2730, 2340, 2048, 1820, 1638,
1544   1489, 1365,  1260, 1170, 1092, 1024, 963,  910,  862,  819,  780,
1545   744,  712,   682,  655,  630,  606,  585,  564,  546,  528,
1546 };
1547 
1548 // TODO(jingning): Consider the use of lookup table for (num / den)
1549 // altogether.
get_mv_projection(MV * output,MV ref,int num,int den)1550 static void get_mv_projection(MV *output, MV ref, int num, int den) {
1551   output->row =
1552       (int16_t)(ROUND_POWER_OF_TWO(ref.row * num * div_mult[den], 14));
1553   output->col =
1554       (int16_t)(ROUND_POWER_OF_TWO(ref.col * num * div_mult[den], 14));
1555 }
1556 
1557 #define MAX_OFFSET_WIDTH 64
1558 #define MAX_OFFSET_HEIGHT 32
1559 
get_block_position(AV1_COMMON * cm,int * mi_r,int * mi_c,int blk_row,int blk_col,MV mv,int sign_bias)1560 static int get_block_position(AV1_COMMON *cm, int *mi_r, int *mi_c, int blk_row,
1561                               int blk_col, MV mv, int sign_bias) {
1562   if ((abs(mv.row) >> 3) > MAX_OFFSET_HEIGHT ||
1563       (abs(mv.col) >> 3) > MAX_OFFSET_WIDTH)
1564     return 0;
1565 
1566   int row = (sign_bias == 1) ? blk_row - (mv.row >> (3 + MI_SIZE_LOG2))
1567                              : blk_row + (mv.row >> (3 + MI_SIZE_LOG2));
1568   int col = (sign_bias == 1) ? blk_col - (mv.col >> (3 + MI_SIZE_LOG2))
1569                              : blk_col + (mv.col >> (3 + MI_SIZE_LOG2));
1570 
1571   if (row < 0 || row >= cm->mi_rows || col < 0 || col >= cm->mi_cols) return 0;
1572 
1573   *mi_r = row;
1574   *mi_c = col;
1575 
1576   return 1;
1577 }
1578 
mv_sign_reverse(int_mv ref)1579 static uint32_t mv_sign_reverse(int_mv ref) {
1580   int_mv this_mv;
1581   this_mv.as_mv.row = -ref.as_mv.row;
1582   this_mv.as_mv.col = -ref.as_mv.col;
1583 
1584   return this_mv.as_int;
1585 }
1586 
av1_setup_motion_field(AV1_COMMON * cm)1587 void av1_setup_motion_field(AV1_COMMON *cm) {
1588   int cur_frame_index = cm->cur_frame->cur_frame_offset;
1589   int lst_frame_index = 0, alt_frame_index = 0, gld_frame_index = 0;
1590 #if CONFIG_EXT_REFS
1591   int lst2_frame_index = 0, lst3_frame_index = 0;
1592   int bwd_frame_index = 0, alt2_frame_index = 0;
1593 #endif
1594   TPL_MV_REF *tpl_mvs_base = cm->cur_frame->tpl_mvs;
1595 
1596   for (int ref_frame = 0; ref_frame < INTER_REFS_PER_FRAME; ++ref_frame) {
1597     int size = (cm->mi_rows + 16) * cm->mi_stride;
1598     for (int idx = 0; idx < size; ++idx) {
1599       for (int i = 0; i < MFMV_STACK_SIZE; ++i)
1600         tpl_mvs_base[idx].mfmv[ref_frame][i].as_int = INVALID_MV;
1601     }
1602   }
1603 
1604   int alt_buf_idx = cm->frame_refs[ALTREF_FRAME - LAST_FRAME].idx;
1605   int lst_buf_idx = cm->frame_refs[LAST_FRAME - LAST_FRAME].idx;
1606   int gld_buf_idx = cm->frame_refs[GOLDEN_FRAME - LAST_FRAME].idx;
1607 #if CONFIG_EXT_REFS
1608   int lst2_buf_idx = cm->frame_refs[LAST2_FRAME - LAST_FRAME].idx;
1609   int lst3_buf_idx = cm->frame_refs[LAST3_FRAME - LAST_FRAME].idx;
1610   int bwd_buf_idx = cm->frame_refs[BWDREF_FRAME - LAST_FRAME].idx;
1611   int alt2_buf_idx = cm->frame_refs[ALTREF2_FRAME - LAST_FRAME].idx;
1612 #endif
1613 
1614   if (alt_buf_idx >= 0)
1615     alt_frame_index = cm->buffer_pool->frame_bufs[alt_buf_idx].cur_frame_offset;
1616 
1617   if (lst_buf_idx >= 0)
1618     lst_frame_index = cm->buffer_pool->frame_bufs[lst_buf_idx].cur_frame_offset;
1619 
1620   if (gld_buf_idx >= 0)
1621     gld_frame_index = cm->buffer_pool->frame_bufs[gld_buf_idx].cur_frame_offset;
1622 
1623 #if CONFIG_EXT_REFS
1624   if (lst2_buf_idx >= 0)
1625     lst2_frame_index =
1626         cm->buffer_pool->frame_bufs[lst2_buf_idx].cur_frame_offset;
1627 
1628   if (lst3_buf_idx >= 0)
1629     lst3_frame_index =
1630         cm->buffer_pool->frame_bufs[lst3_buf_idx].cur_frame_offset;
1631 
1632   if (bwd_buf_idx >= 0)
1633     bwd_frame_index = cm->buffer_pool->frame_bufs[bwd_buf_idx].cur_frame_offset;
1634 
1635   if (alt2_buf_idx >= 0)
1636     alt2_frame_index =
1637         cm->buffer_pool->frame_bufs[alt2_buf_idx].cur_frame_offset;
1638 #endif
1639 
1640   if (alt_frame_index < cur_frame_index) return;
1641 
1642   // ======================
1643   // Process last frame
1644   // ======================
1645   if (lst_buf_idx >= 0) {
1646     MV_REF *mv_ref_base = cm->buffer_pool->frame_bufs[lst_buf_idx].mvs;
1647     const int lst_frame_idx =
1648         cm->buffer_pool->frame_bufs[lst_buf_idx].lst_frame_offset;
1649     const int alt_frame_idx =
1650         cm->buffer_pool->frame_bufs[lst_buf_idx].alt_frame_offset;
1651     const int gld_frame_idx =
1652         cm->buffer_pool->frame_bufs[lst_buf_idx].gld_frame_offset;
1653 #if CONFIG_EXT_REFS
1654     const int lst2_frame_idx =
1655         cm->buffer_pool->frame_bufs[lst_buf_idx].lst2_frame_offset;
1656     const int lst3_frame_idx =
1657         cm->buffer_pool->frame_bufs[lst_buf_idx].lst3_frame_offset;
1658     const int bwd_frame_idx =
1659         cm->buffer_pool->frame_bufs[lst_buf_idx].bwd_frame_offset;
1660     const int alt2_frame_idx =
1661         cm->buffer_pool->frame_bufs[lst_buf_idx].alt2_frame_offset;
1662 #endif
1663 
1664     int alt_offset = AOMMAX(1, alt_frame_idx - lst_frame_index);
1665     int lst_offset = AOMMAX(1, lst_frame_index - lst_frame_idx);
1666     int gld_offset = AOMMAX(1, lst_frame_index - gld_frame_idx);
1667     int cur_to_lst = cur_frame_index - lst_frame_index;
1668     int cur_to_alt = alt_frame_index - cur_frame_index;
1669     int cur_to_gld = cur_frame_index - gld_frame_index;
1670 
1671 #if CONFIG_EXT_REFS
1672     int bwd_offset = AOMMAX(1, bwd_frame_idx - lst_frame_index);
1673     int alt2_offset = AOMMAX(1, alt2_frame_idx - lst_frame_index);
1674     int lst2_offset = AOMMAX(1, lst_frame_index - lst2_frame_idx);
1675     int lst3_offset = AOMMAX(1, lst_frame_index - lst3_frame_idx);
1676     int cur_to_lst2 = cur_frame_index - lst2_frame_index;
1677     int cur_to_lst3 = cur_frame_index - lst3_frame_index;
1678     int cur_to_bwd = bwd_frame_index - cur_frame_index;
1679     int cur_to_alt2 = alt2_frame_index - cur_frame_index;
1680 #endif
1681 
1682     const int is_lst_overlay = (alt_frame_idx == gld_frame_index);
1683     // clang-format off
1684     const int ref_frame_offset_buffer[TOTAL_REFS_PER_FRAME] = {
1685 #if CONFIG_EXT_REFS
1686         0, lst_offset, lst2_offset, lst3_offset, gld_offset,
1687         bwd_offset, alt2_offset, alt_offset
1688 #else
1689         0, lst_offset, gld_offset, alt_offset
1690 #endif
1691     };
1692     // clang-format on
1693 
1694     for (int blk_row = 0; blk_row < cm->mi_rows && !is_lst_overlay; ++blk_row) {
1695       for (int blk_col = 0; blk_col < cm->mi_cols; ++blk_col) {
1696         MV_REF *mv_ref = &mv_ref_base[blk_row * cm->mi_cols + blk_col];
1697         MV fwd_mv = mv_ref->mv[0].as_mv;
1698         MV_REFERENCE_FRAME ref_frame[2] = { mv_ref->ref_frame[0],
1699                                             mv_ref->ref_frame[1] };
1700 
1701         // Derive  motion vectors toward last reference frame.
1702         if (ref_frame[0] <= GOLDEN_FRAME && ref_frame[0] > INTRA_FRAME) {
1703           int_mv this_mv;
1704           int mi_r, mi_c;
1705 
1706           const int ref_frame_offset = ref_frame_offset_buffer[ref_frame[0]];
1707 
1708           get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_lst,
1709                             ref_frame_offset);
1710           int pos_valid = get_block_position(cm, &mi_r, &mi_c, blk_row, blk_col,
1711                                              this_mv.as_mv, 1);
1712 
1713           if (pos_valid) {
1714             int mi_offset = mi_r * cm->mi_stride + mi_c;
1715             tpl_mvs_base[mi_offset].mfmv[FWD_RF_OFFSET(LAST_FRAME)][0].as_int =
1716                 this_mv.as_int;
1717 
1718 #if CONFIG_EXT_REFS
1719             get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_lst2,
1720                               ref_frame_offset);
1721             tpl_mvs_base[mi_offset].mfmv[FWD_RF_OFFSET(LAST2_FRAME)][0].as_int =
1722                 this_mv.as_int;
1723 
1724             get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_lst3,
1725                               ref_frame_offset);
1726             tpl_mvs_base[mi_offset].mfmv[FWD_RF_OFFSET(LAST3_FRAME)][0].as_int =
1727                 this_mv.as_int;
1728 #endif
1729             get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_gld,
1730                               ref_frame_offset);
1731             tpl_mvs_base[mi_offset].mfmv[FWD_RF_OFFSET(GOLDEN_FRAME)]
1732                                         [0].as_int = this_mv.as_int;
1733           }
1734         }
1735 
1736         for (int idx = 0; idx < 2; ++idx) {
1737           if (ref_frame[idx] <= GOLDEN_FRAME) continue;
1738 
1739           int_mv this_mv;
1740           int mi_r, mi_c;
1741           fwd_mv = mv_ref->mv[idx].as_mv;
1742 
1743           const int ref_frame_offset = ref_frame_offset_buffer[ref_frame[idx]];
1744 
1745           get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_lst,
1746                             ref_frame_offset);
1747           int pos_valid = get_block_position(cm, &mi_r, &mi_c, blk_row, blk_col,
1748                                              this_mv.as_mv, 0);
1749 
1750           if (pos_valid) {
1751             int mi_offset = mi_r * cm->mi_stride + mi_c;
1752             get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_alt,
1753                               ref_frame_offset);
1754             tpl_mvs_base[mi_offset].mfmv[FWD_RF_OFFSET(ALTREF_FRAME)]
1755                                         [0].as_int = this_mv.as_int;
1756 
1757 #if CONFIG_EXT_REFS
1758             get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_bwd,
1759                               ref_frame_offset);
1760             tpl_mvs_base[mi_offset].mfmv[FWD_RF_OFFSET(BWDREF_FRAME)]
1761                                         [0].as_int = this_mv.as_int;
1762             get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_alt2,
1763                               ref_frame_offset);
1764             tpl_mvs_base[mi_offset].mfmv[FWD_RF_OFFSET(ALTREF2_FRAME)]
1765                                         [0].as_int = this_mv.as_int;
1766 #endif
1767           }
1768         }
1769       }
1770     }
1771   }
1772 
1773   // =======================
1774   // Process ARF frame
1775   // =======================
1776   if (alt_buf_idx >= 0) {
1777     MV_REF *mv_ref_base = cm->buffer_pool->frame_bufs[alt_buf_idx].mvs;
1778     const int lst_frame_idx =
1779         cm->buffer_pool->frame_bufs[alt_buf_idx].lst_frame_offset;
1780     const int gld_frame_idx =
1781         cm->buffer_pool->frame_bufs[alt_buf_idx].gld_frame_offset;
1782 #if CONFIG_EXT_REFS
1783     const int lst2_frame_idx =
1784         cm->buffer_pool->frame_bufs[alt_buf_idx].lst2_frame_offset;
1785     const int lst3_frame_idx =
1786         cm->buffer_pool->frame_bufs[alt_buf_idx].lst3_frame_offset;
1787     const int bwd_frame_idx =
1788         cm->buffer_pool->frame_bufs[alt_buf_idx].bwd_frame_offset;
1789     const int alt2_frame_idx =
1790         cm->buffer_pool->frame_bufs[alt_buf_idx].alt2_frame_offset;
1791 #endif
1792 
1793     int lst_offset = AOMMAX(1, alt_frame_index - lst_frame_idx);
1794     int gld_offset = AOMMAX(1, alt_frame_index - gld_frame_idx);
1795     int cur_to_alt = alt_frame_index - cur_frame_index;
1796     int cur_to_lst = cur_frame_index - lst_frame_index;
1797     int cur_to_gld = cur_frame_index - gld_frame_index;
1798 #if CONFIG_EXT_REFS
1799     int bwd_offset = AOMMAX(1, alt_frame_index - bwd_frame_idx);
1800     int alt2_offset = AOMMAX(1, alt_frame_index - alt2_frame_idx);
1801     int lst2_offset = AOMMAX(1, alt_frame_index - lst2_frame_idx);
1802     int lst3_offset = AOMMAX(1, alt_frame_index - lst3_frame_idx);
1803     int cur_to_lst2 = cur_frame_index - lst2_frame_index;
1804     int cur_to_lst3 = cur_frame_index - lst3_frame_index;
1805     int cur_to_bwd = bwd_frame_index - cur_frame_index;
1806     int cur_to_alt2 = alt2_frame_index - cur_frame_index;
1807 #endif
1808     const int ref_stamp = FWD_RF_OFFSET(ALTREF_FRAME);
1809     // clang-format off
1810     const int ref_frame_offset_buffer[TOTAL_REFS_PER_FRAME] = {
1811 #if CONFIG_EXT_REFS
1812         0, lst_offset, lst2_offset, lst3_offset, gld_offset,
1813         bwd_offset, alt2_offset, 0,
1814 #else
1815         0, lst_offset, gld_offset, 0,
1816 #endif
1817     };
1818     // clang-format on
1819 
1820     for (int blk_row = 0; blk_row < cm->mi_rows; ++blk_row) {
1821       for (int blk_col = 0; blk_col < cm->mi_cols; ++blk_col) {
1822         MV_REF *mv_ref = &mv_ref_base[blk_row * cm->mi_cols + blk_col];
1823         MV fwd_mv = mv_ref->mv[0].as_mv;
1824         MV_REFERENCE_FRAME ref_frame[2] = { mv_ref->ref_frame[0],
1825                                             mv_ref->ref_frame[1] };
1826 
1827         const int ref_frame_offset = ref_frame_offset_buffer[ref_frame[0]];
1828 
1829         if (ref_frame[0] <= GOLDEN_FRAME && ref_frame[0] > INTRA_FRAME) {
1830           int_mv this_mv;
1831           int mi_r, mi_c;
1832 
1833           get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_alt,
1834                             ref_frame_offset);
1835           int pos_valid = get_block_position(cm, &mi_r, &mi_c, blk_row, blk_col,
1836                                              this_mv.as_mv, 0);
1837 
1838           if (pos_valid) {
1839             int mi_offset = mi_r * cm->mi_stride + mi_c;
1840             tpl_mvs_base[mi_offset]
1841                 .mfmv[FWD_RF_OFFSET(ALTREF_FRAME)][ref_stamp]
1842                 .as_int = mv_sign_reverse(this_mv);
1843 
1844             get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_lst,
1845                               ref_frame_offset);
1846             tpl_mvs_base[mi_offset]
1847                 .mfmv[FWD_RF_OFFSET(LAST_FRAME)][ref_stamp]
1848                 .as_int = this_mv.as_int;
1849 
1850 #if CONFIG_EXT_REFS
1851             get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_bwd,
1852                               ref_frame_offset);
1853             tpl_mvs_base[mi_offset]
1854                 .mfmv[FWD_RF_OFFSET(BWDREF_FRAME)][ref_stamp]
1855                 .as_int = mv_sign_reverse(this_mv);
1856 
1857             get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_alt2,
1858                               ref_frame_offset);
1859             tpl_mvs_base[mi_offset]
1860                 .mfmv[FWD_RF_OFFSET(ALTREF2_FRAME)][ref_stamp]
1861                 .as_int = mv_sign_reverse(this_mv);
1862 
1863             if (ref_frame[0] >= LAST2_FRAME) {
1864               get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_lst2,
1865                                 ref_frame_offset);
1866               tpl_mvs_base[mi_offset]
1867                   .mfmv[FWD_RF_OFFSET(LAST2_FRAME)][ref_stamp]
1868                   .as_int = this_mv.as_int;
1869             }
1870 
1871             if (ref_frame[0] >= LAST3_FRAME) {
1872               get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_lst3,
1873                                 ref_frame_offset);
1874               tpl_mvs_base[mi_offset]
1875                   .mfmv[FWD_RF_OFFSET(LAST3_FRAME)][ref_stamp]
1876                   .as_int = this_mv.as_int;
1877             }
1878 #endif
1879             if (ref_frame[0] >= GOLDEN_FRAME) {
1880               get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_gld,
1881                                 ref_frame_offset);
1882               tpl_mvs_base[mi_offset]
1883                   .mfmv[FWD_RF_OFFSET(GOLDEN_FRAME)][ref_stamp]
1884                   .as_int = this_mv.as_int;
1885             }
1886           }
1887         }
1888       }
1889     }
1890   }
1891 
1892 // ==========================================
1893 // Process BWD reference frame
1894 // ==========================================
1895 #if CONFIG_EXT_REFS
1896   if (bwd_buf_idx >= 0) {
1897     MV_REF *mv_ref_base = cm->buffer_pool->frame_bufs[bwd_buf_idx].mvs;
1898     const int lst_frame_idx =
1899         cm->buffer_pool->frame_bufs[bwd_buf_idx].lst_frame_offset;
1900     const int gld_frame_idx =
1901         cm->buffer_pool->frame_bufs[bwd_buf_idx].gld_frame_offset;
1902     const int lst2_frame_idx =
1903         cm->buffer_pool->frame_bufs[bwd_buf_idx].lst2_frame_offset;
1904     const int lst3_frame_idx =
1905         cm->buffer_pool->frame_bufs[bwd_buf_idx].lst3_frame_offset;
1906     const int bwd_frame_idx =
1907         cm->buffer_pool->frame_bufs[bwd_buf_idx].bwd_frame_offset;
1908     const int alt2_frame_idx =
1909         cm->buffer_pool->frame_bufs[bwd_buf_idx].alt2_frame_offset;
1910     const int alt_frame_idx =
1911         cm->buffer_pool->frame_bufs[bwd_buf_idx].alt_frame_offset;
1912 
1913     int lst_offset = AOMMAX(1, bwd_frame_index - lst_frame_idx);
1914     int gld_offset = AOMMAX(1, bwd_frame_index - gld_frame_idx);
1915     int cur_to_lst = cur_frame_index - lst_frame_index;
1916 
1917     int lst2_offset = AOMMAX(1, bwd_frame_index - lst2_frame_idx);
1918     int lst3_offset = AOMMAX(1, bwd_frame_index - lst3_frame_idx);
1919     int bwd_offset = AOMMAX(1, bwd_frame_idx - bwd_frame_index);
1920     int alt2_offset = AOMMAX(1, alt2_frame_idx - bwd_frame_index);
1921     int alt_offset = AOMMAX(1, alt_frame_idx - bwd_frame_index);
1922     int cur_to_lst2 = cur_frame_index - lst2_frame_index;
1923     int cur_to_lst3 = cur_frame_index - lst3_frame_index;
1924     int cur_to_gld = cur_frame_index - gld_frame_index;
1925     int cur_to_bwd = bwd_frame_index - cur_frame_index;
1926 
1927     const int ref_stamp = FWD_RF_OFFSET(BWDREF_FRAME);
1928     const int ref_frame_offset_buffer[TOTAL_REFS_PER_FRAME] = {
1929       0,          lst_offset, lst2_offset, lst3_offset,
1930       gld_offset, bwd_offset, alt2_offset, alt_offset,
1931     };
1932 
1933     for (int blk_row = 0; blk_row < cm->mi_rows; ++blk_row) {
1934       for (int blk_col = 0; blk_col < cm->mi_cols; ++blk_col) {
1935         MV_REF *mv_ref = &mv_ref_base[blk_row * cm->mi_cols + blk_col];
1936         MV fwd_mv = mv_ref->mv[0].as_mv;
1937         MV_REFERENCE_FRAME ref_frame[2] = { mv_ref->ref_frame[0],
1938                                             mv_ref->ref_frame[1] };
1939 
1940         if (ref_frame[0] <= GOLDEN_FRAME && ref_frame[0] > INTRA_FRAME) {
1941           const int ref_frame_offset = ref_frame_offset_buffer[ref_frame[0]];
1942           int_mv this_mv;
1943           int mi_r, mi_c;
1944 
1945           get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_bwd,
1946                             ref_frame_offset);
1947           int pos_valid = get_block_position(cm, &mi_r, &mi_c, blk_row, blk_col,
1948                                              this_mv.as_mv, 0);
1949 
1950           if (pos_valid) {
1951             int mi_offset = mi_r * cm->mi_stride + mi_c;
1952 
1953             tpl_mvs_base[mi_offset]
1954                 .mfmv[FWD_RF_OFFSET(BWDREF_FRAME)][ref_stamp]
1955                 .as_int = mv_sign_reverse(this_mv);
1956 
1957             // Project the motion vector onto last reference frame
1958             get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_lst,
1959                               ref_frame_offset);
1960             tpl_mvs_base[mi_offset]
1961                 .mfmv[FWD_RF_OFFSET(LAST_FRAME)][ref_stamp]
1962                 .as_int = this_mv.as_int;
1963 
1964             if (ref_frame[0] >= LAST2_FRAME) {
1965               get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_lst2,
1966                                 ref_frame_offset);
1967               tpl_mvs_base[mi_offset]
1968                   .mfmv[FWD_RF_OFFSET(LAST2_FRAME)][ref_stamp]
1969                   .as_int = this_mv.as_int;
1970             }
1971 
1972             if (ref_frame[0] >= LAST3_FRAME) {
1973               get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_lst3,
1974                                 ref_frame_offset);
1975               tpl_mvs_base[mi_offset]
1976                   .mfmv[FWD_RF_OFFSET(LAST3_FRAME)][ref_stamp]
1977                   .as_int = this_mv.as_int;
1978             }
1979 
1980             if (ref_frame[0] >= GOLDEN_FRAME) {
1981               get_mv_projection(&this_mv.as_mv, fwd_mv, cur_to_gld,
1982                                 ref_frame_offset);
1983               tpl_mvs_base[mi_offset]
1984                   .mfmv[FWD_RF_OFFSET(GOLDEN_FRAME)][ref_stamp]
1985                   .as_int = this_mv.as_int;
1986             }
1987           }
1988         }
1989       }
1990     }
1991   }
1992 #endif
1993 }
1994 #endif  // CONFIG_MFMV
1995 
1996 #if CONFIG_WARPED_MOTION
1997 #if WARPED_MOTION_SORT_SAMPLES
record_samples(MB_MODE_INFO * mbmi,int * pts,int * pts_inref,int * pts_mv,int global_offset_r,int global_offset_c,int row_offset,int sign_r,int col_offset,int sign_c)1998 static INLINE void record_samples(MB_MODE_INFO *mbmi, int *pts, int *pts_inref,
1999                                   int *pts_mv, int global_offset_r,
2000                                   int global_offset_c, int row_offset,
2001                                   int sign_r, int col_offset, int sign_c) {
2002   int bw = block_size_wide[mbmi->sb_type];
2003   int bh = block_size_high[mbmi->sb_type];
2004   int cr_offset = row_offset * MI_SIZE + sign_r * AOMMAX(bh, MI_SIZE) / 2 - 1;
2005   int cc_offset = col_offset * MI_SIZE + sign_c * AOMMAX(bw, MI_SIZE) / 2 - 1;
2006   int x = cc_offset + global_offset_c;
2007   int y = cr_offset + global_offset_r;
2008 
2009   pts[0] = (x * 8);
2010   pts[1] = (y * 8);
2011   pts_inref[0] = (x * 8) + mbmi->mv[0].as_mv.col;
2012   pts_inref[1] = (y * 8) + mbmi->mv[0].as_mv.row;
2013   pts_mv[0] = mbmi->mv[0].as_mv.col;
2014   pts_mv[1] = mbmi->mv[0].as_mv.row;
2015 }
2016 
2017 // Only sort pts and pts_inref, and pts_mv is not sorted.
2018 #define TRIM_THR 16
sortSamples(int * pts_mv,MV * mv,int * pts,int * pts_inref,int len)2019 int sortSamples(int *pts_mv, MV *mv, int *pts, int *pts_inref, int len) {
2020   int pts_mvd[SAMPLES_ARRAY_SIZE] = { 0 };
2021   int i, j, k;
2022   int ret = len;
2023 
2024   for (i = 0; i < len; ++i)
2025     pts_mvd[i] =
2026         abs(pts_mv[2 * i] - mv->col) + abs(pts_mv[2 * i + 1] - mv->row);
2027 
2028   for (i = 1; i <= len - 1; ++i) {
2029     for (j = 0; j < i; ++j) {
2030       if (pts_mvd[j] > pts_mvd[i]) {
2031         int temp, tempi, tempj, ptempi, ptempj;
2032 
2033         temp = pts_mvd[i];
2034         tempi = pts[2 * i];
2035         tempj = pts[2 * i + 1];
2036         ptempi = pts_inref[2 * i];
2037         ptempj = pts_inref[2 * i + 1];
2038 
2039         for (k = i; k > j; k--) {
2040           pts_mvd[k] = pts_mvd[k - 1];
2041           pts[2 * k] = pts[2 * (k - 1)];
2042           pts[2 * k + 1] = pts[2 * (k - 1) + 1];
2043           pts_inref[2 * k] = pts_inref[2 * (k - 1)];
2044           pts_inref[2 * k + 1] = pts_inref[2 * (k - 1) + 1];
2045         }
2046 
2047         pts_mvd[j] = temp;
2048         pts[2 * j] = tempi;
2049         pts[2 * j + 1] = tempj;
2050         pts_inref[2 * j] = ptempi;
2051         pts_inref[2 * j + 1] = ptempj;
2052         break;
2053       }
2054     }
2055   }
2056 
2057   for (i = len - 1; i >= 1; i--) {
2058     int low = (i == 1) ? 1 : AOMMAX((pts_mvd[i - 1] - pts_mvd[0]) / (i - 1), 1);
2059 
2060     if ((pts_mvd[i] - pts_mvd[i - 1]) >= TRIM_THR * low) ret = i;
2061   }
2062 
2063   if (ret > LEAST_SQUARES_SAMPLES_MAX) ret = LEAST_SQUARES_SAMPLES_MAX;
2064   return ret;
2065 }
2066 
2067 // Note: Samples returned are at 1/8-pel precision
findSamples(const AV1_COMMON * cm,MACROBLOCKD * xd,int mi_row,int mi_col,int * pts,int * pts_inref,int * pts_mv)2068 int findSamples(const AV1_COMMON *cm, MACROBLOCKD *xd, int mi_row, int mi_col,
2069                 int *pts, int *pts_inref, int *pts_mv) {
2070   MB_MODE_INFO *const mbmi0 = &(xd->mi[0]->mbmi);
2071   int ref_frame = mbmi0->ref_frame[0];
2072   int up_available = xd->up_available;
2073   int left_available = xd->left_available;
2074   int i, mi_step = 1, np = 0;
2075   int global_offset_c = mi_col * MI_SIZE;
2076   int global_offset_r = mi_row * MI_SIZE;
2077 
2078   const TileInfo *const tile = &xd->tile;
2079   int do_tl = 1;
2080   int do_tr = 1;
2081 
2082   // scan the nearest above rows
2083   if (up_available) {
2084     int mi_row_offset = -1;
2085     MODE_INFO *mi = xd->mi[mi_row_offset * xd->mi_stride];
2086     MB_MODE_INFO *mbmi = &mi->mbmi;
2087     uint8_t n8_w = mi_size_wide[mbmi->sb_type];
2088 
2089     if (xd->n8_w <= n8_w) {
2090       // Handle "current block width <= above block width" case.
2091       int col_offset = -mi_col % n8_w;
2092 
2093       if (col_offset < 0) do_tl = 0;
2094       if (col_offset + n8_w > xd->n8_w) do_tr = 0;
2095 
2096       if (mbmi->ref_frame[0] == ref_frame && mbmi->ref_frame[1] == NONE_FRAME) {
2097         record_samples(mbmi, pts, pts_inref, pts_mv, global_offset_r,
2098                        global_offset_c, 0, -1, col_offset, 1);
2099         pts += 2;
2100         pts_inref += 2;
2101         pts_mv += 2;
2102         np++;
2103       }
2104     } else {
2105       // Handle "current block width > above block width" case.
2106       for (i = 0; i < AOMMIN(xd->n8_w, cm->mi_cols - mi_col); i += mi_step) {
2107         int mi_col_offset = i;
2108         mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
2109         mbmi = &mi->mbmi;
2110         n8_w = mi_size_wide[mbmi->sb_type];
2111         mi_step = AOMMIN(xd->n8_w, n8_w);
2112 
2113         if (mbmi->ref_frame[0] == ref_frame &&
2114             mbmi->ref_frame[1] == NONE_FRAME) {
2115           record_samples(mbmi, pts, pts_inref, pts_mv, global_offset_r,
2116                          global_offset_c, 0, -1, i, 1);
2117           pts += 2;
2118           pts_inref += 2;
2119           pts_mv += 2;
2120           np++;
2121         }
2122       }
2123     }
2124   }
2125   assert(2 * np <= SAMPLES_ARRAY_SIZE);
2126 
2127   // scan the nearest left columns
2128   if (left_available) {
2129     int mi_col_offset = -1;
2130 
2131     MODE_INFO *mi = xd->mi[mi_col_offset];
2132     MB_MODE_INFO *mbmi = &mi->mbmi;
2133     uint8_t n8_h = mi_size_high[mbmi->sb_type];
2134 
2135     if (xd->n8_h <= n8_h) {
2136       // Handle "current block height <= above block height" case.
2137       int row_offset = -mi_row % n8_h;
2138 
2139       if (row_offset < 0) do_tl = 0;
2140 
2141       if (mbmi->ref_frame[0] == ref_frame && mbmi->ref_frame[1] == NONE_FRAME) {
2142         record_samples(mbmi, pts, pts_inref, pts_mv, global_offset_r,
2143                        global_offset_c, row_offset, 1, 0, -1);
2144         pts += 2;
2145         pts_inref += 2;
2146         pts_mv += 2;
2147         np++;
2148       }
2149     } else {
2150       // Handle "current block height > above block height" case.
2151       for (i = 0; i < AOMMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) {
2152         int mi_row_offset = i;
2153         mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
2154         mbmi = &mi->mbmi;
2155         n8_h = mi_size_high[mbmi->sb_type];
2156         mi_step = AOMMIN(xd->n8_h, n8_h);
2157 
2158         if (mbmi->ref_frame[0] == ref_frame &&
2159             mbmi->ref_frame[1] == NONE_FRAME) {
2160           record_samples(mbmi, pts, pts_inref, pts_mv, global_offset_r,
2161                          global_offset_c, i, 1, 0, -1);
2162           pts += 2;
2163           pts_inref += 2;
2164           pts_mv += 2;
2165           np++;
2166         }
2167       }
2168     }
2169   }
2170   assert(2 * np <= SAMPLES_ARRAY_SIZE);
2171 
2172   // Top-left block
2173   if (do_tl && left_available && up_available) {
2174     int mi_row_offset = -1;
2175     int mi_col_offset = -1;
2176 
2177     MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
2178     MB_MODE_INFO *mbmi = &mi->mbmi;
2179 
2180     if (mbmi->ref_frame[0] == ref_frame && mbmi->ref_frame[1] == NONE_FRAME) {
2181       record_samples(mbmi, pts, pts_inref, pts_mv, global_offset_r,
2182                      global_offset_c, 0, -1, 0, -1);
2183       pts += 2;
2184       pts_inref += 2;
2185       pts_mv += 2;
2186       np++;
2187     }
2188   }
2189   assert(2 * np <= SAMPLES_ARRAY_SIZE);
2190 
2191   // Top-right block
2192   if (do_tr &&
2193       has_top_right(cm, xd, mi_row, mi_col, AOMMAX(xd->n8_w, xd->n8_h))) {
2194     POSITION trb_pos = { -1, xd->n8_w };
2195 
2196     if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm, &trb_pos)) {
2197       int mi_row_offset = -1;
2198       int mi_col_offset = xd->n8_w;
2199 
2200       MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
2201       MB_MODE_INFO *mbmi = &mi->mbmi;
2202 
2203       if (mbmi->ref_frame[0] == ref_frame && mbmi->ref_frame[1] == NONE_FRAME) {
2204         record_samples(mbmi, pts, pts_inref, pts_mv, global_offset_r,
2205                        global_offset_c, 0, -1, xd->n8_w, 1);
2206         np++;
2207       }
2208     }
2209   }
2210   assert(2 * np <= SAMPLES_ARRAY_SIZE);
2211 
2212   return np;
2213 }
2214 #else
calc_projection_samples(MB_MODE_INFO * const mbmi,int x,int y,int * pts_inref)2215 void calc_projection_samples(MB_MODE_INFO *const mbmi, int x, int y,
2216                              int *pts_inref) {
2217   pts_inref[0] = (x * 8) + mbmi->mv[0].as_mv.col;
2218   pts_inref[1] = (y * 8) + mbmi->mv[0].as_mv.row;
2219 }
2220 
2221 // Note: Samples returned are at 1/8-pel precision
findSamples(const AV1_COMMON * cm,MACROBLOCKD * xd,int mi_row,int mi_col,int * pts,int * pts_inref)2222 int findSamples(const AV1_COMMON *cm, MACROBLOCKD *xd, int mi_row, int mi_col,
2223                 int *pts, int *pts_inref) {
2224   MB_MODE_INFO *const mbmi0 = &(xd->mi[0]->mbmi);
2225   int ref_frame = mbmi0->ref_frame[0];
2226   int up_available = xd->up_available;
2227   int left_available = xd->left_available;
2228   int i, mi_step, np = 0;
2229   int global_offset_c = mi_col * MI_SIZE;
2230   int global_offset_r = mi_row * MI_SIZE;
2231 
2232   // scan the above row
2233   if (up_available) {
2234     for (i = 0; i < AOMMIN(xd->n8_w, cm->mi_cols - mi_col); i += mi_step) {
2235       int mi_row_offset = -1;
2236       int mi_col_offset = i;
2237 
2238       MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
2239       MB_MODE_INFO *mbmi = &mi->mbmi;
2240 
2241       mi_step = AOMMIN(xd->n8_w, mi_size_wide[mbmi->sb_type]);
2242 
2243       if (mbmi->ref_frame[0] == ref_frame && mbmi->ref_frame[1] == NONE_FRAME) {
2244         int bw = block_size_wide[mbmi->sb_type];
2245         int bh = block_size_high[mbmi->sb_type];
2246         int cr_offset = -AOMMAX(bh, MI_SIZE) / 2 - 1;
2247         int cc_offset = i * MI_SIZE + AOMMAX(bw, MI_SIZE) / 2 - 1;
2248         int x = cc_offset + global_offset_c;
2249         int y = cr_offset + global_offset_r;
2250 
2251         pts[0] = (x * 8);
2252         pts[1] = (y * 8);
2253         calc_projection_samples(mbmi, x, y, pts_inref);
2254         pts += 2;
2255         pts_inref += 2;
2256         np++;
2257         if (np >= LEAST_SQUARES_SAMPLES_MAX) return LEAST_SQUARES_SAMPLES_MAX;
2258       }
2259     }
2260   }
2261   assert(2 * np <= SAMPLES_ARRAY_SIZE);
2262 
2263   // scan the left column
2264   if (left_available) {
2265     for (i = 0; i < AOMMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) {
2266       int mi_row_offset = i;
2267       int mi_col_offset = -1;
2268 
2269       MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
2270       MB_MODE_INFO *mbmi = &mi->mbmi;
2271 
2272       mi_step = AOMMIN(xd->n8_h, mi_size_high[mbmi->sb_type]);
2273 
2274       if (mbmi->ref_frame[0] == ref_frame && mbmi->ref_frame[1] == NONE_FRAME) {
2275         int bw = block_size_wide[mbmi->sb_type];
2276         int bh = block_size_high[mbmi->sb_type];
2277         int cr_offset = i * MI_SIZE + AOMMAX(bh, MI_SIZE) / 2 - 1;
2278         int cc_offset = -AOMMAX(bw, MI_SIZE) / 2 - 1;
2279         int x = cc_offset + global_offset_c;
2280         int y = cr_offset + global_offset_r;
2281 
2282         pts[0] = (x * 8);
2283         pts[1] = (y * 8);
2284         calc_projection_samples(mbmi, x, y, pts_inref);
2285         pts += 2;
2286         pts_inref += 2;
2287         np++;
2288         if (np >= LEAST_SQUARES_SAMPLES_MAX) return LEAST_SQUARES_SAMPLES_MAX;
2289       }
2290     }
2291   }
2292   assert(2 * np <= SAMPLES_ARRAY_SIZE);
2293 
2294   if (left_available && up_available) {
2295     int mi_row_offset = -1;
2296     int mi_col_offset = -1;
2297 
2298     MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
2299     MB_MODE_INFO *mbmi = &mi->mbmi;
2300 
2301     if (mbmi->ref_frame[0] == ref_frame && mbmi->ref_frame[1] == NONE_FRAME) {
2302       int bw = block_size_wide[mbmi->sb_type];
2303       int bh = block_size_high[mbmi->sb_type];
2304       int cr_offset = -AOMMAX(bh, MI_SIZE) / 2 - 1;
2305       int cc_offset = -AOMMAX(bw, MI_SIZE) / 2 - 1;
2306       int x = cc_offset + global_offset_c;
2307       int y = cr_offset + global_offset_r;
2308 
2309       pts[0] = (x * 8);
2310       pts[1] = (y * 8);
2311       calc_projection_samples(mbmi, x, y, pts_inref);
2312       np++;
2313     }
2314   }
2315   assert(2 * np <= SAMPLES_ARRAY_SIZE);
2316 
2317   return np;
2318 }
2319 #endif  // WARPED_MOTION_SORT_SAMPLES
2320 #endif  // CONFIG_WARPED_MOTION
2321