Line data Source code
1 : /*
2 : * Copyright(c) 2019 Intel Corporation
3 : * SPDX - License - Identifier: BSD - 2 - Clause - Patent
4 : */
5 :
6 : /*
7 : * Copyright (c) 2016, Alliance for Open Media. All rights reserved
8 : *
9 : * This source code is subject to the terms of the BSD 2 Clause License and
10 : * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
11 : * was not distributed with this source code in the LICENSE file, you can
12 : * obtain it at www.aomedia.org/license/software. If the Alliance for Open
13 : * Media Patent License 1.0 was not distributed with this source code in the
14 : * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
15 : */
16 :
17 : #include <string.h>
18 :
19 : #include "EbDefinitions.h"
20 : #include "EbUtility.h"
21 : #include "EbAdaptiveMotionVectorPrediction.h"
22 : #include "EbSvtAv1.h"
23 : #include "EbModeDecisionProcess.h"
24 : #include "EbCommonUtils.h"
25 : #include "EbEntropyCoding.h"
26 :
27 : #define UNUSED_FUNC
28 :
29 : /** ScaleMV
30 : is used to scale the motion vector in AMVP process.
31 : */
32 : /*
33 : static inline void scale_mv(
34 : uint64_t current_pic_poc, // Iuput parameter, the POC of the current picture to be encoded.
35 : uint64_t target_ref_pic_poc, // Iuput parameter, the POC of the reference picture where the inter coding is searching for.
36 : uint64_t col_pu_pic_poc, // Iuput parameter, the POC of picture where the co-located PU is.
37 : uint64_t col_pu_ref_pic_poc, // Iuput parameter, the POC of the reference picture where the MV of the co-located PU points to.
38 : int16_t *mvx, // Output parameter,
39 : int16_t *mvy) // Output parameter,
40 : {
41 : int16_t td = (int16_t)(col_pu_pic_poc - col_pu_ref_pic_poc);
42 : int16_t tb = (int16_t)(current_pic_poc - target_ref_pic_poc);
43 : int16_t scale_factor;
44 : int16_t temp;
45 :
46 : if (td != tb) {
47 : tb = CLIP3(-128, 127, tb);
48 : td = CLIP3(-128, 127, td);
49 : temp = (int16_t)((0x4000 + ABS(td >> 1)) / td);
50 : scale_factor = CLIP3(-4096, 4095, (tb * temp + 32) >> 6);
51 :
52 : *mvx = CLIP3(-32768, 32767, (scale_factor * (*mvx) + 127 + (scale_factor * (*mvx) < 0)) >> 8);
53 : *mvy = CLIP3(-32768, 32767, (scale_factor * (*mvy) + 127 + (scale_factor * (*mvy) < 0)) >> 8);
54 : }
55 :
56 : return;
57 : }
58 : */
59 : static PartitionType from_shape_to_part[] = {
60 : PARTITION_NONE,
61 : PARTITION_HORZ,
62 : PARTITION_VERT,
63 : PARTITION_HORZ_A,
64 : PARTITION_HORZ_B,
65 : PARTITION_VERT_A,
66 : PARTITION_VERT_B,
67 : PARTITION_HORZ_4,
68 : PARTITION_VERT_4,
69 : PARTITION_SPLIT
70 : };
71 0 : EbErrorType clip_mv(
72 : uint32_t cu_origin_x,
73 : uint32_t cu_origin_y,
74 : int16_t *mvx,
75 : int16_t *mvy,
76 : uint32_t picture_width,
77 : uint32_t picture_height,
78 : uint32_t tb_size)
79 : {
80 0 : EbErrorType return_error = EB_ErrorNone;
81 :
82 : // horizontal clipping
83 0 : (*mvx) = CLIP3(((int16_t)((1 - cu_origin_x - 8 - tb_size) << 2)), ((int16_t)((picture_width + 8 - cu_origin_x - 1) << 2)), (*mvx));
84 : // vertical clipping
85 0 : (*mvy) = CLIP3(((int16_t)((1 - cu_origin_y - 8 - tb_size) << 2)), ((int16_t)((picture_height + 8 - cu_origin_y - 1) << 2)), (*mvy));
86 0 : const int32_t clamp_max = MV_UPP - 1;
87 0 : const int32_t clamp_min = MV_LOW + 1;
88 : // horizontal clipping
89 0 : (*mvx) = CLIP3(clamp_min, clamp_max, (*mvx));
90 : // vertical clipping
91 0 : (*mvy) = CLIP3(clamp_min, clamp_max, (*mvy));
92 :
93 0 : return return_error;
94 : }
95 :
96 : #define MVREF_ROWS 3
97 : #define MVREF_COLS 3
98 :
99 199472000 : /*static INLINE*/ int32_t is_inter_block(const BlockModeInfo *mbmi) {
100 199472000 : return (mbmi->use_intrabc || (mbmi->ref_frame[0] > INTRA_FRAME));
101 : }
102 :
103 9458230 : static int32_t have_newmv_in_inter_mode(PredictionMode mode) {
104 8808260 : return (mode == NEWMV || mode == NEW_NEWMV || mode == NEAREST_NEWMV ||
105 18266500 : mode == NEW_NEARESTMV || mode == NEAR_NEWMV || mode == NEW_NEARMV);
106 : }
107 : #define n_elements(x) (int32_t)(sizeof(x) / sizeof(x[0]))
108 49398500 : MvReferenceFrame comp_ref0(int32_t ref_idx) {
109 : static const MvReferenceFrame lut[] = {
110 : LAST_FRAME, // LAST_LAST2_FRAMES,
111 : LAST_FRAME, // LAST_LAST3_FRAMES,
112 : LAST_FRAME, // LAST_GOLDEN_FRAMES,
113 : BWDREF_FRAME, // BWDREF_ALTREF_FRAMES,
114 : LAST2_FRAME, // LAST2_LAST3_FRAMES
115 : LAST2_FRAME, // LAST2_GOLDEN_FRAMES,
116 : LAST3_FRAME, // LAST3_GOLDEN_FRAMES,
117 : BWDREF_FRAME, // BWDREF_ALTREF2_FRAMES,
118 : ALTREF2_FRAME, // ALTREF2_ALTREF_FRAMES,
119 : };
120 : assert(n_elements(lut) == TOTAL_UNIDIR_COMP_REFS);
121 49398500 : return lut[ref_idx];
122 : }
123 :
124 41180000 : MvReferenceFrame comp_ref1(int32_t ref_idx) {
125 : static const MvReferenceFrame lut[] = {
126 : LAST2_FRAME, // LAST_LAST2_FRAMES,
127 : LAST3_FRAME, // LAST_LAST3_FRAMES,
128 : GOLDEN_FRAME, // LAST_GOLDEN_FRAMES,
129 : ALTREF_FRAME, // BWDREF_ALTREF_FRAMES,
130 : LAST3_FRAME, // LAST2_LAST3_FRAMES
131 : GOLDEN_FRAME, // LAST2_GOLDEN_FRAMES,
132 : GOLDEN_FRAME, // LAST3_GOLDEN_FRAMES,
133 : ALTREF2_FRAME, // BWDREF_ALTREF2_FRAMES,
134 : ALTREF_FRAME, // ALTREF2_ALTREF_FRAMES,
135 : };
136 : assert(n_elements(lut) == TOTAL_UNIDIR_COMP_REFS);
137 41180000 : return lut[ref_idx];
138 : }
139 :
140 : typedef struct position {
141 : int32_t row;
142 : int32_t col;
143 : } Position;
144 :
145 : static MvReferenceFrame ref_frame_map[TOTAL_COMP_REFS][2] = {
146 : { LAST_FRAME, BWDREF_FRAME },{ LAST2_FRAME, BWDREF_FRAME },
147 : { LAST3_FRAME, BWDREF_FRAME },{ GOLDEN_FRAME, BWDREF_FRAME },
148 : { LAST_FRAME, ALTREF2_FRAME },{ LAST2_FRAME, ALTREF2_FRAME },
149 : { LAST3_FRAME, ALTREF2_FRAME },{ GOLDEN_FRAME, ALTREF2_FRAME },
150 : { LAST_FRAME, ALTREF_FRAME },{ LAST2_FRAME, ALTREF_FRAME },
151 : { LAST3_FRAME, ALTREF_FRAME },{ GOLDEN_FRAME, ALTREF_FRAME },
152 : { LAST_FRAME, LAST2_FRAME },{ LAST_FRAME, LAST3_FRAME },
153 : { LAST_FRAME, GOLDEN_FRAME },{ BWDREF_FRAME, ALTREF_FRAME },
154 : // NOTE: Following reference frame pairs are not supported to be explicitly
155 : // signalled, but they are possibly chosen by the use of skip_mode,
156 : // which may use the most recent one-sided reference frame pair.
157 : { LAST2_FRAME, LAST3_FRAME },{ LAST2_FRAME, GOLDEN_FRAME },
158 : { LAST3_FRAME, GOLDEN_FRAME },{ BWDREF_FRAME, ALTREF2_FRAME },
159 : { ALTREF2_FRAME, ALTREF_FRAME }
160 : };
161 :
162 : // clang-format on
163 :
164 1409530000 : void av1_set_ref_frame(MvReferenceFrame *rf,
165 : int8_t ref_frame_type) {
166 1409530000 : if (ref_frame_type >= TOTAL_REFS_PER_FRAME) {
167 841670000 : rf[0] = ref_frame_map[ref_frame_type - TOTAL_REFS_PER_FRAME][0];
168 841670000 : rf[1] = ref_frame_map[ref_frame_type - TOTAL_REFS_PER_FRAME][1];
169 : }
170 : else {
171 567864000 : rf[0] = ref_frame_type;
172 567864000 : rf[1] = NONE_FRAME;
173 : // assert(ref_frame_type > NONE_FRAME); AMIR
174 : }
175 1409530000 : }
176 120234000 : int8_t get_uni_comp_ref_idx(const MvReferenceFrame *const rf) {
177 : // Single ref pred
178 120234000 : if (rf[1] <= INTRA_FRAME) return -1;
179 :
180 : // Bi-directional comp ref pred
181 120234000 : if ((rf[0] < BWDREF_FRAME) && (rf[1] >= BWDREF_FRAME)) return -1;
182 :
183 49265700 : for (int8_t ref_idx = 0; ref_idx < TOTAL_UNIDIR_COMP_REFS; ++ref_idx) {
184 49398100 : if (rf[0] == comp_ref0(ref_idx) && rf[1] == comp_ref1(ref_idx))
185 24472700 : return ref_idx;
186 : }
187 0 : return -1;
188 : }
189 :
190 158969000 : extern INLINE int8_t av1_ref_frame_type(const MvReferenceFrame *const rf) {
191 158969000 : if (rf[1] > INTRA_FRAME) {
192 120222000 : const int8_t uni_comp_ref_idx = get_uni_comp_ref_idx(rf);
193 120235000 : if (uni_comp_ref_idx >= 0) {
194 24473600 : assert((TOTAL_REFS_PER_FRAME + FWD_REFS * BWD_REFS + uni_comp_ref_idx) <
195 : MODE_CTX_REF_FRAMES);
196 24473600 : return TOTAL_REFS_PER_FRAME + FWD_REFS * BWD_REFS + uni_comp_ref_idx;
197 : }
198 : else {
199 95761500 : return TOTAL_REFS_PER_FRAME + FWD_RF_OFFSET(rf[0]) +
200 95761500 : BWD_RF_OFFSET(rf[1]) * FWD_REFS;
201 : }
202 : }
203 :
204 38746600 : return rf[0];
205 : }
206 :
207 6069640 : static INLINE IntMv get_sub_block_mv(const ModeInfo *candidate, int32_t which_mv,
208 : int32_t search_col) {
209 : (void)search_col;
210 6069640 : return candidate->mbmi.block_mi.mv[which_mv];
211 : }
212 84669100 : static INLINE int32_t is_inside(const TileInfo *const tile, int32_t mi_col, int32_t mi_row,
213 : int32_t mi_rows, const Position *mi_pos) {
214 84669100 : const int32_t dependent_horz_tile_flag = 0;
215 84669100 : if (dependent_horz_tile_flag && !tile->tg_horz_boundary) {
216 0 : return !(mi_row + mi_pos->row < 0 ||
217 0 : mi_col + mi_pos->col < tile->mi_col_start ||
218 0 : mi_row + mi_pos->row >= mi_rows ||
219 0 : mi_col + mi_pos->col >= tile->mi_col_end);
220 : }
221 : else {
222 161656000 : return !(mi_row + mi_pos->row < tile->mi_row_start ||
223 76987200 : mi_col + mi_pos->col < tile->mi_col_start ||
224 76677900 : mi_row + mi_pos->row >= tile->mi_row_end ||
225 76430200 : mi_col + mi_pos->col >= tile->mi_col_end);
226 : }
227 : }
228 :
229 32577300 : static INLINE void clamp_mv_ref(MV *mv, int32_t bw, int32_t bh, const MacroBlockD *xd) {
230 32577300 : clamp_mv(mv, xd->mb_to_left_edge - bw * 8 - MV_BORDER,
231 32577300 : xd->mb_to_right_edge + bw * 8 + MV_BORDER,
232 32577300 : xd->mb_to_top_edge - bh * 8 - MV_BORDER,
233 32577300 : xd->mb_to_bottom_edge + bh * 8 + MV_BORDER);
234 32577000 : }
235 :
236 40749500 : static void add_ref_mv_candidate(
237 : const ModeInfo *const candidate_mi, const MbModeInfo *const candidate,
238 : const MvReferenceFrame rf[2], uint8_t refmv_counts[MODE_CTX_REF_FRAMES],
239 : uint8_t ref_match_counts[MODE_CTX_REF_FRAMES],
240 : uint8_t newmv_counts[MODE_CTX_REF_FRAMES],
241 : CandidateMv ref_mv_stacks[][MAX_REF_MV_STACK_SIZE], int32_t len,
242 : #if USE_CUR_GM_REFMV
243 : IntMv *gm_mv_candidates, const EbWarpedMotionParams *gm_params,
244 : #endif // USE_CUR_GM_REFMV
245 : int32_t col, int32_t weight)
246 : {
247 40749500 : if (!is_inter_block(&candidate->block_mi)) return; // for intrabc
248 40535700 : int32_t index = 0, ref;
249 40535700 : assert(weight % 2 == 0);
250 :
251 40535700 : if (rf[1] == NONE_FRAME) {
252 16733500 : uint8_t *refmv_count = &refmv_counts[rf[0]];
253 16733500 : uint8_t *ref_match_count = &ref_match_counts[rf[0]];
254 16733500 : uint8_t *newmv_count = &newmv_counts[rf[0]];
255 16733500 : CandidateMv *ref_mv_stack = ref_mv_stacks[rf[0]];
256 : (void)ref_match_count;
257 :
258 : // single reference frame
259 50189100 : for (ref = 0; ref < 2; ++ref) {
260 33455800 : if (candidate->block_mi.ref_frame[ref] == rf[0]) {
261 : IntMv this_refmv;
262 : #if USE_CUR_GM_REFMV //CHKN this should not be used for TRANSLATION ME model
263 6684040 : if (is_global_mv_block(candidate->block_mi.mode,
264 6684390 : candidate->block_mi.sb_type,
265 6684390 : gm_params[rf[0]].wmtype))
266 3143260 : this_refmv = gm_mv_candidates[0];
267 : else
268 : #endif // USE_CUR_GM_REFMV
269 3540780 : this_refmv = get_sub_block_mv(candidate_mi, ref, col);
270 :
271 10380800 : for (index = 0; index < *refmv_count; ++index)
272 7748710 : if (ref_mv_stack[index].this_mv.as_int == this_refmv.as_int) break;
273 :
274 6683700 : if (index < *refmv_count) ref_mv_stack[index].weight += weight * len;
275 :
276 : // Add a new item to the list.
277 6683700 : if (index == *refmv_count && *refmv_count < MAX_REF_MV_STACK_SIZE) {
278 2603240 : ref_mv_stack[index].this_mv = this_refmv;
279 2603240 : ref_mv_stack[index].weight = weight * len;
280 2603240 : ++(*refmv_count);
281 : }
282 6683700 : if (have_newmv_in_inter_mode(candidate->block_mi.mode))++*newmv_count;
283 6684130 : ++*ref_match_count;
284 : }
285 : }
286 : }
287 : else {
288 23802100 : MvReferenceFrame ref_frame = av1_ref_frame_type(rf);
289 23817700 : uint8_t *refmv_count = &refmv_counts[ref_frame];
290 23817700 : uint8_t *ref_match_count = &ref_match_counts[ref_frame];
291 23817700 : uint8_t *newmv_count = &newmv_counts[ref_frame];
292 23817700 : CandidateMv *ref_mv_stack = ref_mv_stacks[ref_frame];
293 : (void)ref_match_count;
294 :
295 : // compound reference frame
296 23817700 : if (candidate->block_mi.ref_frame[0] == rf[0] && candidate->block_mi.ref_frame[1] == rf[1]) {
297 : IntMv this_refmv[2];
298 :
299 8338870 : for (ref = 0; ref < 2; ++ref) {
300 : #if USE_CUR_GM_REFMV
301 5558820 : if (is_global_mv_block(candidate->block_mi.mode,
302 5558910 : candidate->block_mi.sb_type,
303 5558910 : gm_params[rf[ref]].wmtype))
304 3024730 : this_refmv[ref] = gm_mv_candidates[ref];
305 : else
306 : #endif // USE_CUR_GM_REFMV
307 2534090 : this_refmv[ref] = get_sub_block_mv(candidate_mi, ref, col);
308 : }
309 :
310 3803100 : for (index = 0; index < *refmv_count; ++index)
311 2829150 : if ((ref_mv_stack[index].this_mv.as_int == this_refmv[0].as_int) &&
312 1821570 : (ref_mv_stack[index].comp_mv.as_int == this_refmv[1].as_int))
313 1806010 : break;
314 :
315 2779960 : if (index < *refmv_count) ref_mv_stack[index].weight += weight * len;
316 :
317 : // Add a new item to the list.
318 2779960 : if (index == *refmv_count && *refmv_count < MAX_REF_MV_STACK_SIZE) {
319 965748 : ref_mv_stack[index].this_mv = this_refmv[0];
320 965748 : ref_mv_stack[index].comp_mv = this_refmv[1];
321 965748 : ref_mv_stack[index].weight = weight * len;
322 965748 : ++(*refmv_count);
323 : }
324 2779960 : if (have_newmv_in_inter_mode(candidate->block_mi.mode))++*newmv_count;
325 2779720 : ++*ref_match_count;
326 : }
327 : }
328 : }
329 :
330 13724500 : static void scan_row_mbmi(const Av1Common *cm, const MacroBlockD *xd,
331 : int32_t mi_row, int32_t mi_col,
332 : const MvReferenceFrame rf[2], int32_t row_offset,
333 : CandidateMv ref_mv_stack[][MAX_REF_MV_STACK_SIZE],
334 : uint8_t refmv_count[MODE_CTX_REF_FRAMES],
335 : uint8_t ref_match_count[MODE_CTX_REF_FRAMES],
336 : uint8_t newmv_count[MODE_CTX_REF_FRAMES],
337 : #if USE_CUR_GM_REFMV
338 : IntMv *gm_mv_candidates, const EbWarpedMotionParams *gm_params,
339 : #endif // USE_CUR_GM_REFMV
340 : int32_t max_row_offset, int32_t *processed_rows) {
341 13724500 : int32_t end_mi = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
342 13724500 : end_mi = AOMMIN(end_mi, mi_size_wide[BLOCK_64X64]);
343 13724500 : const int32_t n8_w_8 = mi_size_wide[BLOCK_8X8];
344 13724500 : const int32_t n8_w_16 = mi_size_wide[BLOCK_16X16];
345 : int32_t i;
346 13724500 : int32_t col_offset = 0;
347 13724500 : const int32_t shift = 0;
348 : // TODO(jingning): Revisit this part after cb4x4 is stable.
349 13724500 : if (abs(row_offset) > 1) {
350 6235850 : col_offset = 1;
351 6235850 : if (mi_col & 0x01 && xd->n8_w < n8_w_8) --col_offset;
352 : }
353 13724500 : const int32_t use_step_16 = (xd->n8_w >= 16);
354 13724500 : ModeInfo **const candidate_mi0 = xd->mi + row_offset * xd->mi_stride;
355 : (void)mi_row;
356 :
357 27984700 : for (i = 0; i < end_mi;) {
358 14262200 : const ModeInfo *const candidate_mi = candidate_mi0[col_offset + i];
359 14262200 : const MbModeInfo *const candidate = &candidate_mi->mbmi;
360 14262200 : const int32_t candidate_bsize = candidate->block_mi.sb_type;
361 14262200 : assert(candidate_bsize < BlockSizeS_ALL);
362 14262200 : const int32_t n8_w = mi_size_wide[candidate_bsize];
363 14262200 : int32_t len = AOMMIN(xd->n8_w, n8_w);
364 14262200 : if (use_step_16)
365 572246 : len = AOMMAX(n8_w_16, len);
366 13689900 : else if (abs(row_offset) > 1)
367 6319200 : len = AOMMAX(len, n8_w_8);
368 :
369 14262200 : int32_t weight = 2;
370 14262200 : if (xd->n8_w >= n8_w_8 && xd->n8_w <= n8_w) {
371 9179820 : int32_t inc = AOMMIN(-max_row_offset + row_offset + 1,
372 : mi_size_high[candidate_bsize]);
373 : // Obtain range used in weight calculation.
374 9179820 : weight = AOMMAX(weight, (inc << shift));
375 : // Update processed rows.
376 9179820 : *processed_rows = inc - row_offset - 1;
377 : }
378 :
379 14262200 : add_ref_mv_candidate(candidate_mi, candidate, rf, refmv_count,
380 : ref_match_count, newmv_count, ref_mv_stack, len,
381 : #if USE_CUR_GM_REFMV
382 : gm_mv_candidates, gm_params,
383 : #endif // USE_CUR_GM_REFMV
384 : col_offset + i, weight);
385 :
386 14260300 : i += len;
387 : }
388 13722500 : }
389 :
390 14040500 : static void scan_col_mbmi(const Av1Common *cm, const MacroBlockD *xd,
391 : int32_t mi_row, int32_t mi_col,
392 : const MvReferenceFrame rf[2], int32_t col_offset,
393 : CandidateMv ref_mv_stack[][MAX_REF_MV_STACK_SIZE],
394 : uint8_t refmv_count[MODE_CTX_REF_FRAMES],
395 : uint8_t ref_match_count[MODE_CTX_REF_FRAMES],
396 : uint8_t newmv_count[MODE_CTX_REF_FRAMES],
397 : #if USE_CUR_GM_REFMV
398 : IntMv *gm_mv_candidates, const EbWarpedMotionParams *gm_params,
399 : #endif // USE_CUR_GM_REFMV
400 : int32_t max_col_offset, int32_t *processed_cols) {
401 14040500 : int32_t end_mi = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
402 14040500 : end_mi = AOMMIN(end_mi, mi_size_high[BLOCK_64X64]);
403 14040500 : const int32_t n8_h_8 = mi_size_high[BLOCK_8X8];
404 14040500 : const int32_t n8_h_16 = mi_size_high[BLOCK_16X16];
405 : int32_t i;
406 14040500 : int32_t row_offset = 0;
407 14040500 : const int32_t shift = 0;
408 14040500 : if (abs(col_offset) > 1) {
409 6501030 : row_offset = 1;
410 6501030 : if (mi_row & 0x01 && xd->n8_h < n8_h_8) --row_offset;
411 : }
412 14040500 : const int32_t use_step_16 = (xd->n8_h >= 16);
413 : (void)mi_col;
414 :
415 28760700 : for (i = 0; i < end_mi;) {
416 14723000 : const ModeInfo *const candidate_mi =
417 14723000 : xd->mi[(row_offset + i) * xd->mi_stride + col_offset];
418 14723000 : const MbModeInfo *const candidate = &candidate_mi->mbmi;
419 14723000 : const int32_t candidate_bsize = candidate->block_mi.sb_type;
420 14723000 : assert(candidate_bsize < BlockSizeS_ALL);
421 14723000 : const int32_t n8_h = mi_size_high[candidate_bsize];
422 14723000 : int32_t len = AOMMIN(xd->n8_h, n8_h);
423 14723000 : if (use_step_16)
424 568809 : len = AOMMAX(n8_h_16, len);
425 14154200 : else if (abs(col_offset) > 1)
426 6548310 : len = AOMMAX(len, n8_h_8);
427 :
428 14723000 : int32_t weight = 2;
429 14723000 : if (xd->n8_h >= n8_h_8 && xd->n8_h <= n8_h) {
430 9286050 : int32_t inc = AOMMIN(-max_col_offset + col_offset + 1,
431 : mi_size_wide[candidate_bsize]);
432 : // Obtain range used in weight calculation.
433 9286050 : weight = AOMMAX(weight, (inc << shift));
434 : // Update processed cols.
435 9286050 : *processed_cols = inc - col_offset - 1;
436 : }
437 :
438 14723000 : add_ref_mv_candidate(candidate_mi, candidate, rf, refmv_count,
439 : ref_match_count, newmv_count, ref_mv_stack, len,
440 : #if USE_CUR_GM_REFMV
441 : gm_mv_candidates, gm_params,
442 : #endif // USE_CUR_GM_REFMV
443 : col_offset, weight);
444 :
445 14720300 : i += len;
446 : }
447 14037700 : }
448 :
449 12910300 : static void scan_blk_mbmi(const Av1Common *cm, const MacroBlockD *xd,
450 : const int32_t mi_row, const int32_t mi_col,
451 : const MvReferenceFrame rf[2], int32_t row_offset,
452 : int32_t col_offset,
453 : CandidateMv ref_mv_stack[][MAX_REF_MV_STACK_SIZE],
454 : uint8_t ref_match_count[MODE_CTX_REF_FRAMES],
455 : uint8_t newmv_count[MODE_CTX_REF_FRAMES],
456 : #if USE_CUR_GM_REFMV
457 : IntMv *gm_mv_candidates, const EbWarpedMotionParams *gm_params,
458 : #endif // USE_CUR_GM_REFMV
459 : uint8_t refmv_count[MODE_CTX_REF_FRAMES]) {
460 12910300 : const TileInfo *const tile = &xd->tile;
461 : Position mi_pos;
462 :
463 12910300 : mi_pos.row = row_offset;
464 12910300 : mi_pos.col = col_offset;
465 :
466 12910300 : if (is_inside(tile, mi_col, mi_row, cm->mi_rows, &mi_pos)) {
467 11790300 : const ModeInfo *const candidate_mi =
468 11790300 : xd->mi[mi_pos.row * xd->mi_stride + mi_pos.col];
469 11790300 : const MbModeInfo *const candidate = &candidate_mi->mbmi;
470 11790300 : const int32_t len = mi_size_wide[BLOCK_8X8];
471 :
472 11790300 : add_ref_mv_candidate(candidate_mi, candidate, rf, refmv_count,
473 : ref_match_count, newmv_count, ref_mv_stack, len,
474 : #if USE_CUR_GM_REFMV
475 : gm_mv_candidates, gm_params,
476 : #endif // USE_CUR_GM_REFMV
477 : mi_pos.col, 2);
478 : } // Analyze a single 8x8 block motion information.
479 12908500 : }
480 :
481 99838800 : static int32_t has_top_right(const Av1Common *cm, const MacroBlockD *xd,
482 : int32_t mi_row, int32_t mi_col, int32_t bs) {
483 : (void)xd;
484 : (void)cm;
485 99838800 : const int32_t sb_mi_size = mi_size_wide[cm->p_pcs_ptr->sequence_control_set_ptr->seq_header.sb_size];
486 99838800 : const int32_t mask_row = mi_row & (sb_mi_size - 1);
487 99838800 : const int32_t mask_col = mi_col & (sb_mi_size - 1);
488 :
489 99838800 : if (bs > mi_size_wide[BLOCK_64X64]) return 0;
490 :
491 : // In a split partition all apart from the bottom right has a top right
492 99838800 : int32_t has_tr = !((mask_row & bs) && (mask_col & bs));
493 :
494 : // bs > 0 and bs is a power of 2
495 99838800 : assert(bs > 0 && !(bs & (bs - 1)));
496 :
497 : // For each 4x4 group of blocks, when the bottom right is decoded the blocks
498 : // to the right have not been decoded therefore the bottom right does
499 : // not have a top right
500 149583000 : while (bs < sb_mi_size) {
501 121218000 : if (mask_col & bs) {
502 58640400 : if ((mask_col & (2 * bs)) && (mask_row & (2 * bs))) {
503 8924760 : has_tr = 0;
504 8924760 : break;
505 : }
506 : }
507 : else
508 62577400 : break;
509 49715600 : bs <<= 1;
510 : }
511 :
512 : // The left hand of two vertical rectangles always has a top right (as the
513 : // block above will have been decoded)
514 99867400 : if (xd->n8_w < xd->n8_h)
515 23687100 : if (!xd->is_sec_rect) has_tr = 1;
516 :
517 : // The bottom of two horizontal rectangles never has a top right (as the block
518 : // to the right won't have been decoded)
519 99867400 : if (xd->n8_w > xd->n8_h)
520 41327400 : if (xd->is_sec_rect) has_tr = 0;
521 :
522 : // The bottom left square of a Vertical A (in the old format) does
523 : // not have a top right as it is decoded before the right hand
524 : // rectangle of the partition
525 99867400 : if (xd->mi[0]->mbmi.block_mi.partition == PARTITION_VERT_A) {
526 14029500 : if (xd->n8_w == xd->n8_h)
527 8241230 : if (mask_row & bs) has_tr = 0;
528 : }
529 :
530 99867400 : return has_tr;
531 : }
532 7492720 : static INLINE int32_t find_valid_row_offset(const TileInfo *const tile, int32_t mi_row,
533 : int32_t mi_rows, int32_t row_offset) {
534 7492720 : const int32_t dependent_horz_tile_flag = 0;
535 7492720 : if (dependent_horz_tile_flag && !tile->tg_horz_boundary)
536 0 : return clamp(row_offset, -mi_row, mi_rows - mi_row - 1);
537 : else
538 7492670 : return clamp(row_offset, tile->mi_row_start - mi_row,
539 7492720 : tile->mi_row_end - mi_row - 1);
540 : }
541 :
542 7543950 : static INLINE int32_t find_valid_col_offset(const TileInfo *const tile, int32_t mi_col,
543 : int32_t col_offset) {
544 15087500 : return clamp(col_offset, tile->mi_col_start - mi_col,
545 7543950 : tile->mi_col_end - mi_col - 1);
546 : }
547 45684400 : static INLINE int get_relative_dist(const OrderHintInfo *oh, int a, int b) {
548 45684400 : if (!oh->enable_order_hint) return 0;
549 :
550 45684400 : const int bits = oh->order_hint_bits;
551 :
552 45684400 : assert(bits >= 1);
553 45684400 : assert(a >= 0 && a < (1 << bits));
554 45687200 : assert(b >= 0 && b < (1 << bits));
555 :
556 45688200 : int diff = a - b;
557 45688200 : const int m = 1 << (bits - 1);
558 45688200 : diff = (diff & (m - 1)) - (diff & m);
559 45688200 : return diff;
560 : }
561 30484100 : static int add_tpl_ref_mv(const Av1Common *cm, PictureControlSet *picture_control_set_ptr, const MacroBlockD *xd,
562 : int mi_row, int mi_col, MvReferenceFrame ref_frame,
563 : int blk_row, int blk_col, IntMv *gm_mv_candidates,
564 : uint8_t *const refmv_count,
565 : CandidateMv ref_mv_stack[MAX_REF_MV_STACK_SIZE],
566 : int16_t *mode_context) {
567 : Position mi_pos;
568 30484100 : mi_pos.row = (mi_row & 0x01) ? blk_row : blk_row + 1;
569 30484100 : mi_pos.col = (mi_col & 0x01) ? blk_col : blk_col + 1;
570 :
571 30484100 : if (!is_inside(&xd->tile, mi_col, mi_row, xd->tile.mi_row_end, &mi_pos)) return 0;
572 :
573 30237400 : const TPL_MV_REF *prev_frame_mvs =
574 30237400 : picture_control_set_ptr->tpl_mvs + ((mi_row + mi_pos.row) >> 1) * (cm->mi_stride >> 1) +
575 30237400 : ((mi_col + mi_pos.col) >> 1);
576 30237400 : if (prev_frame_mvs->mfmv0.as_int == INVALID_MV) return 0;
577 :
578 : MvReferenceFrame rf[2];
579 28090000 : av1_set_ref_frame(rf, ref_frame);
580 :
581 : uint8_t list_idx0, list_idx1, ref_idx_l0, ref_idx_l1;
582 28086200 : list_idx0 = get_list_idx(rf[0]);
583 28080200 : ref_idx_l0 = get_ref_frame_idx(rf[0]);
584 28090200 : if (rf[1] == NONE_FRAME) {
585 10452400 : list_idx1 = get_list_idx(rf[0]);
586 10451600 : ref_idx_l1 = get_ref_frame_idx(rf[0]);
587 : }
588 : else {
589 17637900 : list_idx1 = get_list_idx(rf[1]);
590 17637700 : ref_idx_l1 = get_ref_frame_idx(rf[1]);
591 : }
592 :
593 28087500 : const uint16_t weight_unit = 1;
594 28087500 : const int cur_frame_index = picture_control_set_ptr->parent_pcs_ptr->cur_order_hint;
595 28087500 : EbReferenceObject *buf_0 = (EbReferenceObject*)picture_control_set_ptr->ref_pic_ptr_array[list_idx0][ref_idx_l0]->object_ptr;
596 :
597 28087500 : const int frame0_index = buf_0->order_hint;
598 28087500 : const int cur_offset_0 = get_relative_dist(&picture_control_set_ptr->parent_pcs_ptr->sequence_control_set_ptr->seq_header.order_hint_info,
599 : cur_frame_index, frame0_index);
600 : int idx;
601 :
602 : IntMv this_refmv;
603 28078400 : get_mv_projection(&this_refmv.as_mv, prev_frame_mvs->mfmv0.as_mv,
604 28078400 : cur_offset_0, prev_frame_mvs->ref_frame_offset);
605 28079500 : lower_mv_precision(&this_refmv.as_mv, picture_control_set_ptr->parent_pcs_ptr->frm_hdr.allow_high_precision_mv, 0);
606 28091100 : if (rf[1] == NONE_FRAME) {
607 10452200 : if (blk_row == 0 && blk_col == 0) {
608 2241220 : if (abs(this_refmv.as_mv.row - gm_mv_candidates[0].as_mv.row) >= 16 ||
609 969694 : abs(this_refmv.as_mv.col - gm_mv_candidates[0].as_mv.col) >= 16)
610 1436100 : mode_context[ref_frame] |= (1 << GLOBALMV_OFFSET);
611 : }
612 :
613 22705900 : for (idx = 0; idx < *refmv_count; ++idx)
614 18135100 : if (this_refmv.as_int == ref_mv_stack[idx].this_mv.as_int) break;
615 :
616 10452200 : if (idx < *refmv_count) ref_mv_stack[idx].weight += 2 * weight_unit;
617 :
618 10452200 : if (idx == *refmv_count && *refmv_count < MAX_REF_MV_STACK_SIZE) {
619 4482720 : ref_mv_stack[idx].this_mv.as_int = this_refmv.as_int;
620 4482720 : ref_mv_stack[idx].weight = 2 * weight_unit;
621 4482720 : ++(*refmv_count);
622 : }
623 : }
624 : else {
625 : // Process compound inter mode
626 17639000 : EbReferenceObject *buf_1 = (EbReferenceObject*)picture_control_set_ptr->ref_pic_ptr_array[list_idx1][ref_idx_l1]->object_ptr;
627 :
628 17639000 : const int frame1_index = buf_1->order_hint;
629 17639000 : const int cur_offset_1 = get_relative_dist(&picture_control_set_ptr->parent_pcs_ptr->sequence_control_set_ptr->seq_header.order_hint_info,
630 : cur_frame_index, frame1_index);
631 : IntMv comp_refmv;
632 17638800 : get_mv_projection(&comp_refmv.as_mv, prev_frame_mvs->mfmv0.as_mv,
633 17638800 : cur_offset_1, prev_frame_mvs->ref_frame_offset);
634 17636500 : lower_mv_precision(&comp_refmv.as_mv, picture_control_set_ptr->parent_pcs_ptr->frm_hdr.allow_high_precision_mv, 0);
635 17635100 : if (blk_row == 0 && blk_col == 0) {
636 3744010 : if (abs(this_refmv.as_mv.row - gm_mv_candidates[0].as_mv.row) >= 16 ||
637 2063710 : abs(this_refmv.as_mv.col - gm_mv_candidates[0].as_mv.col) >= 16 ||
638 1830710 : abs(comp_refmv.as_mv.row - gm_mv_candidates[1].as_mv.row) >= 16 ||
639 546567 : abs(comp_refmv.as_mv.col - gm_mv_candidates[1].as_mv.col) >= 16)
640 3341960 : mode_context[ref_frame] |= (1 << GLOBALMV_OFFSET);
641 : }
642 :
643 32679900 : for (idx = 0; idx < *refmv_count; ++idx) {
644 24747700 : if (this_refmv.as_int == ref_mv_stack[idx].this_mv.as_int &&
645 10138600 : comp_refmv.as_int == ref_mv_stack[idx].comp_mv.as_int)
646 9702930 : break;
647 : }
648 :
649 17635100 : if (idx < *refmv_count) ref_mv_stack[idx].weight += 2 * weight_unit;
650 :
651 17635100 : if (idx == *refmv_count && *refmv_count < MAX_REF_MV_STACK_SIZE) {
652 7807200 : ref_mv_stack[idx].this_mv.as_int = this_refmv.as_int;
653 7807200 : ref_mv_stack[idx].comp_mv.as_int = comp_refmv.as_int;
654 7807200 : ref_mv_stack[idx].weight = 2 * weight_unit;
655 7807200 : ++(*refmv_count);
656 : }
657 : }
658 :
659 28087200 : return 1;
660 : }
661 :
662 :
663 7870850 : void setup_ref_mv_list(
664 : PictureControlSet *picture_control_set_ptr,
665 : const Av1Common *cm, const MacroBlockD *xd, MvReferenceFrame ref_frame,
666 : uint8_t refmv_count[MODE_CTX_REF_FRAMES],
667 : CandidateMv ref_mv_stack[][MAX_REF_MV_STACK_SIZE],
668 : IntMv mv_ref_list[][MAX_MV_REF_CANDIDATES],
669 : IntMv *gm_mv_candidates, const EbWarpedMotionParams *gm_params,
670 : int32_t mi_row, int32_t mi_col, int16_t *mode_context)
671 : {
672 7870850 : const int32_t bs = AOMMAX(xd->n8_w, xd->n8_h);
673 7870850 : const int32_t has_tr = has_top_right(cm, xd, mi_row, mi_col, bs);
674 : MvReferenceFrame rf[2];
675 :
676 7871060 : const TileInfo *const tile = &xd->tile;
677 7871060 : int32_t max_row_offset = 0, max_col_offset = 0;
678 7871060 : const int32_t row_adj = (xd->n8_h < mi_size_high[BLOCK_8X8]) && (mi_row & 0x01);
679 7871060 : const int32_t col_adj = (xd->n8_w < mi_size_wide[BLOCK_8X8]) && (mi_col & 0x01);
680 7871060 : int32_t processed_rows = 0;
681 7871060 : int32_t processed_cols = 0;
682 :
683 7871060 : av1_set_ref_frame(rf, ref_frame);
684 7870730 : mode_context[ref_frame] = 0;
685 7870730 : refmv_count[ref_frame] = 0;
686 :
687 : // Find valid maximum row/col offset.
688 7870730 : if (xd->up_available) {
689 7493020 : max_row_offset = -(MVREF_ROWS << 1) + row_adj;
690 :
691 7493020 : if (xd->n8_h < mi_size_high[BLOCK_8X8])
692 1522560 : max_row_offset = -(2 << 1) + row_adj;
693 :
694 : max_row_offset =
695 7493020 : find_valid_row_offset(tile, mi_row, cm->mi_rows, max_row_offset);
696 : }
697 :
698 7870320 : if (xd->left_available) {
699 7543960 : max_col_offset = -(MVREF_COLS << 1) + col_adj;
700 :
701 7543960 : if (xd->n8_w < mi_size_wide[BLOCK_8X8])
702 1492310 : max_col_offset = -(2 << 1) + col_adj;
703 :
704 7543960 : max_col_offset = find_valid_col_offset(tile, mi_col, max_col_offset);
705 : }
706 :
707 7869820 : uint8_t ref_match_count[MODE_CTX_REF_FRAMES] = { 0 };
708 7869820 : uint8_t col_match_count[MODE_CTX_REF_FRAMES] = { 0 };
709 7869820 : uint8_t row_match_count[MODE_CTX_REF_FRAMES] = { 0 };
710 7869820 : uint8_t newmv_count[MODE_CTX_REF_FRAMES] = { 0 };
711 :
712 : //CHKN------------- ROW-1
713 :
714 : // Scan the first above row mode info. row_offset = -1;
715 7869820 : if (abs(max_row_offset) >= 1)
716 7492090 : scan_row_mbmi(cm, xd, mi_row, mi_col, rf, -1, ref_mv_stack, refmv_count,
717 : row_match_count, newmv_count,
718 : #if USE_CUR_GM_REFMV
719 : gm_mv_candidates, gm_params,
720 : #endif // USE_CUR_GM_REFMV
721 : max_row_offset, &processed_rows);
722 :
723 : //CHKN------------- COL-1
724 : // Scan the first left column mode info. col_offset = -1;
725 7869630 : if (abs(max_col_offset) >= 1)
726 7543300 : scan_col_mbmi(cm, xd, mi_row, mi_col, rf, -1, ref_mv_stack, refmv_count,
727 : col_match_count, newmv_count,
728 : #if USE_CUR_GM_REFMV
729 : gm_mv_candidates, gm_params,
730 : #endif // USE_CUR_GM_REFMV
731 : max_col_offset, &processed_cols);
732 :
733 : //CHKN------------- TOP-RIGHT
734 :
735 : // Check top-right boundary
736 7869770 : if (has_tr)
737 5041480 : scan_blk_mbmi(cm, xd, mi_row, mi_col, rf, -1, xd->n8_w, ref_mv_stack,
738 : row_match_count, newmv_count,
739 : #if USE_CUR_GM_REFMV
740 : gm_mv_candidates, gm_params,
741 : #endif // USE_CUR_GM_REFMV
742 : refmv_count);
743 :
744 : uint8_t nearest_match[MODE_CTX_REF_FRAMES];
745 : uint8_t nearest_refmv_count[MODE_CTX_REF_FRAMES];
746 :
747 7869490 : nearest_match[ref_frame] =
748 7869490 : (row_match_count[ref_frame] > 0) + (col_match_count[ref_frame] > 0);
749 7869490 : nearest_refmv_count[ref_frame] = refmv_count[ref_frame];
750 :
751 : // TODO(yunqing): for comp_search, do it for all 3 cases.
752 10615700 : for (int32_t idx = 0; idx < nearest_refmv_count[ref_frame]; ++idx)
753 2746230 : ref_mv_stack[ref_frame][idx].weight += REF_CAT_LEVEL;
754 :
755 : //CHKN MFMV - get canididates from reference frames- orderHint has to be on, in order to scale the vectors.
756 7869490 : if (picture_control_set_ptr->parent_pcs_ptr->frm_hdr.use_ref_frame_mvs)
757 : {
758 :
759 6682920 : int is_available = 0;
760 6682920 : const int voffset = AOMMAX(mi_size_high[BLOCK_8X8], xd->n4_h);
761 6682920 : const int hoffset = AOMMAX(mi_size_wide[BLOCK_8X8], xd->n4_w);
762 6682920 : const int blk_row_end = AOMMIN(xd->n4_h, mi_size_high[BLOCK_64X64]);
763 6682920 : const int blk_col_end = AOMMIN(xd->n4_w, mi_size_wide[BLOCK_64X64]);
764 :
765 6682920 : const int tpl_sample_pos[3][2] = {
766 : { voffset, -2 },
767 : { voffset, hoffset },
768 6682920 : { voffset - 2, hoffset },
769 : };
770 18712300 : const int allow_extension = (xd->n4_h >= mi_size_high[BLOCK_8X8]) &&
771 5346440 : (xd->n4_h < mi_size_high[BLOCK_64X64]) &&
772 15965200 : (xd->n4_w >= mi_size_wide[BLOCK_8X8]) &&
773 3935790 : (xd->n4_w < mi_size_wide[BLOCK_64X64]);
774 :
775 13365800 : const int step_h = (xd->n4_h >= mi_size_high[BLOCK_64X64])
776 260745 : ? mi_size_high[BLOCK_16X16]
777 6682920 : : mi_size_high[BLOCK_8X8];
778 13365800 : const int step_w = (xd->n4_w >= mi_size_wide[BLOCK_64X64])
779 246653 : ? mi_size_wide[BLOCK_16X16]
780 6682920 : : mi_size_wide[BLOCK_8X8];
781 :
782 18722600 : for (int blk_row = 0; blk_row < blk_row_end; blk_row += step_h) {
783 34938600 : for (int blk_col = 0; blk_col < blk_col_end; blk_col += step_w) {
784 22898900 : int ret = add_tpl_ref_mv(cm, picture_control_set_ptr, xd, mi_row, mi_col, ref_frame, blk_row,
785 : blk_col, gm_mv_candidates, &refmv_count[ref_frame],
786 22898900 : ref_mv_stack[ref_frame], mode_context);
787 22898600 : if (blk_row == 0 && blk_col == 0) is_available = ret;
788 : }
789 : }
790 :
791 6682670 : if (is_available == 0) mode_context[ref_frame] |= (1 << GLOBALMV_OFFSET);
792 :
793 17870900 : for (int i = 0; i < 3 && allow_extension; ++i) {
794 11188300 : const int blk_row = tpl_sample_pos[i][0];
795 11188300 : const int blk_col = tpl_sample_pos[i][1];
796 :
797 11188300 : if (!check_sb_border(mi_row, mi_col, blk_row, blk_col)) continue;
798 7593170 : add_tpl_ref_mv(cm, picture_control_set_ptr, xd, mi_row, mi_col, ref_frame, blk_row, blk_col,
799 7593170 : gm_mv_candidates, &refmv_count[ref_frame], ref_mv_stack[ref_frame], mode_context);
800 : }
801 : }
802 :
803 : //CHKN------------- TOP-LEFT
804 7869140 : uint8_t dummy_newmv_count[MODE_CTX_REF_FRAMES] = { 0 };
805 :
806 : // Scan the second outer area.
807 7869140 : scan_blk_mbmi(cm, xd, mi_row, mi_col, rf, -1, -1, ref_mv_stack,
808 : row_match_count, dummy_newmv_count,
809 : #if USE_CUR_GM_REFMV
810 : gm_mv_candidates, gm_params,
811 : #endif // USE_CUR_GM_REFMV
812 : refmv_count);
813 :
814 : //CHKN------------- ROW-3 COL-3 ROW-5 COL-5
815 23606400 : for (int32_t idx = 2; idx <= MVREF_ROWS; ++idx) {
816 15736700 : const int32_t row_offset = -(idx << 1) + 1 + row_adj;
817 15736700 : const int32_t col_offset = -(idx << 1) + 1 + col_adj;
818 :
819 15736700 : if (abs(row_offset) <= abs(max_row_offset) &&
820 13077300 : abs(row_offset) > processed_rows)
821 6235540 : scan_row_mbmi(cm, xd, mi_row, mi_col, rf, row_offset, ref_mv_stack,
822 : refmv_count, row_match_count, dummy_newmv_count,
823 : #if USE_CUR_GM_REFMV
824 : gm_mv_candidates, gm_params,
825 : #endif // USE_CUR_GM_REFMV
826 : max_row_offset, &processed_rows);
827 :
828 15736900 : if (abs(col_offset) <= abs(max_col_offset) &&
829 13225700 : abs(col_offset) > processed_cols)
830 6500750 : scan_col_mbmi(cm, xd, mi_row, mi_col, rf, col_offset, ref_mv_stack,
831 : refmv_count, col_match_count, dummy_newmv_count,
832 : #if USE_CUR_GM_REFMV
833 : gm_mv_candidates, gm_params,
834 : #endif // USE_CUR_GM_REFMV
835 : max_col_offset, &processed_cols);
836 : }
837 :
838 : //---------- Mode Context Derivation based on 3 counters -------------
839 7869660 : ref_match_count[ref_frame] =
840 7869660 : (row_match_count[ref_frame] > 0) + (col_match_count[ref_frame] > 0);
841 :
842 7869660 : switch (nearest_match[ref_frame]) {
843 5951730 : case 0:
844 5951730 : mode_context[ref_frame] |= 0;
845 5951730 : if (ref_match_count[ref_frame] >= 1) mode_context[ref_frame] |= 1;
846 5951730 : if (ref_match_count[ref_frame] == 1)
847 43742 : mode_context[ref_frame] |= (1 << REFMV_OFFSET);
848 5907990 : else if (ref_match_count[ref_frame] >= 2)
849 4322 : mode_context[ref_frame] |= (2 << REFMV_OFFSET);
850 5951730 : break;
851 450099 : case 1:
852 450099 : mode_context[ref_frame] |= (newmv_count[ref_frame] > 0) ? 2 : 3;
853 450099 : if (ref_match_count[ref_frame] == 1)
854 234311 : mode_context[ref_frame] |= (3 << REFMV_OFFSET);
855 215788 : else if (ref_match_count[ref_frame] >= 2)
856 215796 : mode_context[ref_frame] |= (4 << REFMV_OFFSET);
857 450099 : break;
858 1467830 : case 2:
859 : default:
860 1467830 : if (newmv_count[ref_frame] >= 1)
861 278818 : mode_context[ref_frame] |= 4;
862 : else
863 1189010 : mode_context[ref_frame] |= 5;
864 :
865 1467830 : mode_context[ref_frame] |= (5 << REFMV_OFFSET);
866 1467830 : break;
867 : }
868 : //---------- Mode Context Derivation based on 3 counters -------------
869 :
870 : // Rank the likelihood and assign nearest and near mvs.
871 7869660 : int32_t len = nearest_refmv_count[ref_frame];
872 10049200 : while (len > 0) {
873 2179510 : int32_t nr_len = 0;
874 3035360 : for (int32_t idx = 1; idx < len; ++idx) {
875 855849 : if (ref_mv_stack[ref_frame][idx - 1].weight <
876 855849 : ref_mv_stack[ref_frame][idx].weight) {
877 268945 : CandidateMv tmp_mv = ref_mv_stack[ref_frame][idx - 1];
878 268945 : ref_mv_stack[ref_frame][idx - 1] = ref_mv_stack[ref_frame][idx];
879 268945 : ref_mv_stack[ref_frame][idx] = tmp_mv;
880 268945 : nr_len = idx;
881 : }
882 : }
883 2179510 : len = nr_len;
884 : }
885 :
886 7869660 : len = refmv_count[ref_frame];
887 16264700 : while (len > nearest_refmv_count[ref_frame]) {
888 8395000 : int32_t nr_len = nearest_refmv_count[ref_frame];
889 17385800 : for (int32_t idx = nearest_refmv_count[ref_frame] + 1; idx < len; ++idx) {
890 8990840 : if (ref_mv_stack[ref_frame][idx - 1].weight <
891 8990840 : ref_mv_stack[ref_frame][idx].weight) {
892 2593630 : CandidateMv tmp_mv = ref_mv_stack[ref_frame][idx - 1];
893 2593630 : ref_mv_stack[ref_frame][idx - 1] = ref_mv_stack[ref_frame][idx];
894 2593630 : ref_mv_stack[ref_frame][idx] = tmp_mv;
895 2593630 : nr_len = idx;
896 : }
897 : }
898 8395000 : len = nr_len;
899 : }
900 :
901 : //CHKN finish the Tables.
902 :
903 7869660 : if (rf[1] > NONE_FRAME) {
904 : // TODO(jingning, yunqing): Refactor and consolidate the compound and
905 : // single reference frame modes. Reduce unnecessary redundancy.
906 :
907 : //CHKN we get here only when refMVCount=0 or 1
908 :
909 4644520 : if (refmv_count[ref_frame] < 2) {
910 : IntMv ref_id[2][2], ref_diff[2][2];
911 2437050 : int32_t ref_id_count[2] = { 0 }, ref_diff_count[2] = { 0 };
912 :
913 2437050 : int32_t mi_width = AOMMIN(mi_size_wide[BLOCK_64X64], xd->n8_w);
914 2437050 : mi_width = AOMMIN(mi_width, cm->mi_cols - mi_col);
915 2437050 : int32_t mi_height = AOMMIN(mi_size_high[BLOCK_64X64], xd->n8_h);
916 2437050 : mi_height = AOMMIN(mi_height, cm->mi_rows - mi_row);
917 2437050 : int32_t mi_size = AOMMIN(mi_width, mi_height);
918 :
919 : //CHKN scan ROW=-1 again but with more relaxed constraints
920 4773320 : for (int32_t idx = 0; abs(max_row_offset) >= 1 && idx < mi_size;) {
921 2336270 : const ModeInfo *const candidate_mi = xd->mi[-xd->mi_stride + idx];
922 2336270 : const MbModeInfo *const candidate = &candidate_mi->mbmi;
923 2336270 : const int32_t candidate_bsize = candidate->block_mi.sb_type;
924 :
925 7008700 : for (int32_t rf_idx = 0; rf_idx < 2; ++rf_idx) {
926 4672430 : MvReferenceFrame can_rf = candidate->block_mi.ref_frame[rf_idx];
927 :
928 14017300 : for (int32_t cmp_idx = 0; cmp_idx < 2; ++cmp_idx) {
929 9344860 : if (can_rf == rf[cmp_idx] && ref_id_count[cmp_idx] < 2) {
930 1680060 : ref_id[cmp_idx][ref_id_count[cmp_idx]] = candidate->block_mi.mv[rf_idx];
931 1680060 : ++ref_id_count[cmp_idx];
932 : }
933 7664800 : else if (can_rf > INTRA_FRAME && ref_diff_count[cmp_idx] < 2) {
934 6415170 : IntMv this_mv = candidate->block_mi.mv[rf_idx];
935 6415170 : if (cm->ref_frame_sign_bias[can_rf] !=
936 6415170 : cm->ref_frame_sign_bias[rf[cmp_idx]]) {
937 3972990 : this_mv.as_mv.row = -this_mv.as_mv.row;
938 3972990 : this_mv.as_mv.col = -this_mv.as_mv.col;
939 : }
940 6415170 : ref_diff[cmp_idx][ref_diff_count[cmp_idx]] = this_mv;
941 6415170 : ++ref_diff_count[cmp_idx];
942 : }
943 : }
944 : }
945 2336270 : idx += mi_size_wide[candidate_bsize];
946 : }
947 :
948 : //CHKN scan COL=-1 again but with more relaxed constraints
949 4756370 : for (int32_t idx = 0; abs(max_col_offset) >= 1 && idx < mi_size;) {
950 2319320 : const ModeInfo *const candidate_mi = xd->mi[idx * xd->mi_stride - 1];
951 2319320 : const MbModeInfo *const candidate = &candidate_mi->mbmi;
952 2319320 : const int32_t candidate_bsize = candidate->block_mi.sb_type;
953 :
954 6957900 : for (int32_t rf_idx = 0; rf_idx < 2; ++rf_idx) {
955 4638580 : MvReferenceFrame can_rf = candidate->block_mi.ref_frame[rf_idx];
956 :
957 13915700 : for (int32_t cmp_idx = 0; cmp_idx < 2; ++cmp_idx) {
958 9277090 : if (can_rf == rf[cmp_idx] && ref_id_count[cmp_idx] < 2) {
959 1645170 : ref_id[cmp_idx][ref_id_count[cmp_idx]] = candidate->block_mi.mv[rf_idx];
960 1645170 : ++ref_id_count[cmp_idx];
961 : }
962 7631920 : else if (can_rf > INTRA_FRAME && ref_diff_count[cmp_idx] < 2) {
963 2344590 : IntMv this_mv = candidate->block_mi.mv[rf_idx];
964 2344590 : if (cm->ref_frame_sign_bias[can_rf] !=
965 2344590 : cm->ref_frame_sign_bias[rf[cmp_idx]]) {
966 1874850 : this_mv.as_mv.row = -this_mv.as_mv.row;
967 1874850 : this_mv.as_mv.col = -this_mv.as_mv.col;
968 : }
969 2344590 : ref_diff[cmp_idx][ref_diff_count[cmp_idx]] = this_mv;
970 2344590 : ++ref_diff_count[cmp_idx];
971 : }
972 : }
973 : }
974 2319320 : idx += mi_size_high[candidate_bsize];
975 : }
976 :
977 : // Build up the compound mv predictor
978 : IntMv comp_list[MAX_MV_REF_CANDIDATES][2];
979 :
980 7311330 : for (int32_t idx = 0; idx < 2; ++idx) {
981 4874280 : int32_t comp_idx = 0;
982 4874280 : for (int32_t list_idx = 0;
983 8199510 : list_idx < ref_id_count[idx] && comp_idx < MAX_MV_REF_CANDIDATES;
984 3325240 : ++list_idx, ++comp_idx)
985 3325240 : comp_list[comp_idx][idx] = ref_id[idx][list_idx];
986 4874280 : for (int32_t list_idx = 0;
987 10983200 : list_idx < ref_diff_count[idx] && comp_idx < MAX_MV_REF_CANDIDATES;
988 6108880 : ++list_idx, ++comp_idx)
989 6108880 : comp_list[comp_idx][idx] = ref_diff[idx][list_idx];
990 5188800 : for (; comp_idx < MAX_MV_REF_CANDIDATES; ++comp_idx)
991 314525 : comp_list[comp_idx][idx] = gm_mv_candidates[idx];
992 : }
993 :
994 : //CHKN fill the stack, increment the counter
995 2437050 : if (refmv_count[ref_frame]) { //CHKN RefMvCount=1
996 1875600 : assert(refmv_count[ref_frame] == 1);
997 1875600 : if (comp_list[0][0].as_int == ref_mv_stack[ref_frame][0].this_mv.as_int
998 156067 : && comp_list[0][1].as_int == ref_mv_stack[ref_frame][0].comp_mv.as_int) {
999 45854 : ref_mv_stack[ref_frame][refmv_count[ref_frame]].this_mv = comp_list[1][0];
1000 45854 : ref_mv_stack[ref_frame][refmv_count[ref_frame]].comp_mv = comp_list[1][1];
1001 : }
1002 : else {
1003 1829740 : ref_mv_stack[ref_frame][refmv_count[ref_frame]].this_mv = comp_list[0][0];
1004 1829740 : ref_mv_stack[ref_frame][refmv_count[ref_frame]].comp_mv = comp_list[0][1];
1005 : }
1006 1875600 : ref_mv_stack[ref_frame][refmv_count[ref_frame]].weight = 2;
1007 1875600 : ++refmv_count[ref_frame];
1008 : }
1009 : else {//CHKN RefMvCount=0
1010 1684640 : for (int32_t idx = 0; idx < MAX_MV_REF_CANDIDATES; ++idx) {
1011 1123180 : ref_mv_stack[ref_frame][refmv_count[ref_frame]].this_mv = comp_list[idx][0];
1012 1123180 : ref_mv_stack[ref_frame][refmv_count[ref_frame]].comp_mv = comp_list[idx][1];
1013 1123180 : ref_mv_stack[ref_frame][refmv_count[ref_frame]].weight = 2;
1014 1123180 : ++refmv_count[ref_frame];
1015 : }
1016 : }
1017 : }
1018 :
1019 4644520 : assert(refmv_count[ref_frame] >= 2);
1020 :
1021 16414100 : for (int32_t idx = 0; idx < refmv_count[ref_frame]; ++idx) {
1022 11771900 : clamp_mv_ref(&ref_mv_stack[ref_frame][idx].this_mv.as_mv,
1023 11771900 : xd->n8_w << MI_SIZE_LOG2, xd->n8_h << MI_SIZE_LOG2, xd);
1024 11771200 : clamp_mv_ref(&ref_mv_stack[ref_frame][idx].comp_mv.as_mv,
1025 11771200 : xd->n8_w << MI_SIZE_LOG2, xd->n8_h << MI_SIZE_LOG2, xd);
1026 : }
1027 : }
1028 : else {
1029 : // Handle single reference frame extension
1030 3225140 : int32_t mi_width = AOMMIN(mi_size_wide[BLOCK_64X64], xd->n8_w);
1031 3225140 : mi_width = AOMMIN(mi_width, cm->mi_cols - mi_col);
1032 3225140 : int32_t mi_height = AOMMIN(mi_size_high[BLOCK_64X64], xd->n8_h);
1033 3225140 : mi_height = AOMMIN(mi_height, cm->mi_rows - mi_row);
1034 3225140 : int32_t mi_size = AOMMIN(mi_width, mi_height);
1035 :
1036 : //CHKn if count is still < 2, re-scan ROW=-1 with less constraints.
1037 : // Order is already fixed. the added candidates are stored as we go at the bottom of the Stack.
1038 : //CHKN TODO: confirm this could be avoided if we have already 2(DRL:OFF), or 4(DRL:ON) candidates
1039 4523590 : for (int32_t idx = 0; abs(max_row_offset) >= 1 && idx < mi_size &&
1040 3082820 : refmv_count[ref_frame] < MAX_MV_REF_CANDIDATES;) {
1041 1298450 : const ModeInfo *const candidate_mi = xd->mi[-xd->mi_stride + idx];
1042 1298450 : const MbModeInfo *const candidate = &candidate_mi->mbmi;
1043 1298450 : const int32_t candidate_bsize = candidate->block_mi.sb_type;
1044 :
1045 : // TODO(jingning): Refactor the following code.
1046 3895440 : for (int32_t rf_idx = 0; rf_idx < 2; ++rf_idx) {
1047 2596980 : if (candidate->block_mi.ref_frame[rf_idx] > INTRA_FRAME) {
1048 2118960 : IntMv this_mv = candidate->block_mi.mv[rf_idx];
1049 2118960 : if (cm->ref_frame_sign_bias[candidate->block_mi.ref_frame[rf_idx]] !=
1050 2118960 : cm->ref_frame_sign_bias[ref_frame]) {
1051 983628 : this_mv.as_mv.row = -this_mv.as_mv.row;
1052 983628 : this_mv.as_mv.col = -this_mv.as_mv.col;
1053 : }
1054 : int32_t stack_idx;
1055 3983460 : for (stack_idx = 0; stack_idx < refmv_count[ref_frame]; ++stack_idx) {
1056 2354220 : IntMv stack_mv = ref_mv_stack[ref_frame][stack_idx].this_mv;
1057 2354220 : if (this_mv.as_int == stack_mv.as_int) break;
1058 : }
1059 :
1060 2118960 : if (stack_idx == refmv_count[ref_frame]) {
1061 1629310 : ref_mv_stack[ref_frame][stack_idx].this_mv = this_mv;
1062 :
1063 : // TODO(jingning): Set an arbitrary small number here. The weight
1064 : // doesn't matter as long as it is properly initialized.
1065 1629310 : ref_mv_stack[ref_frame][stack_idx].weight = 2;
1066 1629310 : ++refmv_count[ref_frame];
1067 : }
1068 : }
1069 : }
1070 1298450 : idx += mi_size_wide[candidate_bsize];
1071 : }
1072 :
1073 : //CHKn if count is still < 2, re-scan COL=-1 with less constraints. the added candidates are stored as we go at the bottom of the Stack.
1074 3626820 : for (int32_t idx = 0; abs(max_col_offset) >= 1 && idx < mi_size &&
1075 3098160 : refmv_count[ref_frame] < MAX_MV_REF_CANDIDATES;) {
1076 401678 : const ModeInfo *const candidate_mi = xd->mi[idx * xd->mi_stride - 1];
1077 401678 : const MbModeInfo *const candidate = &candidate_mi->mbmi;
1078 401678 : const int32_t candidate_bsize = candidate->block_mi.sb_type;
1079 :
1080 : // TODO(jingning): Refactor the following code.
1081 1205020 : for (int32_t rf_idx = 0; rf_idx < 2; ++rf_idx) {
1082 803341 : if (candidate->block_mi.ref_frame[rf_idx] > INTRA_FRAME) {
1083 528652 : IntMv this_mv = candidate->block_mi.mv[rf_idx];
1084 528652 : if (cm->ref_frame_sign_bias[candidate->block_mi.ref_frame[rf_idx]] !=
1085 528652 : cm->ref_frame_sign_bias[ref_frame]) {
1086 195703 : this_mv.as_mv.row = -this_mv.as_mv.row;
1087 195703 : this_mv.as_mv.col = -this_mv.as_mv.col;
1088 : }
1089 : int32_t stack_idx;
1090 922694 : for (stack_idx = 0; stack_idx < refmv_count[ref_frame]; ++stack_idx) {
1091 591672 : IntMv stack_mv = ref_mv_stack[ref_frame][stack_idx].this_mv;
1092 591672 : if (this_mv.as_int == stack_mv.as_int) break;
1093 : }
1094 :
1095 528652 : if (stack_idx == refmv_count[ref_frame]) {
1096 331024 : ref_mv_stack[ref_frame][stack_idx].this_mv = this_mv;
1097 :
1098 : // TODO(jingning): Set an arbitrary small number here. The weight
1099 : // doesn't matter as long as it is properly initialized.
1100 331024 : ref_mv_stack[ref_frame][stack_idx].weight = 2;
1101 331024 : ++refmv_count[ref_frame];
1102 : }
1103 : }
1104 : }
1105 401678 : idx += mi_size_high[candidate_bsize];
1106 : }
1107 :
1108 : //CHKN THIS IS a Single Reference case
1109 :
1110 : //CHKN if the stack has at least 2 cand, then copy the top 2 to the final mvp Table,
1111 : // if the stack has less than 2, use Gm to fill the mvpTable.
1112 : // the stack counter remains 0 or 1 in this case.
1113 :
1114 3423430 : for (int32_t idx = refmv_count[ref_frame]; idx < MAX_MV_REF_CANDIDATES; ++idx)
1115 198294 : mv_ref_list[rf[0]][idx].as_int = gm_mv_candidates[0].as_int;
1116 :
1117 12270600 : for (int32_t idx = 0; idx < refmv_count[ref_frame]; ++idx) {
1118 9045540 : clamp_mv_ref(&ref_mv_stack[ref_frame][idx].this_mv.as_mv,
1119 9045540 : xd->n8_w << MI_SIZE_LOG2, xd->n8_h << MI_SIZE_LOG2, xd);
1120 : }
1121 :
1122 3225040 : for (int32_t idx = 0;
1123 9479890 : idx < AOMMIN(MAX_MV_REF_CANDIDATES, refmv_count[ref_frame]); ++idx) {
1124 6254860 : mv_ref_list[rf[0]][idx].as_int =
1125 6254860 : ref_mv_stack[ref_frame][idx].this_mv.as_int;
1126 : }
1127 : }
1128 : (void)nearest_match;
1129 7867220 : }
1130 :
1131 24173000 : static INLINE int convert_to_trans_prec(int allow_hp, int coor) {
1132 24173000 : if (allow_hp)
1133 24173100 : return ROUND_POWER_OF_TWO_SIGNED(coor, WARPEDMODEL_PREC_BITS - 3);
1134 : else
1135 0 : return ROUND_POWER_OF_TWO_SIGNED(coor, WARPEDMODEL_PREC_BITS - 2) * 2;
1136 : }
1137 :
1138 12087700 : static INLINE int block_center_x(int mi_col, BlockSize bs) {
1139 12087700 : const int bw = block_size_wide[bs];
1140 12087700 : return mi_col * MI_SIZE + bw / 2 - 1;
1141 : }
1142 :
1143 12087500 : static INLINE int block_center_y(int mi_row, BlockSize bs) {
1144 12087500 : const int bh = block_size_high[bs];
1145 12087500 : return mi_row * MI_SIZE + bh / 2 - 1;
1146 : }
1147 :
1148 26081600 : IntMv gm_get_motion_vector_enc(
1149 : const EbWarpedMotionParams *gm,
1150 : int32_t allow_hp,
1151 : BlockSize bsize,
1152 : int32_t mi_col, int32_t mi_row,
1153 : int32_t is_integer)
1154 : {
1155 : IntMv res;
1156 :
1157 26081600 : if (gm->wmtype == IDENTITY) {
1158 13997300 : res.as_int = 0;
1159 13997300 : return res;
1160 : }
1161 :
1162 12084400 : const int32_t *mat = gm->wmmat;
1163 : int x, y, tx, ty;
1164 :
1165 12084400 : if (gm->wmtype == TRANSLATION) {
1166 : // All global motion vectors are stored with WARPEDMODEL_PREC_BITS (16)
1167 : // bits of fractional precision. The offset for a translation is stored in
1168 : // entries 0 and 1. For translations, all but the top three (two if
1169 : // cm->allow_high_precision_mv is false) fractional bits are always zero.
1170 : //
1171 : // After the right shifts, there are 3 fractional bits of precision. If
1172 : // allow_hp is false, the bottom bit is always zero (so we don't need a
1173 : // call to convert_to_trans_prec here)
1174 0 : res.as_mv.row = gm->wmmat[0] >> GM_TRANS_ONLY_PREC_DIFF;
1175 0 : res.as_mv.col = gm->wmmat[1] >> GM_TRANS_ONLY_PREC_DIFF;
1176 0 : assert(IMPLIES(1 & (res.as_mv.row | res.as_mv.col), allow_hp));
1177 0 : if (is_integer) {
1178 0 : integer_mv_precision(&res.as_mv);
1179 : }
1180 0 : return res;
1181 : }
1182 :
1183 12084400 : x = block_center_x(mi_col, bsize);
1184 12087600 : y = block_center_y(mi_row, bsize);
1185 :
1186 12087500 : if (gm->wmtype == ROTZOOM) {
1187 12087500 : assert(gm->wmmat[5] == gm->wmmat[2]);
1188 12087500 : assert(gm->wmmat[4] == -gm->wmmat[3]);
1189 : }
1190 :
1191 12087500 : const int xc =
1192 12087500 : (mat[2] - (1 << WARPEDMODEL_PREC_BITS)) * x + mat[3] * y + mat[0];
1193 12087500 : const int yc =
1194 12087500 : mat[4] * x + (mat[5] - (1 << WARPEDMODEL_PREC_BITS)) * y + mat[1];
1195 12087500 : tx = convert_to_trans_prec(allow_hp, xc);
1196 12087500 : ty = convert_to_trans_prec(allow_hp, yc);
1197 :
1198 12086700 : res.as_mv.row = ty;
1199 12086700 : res.as_mv.col = tx;
1200 :
1201 12086700 : if (is_integer) {
1202 0 : integer_mv_precision(&res.as_mv);
1203 : }
1204 12089600 : return res;
1205 : }
1206 :
1207 772499 : void generate_av1_mvp_table(
1208 : TileInfo *tile,
1209 : ModeDecisionContext *context_ptr,
1210 : CodingUnit *cu_ptr,
1211 : const BlockGeom *blk_geom,
1212 : uint16_t cu_origin_x,
1213 : uint16_t cu_origin_y,
1214 : MvReferenceFrame *ref_frames,
1215 : uint32_t tot_refs,
1216 : PictureControlSet *picture_control_set_ptr)
1217 : {
1218 772499 : int32_t mi_row = cu_origin_y >> MI_SIZE_LOG2;
1219 772499 : int32_t mi_col = cu_origin_x >> MI_SIZE_LOG2;
1220 772499 : Av1Common *cm = picture_control_set_ptr->parent_pcs_ptr->av1_cm;
1221 772499 : FrameHeader *frm_hdr = &picture_control_set_ptr->parent_pcs_ptr->frm_hdr;
1222 772499 : MacroBlockD *xd = cu_ptr->av1xd;
1223 772499 : xd->n8_w = blk_geom->bwidth >> MI_SIZE_LOG2;
1224 772499 : xd->n8_h = blk_geom->bheight >> MI_SIZE_LOG2;
1225 772499 : xd->n4_w = blk_geom->bwidth >> MI_SIZE_LOG2;
1226 772499 : xd->n4_h = blk_geom->bheight >> MI_SIZE_LOG2;
1227 772499 : BlockSize bsize = blk_geom->bsize;
1228 772499 : const int32_t bw = mi_size_wide[bsize];
1229 772499 : const int32_t bh = mi_size_high[bsize];
1230 :
1231 772499 : xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8);
1232 772499 : xd->mb_to_bottom_edge = ((cm->mi_rows - bh - mi_row) * MI_SIZE) * 8;
1233 772499 : xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8);
1234 772499 : xd->mb_to_right_edge = ((cm->mi_cols - bw - mi_col) * MI_SIZE) * 8;
1235 :
1236 772499 : memset(xd->ref_mv_count, 0, sizeof(xd->ref_mv_count));
1237 772499 : memset(context_ptr->md_local_cu_unit[blk_geom->blkidx_mds].ed_ref_mv_stack, 0, sizeof(context_ptr->md_local_cu_unit[blk_geom->blkidx_mds].ed_ref_mv_stack));
1238 :
1239 772499 : xd->up_available = (mi_row > tile->mi_row_start);
1240 772499 : xd->left_available = (mi_col > tile->mi_col_start);
1241 :
1242 772499 : xd->n8_h = bh;
1243 772499 : xd->n8_w = bw;
1244 772499 : xd->is_sec_rect = 0;
1245 772499 : if (xd->n8_w < xd->n8_h) {
1246 : // Only mark is_sec_rect as 1 for the last block.
1247 : // For PARTITION_VERT_4, it would be (0, 0, 0, 1);
1248 : // For other partitions, it would be (0, 1).
1249 267321 : if (!((mi_col + xd->n8_w) & (xd->n8_h - 1))) xd->is_sec_rect = 1;
1250 : }
1251 :
1252 772499 : if (xd->n8_w > xd->n8_h)
1253 251457 : if (mi_row & (xd->n8_w - 1)) xd->is_sec_rect = 1;
1254 :
1255 772499 : xd->tile.mi_col_start = tile->mi_col_start;
1256 772499 : xd->tile.mi_col_end = tile->mi_col_end;
1257 772499 : xd->tile.mi_row_start = tile->mi_row_start;
1258 772499 : xd->tile.mi_row_end = tile->mi_row_end;
1259 :
1260 772499 : xd->mi_stride = picture_control_set_ptr->mi_stride;
1261 772499 : const int32_t offset = mi_row * xd->mi_stride + mi_col;
1262 772499 : xd->mi = picture_control_set_ptr->mi_grid_base + offset;
1263 :
1264 772499 : xd->mi[0]->mbmi.block_mi.partition = from_shape_to_part[blk_geom->shape];
1265 :
1266 : uint32_t refIt;
1267 8642570 : for (refIt = 0; refIt < tot_refs; ++refIt) {
1268 7869530 : MvReferenceFrame ref_frame = ref_frames[refIt];
1269 7869530 : IntMv zeromv[2] = { {0}, {0} };
1270 :
1271 : MvReferenceFrame rf[2];
1272 7869530 : av1_set_ref_frame(rf, ref_frame);
1273 :
1274 7869700 : if (ref_frame != INTRA_FRAME) {
1275 7870800 : zeromv[0].as_int =
1276 7869700 : gm_get_motion_vector_enc(&picture_control_set_ptr->parent_pcs_ptr->global_motion[rf[0]],
1277 7869700 : frm_hdr->allow_high_precision_mv, bsize, mi_col, mi_row,
1278 7869700 : frm_hdr->force_integer_mv)
1279 7870800 : .as_int;
1280 7871450 : zeromv[1].as_int = (rf[1] != NONE_FRAME)
1281 4644200 : ? gm_get_motion_vector_enc(&picture_control_set_ptr->parent_pcs_ptr->global_motion[rf[1]],
1282 4644200 : frm_hdr->allow_high_precision_mv,
1283 : bsize, mi_col, mi_row,
1284 4644200 : frm_hdr->force_integer_mv)
1285 : .as_int
1286 12515600 : : 0;
1287 : }
1288 : else
1289 0 : zeromv[0].as_int = zeromv[1].as_int = 0;
1290 :
1291 : IntMv gm_mv[2];
1292 :
1293 7871450 : if (ref_frame == INTRA_FRAME) {
1294 0 : gm_mv[0].as_int = gm_mv[1].as_int = 0;
1295 : } else {
1296 7871450 : if (ref_frame < REF_FRAMES) {
1297 3226600 : gm_mv[0] = gm_get_motion_vector_enc(
1298 3226600 : &picture_control_set_ptr->parent_pcs_ptr->global_motion[ref_frame], frm_hdr->allow_high_precision_mv, bsize,
1299 3226600 : mi_col, mi_row, frm_hdr->force_integer_mv);
1300 3226620 : gm_mv[1].as_int = 0;
1301 : } else {
1302 : MvReferenceFrame rf[2];
1303 4644840 : av1_set_ref_frame(rf, ref_frame);
1304 4644820 : gm_mv[0] = gm_get_motion_vector_enc(
1305 4644820 : &picture_control_set_ptr->parent_pcs_ptr->global_motion[rf[0]], frm_hdr->allow_high_precision_mv, bsize, mi_col,
1306 4644820 : mi_row, frm_hdr->force_integer_mv);
1307 4644760 : gm_mv[1] = gm_get_motion_vector_enc(
1308 4644760 : &picture_control_set_ptr->parent_pcs_ptr->global_motion[rf[1]], frm_hdr->allow_high_precision_mv, bsize, mi_col,
1309 4644760 : mi_row, frm_hdr->force_integer_mv);
1310 : }
1311 : }
1312 :
1313 7871340 : setup_ref_mv_list(
1314 : picture_control_set_ptr,
1315 : cm,
1316 : xd,
1317 : ref_frame,
1318 7871340 : xd->ref_mv_count,
1319 7871340 : context_ptr->md_local_cu_unit[blk_geom->blkidx_mds].ed_ref_mv_stack,
1320 7871340 : cu_ptr->ref_mvs,
1321 7871340 : gm_mv, picture_control_set_ptr->parent_pcs_ptr->global_motion,
1322 : mi_row,
1323 : mi_col,
1324 7871340 : cu_ptr->inter_mode_ctx);
1325 : }
1326 773043 : }
1327 113676000 : void get_av1_mv_pred_drl(
1328 : ModeDecisionContext *context_ptr,
1329 : CodingUnit *cu_ptr,
1330 : MvReferenceFrame ref_frame,
1331 : uint8_t is_compound,
1332 : PredictionMode mode,
1333 : uint8_t drl_index, //valid value of drl_index
1334 : IntMv nearestmv[2],
1335 : IntMv nearmv[2],
1336 : IntMv ref_mv[2])
1337 : {
1338 113676000 : MacroBlockD* xd = cu_ptr->av1xd;
1339 :
1340 113676000 : if (!is_compound && mode != GLOBALMV) {
1341 : //av1_find_best_ref_mvs(allow_hp, ref_mvs[mbmi->ref_frame[0]], &nearestmv[0], &nearmv[0], cm->cur_frame_force_integer_mv);
1342 :
1343 48826900 : nearestmv[0] = cu_ptr->ref_mvs[ref_frame][0];
1344 48826900 : nearmv[0] = cu_ptr->ref_mvs[ref_frame][1];
1345 : }
1346 :
1347 113676000 : if (is_compound && mode != GLOBAL_GLOBALMV) {
1348 65032500 : int32_t ref_mv_idx = drl_index + 1;
1349 65032500 : nearestmv[0] = context_ptr->md_local_cu_unit[cu_ptr->mds_idx].ed_ref_mv_stack[ref_frame][0].this_mv;
1350 65032500 : nearestmv[1] = context_ptr->md_local_cu_unit[cu_ptr->mds_idx].ed_ref_mv_stack[ref_frame][0].comp_mv;
1351 65032500 : nearmv[0] = context_ptr->md_local_cu_unit[cu_ptr->mds_idx].ed_ref_mv_stack[ref_frame][ref_mv_idx].this_mv;
1352 65032500 : nearmv[1] = context_ptr->md_local_cu_unit[cu_ptr->mds_idx].ed_ref_mv_stack[ref_frame][ref_mv_idx].comp_mv;
1353 : }
1354 48643100 : else if (drl_index > 0 && mode == NEARMV) {
1355 4483140 : assert((1 + drl_index) < MAX_REF_MV_STACK_SIZE);
1356 4483140 : IntMv cur_mv = context_ptr->md_local_cu_unit[cu_ptr->mds_idx].ed_ref_mv_stack[ref_frame][1 + drl_index].this_mv;
1357 4483140 : nearmv[0] = cur_mv;
1358 : }
1359 :
1360 113676000 : ref_mv[0] = nearestmv[0];
1361 113676000 : ref_mv[1] = nearestmv[1];
1362 :
1363 113676000 : if (is_compound) {
1364 65041800 : int32_t ref_mv_idx = drl_index;
1365 : // Special case: NEAR_NEWMV and NEW_NEARMV modes use
1366 : // 1 + mbmi->ref_mv_idx (like NEARMV) instead of
1367 : // mbmi->ref_mv_idx (like NEWMV)
1368 65041800 : if (mode == NEAR_NEWMV || mode == NEW_NEARMV)
1369 4669980 : ref_mv_idx = 1 + drl_index;
1370 :
1371 : // TODO(jingning, yunqing): Do we need a lower_mv_precision() call here?
1372 65041800 : if (compound_ref0_mode(mode) == NEWMV)
1373 52924300 : ref_mv[0] = context_ptr->md_local_cu_unit[cu_ptr->mds_idx].ed_ref_mv_stack[ref_frame][ref_mv_idx].this_mv;
1374 :
1375 65041300 : if (compound_ref1_mode(mode) == NEWMV)
1376 52963900 : ref_mv[1] = context_ptr->md_local_cu_unit[cu_ptr->mds_idx].ed_ref_mv_stack[ref_frame][ref_mv_idx].comp_mv;
1377 : }
1378 : else {
1379 48633800 : if (mode == NEWMV) {
1380 37806900 : if (xd->ref_mv_count[ref_frame] > 1)
1381 37052900 : ref_mv[0] = context_ptr->md_local_cu_unit[cu_ptr->mds_idx].ed_ref_mv_stack[ref_frame][drl_index].this_mv;
1382 : }
1383 : }
1384 113660000 : }
1385 :
1386 27420 : void enc_pass_av1_mv_pred(
1387 : TileInfo *tile,
1388 : ModeDecisionContext *md_context_ptr,
1389 : CodingUnit *cu_ptr,
1390 : const BlockGeom *blk_geom,
1391 : uint16_t cu_origin_x,
1392 : uint16_t cu_origin_y,
1393 : PictureControlSet *picture_control_set_ptr,
1394 : MvReferenceFrame ref_frame,
1395 : uint8_t is_compound,
1396 : PredictionMode mode,
1397 : IntMv ref_mv[2]){ //[OUT]
1398 :
1399 : (void)mode;
1400 : IntMv nearestmv[2], nearmv[2];
1401 27420 : memset(nearestmv, 0, sizeof(nearestmv));
1402 :
1403 27420 : generate_av1_mvp_table(
1404 : tile,
1405 : md_context_ptr,
1406 : cu_ptr,
1407 : blk_geom,
1408 : cu_origin_x,
1409 : cu_origin_y,
1410 : &ref_frame,
1411 : 1,
1412 : picture_control_set_ptr);
1413 :
1414 27426 : get_av1_mv_pred_drl(
1415 : md_context_ptr,
1416 : cu_ptr,
1417 : ref_frame,
1418 : is_compound,
1419 27426 : cu_ptr->pred_mode,
1420 27426 : cu_ptr->drl_index,
1421 : nearestmv,
1422 : nearmv,
1423 : ref_mv);
1424 27426 : }
1425 :
1426 33843 : void update_av1_mi_map(
1427 : CodingUnit *cu_ptr,
1428 : uint32_t cu_origin_x,
1429 : uint32_t cu_origin_y,
1430 : const BlockGeom *blk_geom,
1431 : PictureControlSet *picture_control_set_ptr)
1432 : {
1433 33843 : uint32_t mi_stride = picture_control_set_ptr->mi_stride;
1434 33843 : int32_t mi_row = cu_origin_y >> MI_SIZE_LOG2;
1435 33843 : int32_t mi_col = cu_origin_x >> MI_SIZE_LOG2;
1436 :
1437 33843 : const int32_t offset = mi_row * mi_stride + mi_col;
1438 33843 : ModeInfo *miPtr = *(picture_control_set_ptr->mi_grid_base + offset);
1439 : MvReferenceFrame rf[2];
1440 33843 : av1_set_ref_frame(rf, cu_ptr->prediction_unit_array->ref_frame_type);
1441 : uint8_t miX, miY;
1442 :
1443 222302 : for (miY = 0; miY < (blk_geom->bheight >> MI_SIZE_LOG2); miY++) {
1444 1958220 : for (miX = 0; miX < (blk_geom->bwidth >> MI_SIZE_LOG2); miX++) {
1445 : //these needed for mvPred
1446 : {
1447 1769760 : miPtr[miX + miY * mi_stride].mbmi.block_mi.mode = cu_ptr->pred_mode;
1448 1769760 : miPtr[miX + miY * mi_stride].mbmi.block_mi.uv_mode = cu_ptr->prediction_unit_array->intra_chroma_mode;
1449 1769760 : if (cu_ptr->prediction_mode_flag == INTRA_MODE && cu_ptr->pred_mode == INTRA_MODE_4x4) {
1450 0 : miPtr[miX + miY * mi_stride].mbmi.tx_size = 0;
1451 0 : miPtr[miX + miY * mi_stride].mbmi.block_mi.sb_type = BLOCK_4X4;
1452 0 : miPtr[miX + miY * mi_stride].mbmi.tx_depth = cu_ptr->tx_depth;
1453 : }
1454 : else {
1455 1769760 : miPtr[miX + miY * mi_stride].mbmi.tx_size = blk_geom->txsize[cu_ptr->tx_depth][0]; // inherit tx_size from 1st transform block
1456 1769760 : miPtr[miX + miY * mi_stride].mbmi.block_mi.sb_type = blk_geom->bsize;
1457 1769760 : miPtr[miX + miY * mi_stride].mbmi.tx_depth = cu_ptr->tx_depth;
1458 : }
1459 1769760 : miPtr[miX + miY * mi_stride].mbmi.block_mi.use_intrabc = cu_ptr->av1xd->use_intrabc;
1460 :
1461 1769760 : miPtr[miX + miY * mi_stride].mbmi.block_mi.ref_frame[0] = rf[0];
1462 : #if II_COMP_FLAG
1463 1769760 : miPtr[miX + miY * mi_stride].mbmi.block_mi.ref_frame[1] = cu_ptr->is_interintra_used ? INTRA_FRAME : rf[1];
1464 : #else
1465 : miPtr[miX + miY * mi_stride].mbmi.block_mi.ref_frame[1] = rf[1];
1466 : #endif
1467 1769760 : if (cu_ptr->prediction_unit_array->inter_pred_direction_index == UNI_PRED_LIST_0) {
1468 285451 : miPtr[miX + miY * mi_stride].mbmi.block_mi.mv[0].as_mv.col = cu_ptr->prediction_unit_array->mv[0].x;
1469 285451 : miPtr[miX + miY * mi_stride].mbmi.block_mi.mv[0].as_mv.row = cu_ptr->prediction_unit_array->mv[0].y;
1470 : }
1471 1484310 : else if (cu_ptr->prediction_unit_array->inter_pred_direction_index == UNI_PRED_LIST_1) {
1472 103323 : miPtr[miX + miY * mi_stride].mbmi.block_mi.mv[0].as_mv.col = cu_ptr->prediction_unit_array->mv[1].x;
1473 103323 : miPtr[miX + miY * mi_stride].mbmi.block_mi.mv[0].as_mv.row = cu_ptr->prediction_unit_array->mv[1].y;
1474 : }
1475 : else {
1476 1380990 : miPtr[miX + miY * mi_stride].mbmi.block_mi.mv[0].as_mv.col = cu_ptr->prediction_unit_array->mv[0].x;
1477 1380990 : miPtr[miX + miY * mi_stride].mbmi.block_mi.mv[0].as_mv.row = cu_ptr->prediction_unit_array->mv[0].y;
1478 1380990 : miPtr[miX + miY * mi_stride].mbmi.block_mi.mv[1].as_mv.col = cu_ptr->prediction_unit_array->mv[1].x;
1479 1380990 : miPtr[miX + miY * mi_stride].mbmi.block_mi.mv[1].as_mv.row = cu_ptr->prediction_unit_array->mv[1].y;
1480 : }
1481 :
1482 1769760 : miPtr[miX + miY * mi_stride].mbmi.block_mi.partition = from_shape_to_part[blk_geom->shape];// cu_ptr->part;
1483 : }
1484 : #if OBMC_FLAG
1485 1769760 : miPtr[miX + miY * mi_stride].mbmi.block_mi.interp_filters = cu_ptr->interp_filters;
1486 : #endif
1487 1769760 : miPtr[miX + miY * mi_stride].mbmi.comp_group_idx = cu_ptr->comp_group_idx;
1488 1769760 : miPtr[miX + miY * mi_stride].mbmi.block_mi.compound_idx = cu_ptr->compound_idx;
1489 : #if II_COMP_FLAG
1490 1769760 : miPtr[miX + miY * mi_stride].mbmi.block_mi.interintra_mode_params.interintra_mode = cu_ptr->interintra_mode;
1491 1769760 : miPtr[miX + miY * mi_stride].mbmi.block_mi.interintra_mode_params.wedge_interintra = cu_ptr->use_wedge_interintra;
1492 1769760 : miPtr[miX + miY * mi_stride].mbmi.block_mi.interintra_mode_params.interintra_wedge_index = cu_ptr->interintra_wedge_index;//in
1493 : #endif
1494 :
1495 : #if PAL_SUP
1496 1769760 : memcpy( &miPtr[miX + miY * mi_stride].mbmi.palette_mode_info , &cu_ptr->palette_info.pmi,sizeof(PaletteModeInfo));
1497 : #endif
1498 : //needed for CDEF
1499 1769760 : miPtr[miX + miY * mi_stride].mbmi.block_mi.skip = cu_ptr->block_has_coeff ? EB_FALSE : EB_TRUE;
1500 : }
1501 : }
1502 33843 : }
1503 :
1504 1217100 : void update_mi_map(
1505 : struct ModeDecisionContext *context_ptr,
1506 : CodingUnit *cu_ptr,
1507 : uint32_t cu_origin_x,
1508 : uint32_t cu_origin_y,
1509 : const BlockGeom *blk_geom,
1510 : const CodedUnitStats *cu_stats,
1511 : PictureControlSet *picture_control_set_ptr)
1512 : {
1513 : UNUSED(cu_stats);
1514 1217100 : uint32_t mi_stride = picture_control_set_ptr->mi_stride;
1515 1217100 : int32_t mi_row = cu_origin_y >> MI_SIZE_LOG2;
1516 1217100 : int32_t mi_col = cu_origin_x >> MI_SIZE_LOG2;
1517 :
1518 1217100 : const int32_t offset = mi_row * mi_stride + mi_col;
1519 1217100 : ModeInfo *miPtr = *(picture_control_set_ptr->mi_grid_base + offset);
1520 : MvReferenceFrame rf[2];
1521 1217100 : av1_set_ref_frame(rf, cu_ptr->prediction_unit_array->ref_frame_type);
1522 :
1523 : uint8_t miX, miY;
1524 4969270 : for (miY = 0; miY < (blk_geom->bheight >> MI_SIZE_LOG2); miY++) {
1525 18939700 : for (miX = 0; miX < (blk_geom->bwidth >> MI_SIZE_LOG2); miX++) {
1526 : //these needed for mvPred
1527 : {
1528 15187500 : miPtr[miX + miY * mi_stride].mbmi.block_mi.mode = cu_ptr->pred_mode;
1529 15187500 : miPtr[miX + miY * mi_stride].mbmi.block_mi.uv_mode = cu_ptr->prediction_unit_array->intra_chroma_mode;
1530 15187500 : if (cu_ptr->prediction_mode_flag == INTRA_MODE && cu_ptr->pred_mode == INTRA_MODE_4x4) {
1531 0 : miPtr[miX + miY * mi_stride].mbmi.tx_size = 0;
1532 0 : miPtr[miX + miY * mi_stride].mbmi.block_mi.sb_type = BLOCK_4X4;
1533 0 : miPtr[miX + miY * mi_stride].mbmi.tx_depth = cu_ptr->tx_depth;
1534 : }
1535 : else {
1536 15187500 : miPtr[miX + miY * mi_stride].mbmi.tx_size = blk_geom->txsize[cu_ptr->tx_depth][0]; // inherit tx_size from 1st transform block
1537 :
1538 15187500 : miPtr[miX + miY * mi_stride].mbmi.block_mi.sb_type = blk_geom->bsize;
1539 15187500 : miPtr[miX + miY * mi_stride].mbmi.tx_depth = cu_ptr->tx_depth;
1540 : }
1541 15187500 : miPtr[miX + miY * mi_stride].mbmi.block_mi.use_intrabc = cu_ptr->av1xd->use_intrabc;
1542 15187500 : miPtr[miX + miY * mi_stride].mbmi.block_mi.ref_frame[0] = rf[0];
1543 : #if II_COMP_FLAG
1544 15187500 : miPtr[miX + miY * mi_stride].mbmi.block_mi.ref_frame[1] = cu_ptr->is_interintra_used ? INTRA_FRAME : rf[1];
1545 : #else
1546 : miPtr[miX + miY * mi_stride].mbmi.block_mi.ref_frame[1] = rf[1];
1547 : #endif
1548 15187500 : if (cu_ptr->prediction_unit_array->inter_pred_direction_index == UNI_PRED_LIST_0) {
1549 2671250 : miPtr[miX + miY * mi_stride].mbmi.block_mi.mv[0].as_mv.col = cu_ptr->prediction_unit_array->mv[0].x;
1550 2671250 : miPtr[miX + miY * mi_stride].mbmi.block_mi.mv[0].as_mv.row = cu_ptr->prediction_unit_array->mv[0].y;
1551 : }
1552 12516300 : else if (cu_ptr->prediction_unit_array->inter_pred_direction_index == UNI_PRED_LIST_1) {
1553 1119530 : miPtr[miX + miY * mi_stride].mbmi.block_mi.mv[0].as_mv.col = cu_ptr->prediction_unit_array->mv[1].x;
1554 1119530 : miPtr[miX + miY * mi_stride].mbmi.block_mi.mv[0].as_mv.row = cu_ptr->prediction_unit_array->mv[1].y;
1555 : }
1556 : else {
1557 11396700 : miPtr[miX + miY * mi_stride].mbmi.block_mi.mv[0].as_mv.col = cu_ptr->prediction_unit_array->mv[0].x;
1558 11396700 : miPtr[miX + miY * mi_stride].mbmi.block_mi.mv[0].as_mv.row = cu_ptr->prediction_unit_array->mv[0].y;
1559 11396700 : miPtr[miX + miY * mi_stride].mbmi.block_mi.mv[1].as_mv.col = cu_ptr->prediction_unit_array->mv[1].x;
1560 11396700 : miPtr[miX + miY * mi_stride].mbmi.block_mi.mv[1].as_mv.row = cu_ptr->prediction_unit_array->mv[1].y;
1561 : }
1562 :
1563 15187500 : miPtr[miX + miY * mi_stride].mbmi.block_mi.partition = from_shape_to_part[blk_geom->shape];// cu_ptr->part;
1564 : }
1565 15187500 : if (blk_geom->has_uv && context_ptr->chroma_level <= CHROMA_MODE_1)
1566 12704900 : miPtr[miX + miY * mi_stride].mbmi.block_mi.skip = (cu_ptr->transform_unit_array[0].y_has_coeff == 0 && cu_ptr->transform_unit_array[0].v_has_coeff == 0 && cu_ptr->transform_unit_array[0].u_has_coeff == 0) ? EB_TRUE : EB_FALSE;
1567 : else
1568 2482610 : miPtr[miX + miY * mi_stride].mbmi.block_mi.skip = (cu_ptr->transform_unit_array[0].y_has_coeff == 0) ? EB_TRUE : EB_FALSE;
1569 :
1570 : #if OBMC_FLAG
1571 15187500 : miPtr[miX + miY * mi_stride].mbmi.block_mi.interp_filters = cu_ptr->interp_filters;
1572 : #endif
1573 15187500 : miPtr[miX + miY * mi_stride].mbmi.comp_group_idx = cu_ptr->comp_group_idx;
1574 15187500 : miPtr[miX + miY * mi_stride].mbmi.block_mi.compound_idx = cu_ptr->compound_idx;
1575 : #if II_COMP_FLAG
1576 15187500 : miPtr[miX + miY * mi_stride].mbmi.block_mi.interintra_mode_params.interintra_mode = cu_ptr->interintra_mode;
1577 15187500 : miPtr[miX + miY * mi_stride].mbmi.block_mi.interintra_mode_params.wedge_interintra = cu_ptr->use_wedge_interintra;
1578 15187500 : miPtr[miX + miY * mi_stride].mbmi.block_mi.interintra_mode_params.interintra_wedge_index = cu_ptr->interintra_wedge_index;//in
1579 : #endif
1580 : #if PAL_SUP
1581 15187500 : memcpy(&miPtr[miX + miY * mi_stride].mbmi.palette_mode_info, &cu_ptr->palette_info.pmi, sizeof(PaletteModeInfo));
1582 : #endif
1583 : }
1584 : }
1585 1217100 : }
1586 :
1587 1784930 : static INLINE void record_samples(
1588 : MbModeInfo *mbmi,
1589 : int *pts,
1590 : int *pts_inref,
1591 : int row_offset,
1592 : int sign_r,
1593 : int col_offset,
1594 : int sign_c)
1595 : {
1596 1784930 : uint8_t bw = block_size_wide[mbmi->block_mi.sb_type];
1597 1784930 : uint8_t bh = block_size_high[mbmi->block_mi.sb_type];
1598 1784930 : int x = col_offset * MI_SIZE + sign_c * AOMMAX(bw, MI_SIZE) / 2 - 1;
1599 1784930 : int y = row_offset * MI_SIZE + sign_r * AOMMAX(bh, MI_SIZE) / 2 - 1;
1600 :
1601 1784930 : pts[0] = (x * 8);
1602 1784930 : pts[1] = (y * 8);
1603 1784930 : pts_inref[0] = (x * 8) + mbmi->block_mi.mv[0].as_mv.col;
1604 1784930 : pts_inref[1] = (y * 8) + mbmi->block_mi.mv[0].as_mv.row;
1605 1784930 : }
1606 :
1607 : // Select samples according to the motion vector difference.
1608 533643 : int select_samples(
1609 : MV *mv,
1610 : int *pts,
1611 : int *pts_inref,
1612 : int len,
1613 : BlockSize bsize)
1614 : {
1615 533643 : const uint8_t bw = block_size_wide[bsize];
1616 533643 : const uint8_t bh = block_size_high[bsize];
1617 533643 : const int thresh = clamp(AOMMAX(bw, bh), 16, 112);
1618 533639 : int pts_mvd[SAMPLES_ARRAY_SIZE] = { 0 };
1619 533639 : int i, j, k, l = len;
1620 533639 : int ret = 0;
1621 :
1622 : // Obtain the motion vector difference.
1623 2083250 : for (i = 0; i < len; ++i) {
1624 1549610 : pts_mvd[i] = abs(pts_inref[2 * i] - pts[2 * i] - mv->col) +
1625 1549610 : abs(pts_inref[2 * i + 1] - pts[2 * i + 1] - mv->row);
1626 :
1627 1549610 : if (pts_mvd[i] > thresh)
1628 357042 : pts_mvd[i] = -1;
1629 : else
1630 1192570 : ret++;
1631 : }
1632 :
1633 : // Keep at least 1 sample.
1634 533639 : if (!ret)
1635 64081 : return 1;
1636 :
1637 469558 : i = 0;
1638 469558 : j = l - 1;
1639 541697 : for (k = 0; k < l - ret; k++) {
1640 329051 : while (pts_mvd[i] != -1)
1641 171718 : i++;
1642 157333 : if (j < 0)
1643 0 : break;
1644 274401 : while (pts_mvd[j] == -1) {
1645 117068 : j--;
1646 117068 : if (j < 0)
1647 0 : break;
1648 : }
1649 157333 : if (i > j)
1650 85194 : break;
1651 :
1652 : // Replace the discarded samples;
1653 72139 : pts_mvd[i] = pts_mvd[j];
1654 72139 : pts[2 * i] = pts[2 * j];
1655 72139 : pts[2 * i + 1] = pts[2 * j + 1];
1656 72139 : pts_inref[2 * i] = pts_inref[2 * j];
1657 72139 : pts_inref[2 * i + 1] = pts_inref[2 * j + 1];
1658 72139 : i++;
1659 72139 : j--;
1660 : }
1661 :
1662 469558 : return ret;
1663 : }
1664 :
1665 : // Note: Samples returned are at 1/8-pel precision
1666 : // Sample are the neighbor block center point's coordinates relative to the
1667 : // left-top pixel of current block.
1668 6664800 : int av1_find_samples(
1669 : const Av1Common *cm,
1670 : MacroBlockD *xd,
1671 : int mi_row,
1672 : int mi_col,
1673 : MvReferenceFrame rf0,
1674 : int *pts,
1675 : int *pts_inref)
1676 : {
1677 6664800 : int up_available = xd->up_available;
1678 6664800 : int left_available = xd->left_available;
1679 6664800 : int i, mi_step = 1, np = 0;
1680 :
1681 6664800 : const TileInfo *const tile = &xd->tile;
1682 6664800 : int do_tl = 1;
1683 6664800 : int do_tr = 1;
1684 :
1685 : // scan the nearest above rows
1686 6664800 : if (up_available) {
1687 6310230 : int mi_row_offset = -1;
1688 6310230 : MbModeInfo *mbmi = &xd->mi[mi_row_offset * xd->mi_stride]->mbmi;
1689 6310230 : uint8_t n4_w = mi_size_wide[mbmi->block_mi.sb_type];
1690 :
1691 6310230 : if (xd->n4_w <= n4_w) {
1692 : // Handle "current block width <= above block width" case.
1693 6027230 : int col_offset = -mi_col % n4_w;
1694 :
1695 6027230 : if (col_offset < 0)
1696 2155610 : do_tl = 0;
1697 6027230 : if (col_offset + n4_w > xd->n4_w)
1698 2084000 : do_tr = 0;
1699 :
1700 6027230 : if (mbmi->block_mi.ref_frame[0] == rf0 && mbmi->block_mi.ref_frame[1] == NONE_FRAME) {
1701 527757 : record_samples(mbmi, pts, pts_inref, 0, -1, col_offset, 1);
1702 527751 : pts += 2;
1703 527751 : pts_inref += 2;
1704 527751 : np++;
1705 527751 : if (np >= LEAST_SQUARES_SAMPLES_MAX)
1706 0 : return LEAST_SQUARES_SAMPLES_MAX;
1707 : }
1708 : } else {
1709 : // Handle "current block width > above block width" case.
1710 923866 : for (i = 0; i < AOMMIN(xd->n4_w, cm->mi_cols - mi_col); i += mi_step) {
1711 640861 : int mi_col_offset = i;
1712 640861 : mbmi = &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
1713 640861 : n4_w = mi_size_wide[mbmi->block_mi.sb_type];
1714 640861 : mi_step = AOMMIN(xd->n4_w, n4_w);
1715 :
1716 640861 : if (mbmi->block_mi.ref_frame[0] == rf0 &&
1717 314199 : mbmi->block_mi.ref_frame[1] == NONE_FRAME)
1718 : {
1719 139031 : record_samples(mbmi, pts, pts_inref, 0, -1, i, 1);
1720 139031 : pts += 2;
1721 139031 : pts_inref += 2;
1722 139031 : np++;
1723 139031 : if (np >= LEAST_SQUARES_SAMPLES_MAX)
1724 0 : return LEAST_SQUARES_SAMPLES_MAX;
1725 : }
1726 : }
1727 : }
1728 : }
1729 :
1730 : // scan the nearest left columns
1731 6664790 : if (left_available) {
1732 6393170 : int mi_col_offset = -1;
1733 6393170 : MbModeInfo *mbmi = &xd->mi[mi_col_offset]->mbmi;
1734 6393170 : uint8_t n4_h = mi_size_high[mbmi->block_mi.sb_type];
1735 :
1736 6393170 : if (xd->n4_h <= n4_h) {
1737 : // Handle "current block height <= above block height" case.
1738 5828460 : int row_offset = -mi_row % n4_h;
1739 5828460 : if (row_offset < 0)
1740 2095880 : do_tl = 0;
1741 :
1742 5828460 : if (mbmi->block_mi.ref_frame[0] == rf0 && mbmi->block_mi.ref_frame[1] == NONE_FRAME) {
1743 511567 : record_samples(mbmi, pts, pts_inref, row_offset, 1, 0, -1);
1744 511561 : pts += 2;
1745 511561 : pts_inref += 2;
1746 511561 : np++;
1747 511561 : if (np >= LEAST_SQUARES_SAMPLES_MAX)
1748 52 : return LEAST_SQUARES_SAMPLES_MAX;
1749 : }
1750 : } else {
1751 : // Handle "current block height > above block height" case.
1752 1755900 : for (i = 0; i < AOMMIN(xd->n4_h, cm->mi_rows - mi_row); i += mi_step) {
1753 1192640 : int mi_row_offset = i;
1754 1192640 : mbmi = &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
1755 1192640 : n4_h = mi_size_high[mbmi->block_mi.sb_type];
1756 1192640 : mi_step = AOMMIN(xd->n4_h, n4_h);
1757 :
1758 1192640 : if (mbmi->block_mi.ref_frame[0] == rf0 &&
1759 561979 : mbmi->block_mi.ref_frame[1] == NONE_FRAME)
1760 : {
1761 175576 : record_samples(mbmi, pts, pts_inref, i, 1, 0, -1);
1762 175576 : pts += 2;
1763 175576 : pts_inref += 2;
1764 175576 : np++;
1765 175576 : if (np >= LEAST_SQUARES_SAMPLES_MAX)
1766 1443 : return LEAST_SQUARES_SAMPLES_MAX;
1767 : }
1768 : }
1769 : }
1770 : }
1771 :
1772 : // Top-left block
1773 6663290 : if (do_tl && left_available && up_available) {
1774 1786240 : int mi_row_offset = -1;
1775 1786240 : int mi_col_offset = -1;
1776 1786240 : MbModeInfo *mbmi = &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
1777 :
1778 1786240 : if (mbmi->block_mi.ref_frame[0] == rf0 && mbmi->block_mi.ref_frame[1] == NONE_FRAME) {
1779 238605 : record_samples(mbmi, pts, pts_inref, 0, -1, 0, -1);
1780 238605 : pts += 2;
1781 238605 : pts_inref += 2;
1782 238605 : np++;
1783 238605 : if (np >= LEAST_SQUARES_SAMPLES_MAX)
1784 1064 : return LEAST_SQUARES_SAMPLES_MAX;
1785 : }
1786 : }
1787 :
1788 : // Top-right block
1789 11240800 : if (do_tr &&
1790 4578700 : has_top_right(cm, xd, mi_row, mi_col, AOMMAX(xd->n4_w, xd->n4_h)))
1791 : {
1792 2051310 : Position trb_pos = { -1, xd->n4_w };
1793 :
1794 2051310 : if (is_inside(tile, mi_col, mi_row, cm->mi_rows, &trb_pos)) {
1795 1631220 : int mi_row_offset = -1;
1796 1631220 : int mi_col_offset = xd->n4_w;
1797 :
1798 1631220 : MbModeInfo *mbmi =
1799 1631220 : &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
1800 :
1801 1631220 : if (mbmi->block_mi.ref_frame[0] == rf0 && mbmi->block_mi.ref_frame[1] == NONE_FRAME) {
1802 192518 : record_samples(mbmi, pts, pts_inref, 0, -1, xd->n4_w, 1);
1803 192519 : np++;
1804 192519 : if (np >= LEAST_SQUARES_SAMPLES_MAX)
1805 1221 : return LEAST_SQUARES_SAMPLES_MAX;
1806 : }
1807 : }
1808 : }
1809 :
1810 6660340 : return np;
1811 : }
1812 :
1813 130462000 : void wm_count_samples(
1814 : CodingUnit *cu_ptr,
1815 : const BlockGeom *blk_geom,
1816 : uint16_t cu_origin_x,
1817 : uint16_t cu_origin_y,
1818 : uint8_t ref_frame_type,
1819 : PictureControlSet *picture_control_set_ptr,
1820 : uint16_t *num_samples)
1821 : {
1822 130462000 : Av1Common *cm = picture_control_set_ptr->parent_pcs_ptr->av1_cm;
1823 130462000 : MacroBlockD *xd = cu_ptr->av1xd;
1824 :
1825 130462000 : int32_t mi_row = cu_origin_y >> MI_SIZE_LOG2;
1826 130462000 : int32_t mi_col = cu_origin_x >> MI_SIZE_LOG2;
1827 :
1828 130462000 : xd->n4_w = blk_geom->bwidth >> MI_SIZE_LOG2;
1829 130462000 : xd->n4_h = blk_geom->bheight >> MI_SIZE_LOG2;
1830 :
1831 130462000 : int up_available = xd->up_available;
1832 130462000 : int left_available = xd->left_available;
1833 130462000 : int i, mi_step = 1, np = 0;
1834 :
1835 130462000 : const TileInfo *const tile = &xd->tile;
1836 130462000 : int do_tl = 1;
1837 130462000 : int do_tr = 1;
1838 :
1839 : MvReferenceFrame rf[2];
1840 130462000 : av1_set_ref_frame(rf, ref_frame_type);
1841 :
1842 130327000 : if (up_available) {
1843 123946000 : int mi_row_offset = -1;
1844 123946000 : MbModeInfo *mbmi = &xd->mi[mi_row_offset * xd->mi_stride]->mbmi;
1845 123946000 : uint8_t n4_w = mi_size_wide[mbmi->block_mi.sb_type];
1846 :
1847 123946000 : if (xd->n4_w <= n4_w) {
1848 119001000 : int col_offset = -mi_col % n4_w;
1849 119001000 : if (col_offset < 0)
1850 43681000 : do_tl = 0;
1851 119001000 : if (col_offset + n4_w > xd->n4_w)
1852 43158600 : do_tr = 0;
1853 :
1854 119001000 : if (mbmi->block_mi.ref_frame[0] == rf[0] && mbmi->block_mi.ref_frame[1] == NONE_FRAME) {
1855 10863900 : np++;
1856 10863900 : if (np >= LEAST_SQUARES_SAMPLES_MAX) {
1857 0 : *num_samples = LEAST_SQUARES_SAMPLES_MAX;
1858 50337 : return;
1859 : }
1860 : }
1861 : } else {
1862 16079100 : for (i = 0; i < AOMMIN(xd->n4_w, cm->mi_cols - mi_col); i += mi_step) {
1863 11133600 : int mi_col_offset = i;
1864 11133600 : mbmi = &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
1865 11133600 : n4_w = mi_size_wide[mbmi->block_mi.sb_type];
1866 11133600 : mi_step = AOMMIN(xd->n4_w, n4_w);
1867 :
1868 11133600 : if (mbmi->block_mi.ref_frame[0] == rf[0] &&
1869 5258460 : mbmi->block_mi.ref_frame[1] == NONE_FRAME)
1870 : {
1871 2301200 : np++;
1872 2301200 : if (np >= LEAST_SQUARES_SAMPLES_MAX) {
1873 0 : *num_samples = LEAST_SQUARES_SAMPLES_MAX;
1874 0 : return;
1875 : }
1876 : }
1877 : }
1878 : }
1879 : }
1880 :
1881 130327000 : if (left_available) {
1882 124982000 : int mi_col_offset = -1;
1883 124982000 : MbModeInfo *mbmi = &xd->mi[mi_col_offset]->mbmi;
1884 124982000 : uint8_t n4_h = mi_size_high[mbmi->block_mi.sb_type];
1885 124982000 : if (xd->n4_h <= n4_h) {
1886 115684000 : int row_offset = -mi_row % n4_h;
1887 115684000 : if (row_offset < 0)
1888 40806200 : do_tl = 0;
1889 115684000 : if (mbmi->block_mi.ref_frame[0] == rf[0] && mbmi->block_mi.ref_frame[1] == NONE_FRAME) {
1890 10798100 : np++;
1891 10798100 : if (np >= LEAST_SQUARES_SAMPLES_MAX) {
1892 678 : *num_samples = LEAST_SQUARES_SAMPLES_MAX;
1893 678 : return;
1894 : }
1895 : }
1896 : } else {
1897 29151200 : for (i = 0; i < AOMMIN(xd->n4_h, cm->mi_rows - mi_row); i += mi_step) {
1898 19872000 : int mi_row_offset = i;
1899 19872000 : mbmi = &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
1900 19872000 : n4_h = mi_size_high[mbmi->block_mi.sb_type];
1901 19872000 : mi_step = AOMMIN(xd->n4_h, n4_h);
1902 :
1903 19872000 : if (mbmi->block_mi.ref_frame[0] == rf[0] &&
1904 9022420 : mbmi->block_mi.ref_frame[1] == NONE_FRAME)
1905 : {
1906 2677190 : np++;
1907 2677190 : if (np >= LEAST_SQUARES_SAMPLES_MAX) {
1908 18685 : *num_samples = LEAST_SQUARES_SAMPLES_MAX;
1909 18685 : return;
1910 : }
1911 : }
1912 : }
1913 : }
1914 : }
1915 :
1916 130308000 : if (do_tl && left_available && up_available) {
1917 34361000 : int mi_row_offset = -1;
1918 34361000 : int mi_col_offset = -1;
1919 34361000 : MbModeInfo *mbmi = &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
1920 34361000 : if (mbmi->block_mi.ref_frame[0] == rf[0] && mbmi->block_mi.ref_frame[1] == NONE_FRAME) {
1921 4279520 : np++;
1922 4279520 : if (np >= LEAST_SQUARES_SAMPLES_MAX) {
1923 14040 : *num_samples = LEAST_SQUARES_SAMPLES_MAX;
1924 14040 : return;
1925 : }
1926 : }
1927 : }
1928 :
1929 217758000 : if (do_tr &&
1930 87496800 : has_top_right(cm, xd, mi_row, mi_col, AOMMAX(xd->n4_w, xd->n4_h)))
1931 : {
1932 39393700 : Position trb_pos = { -1, xd->n4_w };
1933 39393700 : if (is_inside(tile, mi_col, mi_row, cm->mi_rows, &trb_pos)) {
1934 31681500 : int mi_row_offset = -1;
1935 31681500 : int mi_col_offset = xd->n4_w;
1936 31681500 : MbModeInfo *mbmi =
1937 31681500 : &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
1938 :
1939 31681500 : if (mbmi->block_mi.ref_frame[0] == rf[0] && mbmi->block_mi.ref_frame[1] == NONE_FRAME) {
1940 3235290 : np++;
1941 3235290 : if (np >= LEAST_SQUARES_SAMPLES_MAX) {
1942 16934 : *num_samples = LEAST_SQUARES_SAMPLES_MAX;
1943 16934 : return;
1944 : }
1945 : }
1946 : }
1947 : }
1948 130163000 : *num_samples = np;
1949 : }
1950 :
1951 6664970 : uint16_t wm_find_samples(
1952 : CodingUnit *cu_ptr,
1953 : const BlockGeom *blk_geom,
1954 : uint16_t cu_origin_x,
1955 : uint16_t cu_origin_y,
1956 : MvReferenceFrame rf0,
1957 : PictureControlSet *picture_control_set_ptr,
1958 : int32_t *pts,
1959 : int32_t *pts_inref)
1960 : {
1961 6664970 : Av1Common *cm = picture_control_set_ptr->parent_pcs_ptr->av1_cm;
1962 6664970 : MacroBlockD *xd = cu_ptr->av1xd;
1963 :
1964 6664970 : int32_t mi_row = cu_origin_y >> MI_SIZE_LOG2;
1965 6664970 : int32_t mi_col = cu_origin_x >> MI_SIZE_LOG2;
1966 :
1967 6664970 : xd->n4_w = blk_geom->bwidth >> MI_SIZE_LOG2;
1968 6664970 : xd->n4_h = blk_geom->bheight >> MI_SIZE_LOG2;
1969 :
1970 6664970 : return (uint16_t) av1_find_samples(cm, xd, mi_row, mi_col, rf0, pts, pts_inref);
1971 : }
1972 :
1973 6665240 : EbBool warped_motion_parameters(
1974 : PictureControlSet *picture_control_set_ptr,
1975 : CodingUnit *cu_ptr,
1976 : MvUnit *mv_unit,
1977 : const BlockGeom *blk_geom,
1978 : uint16_t cu_origin_x,
1979 : uint16_t cu_origin_y,
1980 : uint8_t ref_frame_type,
1981 : EbWarpedMotionParams *wm_params,
1982 : uint16_t *num_samples)
1983 : {
1984 6665240 : MacroBlockD *xd = cu_ptr->av1xd;
1985 6665240 : BlockSize bsize = blk_geom->bsize;
1986 6665240 : EbBool apply_wm = EB_FALSE;
1987 :
1988 : int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
1989 6665240 : int32_t mi_row = cu_origin_y >> MI_SIZE_LOG2;
1990 6665240 : int32_t mi_col = cu_origin_x >> MI_SIZE_LOG2;
1991 6665240 : xd->n4_w = blk_geom->bwidth >> MI_SIZE_LOG2;
1992 6665240 : xd->n4_h = blk_geom->bheight >> MI_SIZE_LOG2;
1993 :
1994 6665240 : *num_samples = 0;
1995 6665240 : if (blk_geom->bwidth < 8 || blk_geom->bheight < 8)
1996 40 : return apply_wm;
1997 :
1998 : MvReferenceFrame rf[2];
1999 6665200 : av1_set_ref_frame(rf, ref_frame_type);
2000 :
2001 6665010 : uint16_t nsamples = wm_find_samples(
2002 : cu_ptr,
2003 : blk_geom,
2004 : cu_origin_x,
2005 : cu_origin_y,
2006 6665010 : rf[0],
2007 : picture_control_set_ptr,
2008 : pts,
2009 : pts_inref);
2010 :
2011 6664470 : if(nsamples==0)
2012 5892680 : return apply_wm;
2013 :
2014 : MV mv;
2015 771789 : mv.col = mv_unit->mv[REF_LIST_0].x;
2016 771789 : mv.row = mv_unit->mv[REF_LIST_0].y;
2017 :
2018 771789 : if(nsamples > 1)
2019 532490 : nsamples = select_samples(&mv, pts, pts_inref, nsamples, bsize);
2020 771786 : *num_samples = nsamples;
2021 :
2022 1543550 : apply_wm = !eb_find_projection(
2023 : (int) nsamples,
2024 : pts,
2025 : pts_inref,
2026 : bsize,
2027 771786 : mv.row,
2028 771786 : mv.col,
2029 : wm_params,
2030 : (int) mi_row,
2031 : (int) mi_col);
2032 :
2033 771766 : return apply_wm;
2034 : }
2035 :
2036 : //foreach_overlappable_nb_above
2037 472544 : int count_overlappable_nb_above(
2038 : const Av1Common *cm,
2039 : MacroBlockD *xd,
2040 : int32_t mi_col,
2041 : int nb_max)
2042 : {
2043 472544 : int nb_count = 0;
2044 472544 : if (!xd->up_available)
2045 26338 : return nb_count;
2046 :
2047 : // prev_row_mi points into the mi array, starting at the beginning of the
2048 : // previous row.
2049 446206 : ModeInfo **prev_row_mi = xd->mi - mi_col - 1 * xd->mi_stride;
2050 446206 : const int end_col = MIN(mi_col + xd->n4_w, cm->mi_cols);
2051 : uint8_t mi_step;
2052 :
2053 915567 : for (int above_mi_col = mi_col; above_mi_col < end_col && nb_count < nb_max;
2054 469361 : above_mi_col += mi_step)
2055 : {
2056 469292 : ModeInfo **above_mi = prev_row_mi + above_mi_col;
2057 469292 : mi_step = MIN(mi_size_wide[above_mi[0]->mbmi.block_mi.sb_type], mi_size_wide[BLOCK_64X64]);
2058 :
2059 : // If we're considering a block with width 4, it should be treated as
2060 : // half of a pair of blocks with chroma information in the second. Move
2061 : // above_mi_col back to the start of the pair if needed, set above_mbmi
2062 : // to point at the block with chroma information, and set mi_step to 2 to
2063 : // step over the entire pair at the end of the iteration.
2064 469292 : if (mi_step == 1) {
2065 1425 : above_mi_col &= ~1;
2066 1425 : above_mi = prev_row_mi + above_mi_col + 1;
2067 1425 : mi_step = 2;
2068 : }
2069 469292 : if (is_neighbor_overlappable(&(*above_mi)->mbmi))
2070 463225 : ++nb_count;
2071 : }
2072 :
2073 446275 : return nb_count;
2074 : }
2075 :
2076 472651 : int count_overlappable_nb_left(
2077 : const Av1Common *cm,
2078 : MacroBlockD *xd,
2079 : int32_t mi_row,
2080 : int nb_max)
2081 : {
2082 472651 : int nb_count = 0;
2083 472651 : if (!xd->left_available)
2084 20673 : return nb_count;
2085 :
2086 : // prev_col_mi points into the mi array, starting at the top of the
2087 : // previous column
2088 451978 : ModeInfo **prev_col_mi = xd->mi - 1 - mi_row * xd->mi_stride;
2089 451978 : const int end_row = MIN(mi_row + xd->n4_h, cm->mi_rows);
2090 : uint8_t mi_step;
2091 :
2092 943198 : for (int left_mi_row = mi_row; left_mi_row < end_row && nb_count < nb_max;
2093 491220 : left_mi_row += mi_step)
2094 : {
2095 491224 : ModeInfo **left_mi = prev_col_mi + left_mi_row * xd->mi_stride;
2096 491224 : mi_step = MIN(mi_size_high[left_mi[0]->mbmi.block_mi.sb_type], mi_size_high[BLOCK_64X64]);
2097 491224 : if (mi_step == 1) {
2098 1594 : left_mi_row &= ~1;
2099 1594 : left_mi = prev_col_mi + (left_mi_row + 1) * xd->mi_stride;
2100 1594 : mi_step = 2;
2101 : }
2102 :
2103 491224 : if (is_neighbor_overlappable(&(*left_mi)->mbmi))
2104 485078 : ++nb_count;
2105 : }
2106 :
2107 451974 : return nb_count;
2108 : }
2109 :
2110 744995 : void eb_av1_count_overlappable_neighbors(
2111 : const PictureControlSet *picture_control_set_ptr,
2112 : CodingUnit *cu_ptr,
2113 : const BlockSize bsize,
2114 : int32_t mi_row,
2115 : int32_t mi_col)
2116 : {
2117 744995 : Av1Common *cm = picture_control_set_ptr->parent_pcs_ptr->av1_cm;
2118 744995 : MacroBlockD *xd = cu_ptr->av1xd;
2119 744995 : cu_ptr->prediction_unit_array[0].overlappable_neighbors[0] = 0;
2120 744995 : cu_ptr->prediction_unit_array[0].overlappable_neighbors[1] = 0;
2121 :
2122 744995 : if (!is_motion_variation_allowed_bsize(bsize))
2123 272471 : return;
2124 :
2125 472652 : cu_ptr->prediction_unit_array[0].overlappable_neighbors[0] =
2126 472550 : count_overlappable_nb_above(cm, xd, mi_col, MAX_SIGNED_VALUE);
2127 :
2128 472687 : cu_ptr->prediction_unit_array[0].overlappable_neighbors[1] =
2129 472652 : count_overlappable_nb_left(cm, xd, mi_row, MAX_SIGNED_VALUE);
2130 : }
2131 :
2132 0 : void av1_find_ref_dv(IntMv *ref_dv, const TileInfo *const tile,
2133 : int mib_size, int mi_row, int mi_col) {
2134 : (void)mi_col;
2135 0 : if (mi_row - mib_size < tile->mi_row_start) {
2136 0 : ref_dv->as_mv.row = 0;
2137 0 : ref_dv->as_mv.col = -MI_SIZE * mib_size - INTRABC_DELAY_PIXELS;
2138 : }
2139 : else {
2140 0 : ref_dv->as_mv.row = -MI_SIZE * mib_size;
2141 0 : ref_dv->as_mv.col = 0;
2142 : }
2143 0 : ref_dv->as_mv.row *= 8;
2144 0 : ref_dv->as_mv.col *= 8;
2145 0 : }
2146 :
2147 0 : int av1_is_dv_valid(const MV dv,
2148 : const MacroBlockD *xd, int mi_row, int mi_col,
2149 : BlockSize bsize, int mib_size_log2) {
2150 0 : const int bw = block_size_wide[bsize];
2151 0 : const int bh = block_size_high[bsize];
2152 0 : const int SCALE_PX_TO_MV = 8;
2153 : // Disallow subpixel for now
2154 : // SUBPEL_MASK is not the correct scale
2155 0 : if (((dv.row & (SCALE_PX_TO_MV - 1)) || (dv.col & (SCALE_PX_TO_MV - 1))))
2156 0 : return 0;
2157 :
2158 0 : const TileInfo *const tile = &xd->tile;
2159 : // Is the source top-left inside the current tile?
2160 0 : const int src_top_edge = mi_row * MI_SIZE * SCALE_PX_TO_MV + dv.row;
2161 0 : const int tile_top_edge = tile->mi_row_start * MI_SIZE * SCALE_PX_TO_MV;
2162 0 : if (src_top_edge < tile_top_edge) return 0;
2163 0 : const int src_left_edge = mi_col * MI_SIZE * SCALE_PX_TO_MV + dv.col;
2164 0 : const int tile_left_edge = tile->mi_col_start * MI_SIZE * SCALE_PX_TO_MV;
2165 0 : if (src_left_edge < tile_left_edge) return 0;
2166 : // Is the bottom right inside the current tile?
2167 0 : const int src_bottom_edge = (mi_row * MI_SIZE + bh) * SCALE_PX_TO_MV + dv.row;
2168 0 : const int tile_bottom_edge = tile->mi_row_end * MI_SIZE * SCALE_PX_TO_MV;
2169 0 : if (src_bottom_edge > tile_bottom_edge) return 0;
2170 0 : const int src_right_edge = (mi_col * MI_SIZE + bw) * SCALE_PX_TO_MV + dv.col;
2171 0 : const int tile_right_edge = tile->mi_col_end * MI_SIZE * SCALE_PX_TO_MV;
2172 0 : if (src_right_edge > tile_right_edge) return 0;
2173 :
2174 : // Special case for sub 8x8 chroma cases, to prevent referring to chroma
2175 : // pixels outside current tile.
2176 0 : for (int plane = 1; plane < 3/* av1_num_planes(cm)*/; ++plane) {
2177 : //const struct MacroBlockDPlane *const pd = &xd->plane[plane];
2178 :
2179 0 : if (is_chroma_reference(mi_row, mi_col, bsize, 1, 1/* pd->subsampling_x,
2180 : pd->subsampling_y*/)) {
2181 0 : if (bw < 8 /*&& pd->subsampling_x*/)
2182 0 : if (src_left_edge < tile_left_edge + 4 * SCALE_PX_TO_MV) return 0;
2183 0 : if (bh < 8/* && pd->subsampling_y*/)
2184 0 : if (src_top_edge < tile_top_edge + 4 * SCALE_PX_TO_MV) return 0;
2185 : }
2186 : }
2187 :
2188 : // Is the bottom right within an already coded SB? Also consider additional
2189 : // constraints to facilitate HW decoder.
2190 0 : const int max_mib_size = 1 << mib_size_log2;
2191 0 : const int active_sb_row = mi_row >> mib_size_log2;
2192 0 : const int active_sb64_col = (mi_col * MI_SIZE) >> 6;
2193 0 : const int sb_size = max_mib_size * MI_SIZE;
2194 0 : const int src_sb_row = ((src_bottom_edge >> 3) - 1) / sb_size;
2195 0 : const int src_sb64_col = ((src_right_edge >> 3) - 1) >> 6;
2196 0 : const int total_sb64_per_row =
2197 0 : ((tile->mi_col_end - tile->mi_col_start - 1) >> 4) + 1;
2198 0 : const int active_sb64 = active_sb_row * total_sb64_per_row + active_sb64_col;
2199 0 : const int src_sb64 = src_sb_row * total_sb64_per_row + src_sb64_col;
2200 0 : if (src_sb64 >= active_sb64 - INTRABC_DELAY_SB64) return 0;
2201 :
2202 : // Wavefront constraint: use only top left area of frame for reference.
2203 0 : const int gradient = 1 + INTRABC_DELAY_SB64 + (sb_size > 64);
2204 0 : const int wf_offset = gradient * (active_sb_row - src_sb_row);
2205 0 : if (src_sb_row > active_sb_row ||
2206 0 : src_sb64_col >= active_sb64_col - INTRABC_DELAY_SB64 + wf_offset)
2207 0 : return 0;
2208 :
2209 : //add a SW-Wavefront constraint
2210 0 : if (sb_size == 64)
2211 : {
2212 0 : if (src_sb64_col > active_sb64_col + (active_sb_row - src_sb_row))
2213 0 : return 0;
2214 : }
2215 : else
2216 : {
2217 0 : const int src_sb128_col = ((src_right_edge >> 3) - 1) >> 7;
2218 0 : const int active_sb128_col = (mi_col * MI_SIZE) >> 7;
2219 :
2220 0 : if (src_sb128_col > active_sb128_col + (active_sb_row - src_sb_row))
2221 0 : return 0;
2222 : }
2223 :
2224 0 : return 1;
2225 : }
2226 :
2227 0 : int is_inside_tile_boundary(TileInfo *tile, int16_t mvx, int16_t mvy, int mi_col, int mi_row, BlockSize bsize)
2228 : {
2229 0 : const int bw = block_size_wide[bsize];
2230 0 : const int bh = block_size_high[bsize];
2231 0 : const int SCALE_PX_TO_MV = 8;
2232 0 : const int src_top_edge = mi_row * MI_SIZE * SCALE_PX_TO_MV + mvy;
2233 0 : const int tile_top_edge = tile->mi_row_start * MI_SIZE * SCALE_PX_TO_MV;
2234 0 : if (src_top_edge < tile_top_edge)
2235 0 : return 0;
2236 0 : const int src_left_edge = mi_col * MI_SIZE * SCALE_PX_TO_MV + mvx;
2237 0 : const int tile_left_edge = tile->mi_col_start * MI_SIZE * SCALE_PX_TO_MV;
2238 0 : if (src_left_edge < tile_left_edge)
2239 0 : return 0;
2240 : // Is the bottom right inside the current tile?
2241 0 : const int src_bottom_edge = (mi_row * MI_SIZE + bh) * SCALE_PX_TO_MV + mvy;
2242 0 : const int tile_bottom_edge = tile->mi_row_end * MI_SIZE * SCALE_PX_TO_MV;
2243 0 : if (src_bottom_edge > tile_bottom_edge)
2244 0 : return 0;
2245 0 : const int src_right_edge = (mi_col * MI_SIZE + bw) * SCALE_PX_TO_MV + mvx;
2246 0 : const int tile_right_edge = tile->mi_col_end * MI_SIZE * SCALE_PX_TO_MV;
2247 0 : if (src_right_edge > tile_right_edge)
2248 0 : return 0;
2249 :
2250 0 : return 1;
2251 : }
2252 :
2253 0 : IntMv eb_av1_get_ref_mv_from_stack(int ref_idx,
2254 : const MvReferenceFrame *ref_frame,
2255 : int ref_mv_idx,
2256 : CandidateMv ref_mv_stack[][MAX_REF_MV_STACK_SIZE],
2257 : MacroBlockD * xd
2258 : /*const MB_MODE_INFO_EXT *mbmi_ext*/) {
2259 0 : const int8_t ref_frame_type = av1_ref_frame_type(ref_frame);
2260 0 : const CandidateMv *curr_ref_mv_stack =
2261 0 : /*mbmi_ext->*/ref_mv_stack[ref_frame_type];
2262 : IntMv ref_mv;
2263 0 : ref_mv.as_int = INVALID_MV;
2264 :
2265 0 : if (ref_frame[1] > INTRA_FRAME) {
2266 0 : if (ref_idx == 0)
2267 0 : ref_mv = curr_ref_mv_stack[ref_mv_idx].this_mv;
2268 : else {
2269 0 : assert(ref_idx == 1);
2270 0 : ref_mv = curr_ref_mv_stack[ref_mv_idx].comp_mv;
2271 : }
2272 : }
2273 : else {
2274 0 : assert(ref_idx == 0);
2275 0 : if (ref_mv_idx < /*mbmi_ext->*/xd->ref_mv_count[ref_frame_type])
2276 0 : ref_mv = curr_ref_mv_stack[ref_mv_idx].this_mv;
2277 : else {
2278 : //CHKN got this from decoder read_intrabc_info global_mvs[ref_frame].as_int = INVALID_MV;
2279 0 : ref_mv.as_int = INVALID_MV;// mbmi_ext->global_mvs[ref_frame_type];
2280 : }
2281 : }
2282 0 : return ref_mv;
2283 : }
2284 :
2285 0 : void eb_av1_find_best_ref_mvs_from_stack(int allow_hp,
2286 : //const MB_MODE_INFO_EXT *mbmi_ext,
2287 : CandidateMv ref_mv_stack[][MAX_REF_MV_STACK_SIZE],
2288 : MacroBlockD * xd,
2289 : MvReferenceFrame ref_frame,
2290 : IntMv *nearest_mv, IntMv *near_mv,
2291 : int is_integer)
2292 : {
2293 0 : const int ref_idx = 0;
2294 0 : MvReferenceFrame ref_frames[2] = { ref_frame, NONE_FRAME };
2295 0 : *nearest_mv = eb_av1_get_ref_mv_from_stack(ref_idx, ref_frames, 0, ref_mv_stack/*mbmi_ext*/, xd);
2296 0 : lower_mv_precision(&nearest_mv->as_mv, allow_hp, is_integer);
2297 0 : *near_mv = eb_av1_get_ref_mv_from_stack(ref_idx, ref_frames, 1, ref_mv_stack/*mbmi_ext*/, xd);
2298 0 : lower_mv_precision(&near_mv->as_mv, allow_hp, is_integer);
2299 0 : }
|