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/av1_common_int.h"
24 #include "av1/common/blockd.h"
25 #include "av1/common/mvref_common.h"
26 #include "av1/common/obmc.h"
27 #include "av1/common/reconinter.h"
28 #include "av1/common/reconintra.h"
29 #include "av1/encoder/reconinter_enc.h"
30
enc_calc_subpel_params(const MV * const src_mv,InterPredParams * const inter_pred_params,MACROBLOCKD * xd,int mi_x,int mi_y,int ref,uint8_t ** mc_buf,uint8_t ** pre,SubpelParams * subpel_params,int * src_stride)31 static void enc_calc_subpel_params(const MV *const src_mv,
32 InterPredParams *const inter_pred_params,
33 MACROBLOCKD *xd, int mi_x, int mi_y, int ref,
34 uint8_t **mc_buf, uint8_t **pre,
35 SubpelParams *subpel_params,
36 int *src_stride) {
37 // These are part of the function signature to use this function through a
38 // function pointer. See typedef of 'CalcSubpelParamsFunc'.
39 (void)xd;
40 (void)mi_x;
41 (void)mi_y;
42 (void)ref;
43 (void)mc_buf;
44
45 const struct scale_factors *sf = inter_pred_params->scale_factors;
46
47 struct buf_2d *pre_buf = &inter_pred_params->ref_frame_buf;
48 int ssx = inter_pred_params->subsampling_x;
49 int ssy = inter_pred_params->subsampling_y;
50 int orig_pos_y = inter_pred_params->pix_row << SUBPEL_BITS;
51 orig_pos_y += src_mv->row * (1 << (1 - ssy));
52 int orig_pos_x = inter_pred_params->pix_col << SUBPEL_BITS;
53 orig_pos_x += src_mv->col * (1 << (1 - ssx));
54 int pos_y = sf->scale_value_y(orig_pos_y, sf);
55 int pos_x = sf->scale_value_x(orig_pos_x, sf);
56 pos_x += SCALE_EXTRA_OFF;
57 pos_y += SCALE_EXTRA_OFF;
58
59 const int top = -AOM_LEFT_TOP_MARGIN_SCALED(ssy);
60 const int left = -AOM_LEFT_TOP_MARGIN_SCALED(ssx);
61 const int bottom = (pre_buf->height + AOM_INTERP_EXTEND) << SCALE_SUBPEL_BITS;
62 const int right = (pre_buf->width + AOM_INTERP_EXTEND) << SCALE_SUBPEL_BITS;
63 pos_y = clamp(pos_y, top, bottom);
64 pos_x = clamp(pos_x, left, right);
65
66 subpel_params->subpel_x = pos_x & SCALE_SUBPEL_MASK;
67 subpel_params->subpel_y = pos_y & SCALE_SUBPEL_MASK;
68 subpel_params->xs = sf->x_step_q4;
69 subpel_params->ys = sf->y_step_q4;
70 *pre = pre_buf->buf0 + (pos_y >> SCALE_SUBPEL_BITS) * pre_buf->stride +
71 (pos_x >> SCALE_SUBPEL_BITS);
72 *src_stride = pre_buf->stride;
73 }
74
av1_enc_build_one_inter_predictor(uint8_t * dst,int dst_stride,const MV * src_mv,InterPredParams * inter_pred_params)75 void av1_enc_build_one_inter_predictor(uint8_t *dst, int dst_stride,
76 const MV *src_mv,
77 InterPredParams *inter_pred_params) {
78 av1_build_one_inter_predictor(
79 dst, dst_stride, src_mv, inter_pred_params, NULL /* xd */, 0 /* mi_x */,
80 0 /* mi_y */, 0 /* ref */, NULL /* mc_buf */, enc_calc_subpel_params);
81 }
82
enc_build_inter_predictors(const AV1_COMMON * cm,MACROBLOCKD * xd,int plane,const MB_MODE_INFO * mi,int bw,int bh,int mi_x,int mi_y)83 static void enc_build_inter_predictors(const AV1_COMMON *cm, MACROBLOCKD *xd,
84 int plane, const MB_MODE_INFO *mi,
85 int bw, int bh, int mi_x, int mi_y) {
86 av1_build_inter_predictors(cm, xd, plane, mi, 0 /* build_for_obmc */, bw, bh,
87 mi_x, mi_y, NULL /* mc_buf */,
88 enc_calc_subpel_params);
89 }
90
av1_enc_build_inter_predictor_y(MACROBLOCKD * xd,int mi_row,int mi_col)91 void av1_enc_build_inter_predictor_y(MACROBLOCKD *xd, int mi_row, int mi_col) {
92 const int mi_x = mi_col * MI_SIZE;
93 const int mi_y = mi_row * MI_SIZE;
94 struct macroblockd_plane *const pd = &xd->plane[AOM_PLANE_Y];
95 InterPredParams inter_pred_params;
96
97 struct buf_2d *const dst_buf = &pd->dst;
98 uint8_t *const dst = dst_buf->buf;
99 const MV mv = xd->mi[0]->mv[0].as_mv;
100 const struct scale_factors *const sf = xd->block_ref_scale_factors[0];
101
102 av1_init_inter_params(&inter_pred_params, pd->width, pd->height, mi_y, mi_x,
103 pd->subsampling_x, pd->subsampling_y, xd->bd,
104 is_cur_buf_hbd(xd), false, sf, pd->pre,
105 xd->mi[0]->interp_filters);
106
107 inter_pred_params.conv_params = get_conv_params_no_round(
108 0, AOM_PLANE_Y, xd->tmp_conv_dst, MAX_SB_SIZE, false, xd->bd);
109
110 inter_pred_params.conv_params.use_dist_wtd_comp_avg = 0;
111 av1_enc_build_one_inter_predictor(dst, dst_buf->stride, &mv,
112 &inter_pred_params);
113 }
114
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)115 void av1_enc_build_inter_predictor(const AV1_COMMON *cm, MACROBLOCKD *xd,
116 int mi_row, int mi_col,
117 const BUFFER_SET *ctx, BLOCK_SIZE bsize,
118 int plane_from, int plane_to) {
119 for (int plane = plane_from; plane <= plane_to; ++plane) {
120 if (plane && !xd->is_chroma_ref) break;
121 const int mi_x = mi_col * MI_SIZE;
122 const int mi_y = mi_row * MI_SIZE;
123 enc_build_inter_predictors(cm, xd, plane, xd->mi[0], xd->plane[plane].width,
124 xd->plane[plane].height, mi_x, mi_y);
125
126 if (is_interintra_pred(xd->mi[0])) {
127 BUFFER_SET default_ctx = {
128 { xd->plane[0].dst.buf, xd->plane[1].dst.buf, xd->plane[2].dst.buf },
129 { xd->plane[0].dst.stride, xd->plane[1].dst.stride,
130 xd->plane[2].dst.stride }
131 };
132 if (!ctx) {
133 ctx = &default_ctx;
134 }
135 av1_build_interintra_predictor(cm, xd, xd->plane[plane].dst.buf,
136 xd->plane[plane].dst.stride, ctx, plane,
137 bsize);
138 }
139 }
140 }
141
setup_address_for_obmc(MACROBLOCKD * xd,int mi_row_offset,int mi_col_offset,MB_MODE_INFO * ref_mbmi,struct build_prediction_ctxt * ctxt,const int num_planes)142 static void setup_address_for_obmc(MACROBLOCKD *xd, int mi_row_offset,
143 int mi_col_offset, MB_MODE_INFO *ref_mbmi,
144 struct build_prediction_ctxt *ctxt,
145 const int num_planes) {
146 const BLOCK_SIZE ref_bsize = AOMMAX(BLOCK_8X8, ref_mbmi->bsize);
147 const int ref_mi_row = xd->mi_row + mi_row_offset;
148 const int ref_mi_col = xd->mi_col + mi_col_offset;
149
150 for (int plane = 0; plane < num_planes; ++plane) {
151 struct macroblockd_plane *const pd = &xd->plane[plane];
152 setup_pred_plane(&pd->dst, ref_bsize, ctxt->tmp_buf[plane],
153 ctxt->tmp_width[plane], ctxt->tmp_height[plane],
154 ctxt->tmp_stride[plane], mi_row_offset, mi_col_offset,
155 NULL, pd->subsampling_x, pd->subsampling_y);
156 }
157
158 const MV_REFERENCE_FRAME frame = ref_mbmi->ref_frame[0];
159
160 const RefCntBuffer *const ref_buf = get_ref_frame_buf(ctxt->cm, frame);
161 const struct scale_factors *const sf =
162 get_ref_scale_factors_const(ctxt->cm, frame);
163
164 xd->block_ref_scale_factors[0] = sf;
165 if ((!av1_is_valid_scale(sf)))
166 aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
167 "Reference frame has invalid dimensions");
168
169 av1_setup_pre_planes(xd, 0, &ref_buf->buf, ref_mi_row, ref_mi_col, sf,
170 num_planes);
171 }
172
build_obmc_prediction(MACROBLOCKD * xd,int rel_mi_row,int rel_mi_col,uint8_t op_mi_size,int dir,MB_MODE_INFO * above_mbmi,void * fun_ctxt,const int num_planes)173 static INLINE void build_obmc_prediction(MACROBLOCKD *xd, int rel_mi_row,
174 int rel_mi_col, uint8_t op_mi_size,
175 int dir, MB_MODE_INFO *above_mbmi,
176 void *fun_ctxt, const int num_planes) {
177 struct build_prediction_ctxt *ctxt = (struct build_prediction_ctxt *)fun_ctxt;
178 setup_address_for_obmc(xd, rel_mi_row, rel_mi_col, above_mbmi, ctxt,
179 num_planes);
180
181 const int mi_x = (xd->mi_col + rel_mi_col) << MI_SIZE_LOG2;
182 const int mi_y = (xd->mi_row + rel_mi_row) << MI_SIZE_LOG2;
183
184 const BLOCK_SIZE bsize = xd->mi[0]->bsize;
185
186 InterPredParams inter_pred_params;
187
188 for (int j = 0; j < num_planes; ++j) {
189 const struct macroblockd_plane *pd = &xd->plane[j];
190 int bw = 0, bh = 0;
191
192 if (dir) {
193 // prepare left reference block size
194 bw = clamp(block_size_wide[bsize] >> (pd->subsampling_x + 1), 4,
195 block_size_wide[BLOCK_64X64] >> (pd->subsampling_x + 1));
196 bh = (op_mi_size << MI_SIZE_LOG2) >> pd->subsampling_y;
197 } else {
198 // prepare above reference block size
199 bw = (op_mi_size * MI_SIZE) >> pd->subsampling_x;
200 bh = clamp(block_size_high[bsize] >> (pd->subsampling_y + 1), 4,
201 block_size_high[BLOCK_64X64] >> (pd->subsampling_y + 1));
202 }
203
204 if (av1_skip_u4x4_pred_in_obmc(bsize, pd, dir)) continue;
205
206 const struct buf_2d *const pre_buf = &pd->pre[0];
207 const MV mv = above_mbmi->mv[0].as_mv;
208
209 av1_init_inter_params(&inter_pred_params, bw, bh, mi_y >> pd->subsampling_y,
210 mi_x >> pd->subsampling_x, pd->subsampling_x,
211 pd->subsampling_y, xd->bd, is_cur_buf_hbd(xd), 0,
212 xd->block_ref_scale_factors[0], pre_buf,
213 above_mbmi->interp_filters);
214 inter_pred_params.conv_params = get_conv_params(0, j, xd->bd);
215
216 av1_enc_build_one_inter_predictor(pd->dst.buf, pd->dst.stride, &mv,
217 &inter_pred_params);
218 }
219 }
220
av1_build_prediction_by_above_preds(const AV1_COMMON * cm,MACROBLOCKD * xd,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])221 void av1_build_prediction_by_above_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
222 uint8_t *tmp_buf[MAX_MB_PLANE],
223 int tmp_width[MAX_MB_PLANE],
224 int tmp_height[MAX_MB_PLANE],
225 int tmp_stride[MAX_MB_PLANE]) {
226 if (!xd->up_available) return;
227 struct build_prediction_ctxt ctxt = {
228 cm, tmp_buf, tmp_width, tmp_height, tmp_stride, xd->mb_to_right_edge, NULL
229 };
230 BLOCK_SIZE bsize = xd->mi[0]->bsize;
231 foreach_overlappable_nb_above(cm, xd,
232 max_neighbor_obmc[mi_size_wide_log2[bsize]],
233 build_obmc_prediction, &ctxt);
234 }
235
av1_build_prediction_by_left_preds(const AV1_COMMON * cm,MACROBLOCKD * xd,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])236 void av1_build_prediction_by_left_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
237 uint8_t *tmp_buf[MAX_MB_PLANE],
238 int tmp_width[MAX_MB_PLANE],
239 int tmp_height[MAX_MB_PLANE],
240 int tmp_stride[MAX_MB_PLANE]) {
241 if (!xd->left_available) return;
242 struct build_prediction_ctxt ctxt = {
243 cm, tmp_buf, tmp_width, tmp_height, tmp_stride, xd->mb_to_bottom_edge, NULL
244 };
245 BLOCK_SIZE bsize = xd->mi[0]->bsize;
246 foreach_overlappable_nb_left(cm, xd,
247 max_neighbor_obmc[mi_size_high_log2[bsize]],
248 build_obmc_prediction, &ctxt);
249 }
250
av1_build_obmc_inter_predictors_sb(const AV1_COMMON * cm,MACROBLOCKD * xd)251 void av1_build_obmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd) {
252 const int num_planes = av1_num_planes(cm);
253 uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
254 int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
255 int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
256 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
257 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
258 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
259 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
260
261 av1_setup_obmc_dst_bufs(xd, dst_buf1, dst_buf2);
262
263 const int mi_row = xd->mi_row;
264 const int mi_col = xd->mi_col;
265 av1_build_prediction_by_above_preds(cm, xd, dst_buf1, dst_width1, dst_height1,
266 dst_stride1);
267 av1_build_prediction_by_left_preds(cm, xd, dst_buf2, dst_width2, dst_height2,
268 dst_stride2);
269 av1_setup_dst_planes(xd->plane, xd->mi[0]->bsize, &cm->cur_frame->buf, mi_row,
270 mi_col, 0, num_planes);
271 av1_build_obmc_inter_prediction(cm, xd, dst_buf1, dst_stride1, dst_buf2,
272 dst_stride2);
273 }
274
av1_build_inter_predictors_for_planes_single_buf(MACROBLOCKD * xd,BLOCK_SIZE bsize,int plane_from,int plane_to,int ref,uint8_t * ext_dst[3],int ext_dst_stride[3])275 void av1_build_inter_predictors_for_planes_single_buf(
276 MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane_from, int plane_to, int ref,
277 uint8_t *ext_dst[3], int ext_dst_stride[3]) {
278 assert(bsize < BLOCK_SIZES_ALL);
279 const MB_MODE_INFO *mi = xd->mi[0];
280 const int mi_row = xd->mi_row;
281 const int mi_col = xd->mi_col;
282 const int mi_x = mi_col * MI_SIZE;
283 const int mi_y = mi_row * MI_SIZE;
284 WarpTypesAllowed warp_types;
285 const WarpedMotionParams *const wm = &xd->global_motion[mi->ref_frame[ref]];
286 warp_types.global_warp_allowed = is_global_mv_block(mi, wm->wmtype);
287 warp_types.local_warp_allowed = mi->motion_mode == WARPED_CAUSAL;
288
289 for (int plane = plane_from; plane <= plane_to; ++plane) {
290 const struct macroblockd_plane *pd = &xd->plane[plane];
291 const BLOCK_SIZE plane_bsize =
292 get_plane_block_size(bsize, pd->subsampling_x, pd->subsampling_y);
293 const int bw = block_size_wide[plane_bsize];
294 const int bh = block_size_high[plane_bsize];
295
296 InterPredParams inter_pred_params;
297
298 av1_init_inter_params(&inter_pred_params, bw, bh, mi_y >> pd->subsampling_y,
299 mi_x >> pd->subsampling_x, pd->subsampling_x,
300 pd->subsampling_y, xd->bd, is_cur_buf_hbd(xd), 0,
301 xd->block_ref_scale_factors[ref], &pd->pre[ref],
302 mi->interp_filters);
303 inter_pred_params.conv_params = get_conv_params(0, plane, xd->bd);
304 av1_init_warp_params(&inter_pred_params, &warp_types, ref, xd, mi);
305
306 uint8_t *const dst = get_buf_by_bd(xd, ext_dst[plane]);
307 const MV mv = mi->mv[ref].as_mv;
308
309 av1_enc_build_one_inter_predictor(dst, ext_dst_stride[plane], &mv,
310 &inter_pred_params);
311 }
312 }
313
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)314 static void build_masked_compound(
315 uint8_t *dst, int dst_stride, const uint8_t *src0, int src0_stride,
316 const uint8_t *src1, int src1_stride,
317 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type, int h,
318 int w) {
319 // Derive subsampling from h and w passed in. May be refactored to
320 // pass in subsampling factors directly.
321 const int subh = (2 << mi_size_high_log2[sb_type]) == h;
322 const int subw = (2 << mi_size_wide_log2[sb_type]) == w;
323 const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type);
324 aom_blend_a64_mask(dst, dst_stride, src0, src0_stride, src1, src1_stride,
325 mask, block_size_wide[sb_type], w, h, subw, subh);
326 }
327
328 #if CONFIG_AV1_HIGHBITDEPTH
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)329 static void build_masked_compound_highbd(
330 uint8_t *dst_8, int dst_stride, const uint8_t *src0_8, int src0_stride,
331 const uint8_t *src1_8, int src1_stride,
332 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type, int h,
333 int w, int bd) {
334 // Derive subsampling from h and w passed in. May be refactored to
335 // pass in subsampling factors directly.
336 const int subh = (2 << mi_size_high_log2[sb_type]) == h;
337 const int subw = (2 << mi_size_wide_log2[sb_type]) == w;
338 const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type);
339 // const uint8_t *mask =
340 // av1_get_contiguous_soft_mask(wedge_index, wedge_sign, sb_type);
341 aom_highbd_blend_a64_mask(dst_8, dst_stride, src0_8, src0_stride, src1_8,
342 src1_stride, mask, block_size_wide[sb_type], w, h,
343 subw, subh, bd);
344 }
345 #endif
346
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)347 static void build_wedge_inter_predictor_from_buf(
348 MACROBLOCKD *xd, int plane, int x, int y, int w, int h, uint8_t *ext_dst0,
349 int ext_dst_stride0, uint8_t *ext_dst1, int ext_dst_stride1) {
350 MB_MODE_INFO *const mbmi = xd->mi[0];
351 const int is_compound = has_second_ref(mbmi);
352 MACROBLOCKD_PLANE *const pd = &xd->plane[plane];
353 struct buf_2d *const dst_buf = &pd->dst;
354 uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x;
355 mbmi->interinter_comp.seg_mask = xd->seg_mask;
356 const INTERINTER_COMPOUND_DATA *comp_data = &mbmi->interinter_comp;
357 const int is_hbd = is_cur_buf_hbd(xd);
358
359 if (is_compound && is_masked_compound_type(comp_data->type)) {
360 if (!plane && comp_data->type == COMPOUND_DIFFWTD) {
361 if (is_hbd) {
362 av1_build_compound_diffwtd_mask_highbd(
363 comp_data->seg_mask, comp_data->mask_type,
364 CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0,
365 CONVERT_TO_BYTEPTR(ext_dst1), ext_dst_stride1, h, w, xd->bd);
366 } else {
367 av1_build_compound_diffwtd_mask(
368 comp_data->seg_mask, comp_data->mask_type, ext_dst0,
369 ext_dst_stride0, ext_dst1, ext_dst_stride1, h, w);
370 }
371 }
372 #if CONFIG_AV1_HIGHBITDEPTH
373 if (is_hbd) {
374 build_masked_compound_highbd(
375 dst, dst_buf->stride, CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0,
376 CONVERT_TO_BYTEPTR(ext_dst1), ext_dst_stride1, comp_data, mbmi->bsize,
377 h, w, xd->bd);
378 } else {
379 build_masked_compound(dst, dst_buf->stride, ext_dst0, ext_dst_stride0,
380 ext_dst1, ext_dst_stride1, comp_data, mbmi->bsize,
381 h, w);
382 }
383 #else
384 build_masked_compound(dst, dst_buf->stride, ext_dst0, ext_dst_stride0,
385 ext_dst1, ext_dst_stride1, comp_data, mbmi->bsize, h,
386 w);
387 #endif
388 } else {
389 #if CONFIG_AV1_HIGHBITDEPTH
390 if (is_hbd) {
391 aom_highbd_convolve_copy(CONVERT_TO_SHORTPTR(ext_dst0), ext_dst_stride0,
392 CONVERT_TO_SHORTPTR(dst), dst_buf->stride, w, h);
393 } else {
394 aom_convolve_copy(ext_dst0, ext_dst_stride0, dst, dst_buf->stride, w, h);
395 }
396 #else
397 aom_convolve_copy(ext_dst0, ext_dst_stride0, dst, dst_buf->stride, w, h);
398 #endif
399 }
400 }
401
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])402 void av1_build_wedge_inter_predictor_from_buf(MACROBLOCKD *xd, BLOCK_SIZE bsize,
403 int plane_from, int plane_to,
404 uint8_t *ext_dst0[3],
405 int ext_dst_stride0[3],
406 uint8_t *ext_dst1[3],
407 int ext_dst_stride1[3]) {
408 int plane;
409 assert(bsize < BLOCK_SIZES_ALL);
410 for (plane = plane_from; plane <= plane_to; ++plane) {
411 const BLOCK_SIZE plane_bsize = get_plane_block_size(
412 bsize, xd->plane[plane].subsampling_x, xd->plane[plane].subsampling_y);
413 const int bw = block_size_wide[plane_bsize];
414 const int bh = block_size_high[plane_bsize];
415 build_wedge_inter_predictor_from_buf(
416 xd, plane, 0, 0, bw, bh, ext_dst0[plane], ext_dst_stride0[plane],
417 ext_dst1[plane], ext_dst_stride1[plane]);
418 }
419 }
420