• 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 #ifndef AOM_AV1_COMMON_RECONINTER_H_
13 #define AOM_AV1_COMMON_RECONINTER_H_
14 
15 #include "av1/common/av1_common_int.h"
16 #include "av1/common/convolve.h"
17 #include "av1/common/filter.h"
18 #include "av1/common/warped_motion.h"
19 #include "aom/aom_integer.h"
20 
21 // Work out how many pixels off the edge of a reference frame we're allowed
22 // to go when forming an inter prediction.
23 // The outermost row/col of each referernce frame is extended by
24 // (AOM_BORDER_IN_PIXELS >> subsampling) pixels, but we need to keep
25 // at least AOM_INTERP_EXTEND pixels within that to account for filtering.
26 //
27 // We have to break this up into two macros to keep both clang-format and
28 // tools/lint-hunks.py happy.
29 #define AOM_LEFT_TOP_MARGIN_PX(subsampling) \
30   ((AOM_BORDER_IN_PIXELS >> subsampling) - AOM_INTERP_EXTEND)
31 #define AOM_LEFT_TOP_MARGIN_SCALED(subsampling) \
32   (AOM_LEFT_TOP_MARGIN_PX(subsampling) << SCALE_SUBPEL_BITS)
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 #define MAX_WEDGE_TYPES 16
39 
40 #define MAX_WEDGE_SIZE_LOG2 5  // 32x32
41 #define MAX_WEDGE_SIZE (1 << MAX_WEDGE_SIZE_LOG2)
42 #define MAX_WEDGE_SQUARE (MAX_WEDGE_SIZE * MAX_WEDGE_SIZE)
43 
44 #define WEDGE_WEIGHT_BITS 6
45 
46 #define WEDGE_NONE -1
47 
48 // Angles are with respect to horizontal anti-clockwise
49 enum {
50   WEDGE_HORIZONTAL = 0,
51   WEDGE_VERTICAL = 1,
52   WEDGE_OBLIQUE27 = 2,
53   WEDGE_OBLIQUE63 = 3,
54   WEDGE_OBLIQUE117 = 4,
55   WEDGE_OBLIQUE153 = 5,
56   WEDGE_DIRECTIONS
57 } UENUM1BYTE(WedgeDirectionType);
58 
59 // 3-tuple: {direction, x_offset, y_offset}
60 typedef struct {
61   WedgeDirectionType direction;
62   int x_offset;
63   int y_offset;
64 } wedge_code_type;
65 
66 typedef uint8_t *wedge_masks_type[MAX_WEDGE_TYPES];
67 
68 typedef struct {
69   int wedge_types;
70   const wedge_code_type *codebook;
71   uint8_t *signflip;
72   wedge_masks_type *masks;
73 } wedge_params_type;
74 
75 extern const wedge_params_type av1_wedge_params_lookup[BLOCK_SIZES_ALL];
76 
77 typedef struct SubpelParams {
78   int xs;
79   int ys;
80   int subpel_x;
81   int subpel_y;
82   int pos_x;
83   int pos_y;
84 } SubpelParams;
85 
86 struct build_prediction_ctxt {
87   const AV1_COMMON *cm;
88   uint8_t **tmp_buf;
89   int *tmp_width;
90   int *tmp_height;
91   int *tmp_stride;
92   int mb_to_far_edge;
93   void *dcb;  // Decoder-only coding block.
94 };
95 
96 typedef enum InterPredMode {
97   TRANSLATION_PRED,
98   WARP_PRED,
99 } InterPredMode;
100 
101 typedef enum InterCompMode {
102   UNIFORM_SINGLE,
103   UNIFORM_COMP,
104   MASK_COMP,
105 } InterCompMode;
106 
107 typedef struct InterPredParams {
108   InterPredMode mode;
109   InterCompMode comp_mode;
110   WarpedMotionParams warp_params;
111   ConvolveParams conv_params;
112   const InterpFilterParams *interp_filter_params[2];
113   int block_width;
114   int block_height;
115   int pix_row;
116   int pix_col;
117   struct buf_2d ref_frame_buf;
118   int subsampling_x;
119   int subsampling_y;
120   const struct scale_factors *scale_factors;
121   int bit_depth;
122   int use_hbd_buf;
123   INTERINTER_COMPOUND_DATA mask_comp;
124   BLOCK_SIZE sb_type;
125   int is_intrabc;
126   int top;
127   int left;
128 } InterPredParams;
129 
130 // Initialize sub-pel params required for inter prediction.
init_subpel_params(const MV * const src_mv,InterPredParams * const inter_pred_params,SubpelParams * subpel_params,int width,int height)131 static AOM_INLINE void init_subpel_params(
132     const MV *const src_mv, InterPredParams *const inter_pred_params,
133     SubpelParams *subpel_params, int width, int height) {
134   const struct scale_factors *sf = inter_pred_params->scale_factors;
135   int ssx = inter_pred_params->subsampling_x;
136   int ssy = inter_pred_params->subsampling_y;
137   int orig_pos_y = inter_pred_params->pix_row << SUBPEL_BITS;
138   orig_pos_y += src_mv->row * (1 << (1 - ssy));
139   int orig_pos_x = inter_pred_params->pix_col << SUBPEL_BITS;
140   orig_pos_x += src_mv->col * (1 << (1 - ssx));
141   const int is_scaled = av1_is_scaled(sf);
142   int pos_x, pos_y;
143   if (LIKELY(!is_scaled)) {
144     pos_y = av1_unscaled_value(orig_pos_y, sf);
145     pos_x = av1_unscaled_value(orig_pos_x, sf);
146   } else {
147     pos_y = av1_scaled_y(orig_pos_y, sf);
148     pos_x = av1_scaled_x(orig_pos_x, sf);
149   }
150 
151   pos_x += SCALE_EXTRA_OFF;
152   pos_y += SCALE_EXTRA_OFF;
153 
154   const int bottom = (height + AOM_INTERP_EXTEND) << SCALE_SUBPEL_BITS;
155   const int right = (width + AOM_INTERP_EXTEND) << SCALE_SUBPEL_BITS;
156   pos_y = clamp(pos_y, inter_pred_params->top, bottom);
157   pos_x = clamp(pos_x, inter_pred_params->left, right);
158 
159   subpel_params->pos_x = pos_x;
160   subpel_params->pos_y = pos_y;
161   subpel_params->subpel_x = pos_x & SCALE_SUBPEL_MASK;
162   subpel_params->subpel_y = pos_y & SCALE_SUBPEL_MASK;
163   subpel_params->xs = sf->x_step_q4;
164   subpel_params->ys = sf->y_step_q4;
165 }
166 
167 // Initialize interp filter required for inter prediction.
init_interp_filter_params(const InterpFilterParams * interp_filter_params[2],const InterpFilters * filter,int block_width,int block_height,int is_intrabc)168 static AOM_INLINE void init_interp_filter_params(
169     const InterpFilterParams *interp_filter_params[2],
170     const InterpFilters *filter, int block_width, int block_height,
171     int is_intrabc) {
172   if (UNLIKELY(is_intrabc)) {
173     interp_filter_params[0] = &av1_intrabc_filter_params;
174     interp_filter_params[1] = &av1_intrabc_filter_params;
175   } else {
176     interp_filter_params[0] = av1_get_interp_filter_params_with_block_size(
177         (InterpFilter)filter->x_filter, block_width);
178     interp_filter_params[1] = av1_get_interp_filter_params_with_block_size(
179         (InterpFilter)filter->y_filter, block_height);
180   }
181 }
182 
183 // Initialize parameters required for inter prediction at mode level.
init_inter_mode_params(const MV * const src_mv,InterPredParams * const inter_pred_params,SubpelParams * subpel_params,const struct scale_factors * sf,int width,int height)184 static AOM_INLINE void init_inter_mode_params(
185     const MV *const src_mv, InterPredParams *const inter_pred_params,
186     SubpelParams *subpel_params, const struct scale_factors *sf, int width,
187     int height) {
188   inter_pred_params->scale_factors = sf;
189   init_subpel_params(src_mv, inter_pred_params, subpel_params, width, height);
190 }
191 
192 // Initialize parameters required for inter prediction at block level.
init_inter_block_params(InterPredParams * inter_pred_params,int block_width,int block_height,int pix_row,int pix_col,int subsampling_x,int subsampling_y,int bit_depth,int use_hbd_buf,int is_intrabc)193 static AOM_INLINE void init_inter_block_params(
194     InterPredParams *inter_pred_params, int block_width, int block_height,
195     int pix_row, int pix_col, int subsampling_x, int subsampling_y,
196     int bit_depth, int use_hbd_buf, int is_intrabc) {
197   inter_pred_params->block_width = block_width;
198   inter_pred_params->block_height = block_height;
199   inter_pred_params->pix_row = pix_row;
200   inter_pred_params->pix_col = pix_col;
201   inter_pred_params->subsampling_x = subsampling_x;
202   inter_pred_params->subsampling_y = subsampling_y;
203   inter_pred_params->bit_depth = bit_depth;
204   inter_pred_params->use_hbd_buf = use_hbd_buf;
205   inter_pred_params->is_intrabc = is_intrabc;
206   inter_pred_params->mode = TRANSLATION_PRED;
207   inter_pred_params->comp_mode = UNIFORM_SINGLE;
208   inter_pred_params->top = -AOM_LEFT_TOP_MARGIN_SCALED(subsampling_y);
209   inter_pred_params->left = -AOM_LEFT_TOP_MARGIN_SCALED(subsampling_x);
210 }
211 
212 // Initialize params required for inter prediction.
av1_init_inter_params(InterPredParams * inter_pred_params,int block_width,int block_height,int pix_row,int pix_col,int subsampling_x,int subsampling_y,int bit_depth,int use_hbd_buf,int is_intrabc,const struct scale_factors * sf,const struct buf_2d * ref_buf,int_interpfilters interp_filters)213 static AOM_INLINE void av1_init_inter_params(
214     InterPredParams *inter_pred_params, int block_width, int block_height,
215     int pix_row, int pix_col, int subsampling_x, int subsampling_y,
216     int bit_depth, int use_hbd_buf, int is_intrabc,
217     const struct scale_factors *sf, const struct buf_2d *ref_buf,
218     int_interpfilters interp_filters) {
219   init_inter_block_params(inter_pred_params, block_width, block_height, pix_row,
220                           pix_col, subsampling_x, subsampling_y, bit_depth,
221                           use_hbd_buf, is_intrabc);
222   init_interp_filter_params(inter_pred_params->interp_filter_params,
223                             &interp_filters.as_filters, block_width,
224                             block_height, is_intrabc);
225   inter_pred_params->scale_factors = sf;
226   inter_pred_params->ref_frame_buf = *ref_buf;
227 }
228 
av1_init_comp_mode(InterPredParams * inter_pred_params)229 static AOM_INLINE void av1_init_comp_mode(InterPredParams *inter_pred_params) {
230   inter_pred_params->comp_mode = UNIFORM_COMP;
231 }
232 
233 void av1_init_warp_params(InterPredParams *inter_pred_params,
234                           const WarpTypesAllowed *warp_types, int ref,
235                           const MACROBLOCKD *xd, const MB_MODE_INFO *mi);
236 
has_scale(int xs,int ys)237 static INLINE int has_scale(int xs, int ys) {
238   return xs != SCALE_SUBPEL_SHIFTS || ys != SCALE_SUBPEL_SHIFTS;
239 }
240 
revert_scale_extra_bits(SubpelParams * sp)241 static INLINE void revert_scale_extra_bits(SubpelParams *sp) {
242   sp->subpel_x >>= SCALE_EXTRA_BITS;
243   sp->subpel_y >>= SCALE_EXTRA_BITS;
244   sp->xs >>= SCALE_EXTRA_BITS;
245   sp->ys >>= SCALE_EXTRA_BITS;
246   assert(sp->subpel_x < SUBPEL_SHIFTS);
247   assert(sp->subpel_y < SUBPEL_SHIFTS);
248   assert(sp->xs <= SUBPEL_SHIFTS);
249   assert(sp->ys <= SUBPEL_SHIFTS);
250 }
251 
inter_predictor(const uint8_t * src,int src_stride,uint8_t * dst,int dst_stride,const SubpelParams * subpel_params,int w,int h,ConvolveParams * conv_params,const InterpFilterParams * interp_filters[2])252 static INLINE void inter_predictor(
253     const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride,
254     const SubpelParams *subpel_params, int w, int h,
255     ConvolveParams *conv_params, const InterpFilterParams *interp_filters[2]) {
256   assert(conv_params->do_average == 0 || conv_params->do_average == 1);
257   const int is_scaled = has_scale(subpel_params->xs, subpel_params->ys);
258   if (is_scaled) {
259     av1_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
260                            interp_filters, subpel_params->subpel_x,
261                            subpel_params->xs, subpel_params->subpel_y,
262                            subpel_params->ys, 1, conv_params);
263   } else {
264     SubpelParams sp = *subpel_params;
265     revert_scale_extra_bits(&sp);
266     av1_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
267                            interp_filters, sp.subpel_x, sp.xs, sp.subpel_y,
268                            sp.ys, 0, conv_params);
269   }
270 }
271 
highbd_inter_predictor(const uint8_t * src,int src_stride,uint8_t * dst,int dst_stride,const SubpelParams * subpel_params,int w,int h,ConvolveParams * conv_params,const InterpFilterParams * interp_filters[2],int bd)272 static INLINE void highbd_inter_predictor(
273     const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride,
274     const SubpelParams *subpel_params, int w, int h,
275     ConvolveParams *conv_params, const InterpFilterParams *interp_filters[2],
276     int bd) {
277   assert(conv_params->do_average == 0 || conv_params->do_average == 1);
278   const int is_scaled = has_scale(subpel_params->xs, subpel_params->ys);
279   if (is_scaled) {
280     av1_highbd_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
281                                   interp_filters, subpel_params->subpel_x,
282                                   subpel_params->xs, subpel_params->subpel_y,
283                                   subpel_params->ys, 1, conv_params, bd);
284   } else {
285     SubpelParams sp = *subpel_params;
286     revert_scale_extra_bits(&sp);
287     av1_highbd_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
288                                   interp_filters, sp.subpel_x, sp.xs,
289                                   sp.subpel_y, sp.ys, 0, conv_params, bd);
290   }
291 }
292 
293 void av1_modify_neighbor_predictor_for_obmc(MB_MODE_INFO *mbmi);
294 int av1_skip_u4x4_pred_in_obmc(BLOCK_SIZE bsize,
295                                const struct macroblockd_plane *pd, int dir);
296 
is_interinter_compound_used(COMPOUND_TYPE type,BLOCK_SIZE sb_type)297 static INLINE int is_interinter_compound_used(COMPOUND_TYPE type,
298                                               BLOCK_SIZE sb_type) {
299   const int comp_allowed = is_comp_ref_allowed(sb_type);
300   switch (type) {
301     case COMPOUND_AVERAGE:
302     case COMPOUND_DISTWTD:
303     case COMPOUND_DIFFWTD: return comp_allowed;
304     case COMPOUND_WEDGE:
305       return comp_allowed && av1_wedge_params_lookup[sb_type].wedge_types > 0;
306     default: assert(0); return 0;
307   }
308 }
309 
is_any_masked_compound_used(BLOCK_SIZE sb_type)310 static INLINE int is_any_masked_compound_used(BLOCK_SIZE sb_type) {
311   COMPOUND_TYPE comp_type;
312   int i;
313   if (!is_comp_ref_allowed(sb_type)) return 0;
314   for (i = 0; i < COMPOUND_TYPES; i++) {
315     comp_type = (COMPOUND_TYPE)i;
316     if (is_masked_compound_type(comp_type) &&
317         is_interinter_compound_used(comp_type, sb_type))
318       return 1;
319   }
320   return 0;
321 }
322 
get_wedge_types_lookup(BLOCK_SIZE sb_type)323 static INLINE int get_wedge_types_lookup(BLOCK_SIZE sb_type) {
324   return av1_wedge_params_lookup[sb_type].wedge_types;
325 }
326 
av1_is_wedge_used(BLOCK_SIZE sb_type)327 static INLINE int av1_is_wedge_used(BLOCK_SIZE sb_type) {
328   return av1_wedge_params_lookup[sb_type].wedge_types > 0;
329 }
330 
331 void av1_make_inter_predictor(const uint8_t *src, int src_stride, uint8_t *dst,
332                               int dst_stride,
333                               InterPredParams *inter_pred_params,
334                               const SubpelParams *subpel_params);
335 void av1_make_masked_inter_predictor(const uint8_t *pre, int pre_stride,
336                                      uint8_t *dst, int dst_stride,
337                                      InterPredParams *inter_pred_params,
338                                      const SubpelParams *subpel_params);
339 
340 // TODO(jkoleszar): yet another mv clamping function :-(
clamp_mv_to_umv_border_sb(const MACROBLOCKD * xd,const MV * src_mv,int bw,int bh,int ss_x,int ss_y)341 static INLINE MV clamp_mv_to_umv_border_sb(const MACROBLOCKD *xd,
342                                            const MV *src_mv, int bw, int bh,
343                                            int ss_x, int ss_y) {
344   // If the MV points so far into the UMV border that no visible pixels
345   // are used for reconstruction, the subpel part of the MV can be
346   // discarded and the MV limited to 16 pixels with equivalent results.
347   const int spel_left = (AOM_INTERP_EXTEND + bw) << SUBPEL_BITS;
348   const int spel_right = spel_left - SUBPEL_SHIFTS;
349   const int spel_top = (AOM_INTERP_EXTEND + bh) << SUBPEL_BITS;
350   const int spel_bottom = spel_top - SUBPEL_SHIFTS;
351   MV clamped_mv = { (int16_t)(src_mv->row * (1 << (1 - ss_y))),
352                     (int16_t)(src_mv->col * (1 << (1 - ss_x))) };
353   assert(ss_x <= 1);
354   assert(ss_y <= 1);
355   const SubpelMvLimits mv_limits = {
356     xd->mb_to_left_edge * (1 << (1 - ss_x)) - spel_left,
357     xd->mb_to_right_edge * (1 << (1 - ss_x)) + spel_right,
358     xd->mb_to_top_edge * (1 << (1 - ss_y)) - spel_top,
359     xd->mb_to_bottom_edge * (1 << (1 - ss_y)) + spel_bottom
360   };
361 
362   clamp_mv(&clamped_mv, &mv_limits);
363 
364   return clamped_mv;
365 }
366 
scaled_buffer_offset(int x_offset,int y_offset,int stride,const struct scale_factors * sf)367 static INLINE int64_t scaled_buffer_offset(int x_offset, int y_offset,
368                                            int stride,
369                                            const struct scale_factors *sf) {
370   int x, y;
371   if (!sf) {
372     x = x_offset;
373     y = y_offset;
374   } else if (av1_is_scaled(sf)) {
375     x = av1_scaled_x(x_offset, sf) >> SCALE_EXTRA_BITS;
376     y = av1_scaled_y(y_offset, sf) >> SCALE_EXTRA_BITS;
377   } else {
378     x = av1_unscaled_value(x_offset, sf) >> SCALE_EXTRA_BITS;
379     y = av1_unscaled_value(y_offset, sf) >> SCALE_EXTRA_BITS;
380   }
381   return (int64_t)y * stride + x;
382 }
383 
setup_pred_plane(struct buf_2d * dst,BLOCK_SIZE bsize,uint8_t * src,int width,int height,int stride,int mi_row,int mi_col,const struct scale_factors * scale,int subsampling_x,int subsampling_y)384 static INLINE void setup_pred_plane(struct buf_2d *dst, BLOCK_SIZE bsize,
385                                     uint8_t *src, int width, int height,
386                                     int stride, int mi_row, int mi_col,
387                                     const struct scale_factors *scale,
388                                     int subsampling_x, int subsampling_y) {
389   // Offset the buffer pointer
390   if (subsampling_y && (mi_row & 0x01) && (mi_size_high[bsize] == 1))
391     mi_row -= 1;
392   if (subsampling_x && (mi_col & 0x01) && (mi_size_wide[bsize] == 1))
393     mi_col -= 1;
394 
395   const int x = (MI_SIZE * mi_col) >> subsampling_x;
396   const int y = (MI_SIZE * mi_row) >> subsampling_y;
397   dst->buf = src + scaled_buffer_offset(x, y, stride, scale);
398   dst->buf0 = src;
399   dst->width = width;
400   dst->height = height;
401   dst->stride = stride;
402 }
403 
404 void av1_setup_dst_planes(struct macroblockd_plane *planes, BLOCK_SIZE bsize,
405                           const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col,
406                           const int plane_start, const int plane_end);
407 
408 void av1_setup_pre_planes(MACROBLOCKD *xd, int idx,
409                           const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col,
410                           const struct scale_factors *sf, const int num_planes);
411 
set_default_interp_filters(MB_MODE_INFO * const mbmi,InterpFilter frame_interp_filter)412 static INLINE void set_default_interp_filters(
413     MB_MODE_INFO *const mbmi, InterpFilter frame_interp_filter) {
414   mbmi->interp_filters =
415       av1_broadcast_interp_filter(av1_unswitchable_filter(frame_interp_filter));
416 }
417 
av1_is_interp_needed(const MACROBLOCKD * const xd)418 static INLINE int av1_is_interp_needed(const MACROBLOCKD *const xd) {
419   const MB_MODE_INFO *const mbmi = xd->mi[0];
420   if (mbmi->skip_mode) return 0;
421   if (mbmi->motion_mode == WARPED_CAUSAL) return 0;
422   if (is_nontrans_global_motion(xd, xd->mi[0])) return 0;
423   return 1;
424 }
425 
426 // Sets up buffers 'dst_buf1' and 'dst_buf2' from relevant buffers in 'xd' for
427 // subsequent use in OBMC prediction.
428 void av1_setup_obmc_dst_bufs(MACROBLOCKD *xd, uint8_t **dst_buf1,
429                              uint8_t **dst_buf2);
430 
431 void av1_setup_build_prediction_by_above_pred(
432     MACROBLOCKD *xd, int rel_mi_col, uint8_t above_mi_width,
433     MB_MODE_INFO *above_mbmi, struct build_prediction_ctxt *ctxt,
434     const int num_planes);
435 void av1_setup_build_prediction_by_left_pred(MACROBLOCKD *xd, int rel_mi_row,
436                                              uint8_t left_mi_height,
437                                              MB_MODE_INFO *left_mbmi,
438                                              struct build_prediction_ctxt *ctxt,
439                                              const int num_planes);
440 void av1_build_obmc_inter_prediction(const AV1_COMMON *cm, MACROBLOCKD *xd,
441                                      uint8_t *above[MAX_MB_PLANE],
442                                      int above_stride[MAX_MB_PLANE],
443                                      uint8_t *left[MAX_MB_PLANE],
444                                      int left_stride[MAX_MB_PLANE]);
445 
446 const uint8_t *av1_get_obmc_mask(int length);
447 void av1_count_overlappable_neighbors(const AV1_COMMON *cm, MACROBLOCKD *xd);
448 
449 #define MASK_MASTER_SIZE ((MAX_WEDGE_SIZE) << 1)
450 #define MASK_MASTER_STRIDE (MASK_MASTER_SIZE)
451 
452 void av1_init_wedge_masks();
453 
av1_get_contiguous_soft_mask(int8_t wedge_index,int8_t wedge_sign,BLOCK_SIZE sb_type)454 static INLINE const uint8_t *av1_get_contiguous_soft_mask(int8_t wedge_index,
455                                                           int8_t wedge_sign,
456                                                           BLOCK_SIZE sb_type) {
457   return av1_wedge_params_lookup[sb_type].masks[wedge_sign][wedge_index];
458 }
459 
460 void av1_dist_wtd_comp_weight_assign(const AV1_COMMON *cm,
461                                      const MB_MODE_INFO *mbmi, int *fwd_offset,
462                                      int *bck_offset,
463                                      int *use_dist_wtd_comp_avg,
464                                      int is_compound);
465 
466 const uint8_t *av1_get_compound_type_mask(
467     const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type);
468 
469 // build interintra_predictors for one plane
470 void av1_build_interintra_predictor(const AV1_COMMON *cm, MACROBLOCKD *xd,
471                                     uint8_t *pred, int stride,
472                                     const BUFFER_SET *ctx, int plane,
473                                     BLOCK_SIZE bsize);
474 
475 void av1_build_intra_predictors_for_interintra(const AV1_COMMON *cm,
476                                                MACROBLOCKD *xd,
477                                                BLOCK_SIZE bsize, int plane,
478                                                const BUFFER_SET *ctx,
479                                                uint8_t *dst, int dst_stride);
480 
481 void av1_combine_interintra(MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane,
482                             const uint8_t *inter_pred, int inter_stride,
483                             const uint8_t *intra_pred, int intra_stride);
484 
485 int av1_allow_warp(const MB_MODE_INFO *const mbmi,
486                    const WarpTypesAllowed *const warp_types,
487                    const WarpedMotionParams *const gm_params,
488                    int build_for_obmc, const struct scale_factors *const sf,
489                    WarpedMotionParams *final_warp_params);
490 
491 #ifdef __cplusplus
492 }  // extern "C"
493 #endif
494 
495 #endif  // AOM_AV1_COMMON_RECONINTER_H_
496