xref: /aosp_15_r20/external/libaom/av1/common/reconinter.h (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
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 inline void init_subpel_params(const MV *const src_mv,
132                                       InterPredParams *const inter_pred_params,
133                                       SubpelParams *subpel_params, int width,
134                                       int height) {
135   const struct scale_factors *sf = inter_pred_params->scale_factors;
136   int ssx = inter_pred_params->subsampling_x;
137   int ssy = inter_pred_params->subsampling_y;
138   int orig_pos_y = inter_pred_params->pix_row << SUBPEL_BITS;
139   orig_pos_y += src_mv->row * (1 << (1 - ssy));
140   int orig_pos_x = inter_pred_params->pix_col << SUBPEL_BITS;
141   orig_pos_x += src_mv->col * (1 << (1 - ssx));
142   const int is_scaled = av1_is_scaled(sf);
143   int pos_x, pos_y;
144   if (LIKELY(!is_scaled)) {
145     pos_y = av1_unscaled_value(orig_pos_y, sf);
146     pos_x = av1_unscaled_value(orig_pos_x, sf);
147   } else {
148     pos_y = av1_scaled_y(orig_pos_y, sf);
149     pos_x = av1_scaled_x(orig_pos_x, sf);
150   }
151 
152   pos_x += SCALE_EXTRA_OFF;
153   pos_y += SCALE_EXTRA_OFF;
154 
155   const int bottom = (height + AOM_INTERP_EXTEND) << SCALE_SUBPEL_BITS;
156   const int right = (width + AOM_INTERP_EXTEND) << SCALE_SUBPEL_BITS;
157   pos_y = clamp(pos_y, inter_pred_params->top, bottom);
158   pos_x = clamp(pos_x, inter_pred_params->left, right);
159 
160   subpel_params->pos_x = pos_x;
161   subpel_params->pos_y = pos_y;
162   subpel_params->subpel_x = pos_x & SCALE_SUBPEL_MASK;
163   subpel_params->subpel_y = pos_y & SCALE_SUBPEL_MASK;
164   subpel_params->xs = sf->x_step_q4;
165   subpel_params->ys = sf->y_step_q4;
166 }
167 
168 // 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)169 static inline void init_interp_filter_params(
170     const InterpFilterParams *interp_filter_params[2],
171     const InterpFilters *filter, int block_width, int block_height,
172     int is_intrabc) {
173   if (UNLIKELY(is_intrabc)) {
174     interp_filter_params[0] = &av1_intrabc_filter_params;
175     interp_filter_params[1] = &av1_intrabc_filter_params;
176   } else {
177     interp_filter_params[0] = av1_get_interp_filter_params_with_block_size(
178         (InterpFilter)filter->x_filter, block_width);
179     interp_filter_params[1] = av1_get_interp_filter_params_with_block_size(
180         (InterpFilter)filter->y_filter, block_height);
181   }
182 }
183 
184 // 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)185 static inline void init_inter_mode_params(
186     const MV *const src_mv, InterPredParams *const inter_pred_params,
187     SubpelParams *subpel_params, const struct scale_factors *sf, int width,
188     int height) {
189   inter_pred_params->scale_factors = sf;
190   init_subpel_params(src_mv, inter_pred_params, subpel_params, width, height);
191 }
192 
193 // 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)194 static inline void init_inter_block_params(InterPredParams *inter_pred_params,
195                                            int block_width, int block_height,
196                                            int pix_row, int pix_col,
197                                            int subsampling_x, int subsampling_y,
198                                            int bit_depth, int use_hbd_buf,
199                                            int is_intrabc) {
200   inter_pred_params->block_width = block_width;
201   inter_pred_params->block_height = block_height;
202   inter_pred_params->pix_row = pix_row;
203   inter_pred_params->pix_col = pix_col;
204   inter_pred_params->subsampling_x = subsampling_x;
205   inter_pred_params->subsampling_y = subsampling_y;
206   inter_pred_params->bit_depth = bit_depth;
207   inter_pred_params->use_hbd_buf = use_hbd_buf;
208   inter_pred_params->is_intrabc = is_intrabc;
209   inter_pred_params->mode = TRANSLATION_PRED;
210   inter_pred_params->comp_mode = UNIFORM_SINGLE;
211   inter_pred_params->top = -AOM_LEFT_TOP_MARGIN_SCALED(subsampling_y);
212   inter_pred_params->left = -AOM_LEFT_TOP_MARGIN_SCALED(subsampling_x);
213 }
214 
215 // 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)216 static inline void av1_init_inter_params(
217     InterPredParams *inter_pred_params, int block_width, int block_height,
218     int pix_row, int pix_col, int subsampling_x, int subsampling_y,
219     int bit_depth, int use_hbd_buf, int is_intrabc,
220     const struct scale_factors *sf, const struct buf_2d *ref_buf,
221     int_interpfilters interp_filters) {
222   init_inter_block_params(inter_pred_params, block_width, block_height, pix_row,
223                           pix_col, subsampling_x, subsampling_y, bit_depth,
224                           use_hbd_buf, is_intrabc);
225   init_interp_filter_params(inter_pred_params->interp_filter_params,
226                             &interp_filters.as_filters, block_width,
227                             block_height, is_intrabc);
228   inter_pred_params->scale_factors = sf;
229   inter_pred_params->ref_frame_buf = *ref_buf;
230 }
231 
av1_init_comp_mode(InterPredParams * inter_pred_params)232 static inline void av1_init_comp_mode(InterPredParams *inter_pred_params) {
233   inter_pred_params->comp_mode = UNIFORM_COMP;
234 }
235 
236 void av1_init_warp_params(InterPredParams *inter_pred_params,
237                           const WarpTypesAllowed *warp_types, int ref,
238                           const MACROBLOCKD *xd, const MB_MODE_INFO *mi);
239 
has_scale(int xs,int ys)240 static inline int has_scale(int xs, int ys) {
241   return xs != SCALE_SUBPEL_SHIFTS || ys != SCALE_SUBPEL_SHIFTS;
242 }
243 
revert_scale_extra_bits(SubpelParams * sp)244 static inline void revert_scale_extra_bits(SubpelParams *sp) {
245   sp->subpel_x >>= SCALE_EXTRA_BITS;
246   sp->subpel_y >>= SCALE_EXTRA_BITS;
247   sp->xs >>= SCALE_EXTRA_BITS;
248   sp->ys >>= SCALE_EXTRA_BITS;
249   assert(sp->subpel_x < SUBPEL_SHIFTS);
250   assert(sp->subpel_y < SUBPEL_SHIFTS);
251   assert(sp->xs <= SUBPEL_SHIFTS);
252   assert(sp->ys <= SUBPEL_SHIFTS);
253 }
254 
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])255 static inline void inter_predictor(
256     const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride,
257     const SubpelParams *subpel_params, int w, int h,
258     ConvolveParams *conv_params, const InterpFilterParams *interp_filters[2]) {
259   assert(conv_params->do_average == 0 || conv_params->do_average == 1);
260   const int is_scaled = has_scale(subpel_params->xs, subpel_params->ys);
261   if (is_scaled) {
262     av1_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
263                            interp_filters, subpel_params->subpel_x,
264                            subpel_params->xs, subpel_params->subpel_y,
265                            subpel_params->ys, 1, conv_params);
266   } else {
267     SubpelParams sp = *subpel_params;
268     revert_scale_extra_bits(&sp);
269     av1_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
270                            interp_filters, sp.subpel_x, sp.xs, sp.subpel_y,
271                            sp.ys, 0, conv_params);
272   }
273 }
274 
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)275 static inline void highbd_inter_predictor(
276     const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride,
277     const SubpelParams *subpel_params, int w, int h,
278     ConvolveParams *conv_params, const InterpFilterParams *interp_filters[2],
279     int bd) {
280   assert(conv_params->do_average == 0 || conv_params->do_average == 1);
281   const int is_scaled = has_scale(subpel_params->xs, subpel_params->ys);
282   if (is_scaled) {
283     av1_highbd_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
284                                   interp_filters, subpel_params->subpel_x,
285                                   subpel_params->xs, subpel_params->subpel_y,
286                                   subpel_params->ys, 1, conv_params, bd);
287   } else {
288     SubpelParams sp = *subpel_params;
289     revert_scale_extra_bits(&sp);
290     av1_highbd_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
291                                   interp_filters, sp.subpel_x, sp.xs,
292                                   sp.subpel_y, sp.ys, 0, conv_params, bd);
293   }
294 }
295 
296 int av1_skip_u4x4_pred_in_obmc(BLOCK_SIZE bsize,
297                                const struct macroblockd_plane *pd, int dir);
298 
is_interinter_compound_used(COMPOUND_TYPE type,BLOCK_SIZE sb_type)299 static inline int is_interinter_compound_used(COMPOUND_TYPE type,
300                                               BLOCK_SIZE sb_type) {
301   const int comp_allowed = is_comp_ref_allowed(sb_type);
302   switch (type) {
303     case COMPOUND_AVERAGE:
304     case COMPOUND_DISTWTD:
305     case COMPOUND_DIFFWTD: return comp_allowed;
306     case COMPOUND_WEDGE:
307       return comp_allowed && av1_wedge_params_lookup[sb_type].wedge_types > 0;
308     default: assert(0); return 0;
309   }
310 }
311 
is_any_masked_compound_used(BLOCK_SIZE sb_type)312 static inline int is_any_masked_compound_used(BLOCK_SIZE sb_type) {
313   COMPOUND_TYPE comp_type;
314   int i;
315   if (!is_comp_ref_allowed(sb_type)) return 0;
316   for (i = 0; i < COMPOUND_TYPES; i++) {
317     comp_type = (COMPOUND_TYPE)i;
318     if (is_masked_compound_type(comp_type) &&
319         is_interinter_compound_used(comp_type, sb_type))
320       return 1;
321   }
322   return 0;
323 }
324 
get_wedge_types_lookup(BLOCK_SIZE sb_type)325 static inline int get_wedge_types_lookup(BLOCK_SIZE sb_type) {
326   return av1_wedge_params_lookup[sb_type].wedge_types;
327 }
328 
av1_is_wedge_used(BLOCK_SIZE sb_type)329 static inline int av1_is_wedge_used(BLOCK_SIZE sb_type) {
330   return av1_wedge_params_lookup[sb_type].wedge_types > 0;
331 }
332 
333 void av1_make_inter_predictor(const uint8_t *src, int src_stride, uint8_t *dst,
334                               int dst_stride,
335                               InterPredParams *inter_pred_params,
336                               const SubpelParams *subpel_params);
337 void av1_make_masked_inter_predictor(const uint8_t *pre, int pre_stride,
338                                      uint8_t *dst, int dst_stride,
339                                      InterPredParams *inter_pred_params,
340                                      const SubpelParams *subpel_params);
341 
342 // 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)343 static inline MV clamp_mv_to_umv_border_sb(const MACROBLOCKD *xd,
344                                            const MV *src_mv, int bw, int bh,
345                                            int ss_x, int ss_y) {
346   // If the MV points so far into the UMV border that no visible pixels
347   // are used for reconstruction, the subpel part of the MV can be
348   // discarded and the MV limited to 16 pixels with equivalent results.
349   const int spel_left = (AOM_INTERP_EXTEND + bw) << SUBPEL_BITS;
350   const int spel_right = spel_left - SUBPEL_SHIFTS;
351   const int spel_top = (AOM_INTERP_EXTEND + bh) << SUBPEL_BITS;
352   const int spel_bottom = spel_top - SUBPEL_SHIFTS;
353   MV clamped_mv = { (int16_t)(src_mv->row * (1 << (1 - ss_y))),
354                     (int16_t)(src_mv->col * (1 << (1 - ss_x))) };
355   assert(ss_x <= 1);
356   assert(ss_y <= 1);
357   const SubpelMvLimits mv_limits = {
358     xd->mb_to_left_edge * (1 << (1 - ss_x)) - spel_left,
359     xd->mb_to_right_edge * (1 << (1 - ss_x)) + spel_right,
360     xd->mb_to_top_edge * (1 << (1 - ss_y)) - spel_top,
361     xd->mb_to_bottom_edge * (1 << (1 - ss_y)) + spel_bottom
362   };
363 
364   clamp_mv(&clamped_mv, &mv_limits);
365 
366   return clamped_mv;
367 }
368 
scaled_buffer_offset(int x_offset,int y_offset,int stride,const struct scale_factors * sf)369 static inline int64_t scaled_buffer_offset(int x_offset, int y_offset,
370                                            int stride,
371                                            const struct scale_factors *sf) {
372   int x, y;
373   if (!sf) {
374     x = x_offset;
375     y = y_offset;
376   } else if (av1_is_scaled(sf)) {
377     x = av1_scaled_x(x_offset, sf) >> SCALE_EXTRA_BITS;
378     y = av1_scaled_y(y_offset, sf) >> SCALE_EXTRA_BITS;
379   } else {
380     x = av1_unscaled_value(x_offset, sf) >> SCALE_EXTRA_BITS;
381     y = av1_unscaled_value(y_offset, sf) >> SCALE_EXTRA_BITS;
382   }
383   return (int64_t)y * stride + x;
384 }
385 
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)386 static inline void setup_pred_plane(struct buf_2d *dst, BLOCK_SIZE bsize,
387                                     uint8_t *src, int width, int height,
388                                     int stride, int mi_row, int mi_col,
389                                     const struct scale_factors *scale,
390                                     int subsampling_x, int subsampling_y) {
391   // Offset the buffer pointer
392   if (subsampling_y && (mi_row & 0x01) && (mi_size_high[bsize] == 1))
393     mi_row -= 1;
394   if (subsampling_x && (mi_col & 0x01) && (mi_size_wide[bsize] == 1))
395     mi_col -= 1;
396 
397   const int x = (MI_SIZE * mi_col) >> subsampling_x;
398   const int y = (MI_SIZE * mi_row) >> subsampling_y;
399   dst->buf = src + scaled_buffer_offset(x, y, stride, scale);
400   dst->buf0 = src;
401   dst->width = width;
402   dst->height = height;
403   dst->stride = stride;
404 }
405 
406 void av1_setup_dst_planes(struct macroblockd_plane *planes, BLOCK_SIZE bsize,
407                           const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col,
408                           const int plane_start, const int plane_end);
409 
410 void av1_setup_pre_planes(MACROBLOCKD *xd, int idx,
411                           const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col,
412                           const struct scale_factors *sf, const int num_planes);
413 
set_default_interp_filters(MB_MODE_INFO * const mbmi,InterpFilter frame_interp_filter)414 static inline void set_default_interp_filters(
415     MB_MODE_INFO *const mbmi, InterpFilter frame_interp_filter) {
416   mbmi->interp_filters =
417       av1_broadcast_interp_filter(av1_unswitchable_filter(frame_interp_filter));
418 }
419 
av1_is_interp_needed(const MACROBLOCKD * const xd)420 static inline int av1_is_interp_needed(const MACROBLOCKD *const xd) {
421   const MB_MODE_INFO *const mbmi = xd->mi[0];
422   if (mbmi->skip_mode) return 0;
423   if (mbmi->motion_mode == WARPED_CAUSAL) return 0;
424   if (is_nontrans_global_motion(xd, xd->mi[0])) return 0;
425   return 1;
426 }
427 
428 // Sets up buffers 'dst_buf1' and 'dst_buf2' from relevant buffers in 'xd' for
429 // subsequent use in OBMC prediction.
430 void av1_setup_obmc_dst_bufs(MACROBLOCKD *xd, uint8_t **dst_buf1,
431                              uint8_t **dst_buf2);
432 
433 void av1_setup_build_prediction_by_above_pred(
434     MACROBLOCKD *xd, int rel_mi_col, uint8_t above_mi_width,
435     MB_MODE_INFO *above_mbmi, struct build_prediction_ctxt *ctxt,
436     const int num_planes);
437 void av1_setup_build_prediction_by_left_pred(MACROBLOCKD *xd, int rel_mi_row,
438                                              uint8_t left_mi_height,
439                                              MB_MODE_INFO *left_mbmi,
440                                              struct build_prediction_ctxt *ctxt,
441                                              const int num_planes);
442 void av1_build_obmc_inter_prediction(const AV1_COMMON *cm, MACROBLOCKD *xd,
443                                      uint8_t *above[MAX_MB_PLANE],
444                                      int above_stride[MAX_MB_PLANE],
445                                      uint8_t *left[MAX_MB_PLANE],
446                                      int left_stride[MAX_MB_PLANE]);
447 
448 const uint8_t *av1_get_obmc_mask(int length);
449 void av1_count_overlappable_neighbors(const AV1_COMMON *cm, MACROBLOCKD *xd);
450 
451 #define MASK_MASTER_SIZE ((MAX_WEDGE_SIZE) << 1)
452 #define MASK_MASTER_STRIDE (MASK_MASTER_SIZE)
453 
454 void av1_init_wedge_masks(void);
455 
av1_get_contiguous_soft_mask(int8_t wedge_index,int8_t wedge_sign,BLOCK_SIZE sb_type)456 static inline const uint8_t *av1_get_contiguous_soft_mask(int8_t wedge_index,
457                                                           int8_t wedge_sign,
458                                                           BLOCK_SIZE sb_type) {
459   return av1_wedge_params_lookup[sb_type].masks[wedge_sign][wedge_index];
460 }
461 
462 void av1_dist_wtd_comp_weight_assign(const AV1_COMMON *cm,
463                                      const MB_MODE_INFO *mbmi, int *fwd_offset,
464                                      int *bck_offset,
465                                      int *use_dist_wtd_comp_avg,
466                                      int is_compound);
467 
468 const uint8_t *av1_get_compound_type_mask(
469     const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type);
470 
471 // build interintra_predictors for one plane
472 void av1_build_interintra_predictor(const AV1_COMMON *cm, MACROBLOCKD *xd,
473                                     uint8_t *pred, int stride,
474                                     const BUFFER_SET *ctx, int plane,
475                                     BLOCK_SIZE bsize);
476 
477 void av1_build_intra_predictors_for_interintra(const AV1_COMMON *cm,
478                                                MACROBLOCKD *xd,
479                                                BLOCK_SIZE bsize, int plane,
480                                                const BUFFER_SET *ctx,
481                                                uint8_t *dst, int dst_stride);
482 
483 void av1_combine_interintra(MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane,
484                             const uint8_t *inter_pred, int inter_stride,
485                             const uint8_t *intra_pred, int intra_stride);
486 
487 #ifdef __cplusplus
488 }  // extern "C"
489 #endif
490 
491 #endif  // AOM_AV1_COMMON_RECONINTER_H_
492