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