1 /*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12 #include <assert.h>
13 #include <stdio.h>
14 #include <limits.h>
15
16 #include "config/aom_config.h"
17 #include "config/aom_dsp_rtcd.h"
18 #include "config/aom_scale_rtcd.h"
19
20 #include "aom/aom_integer.h"
21 #include "aom_dsp/blend.h"
22
23 #include "av1/common/blockd.h"
24 #include "av1/common/mvref_common.h"
25 #include "av1/common/reconinter.h"
26 #include "av1/common/reconintra.h"
27 #include "av1/common/onyxc_int.h"
28 #include "av1/common/obmc.h"
29 #include "av1/encoder/reconinter_enc.h"
30
calc_subpel_params(MACROBLOCKD * xd,const struct scale_factors * const sf,const MV mv,int plane,const int pre_x,const int pre_y,int x,int y,struct buf_2d * const pre_buf,uint8_t ** pre,SubpelParams * subpel_params,int bw,int bh)31 static INLINE void calc_subpel_params(
32 MACROBLOCKD *xd, const struct scale_factors *const sf, const MV mv,
33 int plane, const int pre_x, const int pre_y, int x, int y,
34 struct buf_2d *const pre_buf, uint8_t **pre, SubpelParams *subpel_params,
35 int bw, int bh) {
36 struct macroblockd_plane *const pd = &xd->plane[plane];
37 const int is_scaled = av1_is_scaled(sf);
38 if (is_scaled) {
39 int ssx = pd->subsampling_x;
40 int ssy = pd->subsampling_y;
41 int orig_pos_y = (pre_y + y) << SUBPEL_BITS;
42 orig_pos_y += mv.row * (1 << (1 - ssy));
43 int orig_pos_x = (pre_x + x) << SUBPEL_BITS;
44 orig_pos_x += mv.col * (1 << (1 - ssx));
45 int pos_y = sf->scale_value_y(orig_pos_y, sf);
46 int pos_x = sf->scale_value_x(orig_pos_x, sf);
47 pos_x += SCALE_EXTRA_OFF;
48 pos_y += SCALE_EXTRA_OFF;
49
50 const int top = -AOM_LEFT_TOP_MARGIN_SCALED(ssy);
51 const int left = -AOM_LEFT_TOP_MARGIN_SCALED(ssx);
52 const int bottom = (pre_buf->height + AOM_INTERP_EXTEND)
53 << SCALE_SUBPEL_BITS;
54 const int right = (pre_buf->width + AOM_INTERP_EXTEND) << SCALE_SUBPEL_BITS;
55 pos_y = clamp(pos_y, top, bottom);
56 pos_x = clamp(pos_x, left, right);
57
58 *pre = pre_buf->buf0 + (pos_y >> SCALE_SUBPEL_BITS) * pre_buf->stride +
59 (pos_x >> SCALE_SUBPEL_BITS);
60 subpel_params->subpel_x = pos_x & SCALE_SUBPEL_MASK;
61 subpel_params->subpel_y = pos_y & SCALE_SUBPEL_MASK;
62 subpel_params->xs = sf->x_step_q4;
63 subpel_params->ys = sf->y_step_q4;
64 } else {
65 const MV mv_q4 = clamp_mv_to_umv_border_sb(
66 xd, &mv, bw, bh, pd->subsampling_x, pd->subsampling_y);
67 subpel_params->xs = subpel_params->ys = SCALE_SUBPEL_SHIFTS;
68 subpel_params->subpel_x = (mv_q4.col & SUBPEL_MASK) << SCALE_EXTRA_BITS;
69 subpel_params->subpel_y = (mv_q4.row & SUBPEL_MASK) << SCALE_EXTRA_BITS;
70 *pre = pre_buf->buf + (y + (mv_q4.row >> SUBPEL_BITS)) * pre_buf->stride +
71 (x + (mv_q4.col >> SUBPEL_BITS));
72 }
73 }
74
build_inter_predictors(const AV1_COMMON * cm,MACROBLOCKD * xd,int plane,const MB_MODE_INFO * mi,int build_for_obmc,int bw,int bh,int mi_x,int mi_y)75 static INLINE void build_inter_predictors(const AV1_COMMON *cm, MACROBLOCKD *xd,
76 int plane, const MB_MODE_INFO *mi,
77 int build_for_obmc, int bw, int bh,
78 int mi_x, int mi_y) {
79 struct macroblockd_plane *const pd = &xd->plane[plane];
80 int is_compound = has_second_ref(mi);
81 int ref;
82 const int is_intrabc = is_intrabc_block(mi);
83 assert(IMPLIES(is_intrabc, !is_compound));
84 int is_global[2] = { 0, 0 };
85 for (ref = 0; ref < 1 + is_compound; ++ref) {
86 const WarpedMotionParams *const wm = &xd->global_motion[mi->ref_frame[ref]];
87 is_global[ref] = is_global_mv_block(mi, wm->wmtype);
88 }
89
90 const BLOCK_SIZE bsize = mi->sb_type;
91 const int ss_x = pd->subsampling_x;
92 const int ss_y = pd->subsampling_y;
93 int sub8x8_inter = (block_size_wide[bsize] < 8 && ss_x) ||
94 (block_size_high[bsize] < 8 && ss_y);
95
96 if (is_intrabc) sub8x8_inter = 0;
97
98 // For sub8x8 chroma blocks, we may be covering more than one luma block's
99 // worth of pixels. Thus (mi_x, mi_y) may not be the correct coordinates for
100 // the top-left corner of the prediction source - the correct top-left corner
101 // is at (pre_x, pre_y).
102 const int row_start =
103 (block_size_high[bsize] == 4) && ss_y && !build_for_obmc ? -1 : 0;
104 const int col_start =
105 (block_size_wide[bsize] == 4) && ss_x && !build_for_obmc ? -1 : 0;
106 const int pre_x = (mi_x + MI_SIZE * col_start) >> ss_x;
107 const int pre_y = (mi_y + MI_SIZE * row_start) >> ss_y;
108
109 sub8x8_inter = sub8x8_inter && !build_for_obmc;
110 if (sub8x8_inter) {
111 for (int row = row_start; row <= 0 && sub8x8_inter; ++row) {
112 for (int col = col_start; col <= 0; ++col) {
113 const MB_MODE_INFO *this_mbmi = xd->mi[row * xd->mi_stride + col];
114 if (!is_inter_block(this_mbmi)) sub8x8_inter = 0;
115 if (is_intrabc_block(this_mbmi)) sub8x8_inter = 0;
116 }
117 }
118 }
119
120 if (sub8x8_inter) {
121 // block size
122 const int b4_w = block_size_wide[bsize] >> ss_x;
123 const int b4_h = block_size_high[bsize] >> ss_y;
124 const BLOCK_SIZE plane_bsize = scale_chroma_bsize(bsize, ss_x, ss_y);
125 const int b8_w = block_size_wide[plane_bsize] >> ss_x;
126 const int b8_h = block_size_high[plane_bsize] >> ss_y;
127 assert(!is_compound);
128
129 const struct buf_2d orig_pred_buf[2] = { pd->pre[0], pd->pre[1] };
130
131 int row = row_start;
132 for (int y = 0; y < b8_h; y += b4_h) {
133 int col = col_start;
134 for (int x = 0; x < b8_w; x += b4_w) {
135 MB_MODE_INFO *this_mbmi = xd->mi[row * xd->mi_stride + col];
136 is_compound = has_second_ref(this_mbmi);
137 int tmp_dst_stride = 8;
138 assert(bw < 8 || bh < 8);
139 ConvolveParams conv_params = get_conv_params_no_round(
140 0, plane, xd->tmp_conv_dst, tmp_dst_stride, is_compound, xd->bd);
141 conv_params.use_dist_wtd_comp_avg = 0;
142 struct buf_2d *const dst_buf = &pd->dst;
143 uint8_t *dst = dst_buf->buf + dst_buf->stride * y + x;
144
145 ref = 0;
146 const RefCntBuffer *ref_buf =
147 get_ref_frame_buf(cm, this_mbmi->ref_frame[ref]);
148 const struct scale_factors *ref_scale_factors =
149 get_ref_scale_factors_const(cm, this_mbmi->ref_frame[ref]);
150
151 pd->pre[ref].buf0 =
152 (plane == 1) ? ref_buf->buf.u_buffer : ref_buf->buf.v_buffer;
153 pd->pre[ref].buf =
154 pd->pre[ref].buf0 + scaled_buffer_offset(pre_x, pre_y,
155 ref_buf->buf.uv_stride,
156 ref_scale_factors);
157 pd->pre[ref].width = ref_buf->buf.uv_crop_width;
158 pd->pre[ref].height = ref_buf->buf.uv_crop_height;
159 pd->pre[ref].stride = ref_buf->buf.uv_stride;
160
161 const struct scale_factors *const sf =
162 is_intrabc ? &cm->sf_identity : ref_scale_factors;
163 struct buf_2d *const pre_buf = is_intrabc ? dst_buf : &pd->pre[ref];
164
165 const MV mv = this_mbmi->mv[ref].as_mv;
166
167 uint8_t *pre;
168 SubpelParams subpel_params;
169 WarpTypesAllowed warp_types;
170 warp_types.global_warp_allowed = is_global[ref];
171 warp_types.local_warp_allowed = this_mbmi->motion_mode == WARPED_CAUSAL;
172
173 calc_subpel_params(xd, sf, mv, plane, pre_x, pre_y, x, y, pre_buf, &pre,
174 &subpel_params, bw, bh);
175 conv_params.do_average = ref;
176 if (is_masked_compound_type(mi->interinter_comp.type)) {
177 // masked compound type has its own average mechanism
178 conv_params.do_average = 0;
179 }
180
181 av1_make_inter_predictor(
182 pre, pre_buf->stride, dst, dst_buf->stride, &subpel_params, sf,
183 b4_w, b4_h, &conv_params, this_mbmi->interp_filters, &warp_types,
184 (mi_x >> pd->subsampling_x) + x, (mi_y >> pd->subsampling_y) + y,
185 plane, ref, mi, build_for_obmc, xd, cm->allow_warped_motion);
186
187 ++col;
188 }
189 ++row;
190 }
191
192 for (ref = 0; ref < 2; ++ref) pd->pre[ref] = orig_pred_buf[ref];
193 return;
194 }
195
196 {
197 ConvolveParams conv_params = get_conv_params_no_round(
198 0, plane, xd->tmp_conv_dst, MAX_SB_SIZE, is_compound, xd->bd);
199 av1_dist_wtd_comp_weight_assign(
200 cm, mi, 0, &conv_params.fwd_offset, &conv_params.bck_offset,
201 &conv_params.use_dist_wtd_comp_avg, is_compound);
202
203 struct buf_2d *const dst_buf = &pd->dst;
204 uint8_t *const dst = dst_buf->buf;
205 for (ref = 0; ref < 1 + is_compound; ++ref) {
206 const struct scale_factors *const sf =
207 is_intrabc ? &cm->sf_identity : xd->block_ref_scale_factors[ref];
208 struct buf_2d *const pre_buf = is_intrabc ? dst_buf : &pd->pre[ref];
209 const MV mv = mi->mv[ref].as_mv;
210
211 uint8_t *pre;
212 SubpelParams subpel_params;
213 calc_subpel_params(xd, sf, mv, plane, pre_x, pre_y, 0, 0, pre_buf, &pre,
214 &subpel_params, bw, bh);
215
216 WarpTypesAllowed warp_types;
217 warp_types.global_warp_allowed = is_global[ref];
218 warp_types.local_warp_allowed = mi->motion_mode == WARPED_CAUSAL;
219
220 if (ref && is_masked_compound_type(mi->interinter_comp.type)) {
221 // masked compound type has its own average mechanism
222 conv_params.do_average = 0;
223 av1_make_masked_inter_predictor(
224 pre, pre_buf->stride, dst, dst_buf->stride, &subpel_params, sf, bw,
225 bh, &conv_params, mi->interp_filters, plane, &warp_types,
226 mi_x >> pd->subsampling_x, mi_y >> pd->subsampling_y, ref, xd,
227 cm->allow_warped_motion);
228 } else {
229 conv_params.do_average = ref;
230 av1_make_inter_predictor(
231 pre, pre_buf->stride, dst, dst_buf->stride, &subpel_params, sf, bw,
232 bh, &conv_params, mi->interp_filters, &warp_types,
233 mi_x >> pd->subsampling_x, mi_y >> pd->subsampling_y, plane, ref,
234 mi, build_for_obmc, xd, cm->allow_warped_motion);
235 }
236 }
237 }
238 }
239
build_inter_predictors_for_plane(const AV1_COMMON * cm,MACROBLOCKD * xd,int mi_row,int mi_col,const BUFFER_SET * ctx,BLOCK_SIZE bsize,int plane_idx)240 static void build_inter_predictors_for_plane(const AV1_COMMON *cm,
241 MACROBLOCKD *xd, int mi_row,
242 int mi_col, const BUFFER_SET *ctx,
243 BLOCK_SIZE bsize, int plane_idx) {
244 const struct macroblockd_plane *pd = &xd->plane[plane_idx];
245 if (!is_chroma_reference(mi_row, mi_col, bsize, pd->subsampling_x,
246 pd->subsampling_y))
247 return;
248
249 const int mi_x = mi_col * MI_SIZE;
250 const int mi_y = mi_row * MI_SIZE;
251 build_inter_predictors(cm, xd, plane_idx, xd->mi[0], 0, pd->width, pd->height,
252 mi_x, mi_y);
253
254 if (is_interintra_pred(xd->mi[0])) {
255 BUFFER_SET default_ctx = { { NULL, NULL, NULL }, { 0, 0, 0 } };
256 if (!ctx) {
257 default_ctx.plane[plane_idx] = xd->plane[plane_idx].dst.buf;
258 default_ctx.stride[plane_idx] = xd->plane[plane_idx].dst.stride;
259 ctx = &default_ctx;
260 }
261 av1_build_interintra_predictors_sbp(cm, xd, xd->plane[plane_idx].dst.buf,
262 xd->plane[plane_idx].dst.stride, ctx,
263 plane_idx, bsize);
264 }
265 }
266
av1_enc_build_inter_predictor(const AV1_COMMON * cm,MACROBLOCKD * xd,int mi_row,int mi_col,const BUFFER_SET * ctx,BLOCK_SIZE bsize,int plane_from,int plane_to)267 void av1_enc_build_inter_predictor(const AV1_COMMON *cm, MACROBLOCKD *xd,
268 int mi_row, int mi_col,
269 const BUFFER_SET *ctx, BLOCK_SIZE bsize,
270 int plane_from, int plane_to) {
271 for (int plane_idx = plane_from; plane_idx <= plane_to; ++plane_idx) {
272 build_inter_predictors_for_plane(cm, xd, mi_row, mi_col, ctx, bsize,
273 plane_idx);
274 }
275 }
276
277 // TODO(sarahparker):
278 // av1_build_inter_predictor should be combined with
279 // av1_make_inter_predictor
av1_build_inter_predictor(const uint8_t * src,int src_stride,uint8_t * dst,int dst_stride,const MV * src_mv,const struct scale_factors * sf,int w,int h,ConvolveParams * conv_params,InterpFilters interp_filters,const WarpTypesAllowed * warp_types,int p_col,int p_row,int plane,int ref,mv_precision precision,int x,int y,const MACROBLOCKD * xd,int can_use_previous)280 void av1_build_inter_predictor(const uint8_t *src, int src_stride, uint8_t *dst,
281 int dst_stride, const MV *src_mv,
282 const struct scale_factors *sf, int w, int h,
283 ConvolveParams *conv_params,
284 InterpFilters interp_filters,
285 const WarpTypesAllowed *warp_types, int p_col,
286 int p_row, int plane, int ref,
287 mv_precision precision, int x, int y,
288 const MACROBLOCKD *xd, int can_use_previous) {
289 const int is_q4 = precision == MV_PRECISION_Q4;
290 const MV mv_q4 = { is_q4 ? src_mv->row : src_mv->row * 2,
291 is_q4 ? src_mv->col : src_mv->col * 2 };
292 MV32 mv = av1_scale_mv(&mv_q4, x, y, sf);
293 mv.col += SCALE_EXTRA_OFF;
294 mv.row += SCALE_EXTRA_OFF;
295
296 const SubpelParams subpel_params = { sf->x_step_q4, sf->y_step_q4,
297 mv.col & SCALE_SUBPEL_MASK,
298 mv.row & SCALE_SUBPEL_MASK };
299 src += (mv.row >> SCALE_SUBPEL_BITS) * src_stride +
300 (mv.col >> SCALE_SUBPEL_BITS);
301
302 av1_make_inter_predictor(src, src_stride, dst, dst_stride, &subpel_params, sf,
303 w, h, conv_params, interp_filters, warp_types, p_col,
304 p_row, plane, ref, xd->mi[0], 0, xd,
305 can_use_previous);
306 }
307
build_prediction_by_above_pred(MACROBLOCKD * xd,int rel_mi_col,uint8_t above_mi_width,MB_MODE_INFO * above_mbmi,void * fun_ctxt,const int num_planes)308 static INLINE void build_prediction_by_above_pred(
309 MACROBLOCKD *xd, int rel_mi_col, uint8_t above_mi_width,
310 MB_MODE_INFO *above_mbmi, void *fun_ctxt, const int num_planes) {
311 struct build_prediction_ctxt *ctxt = (struct build_prediction_ctxt *)fun_ctxt;
312 const int above_mi_col = ctxt->mi_col + rel_mi_col;
313 int mi_x, mi_y;
314 MB_MODE_INFO backup_mbmi = *above_mbmi;
315
316 av1_setup_build_prediction_by_above_pred(xd, rel_mi_col, above_mi_width,
317 &backup_mbmi, ctxt, num_planes);
318 mi_x = above_mi_col << MI_SIZE_LOG2;
319 mi_y = ctxt->mi_row << MI_SIZE_LOG2;
320
321 const BLOCK_SIZE bsize = xd->mi[0]->sb_type;
322
323 for (int j = 0; j < num_planes; ++j) {
324 const struct macroblockd_plane *pd = &xd->plane[j];
325 int bw = (above_mi_width * MI_SIZE) >> pd->subsampling_x;
326 int bh = clamp(block_size_high[bsize] >> (pd->subsampling_y + 1), 4,
327 block_size_high[BLOCK_64X64] >> (pd->subsampling_y + 1));
328
329 if (av1_skip_u4x4_pred_in_obmc(bsize, pd, 0)) continue;
330 build_inter_predictors(ctxt->cm, xd, j, &backup_mbmi, 1, bw, bh, mi_x,
331 mi_y);
332 }
333 }
334
av1_build_prediction_by_above_preds(const AV1_COMMON * cm,MACROBLOCKD * xd,int mi_row,int mi_col,uint8_t * tmp_buf[MAX_MB_PLANE],int tmp_width[MAX_MB_PLANE],int tmp_height[MAX_MB_PLANE],int tmp_stride[MAX_MB_PLANE])335 void av1_build_prediction_by_above_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
336 int mi_row, int mi_col,
337 uint8_t *tmp_buf[MAX_MB_PLANE],
338 int tmp_width[MAX_MB_PLANE],
339 int tmp_height[MAX_MB_PLANE],
340 int tmp_stride[MAX_MB_PLANE]) {
341 if (!xd->up_available) return;
342
343 // Adjust mb_to_bottom_edge to have the correct value for the OBMC
344 // prediction block. This is half the height of the original block,
345 // except for 128-wide blocks, where we only use a height of 32.
346 int this_height = xd->n4_h * MI_SIZE;
347 int pred_height = AOMMIN(this_height / 2, 32);
348 xd->mb_to_bottom_edge += (this_height - pred_height) * 8;
349
350 struct build_prediction_ctxt ctxt = { cm, mi_row,
351 mi_col, tmp_buf,
352 tmp_width, tmp_height,
353 tmp_stride, xd->mb_to_right_edge };
354 BLOCK_SIZE bsize = xd->mi[0]->sb_type;
355 foreach_overlappable_nb_above(cm, xd, mi_col,
356 max_neighbor_obmc[mi_size_wide_log2[bsize]],
357 build_prediction_by_above_pred, &ctxt);
358
359 xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8);
360 xd->mb_to_right_edge = ctxt.mb_to_far_edge;
361 xd->mb_to_bottom_edge -= (this_height - pred_height) * 8;
362 }
363
build_prediction_by_left_pred(MACROBLOCKD * xd,int rel_mi_row,uint8_t left_mi_height,MB_MODE_INFO * left_mbmi,void * fun_ctxt,const int num_planes)364 static INLINE void build_prediction_by_left_pred(
365 MACROBLOCKD *xd, int rel_mi_row, uint8_t left_mi_height,
366 MB_MODE_INFO *left_mbmi, void *fun_ctxt, const int num_planes) {
367 struct build_prediction_ctxt *ctxt = (struct build_prediction_ctxt *)fun_ctxt;
368 const int left_mi_row = ctxt->mi_row + rel_mi_row;
369 int mi_x, mi_y;
370 MB_MODE_INFO backup_mbmi = *left_mbmi;
371
372 av1_setup_build_prediction_by_left_pred(xd, rel_mi_row, left_mi_height,
373 &backup_mbmi, ctxt, num_planes);
374 mi_x = ctxt->mi_col << MI_SIZE_LOG2;
375 mi_y = left_mi_row << MI_SIZE_LOG2;
376 const BLOCK_SIZE bsize = xd->mi[0]->sb_type;
377
378 for (int j = 0; j < num_planes; ++j) {
379 const struct macroblockd_plane *pd = &xd->plane[j];
380 int bw = clamp(block_size_wide[bsize] >> (pd->subsampling_x + 1), 4,
381 block_size_wide[BLOCK_64X64] >> (pd->subsampling_x + 1));
382 int bh = (left_mi_height << MI_SIZE_LOG2) >> pd->subsampling_y;
383
384 if (av1_skip_u4x4_pred_in_obmc(bsize, pd, 1)) continue;
385 build_inter_predictors(ctxt->cm, xd, j, &backup_mbmi, 1, bw, bh, mi_x,
386 mi_y);
387 }
388 }
389
av1_build_prediction_by_left_preds(const AV1_COMMON * cm,MACROBLOCKD * xd,int mi_row,int mi_col,uint8_t * tmp_buf[MAX_MB_PLANE],int tmp_width[MAX_MB_PLANE],int tmp_height[MAX_MB_PLANE],int tmp_stride[MAX_MB_PLANE])390 void av1_build_prediction_by_left_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
391 int mi_row, int mi_col,
392 uint8_t *tmp_buf[MAX_MB_PLANE],
393 int tmp_width[MAX_MB_PLANE],
394 int tmp_height[MAX_MB_PLANE],
395 int tmp_stride[MAX_MB_PLANE]) {
396 if (!xd->left_available) return;
397
398 // Adjust mb_to_right_edge to have the correct value for the OBMC
399 // prediction block. This is half the width of the original block,
400 // except for 128-wide blocks, where we only use a width of 32.
401 int this_width = xd->n4_w * MI_SIZE;
402 int pred_width = AOMMIN(this_width / 2, 32);
403 xd->mb_to_right_edge += (this_width - pred_width) * 8;
404
405 struct build_prediction_ctxt ctxt = { cm, mi_row,
406 mi_col, tmp_buf,
407 tmp_width, tmp_height,
408 tmp_stride, xd->mb_to_bottom_edge };
409 BLOCK_SIZE bsize = xd->mi[0]->sb_type;
410 foreach_overlappable_nb_left(cm, xd, mi_row,
411 max_neighbor_obmc[mi_size_high_log2[bsize]],
412 build_prediction_by_left_pred, &ctxt);
413
414 xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8);
415 xd->mb_to_right_edge -= (this_width - pred_width) * 8;
416 xd->mb_to_bottom_edge = ctxt.mb_to_far_edge;
417 }
418
av1_build_obmc_inter_predictors_sb(const AV1_COMMON * cm,MACROBLOCKD * xd,int mi_row,int mi_col)419 void av1_build_obmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
420 int mi_row, int mi_col) {
421 const int num_planes = av1_num_planes(cm);
422 uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
423 int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
424 int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
425 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
426 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
427 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
428 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
429
430 if (is_cur_buf_hbd(xd)) {
431 int len = sizeof(uint16_t);
432 dst_buf1[0] = CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[0]);
433 dst_buf1[1] =
434 CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[0] + MAX_SB_SQUARE * len);
435 dst_buf1[2] =
436 CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[0] + MAX_SB_SQUARE * 2 * len);
437 dst_buf2[0] = CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[1]);
438 dst_buf2[1] =
439 CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[1] + MAX_SB_SQUARE * len);
440 dst_buf2[2] =
441 CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[1] + MAX_SB_SQUARE * 2 * len);
442 } else {
443 dst_buf1[0] = xd->tmp_obmc_bufs[0];
444 dst_buf1[1] = xd->tmp_obmc_bufs[0] + MAX_SB_SQUARE;
445 dst_buf1[2] = xd->tmp_obmc_bufs[0] + MAX_SB_SQUARE * 2;
446 dst_buf2[0] = xd->tmp_obmc_bufs[1];
447 dst_buf2[1] = xd->tmp_obmc_bufs[1] + MAX_SB_SQUARE;
448 dst_buf2[2] = xd->tmp_obmc_bufs[1] + MAX_SB_SQUARE * 2;
449 }
450 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col, dst_buf1,
451 dst_width1, dst_height1, dst_stride1);
452 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col, dst_buf2,
453 dst_width2, dst_height2, dst_stride2);
454 av1_setup_dst_planes(xd->plane, xd->mi[0]->sb_type, &cm->cur_frame->buf,
455 mi_row, mi_col, 0, num_planes);
456 av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, dst_buf1, dst_stride1,
457 dst_buf2, dst_stride2);
458 }
459
460 // Builds the inter-predictor for the single ref case
461 // for use in the encoder to search the wedges efficiently.
build_inter_predictors_single_buf(MACROBLOCKD * xd,int plane,int bw,int bh,int x,int y,int w,int h,int mi_x,int mi_y,int ref,uint8_t * const ext_dst,int ext_dst_stride,int can_use_previous)462 static void build_inter_predictors_single_buf(MACROBLOCKD *xd, int plane,
463 int bw, int bh, int x, int y,
464 int w, int h, int mi_x, int mi_y,
465 int ref, uint8_t *const ext_dst,
466 int ext_dst_stride,
467 int can_use_previous) {
468 struct macroblockd_plane *const pd = &xd->plane[plane];
469 const MB_MODE_INFO *mi = xd->mi[0];
470
471 const struct scale_factors *const sf = xd->block_ref_scale_factors[ref];
472 struct buf_2d *const pre_buf = &pd->pre[ref];
473 uint8_t *const dst = get_buf_by_bd(xd, ext_dst) + ext_dst_stride * y + x;
474 const MV mv = mi->mv[ref].as_mv;
475
476 ConvolveParams conv_params = get_conv_params(0, plane, xd->bd);
477 WarpTypesAllowed warp_types;
478 const WarpedMotionParams *const wm = &xd->global_motion[mi->ref_frame[ref]];
479 warp_types.global_warp_allowed = is_global_mv_block(mi, wm->wmtype);
480 warp_types.local_warp_allowed = mi->motion_mode == WARPED_CAUSAL;
481 const int pre_x = (mi_x) >> pd->subsampling_x;
482 const int pre_y = (mi_y) >> pd->subsampling_y;
483 uint8_t *pre;
484 SubpelParams subpel_params;
485 calc_subpel_params(xd, sf, mv, plane, pre_x, pre_y, x, y, pre_buf, &pre,
486 &subpel_params, bw, bh);
487
488 av1_make_inter_predictor(pre, pre_buf->stride, dst, ext_dst_stride,
489 &subpel_params, sf, w, h, &conv_params,
490 mi->interp_filters, &warp_types, pre_x + x,
491 pre_y + y, plane, ref, mi, 0, xd, can_use_previous);
492 }
493
av1_build_inter_predictors_for_planes_single_buf(MACROBLOCKD * xd,BLOCK_SIZE bsize,int plane_from,int plane_to,int mi_row,int mi_col,int ref,uint8_t * ext_dst[3],int ext_dst_stride[3],int can_use_previous)494 void av1_build_inter_predictors_for_planes_single_buf(
495 MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane_from, int plane_to, int mi_row,
496 int mi_col, int ref, uint8_t *ext_dst[3], int ext_dst_stride[3],
497 int can_use_previous) {
498 int plane;
499 const int mi_x = mi_col * MI_SIZE;
500 const int mi_y = mi_row * MI_SIZE;
501 for (plane = plane_from; plane <= plane_to; ++plane) {
502 const BLOCK_SIZE plane_bsize = get_plane_block_size(
503 bsize, xd->plane[plane].subsampling_x, xd->plane[plane].subsampling_y);
504 const int bw = block_size_wide[plane_bsize];
505 const int bh = block_size_high[plane_bsize];
506 build_inter_predictors_single_buf(xd, plane, bw, bh, 0, 0, bw, bh, mi_x,
507 mi_y, ref, ext_dst[plane],
508 ext_dst_stride[plane], can_use_previous);
509 }
510 }
511
build_masked_compound(uint8_t * dst,int dst_stride,const uint8_t * src0,int src0_stride,const uint8_t * src1,int src1_stride,const INTERINTER_COMPOUND_DATA * const comp_data,BLOCK_SIZE sb_type,int h,int w)512 static void build_masked_compound(
513 uint8_t *dst, int dst_stride, const uint8_t *src0, int src0_stride,
514 const uint8_t *src1, int src1_stride,
515 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type, int h,
516 int w) {
517 // Derive subsampling from h and w passed in. May be refactored to
518 // pass in subsampling factors directly.
519 const int subh = (2 << mi_size_high_log2[sb_type]) == h;
520 const int subw = (2 << mi_size_wide_log2[sb_type]) == w;
521 const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type);
522 aom_blend_a64_mask(dst, dst_stride, src0, src0_stride, src1, src1_stride,
523 mask, block_size_wide[sb_type], w, h, subw, subh);
524 }
525
build_masked_compound_highbd(uint8_t * dst_8,int dst_stride,const uint8_t * src0_8,int src0_stride,const uint8_t * src1_8,int src1_stride,const INTERINTER_COMPOUND_DATA * const comp_data,BLOCK_SIZE sb_type,int h,int w,int bd)526 static void build_masked_compound_highbd(
527 uint8_t *dst_8, int dst_stride, const uint8_t *src0_8, int src0_stride,
528 const uint8_t *src1_8, int src1_stride,
529 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type, int h,
530 int w, int bd) {
531 // Derive subsampling from h and w passed in. May be refactored to
532 // pass in subsampling factors directly.
533 const int subh = (2 << mi_size_high_log2[sb_type]) == h;
534 const int subw = (2 << mi_size_wide_log2[sb_type]) == w;
535 const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type);
536 // const uint8_t *mask =
537 // av1_get_contiguous_soft_mask(wedge_index, wedge_sign, sb_type);
538 aom_highbd_blend_a64_mask(dst_8, dst_stride, src0_8, src0_stride, src1_8,
539 src1_stride, mask, block_size_wide[sb_type], w, h,
540 subw, subh, bd);
541 }
542
build_wedge_inter_predictor_from_buf(MACROBLOCKD * xd,int plane,int x,int y,int w,int h,uint8_t * ext_dst0,int ext_dst_stride0,uint8_t * ext_dst1,int ext_dst_stride1)543 static void build_wedge_inter_predictor_from_buf(
544 MACROBLOCKD *xd, int plane, int x, int y, int w, int h, uint8_t *ext_dst0,
545 int ext_dst_stride0, uint8_t *ext_dst1, int ext_dst_stride1) {
546 MB_MODE_INFO *const mbmi = xd->mi[0];
547 const int is_compound = has_second_ref(mbmi);
548 MACROBLOCKD_PLANE *const pd = &xd->plane[plane];
549 struct buf_2d *const dst_buf = &pd->dst;
550 uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x;
551 mbmi->interinter_comp.seg_mask = xd->seg_mask;
552 const INTERINTER_COMPOUND_DATA *comp_data = &mbmi->interinter_comp;
553 const int is_hbd = is_cur_buf_hbd(xd);
554
555 if (is_compound && is_masked_compound_type(comp_data->type)) {
556 if (!plane && comp_data->type == COMPOUND_DIFFWTD) {
557 if (is_hbd) {
558 av1_build_compound_diffwtd_mask_highbd(
559 comp_data->seg_mask, comp_data->mask_type,
560 CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0,
561 CONVERT_TO_BYTEPTR(ext_dst1), ext_dst_stride1, h, w, xd->bd);
562 } else {
563 av1_build_compound_diffwtd_mask(
564 comp_data->seg_mask, comp_data->mask_type, ext_dst0,
565 ext_dst_stride0, ext_dst1, ext_dst_stride1, h, w);
566 }
567 }
568
569 if (is_hbd) {
570 build_masked_compound_highbd(
571 dst, dst_buf->stride, CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0,
572 CONVERT_TO_BYTEPTR(ext_dst1), ext_dst_stride1, comp_data,
573 mbmi->sb_type, h, w, xd->bd);
574 } else {
575 build_masked_compound(dst, dst_buf->stride, ext_dst0, ext_dst_stride0,
576 ext_dst1, ext_dst_stride1, comp_data, mbmi->sb_type,
577 h, w);
578 }
579 } else {
580 if (is_hbd) {
581 aom_highbd_convolve_copy(CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0,
582 dst, dst_buf->stride, NULL, 0, NULL, 0, w, h,
583 xd->bd);
584 } else {
585 aom_convolve_copy(ext_dst0, ext_dst_stride0, dst, dst_buf->stride, NULL,
586 0, NULL, 0, w, h);
587 }
588 }
589 }
590
av1_build_wedge_inter_predictor_from_buf(MACROBLOCKD * xd,BLOCK_SIZE bsize,int plane_from,int plane_to,uint8_t * ext_dst0[3],int ext_dst_stride0[3],uint8_t * ext_dst1[3],int ext_dst_stride1[3])591 void av1_build_wedge_inter_predictor_from_buf(MACROBLOCKD *xd, BLOCK_SIZE bsize,
592 int plane_from, int plane_to,
593 uint8_t *ext_dst0[3],
594 int ext_dst_stride0[3],
595 uint8_t *ext_dst1[3],
596 int ext_dst_stride1[3]) {
597 int plane;
598 for (plane = plane_from; plane <= plane_to; ++plane) {
599 const BLOCK_SIZE plane_bsize = get_plane_block_size(
600 bsize, xd->plane[plane].subsampling_x, xd->plane[plane].subsampling_y);
601 const int bw = block_size_wide[plane_bsize];
602 const int bh = block_size_high[plane_bsize];
603 build_wedge_inter_predictor_from_buf(
604 xd, plane, 0, 0, bw, bh, ext_dst0[plane], ext_dst_stride0[plane],
605 ext_dst1[plane], ext_dst_stride1[plane]);
606 }
607 }
608