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_jnt_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 RefBuffer *ref_buf =
147             &cm->frame_refs[this_mbmi->ref_frame[ref] - LAST_FRAME];
148 
149         pd->pre[ref].buf0 =
150             (plane == 1) ? ref_buf->buf->u_buffer : ref_buf->buf->v_buffer;
151         pd->pre[ref].buf =
152             pd->pre[ref].buf0 + scaled_buffer_offset(pre_x, pre_y,
153                                                      ref_buf->buf->uv_stride,
154                                                      &ref_buf->sf);
155         pd->pre[ref].width = ref_buf->buf->uv_crop_width;
156         pd->pre[ref].height = ref_buf->buf->uv_crop_height;
157         pd->pre[ref].stride = ref_buf->buf->uv_stride;
158 
159         const struct scale_factors *const sf =
160             is_intrabc ? &cm->sf_identity : &ref_buf->sf;
161         struct buf_2d *const pre_buf = is_intrabc ? dst_buf : &pd->pre[ref];
162 
163         const MV mv = this_mbmi->mv[ref].as_mv;
164 
165         uint8_t *pre;
166         SubpelParams subpel_params;
167         WarpTypesAllowed warp_types;
168         warp_types.global_warp_allowed = is_global[ref];
169         warp_types.local_warp_allowed = this_mbmi->motion_mode == WARPED_CAUSAL;
170 
171         calc_subpel_params(xd, sf, mv, plane, pre_x, pre_y, x, y, pre_buf, &pre,
172                            &subpel_params, bw, bh);
173         conv_params.do_average = ref;
174         if (is_masked_compound_type(mi->interinter_comp.type)) {
175           // masked compound type has its own average mechanism
176           conv_params.do_average = 0;
177         }
178 
179         av1_make_inter_predictor(
180             pre, pre_buf->stride, dst, dst_buf->stride, &subpel_params, sf,
181             b4_w, b4_h, &conv_params, this_mbmi->interp_filters, &warp_types,
182             (mi_x >> pd->subsampling_x) + x, (mi_y >> pd->subsampling_y) + y,
183             plane, ref, mi, build_for_obmc, xd, cm->allow_warped_motion);
184 
185         ++col;
186       }
187       ++row;
188     }
189 
190     for (ref = 0; ref < 2; ++ref) pd->pre[ref] = orig_pred_buf[ref];
191     return;
192   }
193 
194   {
195     ConvolveParams conv_params = get_conv_params_no_round(
196         0, plane, xd->tmp_conv_dst, MAX_SB_SIZE, is_compound, xd->bd);
197     av1_jnt_comp_weight_assign(cm, mi, 0, &conv_params.fwd_offset,
198                                &conv_params.bck_offset,
199                                &conv_params.use_jnt_comp_avg, is_compound);
200 
201     struct buf_2d *const dst_buf = &pd->dst;
202     uint8_t *const dst = dst_buf->buf;
203     for (ref = 0; ref < 1 + is_compound; ++ref) {
204       const struct scale_factors *const sf =
205           is_intrabc ? &cm->sf_identity : &xd->block_refs[ref]->sf;
206       struct buf_2d *const pre_buf = is_intrabc ? dst_buf : &pd->pre[ref];
207       const MV mv = mi->mv[ref].as_mv;
208 
209       uint8_t *pre;
210       SubpelParams subpel_params;
211       calc_subpel_params(xd, sf, mv, plane, pre_x, pre_y, 0, 0, pre_buf, &pre,
212                          &subpel_params, bw, bh);
213 
214       WarpTypesAllowed warp_types;
215       warp_types.global_warp_allowed = is_global[ref];
216       warp_types.local_warp_allowed = mi->motion_mode == WARPED_CAUSAL;
217 
218       if (ref && is_masked_compound_type(mi->interinter_comp.type)) {
219         // masked compound type has its own average mechanism
220         conv_params.do_average = 0;
221         av1_make_masked_inter_predictor(
222             pre, pre_buf->stride, dst, dst_buf->stride, &subpel_params, sf, bw,
223             bh, &conv_params, mi->interp_filters, plane, &warp_types,
224             mi_x >> pd->subsampling_x, mi_y >> pd->subsampling_y, ref, xd,
225             cm->allow_warped_motion);
226       } else {
227         conv_params.do_average = ref;
228         av1_make_inter_predictor(
229             pre, pre_buf->stride, dst, dst_buf->stride, &subpel_params, sf, bw,
230             bh, &conv_params, mi->interp_filters, &warp_types,
231             mi_x >> pd->subsampling_x, mi_y >> pd->subsampling_y, plane, ref,
232             mi, build_for_obmc, xd, cm->allow_warped_motion);
233       }
234     }
235   }
236 }
237 
build_inter_predictors_for_planes(const AV1_COMMON * cm,MACROBLOCKD * xd,BLOCK_SIZE bsize,int mi_row,int mi_col,int plane_from,int plane_to)238 static void build_inter_predictors_for_planes(const AV1_COMMON *cm,
239                                               MACROBLOCKD *xd, BLOCK_SIZE bsize,
240                                               int mi_row, int mi_col,
241                                               int plane_from, int plane_to) {
242   int plane;
243   const int mi_x = mi_col * MI_SIZE;
244   const int mi_y = mi_row * MI_SIZE;
245   for (plane = plane_from; plane <= plane_to; ++plane) {
246     const struct macroblockd_plane *pd = &xd->plane[plane];
247     const int bw = pd->width;
248     const int bh = pd->height;
249 
250     if (!is_chroma_reference(mi_row, mi_col, bsize, pd->subsampling_x,
251                              pd->subsampling_y))
252       continue;
253 
254     build_inter_predictors(cm, xd, plane, xd->mi[0], 0, bw, bh, mi_x, mi_y);
255   }
256 }
257 
av1_build_inter_predictors_sby(const AV1_COMMON * cm,MACROBLOCKD * xd,int mi_row,int mi_col,BUFFER_SET * ctx,BLOCK_SIZE bsize)258 void av1_build_inter_predictors_sby(const AV1_COMMON *cm, MACROBLOCKD *xd,
259                                     int mi_row, int mi_col, BUFFER_SET *ctx,
260                                     BLOCK_SIZE bsize) {
261   av1_build_inter_predictors_sbp(cm, xd, mi_row, mi_col, ctx, bsize, 0);
262 }
263 
av1_build_inter_predictors_sbuv(const AV1_COMMON * cm,MACROBLOCKD * xd,int mi_row,int mi_col,BUFFER_SET * ctx,BLOCK_SIZE bsize)264 void av1_build_inter_predictors_sbuv(const AV1_COMMON *cm, MACROBLOCKD *xd,
265                                      int mi_row, int mi_col, BUFFER_SET *ctx,
266                                      BLOCK_SIZE bsize) {
267   for (int plane_idx = 1; plane_idx < MAX_MB_PLANE; plane_idx++) {
268     av1_build_inter_predictors_sbp(cm, xd, mi_row, mi_col, ctx, bsize,
269                                    plane_idx);
270   }
271 }
272 
av1_build_inter_predictors_sbp(const AV1_COMMON * cm,MACROBLOCKD * xd,int mi_row,int mi_col,BUFFER_SET * ctx,BLOCK_SIZE bsize,int plane_idx)273 void av1_build_inter_predictors_sbp(const AV1_COMMON *cm, MACROBLOCKD *xd,
274                                     int mi_row, int mi_col, BUFFER_SET *ctx,
275                                     BLOCK_SIZE bsize, int plane_idx) {
276   build_inter_predictors_for_planes(cm, xd, bsize, mi_row, mi_col, plane_idx,
277                                     plane_idx);
278 
279   if (is_interintra_pred(xd->mi[0])) {
280     BUFFER_SET default_ctx = { { NULL, NULL, NULL }, { 0, 0, 0 } };
281     if (!ctx) {
282       default_ctx.plane[plane_idx] = xd->plane[plane_idx].dst.buf;
283       default_ctx.stride[plane_idx] = xd->plane[plane_idx].dst.stride;
284       ctx = &default_ctx;
285     }
286     av1_build_interintra_predictors_sbp(cm, xd, xd->plane[plane_idx].dst.buf,
287                                         xd->plane[plane_idx].dst.stride, ctx,
288                                         plane_idx, bsize);
289   }
290 }
291 
av1_build_inter_predictors_sb(const AV1_COMMON * cm,MACROBLOCKD * xd,int mi_row,int mi_col,BUFFER_SET * ctx,BLOCK_SIZE bsize)292 void av1_build_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
293                                    int mi_row, int mi_col, BUFFER_SET *ctx,
294                                    BLOCK_SIZE bsize) {
295   const int num_planes = av1_num_planes(cm);
296   av1_build_inter_predictors_sby(cm, xd, mi_row, mi_col, ctx, bsize);
297   if (num_planes > 1)
298     av1_build_inter_predictors_sbuv(cm, xd, mi_row, mi_col, ctx, bsize);
299 }
300 
301 // TODO(sarahparker):
302 // av1_build_inter_predictor should be combined with
303 // 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,enum mv_precision precision,int x,int y,const MACROBLOCKD * xd,int can_use_previous)304 void av1_build_inter_predictor(const uint8_t *src, int src_stride, uint8_t *dst,
305                                int dst_stride, const MV *src_mv,
306                                const struct scale_factors *sf, int w, int h,
307                                ConvolveParams *conv_params,
308                                InterpFilters interp_filters,
309                                const WarpTypesAllowed *warp_types, int p_col,
310                                int p_row, int plane, int ref,
311                                enum mv_precision precision, int x, int y,
312                                const MACROBLOCKD *xd, int can_use_previous) {
313   const int is_q4 = precision == MV_PRECISION_Q4;
314   const MV mv_q4 = { is_q4 ? src_mv->row : src_mv->row * 2,
315                      is_q4 ? src_mv->col : src_mv->col * 2 };
316   MV32 mv = av1_scale_mv(&mv_q4, x, y, sf);
317   mv.col += SCALE_EXTRA_OFF;
318   mv.row += SCALE_EXTRA_OFF;
319 
320   const SubpelParams subpel_params = { sf->x_step_q4, sf->y_step_q4,
321                                        mv.col & SCALE_SUBPEL_MASK,
322                                        mv.row & SCALE_SUBPEL_MASK };
323   src += (mv.row >> SCALE_SUBPEL_BITS) * src_stride +
324          (mv.col >> SCALE_SUBPEL_BITS);
325 
326   av1_make_inter_predictor(src, src_stride, dst, dst_stride, &subpel_params, sf,
327                            w, h, conv_params, interp_filters, warp_types, p_col,
328                            p_row, plane, ref, xd->mi[0], 0, xd,
329                            can_use_previous);
330 }
331 
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)332 static INLINE void build_prediction_by_above_pred(
333     MACROBLOCKD *xd, int rel_mi_col, uint8_t above_mi_width,
334     MB_MODE_INFO *above_mbmi, void *fun_ctxt, const int num_planes) {
335   struct build_prediction_ctxt *ctxt = (struct build_prediction_ctxt *)fun_ctxt;
336   const int above_mi_col = ctxt->mi_col + rel_mi_col;
337   int mi_x, mi_y;
338   MB_MODE_INFO backup_mbmi = *above_mbmi;
339 
340   av1_setup_build_prediction_by_above_pred(xd, rel_mi_col, above_mi_width,
341                                            above_mbmi, ctxt, num_planes);
342   mi_x = above_mi_col << MI_SIZE_LOG2;
343   mi_y = ctxt->mi_row << MI_SIZE_LOG2;
344 
345   const BLOCK_SIZE bsize = xd->mi[0]->sb_type;
346 
347   for (int j = 0; j < num_planes; ++j) {
348     const struct macroblockd_plane *pd = &xd->plane[j];
349     int bw = (above_mi_width * MI_SIZE) >> pd->subsampling_x;
350     int bh = clamp(block_size_high[bsize] >> (pd->subsampling_y + 1), 4,
351                    block_size_high[BLOCK_64X64] >> (pd->subsampling_y + 1));
352 
353     if (av1_skip_u4x4_pred_in_obmc(bsize, pd, 0)) continue;
354     build_inter_predictors(ctxt->cm, xd, j, above_mbmi, 1, bw, bh, mi_x, mi_y);
355   }
356   *above_mbmi = backup_mbmi;
357 }
358 
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])359 void av1_build_prediction_by_above_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
360                                          int mi_row, int mi_col,
361                                          uint8_t *tmp_buf[MAX_MB_PLANE],
362                                          int tmp_width[MAX_MB_PLANE],
363                                          int tmp_height[MAX_MB_PLANE],
364                                          int tmp_stride[MAX_MB_PLANE]) {
365   if (!xd->up_available) return;
366 
367   // Adjust mb_to_bottom_edge to have the correct value for the OBMC
368   // prediction block. This is half the height of the original block,
369   // except for 128-wide blocks, where we only use a height of 32.
370   int this_height = xd->n4_h * MI_SIZE;
371   int pred_height = AOMMIN(this_height / 2, 32);
372   xd->mb_to_bottom_edge += (this_height - pred_height) * 8;
373 
374   struct build_prediction_ctxt ctxt = { cm,         mi_row,
375                                         mi_col,     tmp_buf,
376                                         tmp_width,  tmp_height,
377                                         tmp_stride, xd->mb_to_right_edge };
378   BLOCK_SIZE bsize = xd->mi[0]->sb_type;
379   foreach_overlappable_nb_above(cm, xd, mi_col,
380                                 max_neighbor_obmc[mi_size_wide_log2[bsize]],
381                                 build_prediction_by_above_pred, &ctxt);
382 
383   xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8);
384   xd->mb_to_right_edge = ctxt.mb_to_far_edge;
385   xd->mb_to_bottom_edge -= (this_height - pred_height) * 8;
386 }
387 
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)388 static INLINE void build_prediction_by_left_pred(
389     MACROBLOCKD *xd, int rel_mi_row, uint8_t left_mi_height,
390     MB_MODE_INFO *left_mbmi, void *fun_ctxt, const int num_planes) {
391   struct build_prediction_ctxt *ctxt = (struct build_prediction_ctxt *)fun_ctxt;
392   const int left_mi_row = ctxt->mi_row + rel_mi_row;
393   int mi_x, mi_y;
394   MB_MODE_INFO backup_mbmi = *left_mbmi;
395 
396   av1_setup_build_prediction_by_left_pred(xd, rel_mi_row, left_mi_height,
397                                           left_mbmi, ctxt, num_planes);
398   mi_x = ctxt->mi_col << MI_SIZE_LOG2;
399   mi_y = left_mi_row << MI_SIZE_LOG2;
400   const BLOCK_SIZE bsize = xd->mi[0]->sb_type;
401 
402   for (int j = 0; j < num_planes; ++j) {
403     const struct macroblockd_plane *pd = &xd->plane[j];
404     int bw = clamp(block_size_wide[bsize] >> (pd->subsampling_x + 1), 4,
405                    block_size_wide[BLOCK_64X64] >> (pd->subsampling_x + 1));
406     int bh = (left_mi_height << MI_SIZE_LOG2) >> pd->subsampling_y;
407 
408     if (av1_skip_u4x4_pred_in_obmc(bsize, pd, 1)) continue;
409     build_inter_predictors(ctxt->cm, xd, j, left_mbmi, 1, bw, bh, mi_x, mi_y);
410   }
411   *left_mbmi = backup_mbmi;
412 }
413 
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])414 void av1_build_prediction_by_left_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
415                                         int mi_row, int mi_col,
416                                         uint8_t *tmp_buf[MAX_MB_PLANE],
417                                         int tmp_width[MAX_MB_PLANE],
418                                         int tmp_height[MAX_MB_PLANE],
419                                         int tmp_stride[MAX_MB_PLANE]) {
420   if (!xd->left_available) return;
421 
422   // Adjust mb_to_right_edge to have the correct value for the OBMC
423   // prediction block. This is half the width of the original block,
424   // except for 128-wide blocks, where we only use a width of 32.
425   int this_width = xd->n4_w * MI_SIZE;
426   int pred_width = AOMMIN(this_width / 2, 32);
427   xd->mb_to_right_edge += (this_width - pred_width) * 8;
428 
429   struct build_prediction_ctxt ctxt = { cm,         mi_row,
430                                         mi_col,     tmp_buf,
431                                         tmp_width,  tmp_height,
432                                         tmp_stride, xd->mb_to_bottom_edge };
433   BLOCK_SIZE bsize = xd->mi[0]->sb_type;
434   foreach_overlappable_nb_left(cm, xd, mi_row,
435                                max_neighbor_obmc[mi_size_high_log2[bsize]],
436                                build_prediction_by_left_pred, &ctxt);
437 
438   xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8);
439   xd->mb_to_right_edge -= (this_width - pred_width) * 8;
440   xd->mb_to_bottom_edge = ctxt.mb_to_far_edge;
441 }
442 
av1_build_obmc_inter_predictors_sb(const AV1_COMMON * cm,MACROBLOCKD * xd,int mi_row,int mi_col)443 void av1_build_obmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
444                                         int mi_row, int mi_col) {
445   const int num_planes = av1_num_planes(cm);
446   uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
447   int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
448   int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
449   int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
450   int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
451   int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
452   int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
453 
454   if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
455     int len = sizeof(uint16_t);
456     dst_buf1[0] = CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[0]);
457     dst_buf1[1] =
458         CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[0] + MAX_SB_SQUARE * len);
459     dst_buf1[2] =
460         CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[0] + MAX_SB_SQUARE * 2 * len);
461     dst_buf2[0] = CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[1]);
462     dst_buf2[1] =
463         CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[1] + MAX_SB_SQUARE * len);
464     dst_buf2[2] =
465         CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[1] + MAX_SB_SQUARE * 2 * len);
466   } else {
467     dst_buf1[0] = xd->tmp_obmc_bufs[0];
468     dst_buf1[1] = xd->tmp_obmc_bufs[0] + MAX_SB_SQUARE;
469     dst_buf1[2] = xd->tmp_obmc_bufs[0] + MAX_SB_SQUARE * 2;
470     dst_buf2[0] = xd->tmp_obmc_bufs[1];
471     dst_buf2[1] = xd->tmp_obmc_bufs[1] + MAX_SB_SQUARE;
472     dst_buf2[2] = xd->tmp_obmc_bufs[1] + MAX_SB_SQUARE * 2;
473   }
474   av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col, dst_buf1,
475                                       dst_width1, dst_height1, dst_stride1);
476   av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col, dst_buf2,
477                                      dst_width2, dst_height2, dst_stride2);
478   av1_setup_dst_planes(xd->plane, xd->mi[0]->sb_type, get_frame_new_buffer(cm),
479                        mi_row, mi_col, 0, num_planes);
480   av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, dst_buf1, dst_stride1,
481                                   dst_buf2, dst_stride2);
482 }
483 
484 // Builds the inter-predictor for the single ref case
485 // 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)486 static void build_inter_predictors_single_buf(MACROBLOCKD *xd, int plane,
487                                               int bw, int bh, int x, int y,
488                                               int w, int h, int mi_x, int mi_y,
489                                               int ref, uint8_t *const ext_dst,
490                                               int ext_dst_stride,
491                                               int can_use_previous) {
492   struct macroblockd_plane *const pd = &xd->plane[plane];
493   const MB_MODE_INFO *mi = xd->mi[0];
494 
495   const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
496   struct buf_2d *const pre_buf = &pd->pre[ref];
497   uint8_t *const dst = get_buf_by_bd(xd, ext_dst) + ext_dst_stride * y + x;
498   const MV mv = mi->mv[ref].as_mv;
499 
500   ConvolveParams conv_params = get_conv_params(0, plane, xd->bd);
501   WarpTypesAllowed warp_types;
502   const WarpedMotionParams *const wm = &xd->global_motion[mi->ref_frame[ref]];
503   warp_types.global_warp_allowed = is_global_mv_block(mi, wm->wmtype);
504   warp_types.local_warp_allowed = mi->motion_mode == WARPED_CAUSAL;
505   const int pre_x = (mi_x) >> pd->subsampling_x;
506   const int pre_y = (mi_y) >> pd->subsampling_y;
507   uint8_t *pre;
508   SubpelParams subpel_params;
509   calc_subpel_params(xd, sf, mv, plane, pre_x, pre_y, x, y, pre_buf, &pre,
510                      &subpel_params, bw, bh);
511 
512   av1_make_inter_predictor(pre, pre_buf->stride, dst, ext_dst_stride,
513                            &subpel_params, sf, w, h, &conv_params,
514                            mi->interp_filters, &warp_types, pre_x + x,
515                            pre_y + y, plane, ref, mi, 0, xd, can_use_previous);
516 }
517 
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)518 void av1_build_inter_predictors_for_planes_single_buf(
519     MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane_from, int plane_to, int mi_row,
520     int mi_col, int ref, uint8_t *ext_dst[3], int ext_dst_stride[3],
521     int can_use_previous) {
522   int plane;
523   const int mi_x = mi_col * MI_SIZE;
524   const int mi_y = mi_row * MI_SIZE;
525   for (plane = plane_from; plane <= plane_to; ++plane) {
526     const BLOCK_SIZE plane_bsize = get_plane_block_size(
527         bsize, xd->plane[plane].subsampling_x, xd->plane[plane].subsampling_y);
528     const int bw = block_size_wide[plane_bsize];
529     const int bh = block_size_high[plane_bsize];
530     build_inter_predictors_single_buf(xd, plane, bw, bh, 0, 0, bw, bh, mi_x,
531                                       mi_y, ref, ext_dst[plane],
532                                       ext_dst_stride[plane], can_use_previous);
533   }
534 }
535 
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)536 static void build_masked_compound(
537     uint8_t *dst, int dst_stride, const uint8_t *src0, int src0_stride,
538     const uint8_t *src1, int src1_stride,
539     const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type, int h,
540     int w) {
541   // Derive subsampling from h and w passed in. May be refactored to
542   // pass in subsampling factors directly.
543   const int subh = (2 << mi_size_high_log2[sb_type]) == h;
544   const int subw = (2 << mi_size_wide_log2[sb_type]) == w;
545   const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type);
546   aom_blend_a64_mask(dst, dst_stride, src0, src0_stride, src1, src1_stride,
547                      mask, block_size_wide[sb_type], w, h, subw, subh);
548 }
549 
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)550 static void build_masked_compound_highbd(
551     uint8_t *dst_8, int dst_stride, const uint8_t *src0_8, int src0_stride,
552     const uint8_t *src1_8, int src1_stride,
553     const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type, int h,
554     int w, int bd) {
555   // Derive subsampling from h and w passed in. May be refactored to
556   // pass in subsampling factors directly.
557   const int subh = (2 << mi_size_high_log2[sb_type]) == h;
558   const int subw = (2 << mi_size_wide_log2[sb_type]) == w;
559   const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type);
560   // const uint8_t *mask =
561   //     av1_get_contiguous_soft_mask(wedge_index, wedge_sign, sb_type);
562   aom_highbd_blend_a64_mask(dst_8, dst_stride, src0_8, src0_stride, src1_8,
563                             src1_stride, mask, block_size_wide[sb_type], w, h,
564                             subw, subh, bd);
565 }
566 
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)567 static void build_wedge_inter_predictor_from_buf(
568     MACROBLOCKD *xd, int plane, int x, int y, int w, int h, uint8_t *ext_dst0,
569     int ext_dst_stride0, uint8_t *ext_dst1, int ext_dst_stride1) {
570   MB_MODE_INFO *const mbmi = xd->mi[0];
571   const int is_compound = has_second_ref(mbmi);
572   MACROBLOCKD_PLANE *const pd = &xd->plane[plane];
573   struct buf_2d *const dst_buf = &pd->dst;
574   uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x;
575   mbmi->interinter_comp.seg_mask = xd->seg_mask;
576   const INTERINTER_COMPOUND_DATA *comp_data = &mbmi->interinter_comp;
577 
578   if (is_compound && is_masked_compound_type(comp_data->type)) {
579     if (!plane && comp_data->type == COMPOUND_DIFFWTD) {
580       if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
581         av1_build_compound_diffwtd_mask_highbd(
582             comp_data->seg_mask, comp_data->mask_type,
583             CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0,
584             CONVERT_TO_BYTEPTR(ext_dst1), ext_dst_stride1, h, w, xd->bd);
585       else
586         av1_build_compound_diffwtd_mask(
587             comp_data->seg_mask, comp_data->mask_type, ext_dst0,
588             ext_dst_stride0, ext_dst1, ext_dst_stride1, h, w);
589     }
590 
591     if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
592       build_masked_compound_highbd(
593           dst, dst_buf->stride, CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0,
594           CONVERT_TO_BYTEPTR(ext_dst1), ext_dst_stride1, comp_data,
595           mbmi->sb_type, h, w, xd->bd);
596     else
597       build_masked_compound(dst, dst_buf->stride, ext_dst0, ext_dst_stride0,
598                             ext_dst1, ext_dst_stride1, comp_data, mbmi->sb_type,
599                             h, w);
600   } else {
601     if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
602       aom_highbd_convolve_copy(CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0,
603                                dst, dst_buf->stride, NULL, 0, NULL, 0, w, h,
604                                xd->bd);
605     else
606       aom_convolve_copy(ext_dst0, ext_dst_stride0, dst, dst_buf->stride, NULL,
607                         0, NULL, 0, w, h);
608   }
609 }
610 
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])611 void av1_build_wedge_inter_predictor_from_buf(MACROBLOCKD *xd, BLOCK_SIZE bsize,
612                                               int plane_from, int plane_to,
613                                               uint8_t *ext_dst0[3],
614                                               int ext_dst_stride0[3],
615                                               uint8_t *ext_dst1[3],
616                                               int ext_dst_stride1[3]) {
617   int plane;
618   for (plane = plane_from; plane <= plane_to; ++plane) {
619     const BLOCK_SIZE plane_bsize = get_plane_block_size(
620         bsize, xd->plane[plane].subsampling_x, xd->plane[plane].subsampling_y);
621     const int bw = block_size_wide[plane_bsize];
622     const int bh = block_size_high[plane_bsize];
623     build_wedge_inter_predictor_from_buf(
624         xd, plane, 0, 0, bw, bh, ext_dst0[plane], ext_dst_stride0[plane],
625         ext_dst1[plane], ext_dst_stride1[plane]);
626   }
627 }
628