blob: afc78c0c762d6b711a87bd484e73ea6ac114482e [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
12#include "av1/common/mvref_common.h"
Yue Chen69f18e12016-09-08 14:48:15 -070013#if CONFIG_WARPED_MOTION
14#include "av1/common/warped_motion.h"
15#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070016
Yaowu Xuc27fc142016-08-22 16:08:15 -070017static uint8_t add_ref_mv_candidate(
18 const MODE_INFO *const candidate_mi, const MB_MODE_INFO *const candidate,
19 const MV_REFERENCE_FRAME rf[2], uint8_t *refmv_count,
20 CANDIDATE_MV *ref_mv_stack, const int use_hp, int len, int block, int col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070021 int index = 0, ref;
22 int newmv_count = 0;
Jingning Han8570b352016-12-14 11:05:10 -080023#if CONFIG_CB4X4
24 const int unify_bsize = 1;
25#else
26 const int unify_bsize = 0;
27#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070028
Emil Keyder01770b32017-01-20 18:03:11 -050029 if (rf[1] == NONE_FRAME) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070030 // single reference frame
31 for (ref = 0; ref < 2; ++ref) {
32 if (candidate->ref_frame[ref] == rf[0]) {
33 int_mv this_refmv = get_sub_block_mv(candidate_mi, ref, col, block);
34 lower_mv_precision(&this_refmv.as_mv, use_hp);
35
36 for (index = 0; index < *refmv_count; ++index)
37 if (ref_mv_stack[index].this_mv.as_int == this_refmv.as_int) break;
38
Yaowu Xu439286a2016-09-27 10:13:33 -070039 if (index < *refmv_count) ref_mv_stack[index].weight += 2 * len;
Yaowu Xuc27fc142016-08-22 16:08:15 -070040
41 // Add a new item to the list.
42 if (index == *refmv_count) {
43 ref_mv_stack[index].this_mv = this_refmv;
Jingning Han3f338832016-11-18 11:01:48 -080044 ref_mv_stack[index].pred_diff[0] = av1_get_pred_diff_ctx(
45 get_sub_block_pred_mv(candidate_mi, ref, col, block), this_refmv);
Yaowu Xu439286a2016-09-27 10:13:33 -070046 ref_mv_stack[index].weight = 2 * len;
Yaowu Xuc27fc142016-08-22 16:08:15 -070047 ++(*refmv_count);
48
Zoe Liu7f24e1b2017-03-17 17:42:05 -070049 if (candidate->mode == NEWMV) ++newmv_count;
Yaowu Xuc27fc142016-08-22 16:08:15 -070050 }
51
Jingning Han8570b352016-12-14 11:05:10 -080052 if (candidate_mi->mbmi.sb_type < BLOCK_8X8 && block >= 0 &&
53 !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070054 int alt_block = 3 - block;
55 this_refmv = get_sub_block_mv(candidate_mi, ref, col, alt_block);
56 lower_mv_precision(&this_refmv.as_mv, use_hp);
57
58 for (index = 0; index < *refmv_count; ++index)
59 if (ref_mv_stack[index].this_mv.as_int == this_refmv.as_int) break;
60
Yaowu Xu439286a2016-09-27 10:13:33 -070061 if (index < *refmv_count) ref_mv_stack[index].weight += len;
Yaowu Xuc27fc142016-08-22 16:08:15 -070062
63 // Add a new item to the list.
64 if (index == *refmv_count) {
65 ref_mv_stack[index].this_mv = this_refmv;
Jingning Han3f338832016-11-18 11:01:48 -080066 ref_mv_stack[index].pred_diff[0] = av1_get_pred_diff_ctx(
67 get_sub_block_pred_mv(candidate_mi, ref, col, alt_block),
68 this_refmv);
Yaowu Xu439286a2016-09-27 10:13:33 -070069 ref_mv_stack[index].weight = len;
Yaowu Xuc27fc142016-08-22 16:08:15 -070070 ++(*refmv_count);
71
Zoe Liu7f24e1b2017-03-17 17:42:05 -070072 if (candidate->mode == NEWMV) ++newmv_count;
Yaowu Xuc27fc142016-08-22 16:08:15 -070073 }
74 }
75 }
76 }
77 } else {
78 // compound reference frame
79 if (candidate->ref_frame[0] == rf[0] && candidate->ref_frame[1] == rf[1]) {
80 int_mv this_refmv[2];
81
82 for (ref = 0; ref < 2; ++ref) {
83 this_refmv[ref] = get_sub_block_mv(candidate_mi, ref, col, block);
84 lower_mv_precision(&this_refmv[ref].as_mv, use_hp);
85 }
86
87 for (index = 0; index < *refmv_count; ++index)
88 if ((ref_mv_stack[index].this_mv.as_int == this_refmv[0].as_int) &&
89 (ref_mv_stack[index].comp_mv.as_int == this_refmv[1].as_int))
90 break;
91
Yaowu Xu439286a2016-09-27 10:13:33 -070092 if (index < *refmv_count) ref_mv_stack[index].weight += 2 * len;
Yaowu Xuc27fc142016-08-22 16:08:15 -070093
94 // Add a new item to the list.
95 if (index == *refmv_count) {
96 ref_mv_stack[index].this_mv = this_refmv[0];
97 ref_mv_stack[index].comp_mv = this_refmv[1];
Jingning Han3f338832016-11-18 11:01:48 -080098 ref_mv_stack[index].pred_diff[0] = av1_get_pred_diff_ctx(
99 get_sub_block_pred_mv(candidate_mi, 0, col, block), this_refmv[0]);
100 ref_mv_stack[index].pred_diff[1] = av1_get_pred_diff_ctx(
101 get_sub_block_pred_mv(candidate_mi, 1, col, block), this_refmv[1]);
Yaowu Xu439286a2016-09-27 10:13:33 -0700102 ref_mv_stack[index].weight = 2 * len;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700103 ++(*refmv_count);
104
105#if CONFIG_EXT_INTER
106 if (candidate->mode == NEW_NEWMV)
107#else
108 if (candidate->mode == NEWMV)
109#endif // CONFIG_EXT_INTER
110 ++newmv_count;
111 }
112
Jingning Han8570b352016-12-14 11:05:10 -0800113 if (candidate_mi->mbmi.sb_type < BLOCK_8X8 && block >= 0 &&
114 !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700115 int alt_block = 3 - block;
116 this_refmv[0] = get_sub_block_mv(candidate_mi, 0, col, alt_block);
117 this_refmv[1] = get_sub_block_mv(candidate_mi, 1, col, alt_block);
118
119 for (ref = 0; ref < 2; ++ref)
120 lower_mv_precision(&this_refmv[ref].as_mv, use_hp);
121
122 for (index = 0; index < *refmv_count; ++index)
123 if (ref_mv_stack[index].this_mv.as_int == this_refmv[0].as_int &&
124 ref_mv_stack[index].comp_mv.as_int == this_refmv[1].as_int)
125 break;
126
Yaowu Xu439286a2016-09-27 10:13:33 -0700127 if (index < *refmv_count) ref_mv_stack[index].weight += len;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700128
129 // Add a new item to the list.
130 if (index == *refmv_count) {
131 ref_mv_stack[index].this_mv = this_refmv[0];
132 ref_mv_stack[index].comp_mv = this_refmv[1];
Jingning Han3f338832016-11-18 11:01:48 -0800133 ref_mv_stack[index].pred_diff[0] = av1_get_pred_diff_ctx(
134 get_sub_block_pred_mv(candidate_mi, 0, col, block),
135 this_refmv[0]);
136 ref_mv_stack[index].pred_diff[0] = av1_get_pred_diff_ctx(
137 get_sub_block_pred_mv(candidate_mi, 1, col, block),
138 this_refmv[1]);
Yaowu Xu439286a2016-09-27 10:13:33 -0700139 ref_mv_stack[index].weight = len;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700140 ++(*refmv_count);
141
142#if CONFIG_EXT_INTER
143 if (candidate->mode == NEW_NEWMV)
144#else
145 if (candidate->mode == NEWMV)
146#endif // CONFIG_EXT_INTER
147 ++newmv_count;
148 }
149 }
150 }
151 }
152 return newmv_count;
153}
154
Yaowu Xuf883b422016-08-30 14:01:10 -0700155static uint8_t scan_row_mbmi(const AV1_COMMON *cm, const MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700156 const int mi_row, const int mi_col, int block,
157 const MV_REFERENCE_FRAME rf[2], int row_offset,
158 CANDIDATE_MV *ref_mv_stack, uint8_t *refmv_count) {
159 const TileInfo *const tile = &xd->tile;
160 int i;
161 uint8_t newmv_count = 0;
Jingning Hanc016df82016-12-09 12:37:28 -0800162#if CONFIG_CB4X4
Jingning Hanfab16032016-12-16 14:52:45 -0800163 const int bsize = xd->mi[0]->mbmi.sb_type;
164 const int mi_offset =
165 bsize < BLOCK_8X8 ? mi_size_wide[BLOCK_4X4] : mi_size_wide[BLOCK_8X8];
Jingning Hanc016df82016-12-09 12:37:28 -0800166 // TODO(jingning): Revisit this part after cb4x4 is stable.
Jingning Hanfab16032016-12-16 14:52:45 -0800167 if (bsize >= BLOCK_8X8) row_offset *= 2;
168#else
169 const int mi_offset = mi_size_wide[BLOCK_8X8];
Jingning Hanc016df82016-12-09 12:37:28 -0800170#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700171
172 for (i = 0; i < xd->n8_w && *refmv_count < MAX_REF_MV_STACK_SIZE;) {
173 POSITION mi_pos;
Jingning Hanc016df82016-12-09 12:37:28 -0800174#if CONFIG_CB4X4
175 const int use_step_16 = (xd->n8_w >= 16);
176#else
Jingning Han75e513f2016-09-30 09:10:26 -0700177 const int use_step_16 = (xd->n8_w >= 8);
Jingning Hanc016df82016-12-09 12:37:28 -0800178#endif
Jingning Han75e513f2016-09-30 09:10:26 -0700179
Yaowu Xuc27fc142016-08-22 16:08:15 -0700180 mi_pos.row = row_offset;
181 mi_pos.col = i;
Yaowu Xu531d6af2017-03-07 17:48:52 -0800182 if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm, &mi_pos)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700183 const MODE_INFO *const candidate_mi =
184 xd->mi[mi_pos.row * xd->mi_stride + mi_pos.col];
185 const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
Jingning Hanc709e1f2016-12-06 14:48:09 -0800186 int len = AOMMIN(xd->n8_w, mi_size_wide[candidate->sb_type]);
Jingning Han24ea91d2016-12-13 11:29:23 -0800187 if (use_step_16) len = AOMMAX(mi_size_wide[BLOCK_16X16], len);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700188 newmv_count += add_ref_mv_candidate(
189 candidate_mi, candidate, rf, refmv_count, ref_mv_stack,
190 cm->allow_high_precision_mv, len, block, mi_pos.col);
191 i += len;
192 } else {
Jingning Han75e513f2016-09-30 09:10:26 -0700193 if (use_step_16)
Jingning Hanc016df82016-12-09 12:37:28 -0800194 i += (mi_offset << 1);
Jingning Han75e513f2016-09-30 09:10:26 -0700195 else
Jingning Hanc016df82016-12-09 12:37:28 -0800196 i += mi_offset;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700197 }
198 }
199
200 return newmv_count;
201}
202
Yaowu Xuf883b422016-08-30 14:01:10 -0700203static uint8_t scan_col_mbmi(const AV1_COMMON *cm, const MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700204 const int mi_row, const int mi_col, int block,
205 const MV_REFERENCE_FRAME rf[2], int col_offset,
206 CANDIDATE_MV *ref_mv_stack, uint8_t *refmv_count) {
207 const TileInfo *const tile = &xd->tile;
208 int i;
209 uint8_t newmv_count = 0;
Jingning Hanc016df82016-12-09 12:37:28 -0800210#if CONFIG_CB4X4
Jingning Hanfab16032016-12-16 14:52:45 -0800211 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
212 const int mi_offset =
213 (bsize < BLOCK_8X8) ? mi_size_high[BLOCK_4X4] : mi_size_high[BLOCK_8X8];
214 if (bsize >= BLOCK_8X8) col_offset *= 2;
215#else
216 const int mi_offset = mi_size_wide[BLOCK_8X8];
Jingning Hanc016df82016-12-09 12:37:28 -0800217#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700218
219 for (i = 0; i < xd->n8_h && *refmv_count < MAX_REF_MV_STACK_SIZE;) {
220 POSITION mi_pos;
Jingning Hanc016df82016-12-09 12:37:28 -0800221#if CONFIG_CB4X4
222 const int use_step_16 = (xd->n8_h >= 16);
223#else
Jingning Han75e513f2016-09-30 09:10:26 -0700224 const int use_step_16 = (xd->n8_h >= 8);
Jingning Hanc016df82016-12-09 12:37:28 -0800225#endif
Jingning Han75e513f2016-09-30 09:10:26 -0700226
Yaowu Xuc27fc142016-08-22 16:08:15 -0700227 mi_pos.row = i;
228 mi_pos.col = col_offset;
Yaowu Xu531d6af2017-03-07 17:48:52 -0800229 if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm, &mi_pos)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700230 const MODE_INFO *const candidate_mi =
231 xd->mi[mi_pos.row * xd->mi_stride + mi_pos.col];
232 const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
Jingning Hanc709e1f2016-12-06 14:48:09 -0800233 int len = AOMMIN(xd->n8_h, mi_size_high[candidate->sb_type]);
Jingning Han24ea91d2016-12-13 11:29:23 -0800234 if (use_step_16) len = AOMMAX(mi_size_high[BLOCK_16X16], len);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700235 newmv_count += add_ref_mv_candidate(
236 candidate_mi, candidate, rf, refmv_count, ref_mv_stack,
237 cm->allow_high_precision_mv, len, block, mi_pos.col);
238 i += len;
239 } else {
Jingning Han75e513f2016-09-30 09:10:26 -0700240 if (use_step_16)
Jingning Hanc016df82016-12-09 12:37:28 -0800241 i += (mi_offset << 1);
Jingning Han75e513f2016-09-30 09:10:26 -0700242 else
Jingning Hanc016df82016-12-09 12:37:28 -0800243 i += mi_offset;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700244 }
245 }
246
247 return newmv_count;
248}
249
Yaowu Xuf883b422016-08-30 14:01:10 -0700250static uint8_t scan_blk_mbmi(const AV1_COMMON *cm, const MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700251 const int mi_row, const int mi_col, int block,
252 const MV_REFERENCE_FRAME rf[2], int row_offset,
253 int col_offset, CANDIDATE_MV *ref_mv_stack,
254 uint8_t *refmv_count) {
255 const TileInfo *const tile = &xd->tile;
256 POSITION mi_pos;
257 uint8_t newmv_count = 0;
258
259 mi_pos.row = row_offset;
260 mi_pos.col = col_offset;
261
Yaowu Xu531d6af2017-03-07 17:48:52 -0800262 if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm, &mi_pos) &&
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800263 *refmv_count < MAX_REF_MV_STACK_SIZE) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700264 const MODE_INFO *const candidate_mi =
265 xd->mi[mi_pos.row * xd->mi_stride + mi_pos.col];
266 const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
Jingning Hanc016df82016-12-09 12:37:28 -0800267 const int len = mi_size_wide[BLOCK_8X8];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700268
269 newmv_count += add_ref_mv_candidate(
270 candidate_mi, candidate, rf, refmv_count, ref_mv_stack,
271 cm->allow_high_precision_mv, len, block, mi_pos.col);
272 } // Analyze a single 8x8 block motion information.
Yaowu Xu4306b6e2016-09-27 12:55:32 -0700273
Yaowu Xuc27fc142016-08-22 16:08:15 -0700274 return newmv_count;
275}
276
277static int has_top_right(const MACROBLOCKD *xd, int mi_row, int mi_col,
278 int bs) {
Jingning Han3eb1f072016-11-17 15:17:25 -0800279 const int mask_row = mi_row & MAX_MIB_MASK;
280 const int mask_col = mi_col & MAX_MIB_MASK;
281
Yaowu Xuc27fc142016-08-22 16:08:15 -0700282 // In a split partition all apart from the bottom right has a top right
Jingning Han3eb1f072016-11-17 15:17:25 -0800283 int has_tr = !((mask_row & bs) && (mask_col & bs));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700284
285 // bs > 0 and bs is a power of 2
286 assert(bs > 0 && !(bs & (bs - 1)));
287
288 // For each 4x4 group of blocks, when the bottom right is decoded the blocks
289 // to the right have not been decoded therefore the bottom right does
290 // not have a top right
291 while (bs < MAX_MIB_SIZE) {
Jingning Han3eb1f072016-11-17 15:17:25 -0800292 if (mask_col & bs) {
293 if ((mask_col & (2 * bs)) && (mask_row & (2 * bs))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700294 has_tr = 0;
295 break;
296 }
297 } else {
298 break;
299 }
300 bs <<= 1;
301 }
302
303 // The left hand of two vertical rectangles always has a top right (as the
304 // block above will have been decoded)
305 if (xd->n8_w < xd->n8_h)
306 if (!xd->is_sec_rect) has_tr = 1;
307
308 // The bottom of two horizontal rectangles never has a top right (as the block
309 // to the right won't have been decoded)
310 if (xd->n8_w > xd->n8_h)
311 if (xd->is_sec_rect) has_tr = 0;
312
313#if CONFIG_EXT_PARTITION_TYPES
314 // The bottom left square of a Vertical A does not have a top right as it is
315 // decoded before the right hand rectangle of the partition
316 if (xd->mi[0]->mbmi.partition == PARTITION_VERT_A)
Jingning Han3eb1f072016-11-17 15:17:25 -0800317 if ((mask_row & bs) && !(mask_col & bs)) has_tr = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700318#endif // CONFIG_EXT_PARTITION_TYPES
319
320 return has_tr;
321}
322
Yaowu Xudc035da2016-09-27 10:29:34 -0700323static int add_col_ref_mv(const AV1_COMMON *cm,
324 const MV_REF *prev_frame_mvs_base,
325 const MACROBLOCKD *xd, int mi_row, int mi_col,
326 MV_REFERENCE_FRAME ref_frame, int blk_row,
327 int blk_col, uint8_t *refmv_count,
328 CANDIDATE_MV *ref_mv_stack, int16_t *mode_context) {
329 const MV_REF *prev_frame_mvs =
330 prev_frame_mvs_base + blk_row * cm->mi_cols + blk_col;
331 POSITION mi_pos;
332 int ref, idx;
333 int coll_blk_count = 0;
Jingning Hanc016df82016-12-09 12:37:28 -0800334 const int weight_unit = mi_size_wide[BLOCK_8X8];
Yaowu Xudc035da2016-09-27 10:29:34 -0700335
zhipin dengeb019b82017-02-17 17:49:03 +0800336#if CONFIG_MV_COMPRESS
337 mi_pos.row = (mi_row & 0x01) ? blk_row : blk_row + 1;
338 mi_pos.col = (mi_col & 0x01) ? blk_col : blk_col + 1;
339#else
Yaowu Xudc035da2016-09-27 10:29:34 -0700340 mi_pos.row = blk_row;
341 mi_pos.col = blk_col;
zhipin dengeb019b82017-02-17 17:49:03 +0800342#endif
Yaowu Xudc035da2016-09-27 10:29:34 -0700343
Yaowu Xu531d6af2017-03-07 17:48:52 -0800344 if (!is_inside(&xd->tile, mi_col, mi_row, cm->mi_rows, cm, &mi_pos))
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800345 return coll_blk_count;
Yaowu Xudc035da2016-09-27 10:29:34 -0700346 for (ref = 0; ref < 2; ++ref) {
347 if (prev_frame_mvs->ref_frame[ref] == ref_frame) {
348 int_mv this_refmv = prev_frame_mvs->mv[ref];
349 lower_mv_precision(&this_refmv.as_mv, cm->allow_high_precision_mv);
350
351 if (abs(this_refmv.as_mv.row) >= 16 || abs(this_refmv.as_mv.col) >= 16)
352 mode_context[ref_frame] |= (1 << ZEROMV_OFFSET);
353
354 for (idx = 0; idx < *refmv_count; ++idx)
355 if (this_refmv.as_int == ref_mv_stack[idx].this_mv.as_int) break;
356
Jingning Hanc016df82016-12-09 12:37:28 -0800357 if (idx < *refmv_count) ref_mv_stack[idx].weight += 2 * weight_unit;
Yaowu Xudc035da2016-09-27 10:29:34 -0700358
359 if (idx == *refmv_count && *refmv_count < MAX_REF_MV_STACK_SIZE) {
360 ref_mv_stack[idx].this_mv.as_int = this_refmv.as_int;
Jingning Han3f338832016-11-18 11:01:48 -0800361 ref_mv_stack[idx].pred_diff[0] =
362 av1_get_pred_diff_ctx(prev_frame_mvs->pred_mv[ref], this_refmv);
Jingning Hanc016df82016-12-09 12:37:28 -0800363 ref_mv_stack[idx].weight = 2 * weight_unit;
Yaowu Xudc035da2016-09-27 10:29:34 -0700364 ++(*refmv_count);
365 }
366
367 ++coll_blk_count;
368 }
369 }
370
371 return coll_blk_count;
372}
373
Yaowu Xuf883b422016-08-30 14:01:10 -0700374static void setup_ref_mv_list(const AV1_COMMON *cm, const MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700375 MV_REFERENCE_FRAME ref_frame,
376 uint8_t *refmv_count, CANDIDATE_MV *ref_mv_stack,
377 int_mv *mv_ref_list, int block, int mi_row,
378 int mi_col, int16_t *mode_context) {
379 int idx, nearest_refmv_count = 0;
380 uint8_t newmv_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700381 CANDIDATE_MV tmp_mv;
382 int len, nr_len;
383
zhipin dengeb019b82017-02-17 17:49:03 +0800384#if CONFIG_MV_COMPRESS
385 const MV_REF *const prev_frame_mvs_base =
386 cm->use_prev_frame_mvs
387 ? cm->prev_frame->mvs + (((mi_row >> 1) << 1) + 1) * cm->mi_cols +
388 ((mi_col >> 1) << 1) + 1
389 : NULL;
390#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700391 const MV_REF *const prev_frame_mvs_base =
392 cm->use_prev_frame_mvs
393 ? cm->prev_frame->mvs + mi_row * cm->mi_cols + mi_col
394 : NULL;
zhipin dengeb019b82017-02-17 17:49:03 +0800395#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700396
Yaowu Xudc035da2016-09-27 10:29:34 -0700397 const int bs = AOMMAX(xd->n8_w, xd->n8_h);
398 const int has_tr = has_top_right(xd, mi_row, mi_col, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700399 MV_REFERENCE_FRAME rf[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700400
Yaowu Xudc035da2016-09-27 10:29:34 -0700401 av1_set_ref_frame(rf, ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700402 mode_context[ref_frame] = 0;
403 *refmv_count = 0;
404
405 // Scan the first above row mode info.
Yaowu Xudc035da2016-09-27 10:29:34 -0700406 newmv_count += scan_row_mbmi(cm, xd, mi_row, mi_col, block, rf, -1,
407 ref_mv_stack, refmv_count);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700408 // Scan the first left column mode info.
409 newmv_count += scan_col_mbmi(cm, xd, mi_row, mi_col, block, rf, -1,
410 ref_mv_stack, refmv_count);
411
412 // Check top-right boundary
413 if (has_tr)
Jingning Hanea9cf092016-10-28 14:19:12 -0700414 newmv_count += scan_blk_mbmi(cm, xd, mi_row, mi_col, block, rf, -1,
415 xd->n8_w, ref_mv_stack, refmv_count);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700416
417 nearest_refmv_count = *refmv_count;
418
Yaowu Xudc035da2016-09-27 10:29:34 -0700419 for (idx = 0; idx < nearest_refmv_count; ++idx)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700420 ref_mv_stack[idx].weight += REF_CAT_LEVEL;
Fangwen Fu8d164de2016-12-14 13:40:54 -0800421#if CONFIG_TEMPMV_SIGNALING
422 if (cm->use_prev_frame_mvs && rf[1] == NONE_FRAME) {
423#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700424 if (prev_frame_mvs_base && cm->show_frame && cm->last_show_frame &&
Emil Keyder01770b32017-01-20 18:03:11 -0500425 rf[1] == NONE_FRAME) {
Fangwen Fu8d164de2016-12-14 13:40:54 -0800426#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700427 int blk_row, blk_col;
Yaowu Xudc035da2016-09-27 10:29:34 -0700428 int coll_blk_count = 0;
Jingning Hanfab16032016-12-16 14:52:45 -0800429#if CONFIG_CB4X4
430 const int mi_step = (xd->n8_w == 1 || xd->n8_h == 1)
431 ? mi_size_wide[BLOCK_8X8]
432 : mi_size_wide[BLOCK_16X16];
433#else
Jingning Hanc016df82016-12-09 12:37:28 -0800434 const int mi_step = mi_size_wide[BLOCK_16X16];
Jingning Hanfab16032016-12-16 14:52:45 -0800435#endif
Jingning Han8cf83642017-01-30 14:39:28 -0800436
437#if CONFIG_TPL_MV
438 int tpl_sample_pos[5][2] = { { -1, xd->n8_w },
439 { 0, xd->n8_w },
440 { xd->n8_h, xd->n8_w },
441 { xd->n8_h, 0 },
442 { xd->n8_h, -1 } };
443 int i;
444#endif
445
Jingning Hanc016df82016-12-09 12:37:28 -0800446 for (blk_row = 0; blk_row < xd->n8_h; blk_row += mi_step) {
447 for (blk_col = 0; blk_col < xd->n8_w; blk_col += mi_step) {
Yaowu Xudc035da2016-09-27 10:29:34 -0700448 coll_blk_count += add_col_ref_mv(
449 cm, prev_frame_mvs_base, xd, mi_row, mi_col, ref_frame, blk_row,
450 blk_col, refmv_count, ref_mv_stack, mode_context);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700451 }
452 }
Jingning Han8cf83642017-01-30 14:39:28 -0800453
454#if CONFIG_TPL_MV
455 for (i = 0; i < 5; ++i) {
456 blk_row = tpl_sample_pos[i][0];
457 blk_col = tpl_sample_pos[i][1];
458 coll_blk_count += add_col_ref_mv(cm, prev_frame_mvs_base, xd, mi_row,
459 mi_col, ref_frame, blk_row, blk_col,
460 refmv_count, ref_mv_stack, mode_context);
461 }
462#endif
463
Yaowu Xudc035da2016-09-27 10:29:34 -0700464 if (coll_blk_count == 0) mode_context[ref_frame] |= (1 << ZEROMV_OFFSET);
465 } else {
466 mode_context[ref_frame] |= (1 << ZEROMV_OFFSET);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700467 }
468
Jingning Han24e0a182016-11-20 22:34:12 -0800469 // Scan the second outer area.
Dengca8d24d2016-10-17 14:06:35 +0800470 scan_blk_mbmi(cm, xd, mi_row, mi_col, block, rf, -1, -1, ref_mv_stack,
471 refmv_count);
472 for (idx = 2; idx <= 3; ++idx) {
473 scan_row_mbmi(cm, xd, mi_row, mi_col, block, rf, -idx, ref_mv_stack,
474 refmv_count);
475 scan_col_mbmi(cm, xd, mi_row, mi_col, block, rf, -idx, ref_mv_stack,
476 refmv_count);
477 }
478 scan_col_mbmi(cm, xd, mi_row, mi_col, block, rf, -4, ref_mv_stack,
479 refmv_count);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700480
481 switch (nearest_refmv_count) {
482 case 0:
483 mode_context[ref_frame] |= 0;
484 if (*refmv_count >= 1) mode_context[ref_frame] |= 1;
485
486 if (*refmv_count == 1)
487 mode_context[ref_frame] |= (1 << REFMV_OFFSET);
488 else if (*refmv_count >= 2)
489 mode_context[ref_frame] |= (2 << REFMV_OFFSET);
490 break;
491 case 1:
492 mode_context[ref_frame] |= (newmv_count > 0) ? 2 : 3;
493
494 if (*refmv_count == 1)
495 mode_context[ref_frame] |= (3 << REFMV_OFFSET);
496 else if (*refmv_count >= 2)
497 mode_context[ref_frame] |= (4 << REFMV_OFFSET);
498 break;
499
500 case 2:
501 default:
502 if (newmv_count >= 2)
503 mode_context[ref_frame] |= 4;
504 else if (newmv_count == 1)
505 mode_context[ref_frame] |= 5;
506 else
507 mode_context[ref_frame] |= 6;
508
509 mode_context[ref_frame] |= (5 << REFMV_OFFSET);
510 break;
511 }
512
513 // Rank the likelihood and assign nearest and near mvs.
514 len = nearest_refmv_count;
515 while (len > 0) {
516 nr_len = 0;
517 for (idx = 1; idx < len; ++idx) {
518 if (ref_mv_stack[idx - 1].weight < ref_mv_stack[idx].weight) {
519 tmp_mv = ref_mv_stack[idx - 1];
520 ref_mv_stack[idx - 1] = ref_mv_stack[idx];
521 ref_mv_stack[idx] = tmp_mv;
522 nr_len = idx;
523 }
524 }
525 len = nr_len;
526 }
527
528 len = *refmv_count;
529 while (len > nearest_refmv_count) {
530 nr_len = nearest_refmv_count;
531 for (idx = nearest_refmv_count + 1; idx < len; ++idx) {
532 if (ref_mv_stack[idx - 1].weight < ref_mv_stack[idx].weight) {
533 tmp_mv = ref_mv_stack[idx - 1];
534 ref_mv_stack[idx - 1] = ref_mv_stack[idx];
535 ref_mv_stack[idx] = tmp_mv;
536 nr_len = idx;
537 }
538 }
539 len = nr_len;
540 }
541
Emil Keyder01770b32017-01-20 18:03:11 -0500542 if (rf[1] > NONE_FRAME) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700543 for (idx = 0; idx < *refmv_count; ++idx) {
Jingning Hanff6ee6a2016-12-07 09:55:21 -0800544 clamp_mv_ref(&ref_mv_stack[idx].this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
545 xd->n8_h << MI_SIZE_LOG2, xd);
546 clamp_mv_ref(&ref_mv_stack[idx].comp_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
547 xd->n8_h << MI_SIZE_LOG2, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700548 }
549 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700550 for (idx = 0; idx < AOMMIN(MAX_MV_REF_CANDIDATES, *refmv_count); ++idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700551 mv_ref_list[idx].as_int = ref_mv_stack[idx].this_mv.as_int;
Jingning Hanff6ee6a2016-12-07 09:55:21 -0800552 clamp_mv_ref(&mv_ref_list[idx].as_mv, xd->n8_w << MI_SIZE_LOG2,
553 xd->n8_h << MI_SIZE_LOG2, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700554 }
555 }
556}
Yaowu Xuc27fc142016-08-22 16:08:15 -0700557
558// This function searches the neighbourhood of a given MB/SB
559// to try and find candidate reference vectors.
Yaowu Xuf883b422016-08-30 14:01:10 -0700560static void find_mv_refs_idx(const AV1_COMMON *cm, const MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700561 MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
562 int_mv *mv_ref_list, int block, int mi_row,
563 int mi_col, find_mv_refs_sync sync,
David Barkercdcac6d2016-12-01 17:04:16 +0000564 void *const data, int16_t *mode_context,
565 int_mv zeromv) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700566 const int *ref_sign_bias = cm->ref_frame_sign_bias;
567 int i, refmv_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700568 int different_ref_found = 0;
569 int context_counter = 0;
zhipin dengeb019b82017-02-17 17:49:03 +0800570#if CONFIG_MV_COMPRESS
571 const TileInfo *const tile_ = &xd->tile;
572 int mi_row_end = tile_->mi_row_end;
573 int mi_col_end = tile_->mi_col_end;
574 const MV_REF *const prev_frame_mvs =
575 cm->use_prev_frame_mvs
576 ? cm->prev_frame->mvs +
577 AOMMIN(((mi_row >> 1) << 1) + 1 + (((xd->n8_h - 1) >> 1) << 1),
578 mi_row_end - 1) *
579 cm->mi_cols +
580 AOMMIN(((mi_col >> 1) << 1) + 1 + (((xd->n8_w - 1) >> 1) << 1),
581 mi_col_end - 1)
582 : NULL;
583#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700584 const MV_REF *const prev_frame_mvs =
585 cm->use_prev_frame_mvs
586 ? cm->prev_frame->mvs + mi_row * cm->mi_cols + mi_col
587 : NULL;
zhipin dengeb019b82017-02-17 17:49:03 +0800588#endif
Alex Converse44c2bad2017-05-11 09:36:10 -0700589#if CONFIG_INTRABC
590 assert(IMPLIES(ref_frame == INTRA_FRAME, cm->use_prev_frame_mvs == 0));
591#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700592 const TileInfo *const tile = &xd->tile;
Jingning Hanc016df82016-12-09 12:37:28 -0800593 const BLOCK_SIZE bsize = mi->mbmi.sb_type;
594 const int bw = block_size_wide[AOMMAX(bsize, BLOCK_8X8)];
595 const int bh = block_size_high[AOMMAX(bsize, BLOCK_8X8)];
Dengca8d24d2016-10-17 14:06:35 +0800596 POSITION mv_ref_search[MVREF_NEIGHBOURS];
Jingning Hanc016df82016-12-09 12:37:28 -0800597 const int num_8x8_blocks_wide = num_8x8_blocks_wide_lookup[bsize];
598 const int num_8x8_blocks_high = num_8x8_blocks_high_lookup[bsize];
Dengca8d24d2016-10-17 14:06:35 +0800599 mv_ref_search[0].row = num_8x8_blocks_high - 1;
600 mv_ref_search[0].col = -1;
601 mv_ref_search[1].row = -1;
602 mv_ref_search[1].col = num_8x8_blocks_wide - 1;
603 mv_ref_search[2].row = -1;
604 mv_ref_search[2].col = (num_8x8_blocks_wide - 1) >> 1;
605 mv_ref_search[3].row = (num_8x8_blocks_high - 1) >> 1;
606 mv_ref_search[3].col = -1;
607 mv_ref_search[4].row = -1;
608 mv_ref_search[4].col = -1;
Debargha Mukherjeeff59b6a2017-01-26 08:50:48 -0800609#if CONFIG_EXT_PARTITION_TYPES
610 if (num_8x8_blocks_wide == num_8x8_blocks_high) {
611 mv_ref_search[5].row = -1;
612 mv_ref_search[5].col = 0;
613 mv_ref_search[6].row = 0;
614 mv_ref_search[6].col = -1;
615 } else {
616 mv_ref_search[5].row = -1;
617 mv_ref_search[5].col = num_8x8_blocks_wide;
618 mv_ref_search[6].row = num_8x8_blocks_high;
619 mv_ref_search[6].col = -1;
620 }
621#else
Dengca8d24d2016-10-17 14:06:35 +0800622 mv_ref_search[5].row = -1;
623 mv_ref_search[5].col = num_8x8_blocks_wide;
624 mv_ref_search[6].row = num_8x8_blocks_high;
625 mv_ref_search[6].col = -1;
Debargha Mukherjeeff59b6a2017-01-26 08:50:48 -0800626#endif // CONFIG_EXT_PARTITION_TYPES
Dengca8d24d2016-10-17 14:06:35 +0800627 mv_ref_search[7].row = -1;
628 mv_ref_search[7].col = -3;
629 mv_ref_search[8].row = num_8x8_blocks_high - 1;
630 mv_ref_search[8].col = -3;
Jingning Hanc016df82016-12-09 12:37:28 -0800631
632#if CONFIG_CB4X4
633 for (i = 0; i < MVREF_NEIGHBOURS; ++i) {
634 mv_ref_search[i].row *= 2;
635 mv_ref_search[i].col *= 2;
636 }
637#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -0700638
639 // The nearest 2 blocks are treated differently
640 // if the size < 8x8 we get the mv from the bmi substructure,
641 // and we also need to keep a mode count.
642 for (i = 0; i < 2; ++i) {
643 const POSITION *const mv_ref = &mv_ref_search[i];
Yaowu Xu531d6af2017-03-07 17:48:52 -0800644 if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm, mv_ref)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700645 const MODE_INFO *const candidate_mi =
646 xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride];
647 const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
648 // Keep counts for entropy encoding.
649 context_counter += mode_2_counter[candidate->mode];
650 different_ref_found = 1;
651
652 if (candidate->ref_frame[0] == ref_frame)
653 ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 0, mv_ref->col, block),
654 refmv_count, mv_ref_list, bw, bh, xd, Done);
655 else if (candidate->ref_frame[1] == ref_frame)
656 ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 1, mv_ref->col, block),
657 refmv_count, mv_ref_list, bw, bh, xd, Done);
658 }
659 }
660
661 // Check the rest of the neighbors in much the same way
662 // as before except we don't need to keep track of sub blocks or
663 // mode counts.
664 for (; i < MVREF_NEIGHBOURS; ++i) {
665 const POSITION *const mv_ref = &mv_ref_search[i];
Yaowu Xu531d6af2017-03-07 17:48:52 -0800666 if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm, mv_ref)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700667 const MB_MODE_INFO *const candidate =
Yaowu Xuf0602bb2016-12-14 09:30:03 -0800668 !xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]
669 ? NULL
670 : &xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]->mbmi;
Yaowu Xu750955b2016-10-31 08:55:27 -0700671 if (candidate == NULL) continue;
Jingning Han423ecd02016-12-07 12:01:35 -0800672 if ((mi_row % MAX_MIB_SIZE) + mv_ref->row >= MAX_MIB_SIZE ||
673 (mi_col % MAX_MIB_SIZE) + mv_ref->col >= MAX_MIB_SIZE)
Dengca8d24d2016-10-17 14:06:35 +0800674 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700675 different_ref_found = 1;
676
677 if (candidate->ref_frame[0] == ref_frame)
678 ADD_MV_REF_LIST(candidate->mv[0], refmv_count, mv_ref_list, bw, bh, xd,
679 Done);
680 else if (candidate->ref_frame[1] == ref_frame)
681 ADD_MV_REF_LIST(candidate->mv[1], refmv_count, mv_ref_list, bw, bh, xd,
682 Done);
683 }
684 }
685
686// TODO(hkuang): Remove this sync after fixing pthread_cond_broadcast
687// on windows platform. The sync here is unncessary if use_perv_frame_mvs
688// is 0. But after removing it, there will be hang in the unit test on windows
689// due to several threads waiting for a thread's signal.
690#if defined(_WIN32) && !HAVE_PTHREAD_H
691 if (cm->frame_parallel_decode && sync != NULL) {
692 sync(data, mi_row);
693 }
694#endif
695
696 // Check the last frame's mode and mv info.
697 if (cm->use_prev_frame_mvs) {
698 // Synchronize here for frame parallel decode if sync function is provided.
699 if (cm->frame_parallel_decode && sync != NULL) {
700 sync(data, mi_row);
701 }
702
703 if (prev_frame_mvs->ref_frame[0] == ref_frame) {
704 ADD_MV_REF_LIST(prev_frame_mvs->mv[0], refmv_count, mv_ref_list, bw, bh,
705 xd, Done);
706 } else if (prev_frame_mvs->ref_frame[1] == ref_frame) {
707 ADD_MV_REF_LIST(prev_frame_mvs->mv[1], refmv_count, mv_ref_list, bw, bh,
708 xd, Done);
709 }
710 }
711
712 // Since we couldn't find 2 mvs from the same reference frame
713 // go back through the neighbors and find motion vectors from
714 // different reference frames.
715 if (different_ref_found) {
716 for (i = 0; i < MVREF_NEIGHBOURS; ++i) {
717 const POSITION *mv_ref = &mv_ref_search[i];
Yaowu Xu531d6af2017-03-07 17:48:52 -0800718 if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm, mv_ref)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700719 const MB_MODE_INFO *const candidate =
Yaowu Xuf0602bb2016-12-14 09:30:03 -0800720 !xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]
721 ? NULL
722 : &xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride]->mbmi;
Yaowu Xu750955b2016-10-31 08:55:27 -0700723 if (candidate == NULL) continue;
Jingning Han423ecd02016-12-07 12:01:35 -0800724 if ((mi_row % MAX_MIB_SIZE) + mv_ref->row >= MAX_MIB_SIZE ||
725 (mi_col % MAX_MIB_SIZE) + mv_ref->col >= MAX_MIB_SIZE)
Dengca8d24d2016-10-17 14:06:35 +0800726 continue;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700727
728 // If the candidate is INTRA we don't want to consider its mv.
729 IF_DIFF_REF_FRAME_ADD_MV(candidate, ref_frame, ref_sign_bias,
730 refmv_count, mv_ref_list, bw, bh, xd, Done);
731 }
732 }
733 }
734
735 // Since we still don't have a candidate we'll try the last frame.
736 if (cm->use_prev_frame_mvs) {
737 if (prev_frame_mvs->ref_frame[0] != ref_frame &&
738 prev_frame_mvs->ref_frame[0] > INTRA_FRAME) {
739 int_mv mv = prev_frame_mvs->mv[0];
740 if (ref_sign_bias[prev_frame_mvs->ref_frame[0]] !=
741 ref_sign_bias[ref_frame]) {
742 mv.as_mv.row *= -1;
743 mv.as_mv.col *= -1;
744 }
745 ADD_MV_REF_LIST(mv, refmv_count, mv_ref_list, bw, bh, xd, Done);
746 }
747
748 if (prev_frame_mvs->ref_frame[1] > INTRA_FRAME &&
749 prev_frame_mvs->ref_frame[1] != ref_frame) {
750 int_mv mv = prev_frame_mvs->mv[1];
751 if (ref_sign_bias[prev_frame_mvs->ref_frame[1]] !=
752 ref_sign_bias[ref_frame]) {
753 mv.as_mv.row *= -1;
754 mv.as_mv.col *= -1;
755 }
756 ADD_MV_REF_LIST(mv, refmv_count, mv_ref_list, bw, bh, xd, Done);
757 }
758 }
759
760Done:
761 if (mode_context)
762 mode_context[ref_frame] = counter_to_context[context_counter];
763 for (i = refmv_count; i < MAX_MV_REF_CANDIDATES; ++i)
David Barkercdcac6d2016-12-01 17:04:16 +0000764 mv_ref_list[i].as_int = zeromv.as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700765}
766
767#if CONFIG_EXT_INTER
768// This function keeps a mode count for a given MB/SB
Yaowu Xu531d6af2017-03-07 17:48:52 -0800769void av1_update_mv_context(const AV1_COMMON *cm, const MACROBLOCKD *xd,
770 MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
771 int_mv *mv_ref_list, int block, int mi_row,
772 int mi_col, int16_t *mode_context) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700773 int i, refmv_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700774 int context_counter = 0;
Jingning Han61418bb2017-01-23 17:12:48 -0800775 const int bw = block_size_wide[mi->mbmi.sb_type];
776 const int bh = block_size_high[mi->mbmi.sb_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700777 const TileInfo *const tile = &xd->tile;
Zoe Liu40bc8b82017-05-12 10:18:39 -0700778 POSITION mv_ref_search[2];
Jingning Han61418bb2017-01-23 17:12:48 -0800779 const int num_8x8_blocks_wide = mi_size_wide[mi->mbmi.sb_type];
780 const int num_8x8_blocks_high = mi_size_high[mi->mbmi.sb_type];
Zoe Liu40bc8b82017-05-12 10:18:39 -0700781
Yaowu Xu33f210c2016-11-17 17:42:20 -0800782 mv_ref_search[0].row = num_8x8_blocks_high - 1;
783 mv_ref_search[0].col = -1;
784 mv_ref_search[1].row = -1;
785 mv_ref_search[1].col = num_8x8_blocks_wide - 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700786
787 // Blank the reference vector list
788 memset(mv_ref_list, 0, sizeof(*mv_ref_list) * MAX_MV_REF_CANDIDATES);
789
790 // The nearest 2 blocks are examined only.
791 // If the size < 8x8, we get the mv from the bmi substructure;
792 for (i = 0; i < 2; ++i) {
793 const POSITION *const mv_ref = &mv_ref_search[i];
Yaowu Xu531d6af2017-03-07 17:48:52 -0800794 if (is_inside(tile, mi_col, mi_row, cm->mi_rows, cm, mv_ref)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700795 const MODE_INFO *const candidate_mi =
796 xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride];
797 const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
798
799 // Keep counts for entropy encoding.
800 context_counter += mode_2_counter[candidate->mode];
801
802 if (candidate->ref_frame[0] == ref_frame) {
803 ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 0, mv_ref->col, block),
804 refmv_count, mv_ref_list, bw, bh, xd, Done);
805 } else if (candidate->ref_frame[1] == ref_frame) {
806 ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 1, mv_ref->col, block),
807 refmv_count, mv_ref_list, bw, bh, xd, Done);
808 }
809 }
810 }
811
812Done:
813
814 if (mode_context)
815 mode_context[ref_frame] = counter_to_context[context_counter];
816}
817#endif // CONFIG_EXT_INTER
818
Yaowu Xuf883b422016-08-30 14:01:10 -0700819void av1_find_mv_refs(const AV1_COMMON *cm, const MACROBLOCKD *xd,
820 MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
Yaowu Xuf883b422016-08-30 14:01:10 -0700821 uint8_t *ref_mv_count, CANDIDATE_MV *ref_mv_stack,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700822#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -0700823 int16_t *compound_mode_context,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700824#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -0700825 int_mv *mv_ref_list, int mi_row, int mi_col,
826 find_mv_refs_sync sync, void *const data,
827 int16_t *mode_context) {
David Barkercdcac6d2016-12-01 17:04:16 +0000828 int_mv zeromv[2];
Debargha Mukherjee0bae6242017-05-02 21:54:41 -0700829#if CONFIG_GLOBAL_MOTION
830 BLOCK_SIZE bsize = mi->mbmi.sb_type;
831#endif // CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +0000832 int idx, all_zero = 1;
David Barkercdcac6d2016-12-01 17:04:16 +0000833#if CONFIG_GLOBAL_MOTION
834 MV_REFERENCE_FRAME rf[2];
Debargha Mukherjee0bae6242017-05-02 21:54:41 -0700835#endif // CONFIG_GLOBAL_MOTION
Sebastien Alaiwane140c502017-04-27 09:52:34 +0200836
Yaowu Xuc27fc142016-08-22 16:08:15 -0700837#if CONFIG_EXT_INTER
Yaowu Xu531d6af2017-03-07 17:48:52 -0800838 av1_update_mv_context(cm, xd, mi, ref_frame, mv_ref_list, -1, mi_row, mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -0700839 compound_mode_context);
Yaowu Xu4306b6e2016-09-27 12:55:32 -0700840#endif // CONFIG_EXT_INTER
David Barkercdcac6d2016-12-01 17:04:16 +0000841
842#if CONFIG_GLOBAL_MOTION
Alex Converse7d5559c2017-06-14 12:32:35 -0700843 if (!CONFIG_INTRABC || ref_frame != INTRA_FRAME) {
844 av1_set_ref_frame(rf, ref_frame);
845 zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[rf[0]],
846 cm->allow_high_precision_mv, bsize,
847 mi_col, mi_row, 0)
848 .as_int;
849 zeromv[1].as_int = (rf[1] != NONE_FRAME)
850 ? gm_get_motion_vector(&cm->global_motion[rf[1]],
851 cm->allow_high_precision_mv,
852 bsize, mi_col, mi_row, 0)
853 .as_int
854 : 0;
855 } else {
856 zeromv[0].as_int = zeromv[1].as_int = 0;
857 }
David Barkercdcac6d2016-12-01 17:04:16 +0000858#else
859 zeromv[0].as_int = zeromv[1].as_int = 0;
David Barkere0b71512017-02-03 11:07:56 +0000860#endif // CONFIG_GLOBAL_MOTION
David Barkercdcac6d2016-12-01 17:04:16 +0000861
Yaowu Xu4306b6e2016-09-27 12:55:32 -0700862 if (ref_frame <= ALTREF_FRAME)
David Barkercdcac6d2016-12-01 17:04:16 +0000863 find_mv_refs_idx(cm, xd, mi, ref_frame, mv_ref_list, -1, mi_row, mi_col,
864 sync, data, mode_context, zeromv[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700865
Yaowu Xuc27fc142016-08-22 16:08:15 -0700866 setup_ref_mv_list(cm, xd, ref_frame, ref_mv_count, ref_mv_stack, mv_ref_list,
867 -1, mi_row, mi_col, mode_context);
David Barkercdcac6d2016-12-01 17:04:16 +0000868 /* Note: If global motion is enabled, then we want to set the ALL_ZERO flag
869 iff all of the MVs we could generate with NEARMV/NEARESTMV are equivalent
870 to the global motion vector.
871 Note: For the following to work properly, the encoder can't throw away
872 any global motion models after calling this function, even if they are
873 unused. Instead we rely on the recode loop: If any non-IDENTITY model
874 is unused, the whole frame will be re-encoded without it.
875 The problem is that, otherwise, we can end up in the following situation:
876 * Encoder has a global motion model with nonzero translational part,
877 and all candidate MVs are zero. So the ALL_ZERO flag is unset.
878 * Encoder throws away global motion because it is never used.
879 * Decoder sees that there is no global motion and all candidate MVs are
880 zero, so sets the ALL_ZERO flag.
881 * This leads to an encode/decode mismatch.
882 */
Yaowu Xu4306b6e2016-09-27 12:55:32 -0700883 if (*ref_mv_count >= 2) {
884 for (idx = 0; idx < AOMMIN(3, *ref_mv_count); ++idx) {
David Barkercdcac6d2016-12-01 17:04:16 +0000885 if (ref_mv_stack[idx].this_mv.as_int != zeromv[0].as_int) all_zero = 0;
Yaowu Xu4306b6e2016-09-27 12:55:32 -0700886 if (ref_frame > ALTREF_FRAME)
David Barkercdcac6d2016-12-01 17:04:16 +0000887 if (ref_mv_stack[idx].comp_mv.as_int != zeromv[1].as_int) all_zero = 0;
Yaowu Xu4306b6e2016-09-27 12:55:32 -0700888 }
889 } else if (ref_frame <= ALTREF_FRAME) {
890 for (idx = 0; idx < MAX_MV_REF_CANDIDATES; ++idx)
David Barkercdcac6d2016-12-01 17:04:16 +0000891 if (mv_ref_list[idx].as_int != zeromv[0].as_int) all_zero = 0;
Yaowu Xu4306b6e2016-09-27 12:55:32 -0700892 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700893
894 if (all_zero) mode_context[ref_frame] |= (1 << ALL_ZERO_FLAG_OFFSET);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700895}
896
Yaowu Xuf883b422016-08-30 14:01:10 -0700897void av1_find_best_ref_mvs(int allow_hp, int_mv *mvlist, int_mv *nearest_mv,
898 int_mv *near_mv) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700899 int i;
900 // Make sure all the candidates are properly clamped etc
901 for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
902 lower_mv_precision(&mvlist[i].as_mv, allow_hp);
903 }
904 *nearest_mv = mvlist[0];
905 *near_mv = mvlist[1];
906}
907
Urvang Joshi52648442016-10-13 17:27:51 -0700908void av1_append_sub8x8_mvs_for_idx(const AV1_COMMON *cm, MACROBLOCKD *xd,
909 int block, int ref, int mi_row, int mi_col,
Yaowu Xuf883b422016-08-30 14:01:10 -0700910 CANDIDATE_MV *ref_mv_stack,
911 uint8_t *ref_mv_count,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700912#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -0700913 int_mv *mv_list,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700914#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -0700915 int_mv *nearest_mv, int_mv *near_mv) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700916#if !CONFIG_EXT_INTER
917 int_mv mv_list[MAX_MV_REF_CANDIDATES];
918#endif // !CONFIG_EXT_INTER
919 MODE_INFO *const mi = xd->mi[0];
920 b_mode_info *bmi = mi->bmi;
921 int n;
David Barkercdcac6d2016-12-01 17:04:16 +0000922 int_mv zeromv;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700923 CANDIDATE_MV tmp_mv;
924 uint8_t idx;
925 uint8_t above_count = 0, left_count = 0;
Emil Keyder01770b32017-01-20 18:03:11 -0500926 MV_REFERENCE_FRAME rf[2] = { mi->mbmi.ref_frame[ref], NONE_FRAME };
Yaowu Xuc27fc142016-08-22 16:08:15 -0700927 *ref_mv_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700928
929 assert(MAX_MV_REF_CANDIDATES == 2);
930
David Barkercdcac6d2016-12-01 17:04:16 +0000931#if CONFIG_GLOBAL_MOTION
David Barkere3afdd82017-06-30 17:08:11 +0100932 zeromv.as_int = gm_get_motion_vector(&cm->global_motion[rf[0]],
933 cm->allow_high_precision_mv,
934 mi->mbmi.sb_type, mi_col, mi_row, block)
935 .as_int;
David Barkercdcac6d2016-12-01 17:04:16 +0000936#else
937 zeromv.as_int = 0;
938#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700939 find_mv_refs_idx(cm, xd, mi, mi->mbmi.ref_frame[ref], mv_list, block, mi_row,
David Barkercdcac6d2016-12-01 17:04:16 +0000940 mi_col, NULL, NULL, NULL, zeromv);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700941
Yaowu Xuc27fc142016-08-22 16:08:15 -0700942 scan_blk_mbmi(cm, xd, mi_row, mi_col, block, rf, -1, 0, ref_mv_stack,
943 ref_mv_count);
944 above_count = *ref_mv_count;
945
946 scan_blk_mbmi(cm, xd, mi_row, mi_col, block, rf, 0, -1, ref_mv_stack,
947 ref_mv_count);
948 left_count = *ref_mv_count - above_count;
949
950 if (above_count > 1 && left_count > 0) {
951 tmp_mv = ref_mv_stack[1];
952 ref_mv_stack[1] = ref_mv_stack[above_count];
953 ref_mv_stack[above_count] = tmp_mv;
954 }
955
956 for (idx = 0; idx < *ref_mv_count; ++idx)
Jingning Hanff6ee6a2016-12-07 09:55:21 -0800957 clamp_mv_ref(&ref_mv_stack[idx].this_mv.as_mv, xd->n8_w << MI_SIZE_LOG2,
958 xd->n8_h << MI_SIZE_LOG2, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700959
Yaowu Xuf883b422016-08-30 14:01:10 -0700960 for (idx = 0; idx < AOMMIN(MAX_MV_REF_CANDIDATES, *ref_mv_count); ++idx)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700961 mv_list[idx].as_int = ref_mv_stack[idx].this_mv.as_int;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700962
963 near_mv->as_int = 0;
964 switch (block) {
965 case 0:
966 nearest_mv->as_int = mv_list[0].as_int;
967 near_mv->as_int = mv_list[1].as_int;
968 break;
969 case 1:
970 case 2:
971 nearest_mv->as_int = bmi[0].as_mv[ref].as_int;
972 for (n = 0; n < MAX_MV_REF_CANDIDATES; ++n)
973 if (nearest_mv->as_int != mv_list[n].as_int) {
974 near_mv->as_int = mv_list[n].as_int;
975 break;
976 }
977 break;
978 case 3: {
979 int_mv candidates[2 + MAX_MV_REF_CANDIDATES];
980 candidates[0] = bmi[1].as_mv[ref];
981 candidates[1] = bmi[0].as_mv[ref];
982 candidates[2] = mv_list[0];
983 candidates[3] = mv_list[1];
984
985 nearest_mv->as_int = bmi[2].as_mv[ref].as_int;
986 for (n = 0; n < 2 + MAX_MV_REF_CANDIDATES; ++n)
987 if (nearest_mv->as_int != candidates[n].as_int) {
988 near_mv->as_int = candidates[n].as_int;
989 break;
990 }
991 break;
992 }
993 default: assert(0 && "Invalid block index.");
994 }
995}
Yue Chen69f18e12016-09-08 14:48:15 -0700996
997#if CONFIG_WARPED_MOTION
Yue Chenff616102017-04-04 15:50:12 -0700998void calc_projection_samples(MB_MODE_INFO *const mbmi, int x, int y,
999 int *pts_inref) {
1000 pts_inref[0] = (x * 8) + mbmi->mv[0].as_mv.col;
1001 pts_inref[1] = (y * 8) + mbmi->mv[0].as_mv.row;
Yue Chend193cdc2017-01-13 00:52:23 -08001002}
1003
Debargha Mukherjeee6eb3b52017-02-26 08:50:56 -08001004// Note: Samples returned are at 1/8-pel precision
Yue Chen69f18e12016-09-08 14:48:15 -07001005int findSamples(const AV1_COMMON *cm, MACROBLOCKD *xd, int mi_row, int mi_col,
Debargha Mukherjeee6eb3b52017-02-26 08:50:56 -08001006 int *pts, int *pts_inref) {
Yue Chen69f18e12016-09-08 14:48:15 -07001007 MB_MODE_INFO *const mbmi0 = &(xd->mi[0]->mbmi);
1008 int ref_frame = mbmi0->ref_frame[0];
1009 int up_available = xd->up_available;
1010 int left_available = xd->left_available;
1011 int i, mi_step, np = 0;
Yue Chend0d3bcc2017-01-30 11:22:32 -08001012 int global_offset_c = mi_col * MI_SIZE;
1013 int global_offset_r = mi_row * MI_SIZE;
Yue Chen69f18e12016-09-08 14:48:15 -07001014
1015 // scan the above row
1016 if (up_available) {
1017 for (i = 0; i < AOMMIN(xd->n8_w, cm->mi_cols - mi_col); i += mi_step) {
1018 int mi_row_offset = -1;
1019 int mi_col_offset = i;
1020
1021 MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
1022 MB_MODE_INFO *mbmi = &mi->mbmi;
1023
Yue Chend0d3bcc2017-01-30 11:22:32 -08001024 mi_step = AOMMIN(xd->n8_w, mi_size_wide[mbmi->sb_type]);
Yue Chen69f18e12016-09-08 14:48:15 -07001025
Emil Keyder01770b32017-01-20 18:03:11 -05001026 if (mbmi->ref_frame[0] == ref_frame && mbmi->ref_frame[1] == NONE_FRAME) {
David Barkercdcac6d2016-12-01 17:04:16 +00001027 int bw = block_size_wide[mbmi->sb_type];
1028 int bh = block_size_high[mbmi->sb_type];
Yue Chend0d3bcc2017-01-30 11:22:32 -08001029 int cr_offset = -AOMMAX(bh, MI_SIZE) / 2 - 1;
1030 int cc_offset = i * MI_SIZE + AOMMAX(bw, MI_SIZE) / 2 - 1;
Yue Chen5558e5d2017-03-31 12:24:42 -07001031 int x = cc_offset + global_offset_c;
1032 int y = cr_offset + global_offset_r;
Yue Chen69f18e12016-09-08 14:48:15 -07001033
Yue Chen5558e5d2017-03-31 12:24:42 -07001034 pts[0] = (x * 8);
1035 pts[1] = (y * 8);
Yue Chenff616102017-04-04 15:50:12 -07001036 calc_projection_samples(mbmi, x, y, pts_inref);
Yue Chen5558e5d2017-03-31 12:24:42 -07001037 pts += 2;
1038 pts_inref += 2;
1039 np++;
1040 if (np >= LEAST_SQUARES_SAMPLES_MAX) return LEAST_SQUARES_SAMPLES_MAX;
Yue Chen69f18e12016-09-08 14:48:15 -07001041 }
1042 }
1043 }
Debargha Mukherjee9868c742017-01-26 15:23:35 -08001044 assert(2 * np <= SAMPLES_ARRAY_SIZE);
Yue Chen69f18e12016-09-08 14:48:15 -07001045
1046 // scan the left column
1047 if (left_available) {
1048 for (i = 0; i < AOMMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) {
1049 int mi_row_offset = i;
1050 int mi_col_offset = -1;
1051
1052 MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
1053 MB_MODE_INFO *mbmi = &mi->mbmi;
1054
Yue Chend0d3bcc2017-01-30 11:22:32 -08001055 mi_step = AOMMIN(xd->n8_h, mi_size_high[mbmi->sb_type]);
Yue Chen69f18e12016-09-08 14:48:15 -07001056
Emil Keyder01770b32017-01-20 18:03:11 -05001057 if (mbmi->ref_frame[0] == ref_frame && mbmi->ref_frame[1] == NONE_FRAME) {
David Barkercdcac6d2016-12-01 17:04:16 +00001058 int bw = block_size_wide[mbmi->sb_type];
1059 int bh = block_size_high[mbmi->sb_type];
Yue Chend0d3bcc2017-01-30 11:22:32 -08001060 int cr_offset = i * MI_SIZE + AOMMAX(bh, MI_SIZE) / 2 - 1;
1061 int cc_offset = -AOMMAX(bw, MI_SIZE) / 2 - 1;
Yue Chen5558e5d2017-03-31 12:24:42 -07001062 int x = cc_offset + global_offset_c;
1063 int y = cr_offset + global_offset_r;
Yue Chen69f18e12016-09-08 14:48:15 -07001064
Yue Chen5558e5d2017-03-31 12:24:42 -07001065 pts[0] = (x * 8);
1066 pts[1] = (y * 8);
Yue Chenff616102017-04-04 15:50:12 -07001067 calc_projection_samples(mbmi, x, y, pts_inref);
Yue Chen5558e5d2017-03-31 12:24:42 -07001068 pts += 2;
1069 pts_inref += 2;
1070 np++;
1071 if (np >= LEAST_SQUARES_SAMPLES_MAX) return LEAST_SQUARES_SAMPLES_MAX;
Yue Chen69f18e12016-09-08 14:48:15 -07001072 }
1073 }
1074 }
Debargha Mukherjee9868c742017-01-26 15:23:35 -08001075 assert(2 * np <= SAMPLES_ARRAY_SIZE);
Yue Chen69f18e12016-09-08 14:48:15 -07001076
1077 if (left_available && up_available) {
1078 int mi_row_offset = -1;
1079 int mi_col_offset = -1;
1080
1081 MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
1082 MB_MODE_INFO *mbmi = &mi->mbmi;
1083
Emil Keyder01770b32017-01-20 18:03:11 -05001084 if (mbmi->ref_frame[0] == ref_frame && mbmi->ref_frame[1] == NONE_FRAME) {
David Barkercdcac6d2016-12-01 17:04:16 +00001085 int bw = block_size_wide[mbmi->sb_type];
1086 int bh = block_size_high[mbmi->sb_type];
Yue Chend0d3bcc2017-01-30 11:22:32 -08001087 int cr_offset = -AOMMAX(bh, MI_SIZE) / 2 - 1;
1088 int cc_offset = -AOMMAX(bw, MI_SIZE) / 2 - 1;
Yue Chen5558e5d2017-03-31 12:24:42 -07001089 int x = cc_offset + global_offset_c;
1090 int y = cr_offset + global_offset_r;
Yue Chen69f18e12016-09-08 14:48:15 -07001091
Yue Chen5558e5d2017-03-31 12:24:42 -07001092 pts[0] = (x * 8);
1093 pts[1] = (y * 8);
Yue Chenff616102017-04-04 15:50:12 -07001094 calc_projection_samples(mbmi, x, y, pts_inref);
Yue Chen5558e5d2017-03-31 12:24:42 -07001095 np++;
Yue Chen69f18e12016-09-08 14:48:15 -07001096 }
1097 }
Debargha Mukherjee9868c742017-01-26 15:23:35 -08001098 assert(2 * np <= SAMPLES_ARRAY_SIZE);
Yue Chen69f18e12016-09-08 14:48:15 -07001099
Yue Chen69f18e12016-09-08 14:48:15 -07001100 return np;
1101}
1102#endif // CONFIG_WARPED_MOTION