blob: abe309656b8ca6eac9f85e79b9a578f4bad57a2f [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * 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.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
Yaowu Xuf883b422016-08-30 14:01:10 -070012#ifndef AV1_COMMON_RECONINTER_H_
13#define AV1_COMMON_RECONINTER_H_
Yaowu Xuc27fc142016-08-22 16:08:15 -070014
15#include "av1/common/filter.h"
16#include "av1/common/onyxc_int.h"
Yaowu Xu6557ea92016-10-31 16:33:36 -070017#include "av1/common/convolve.h"
Sarah Parkerc2d38712017-01-24 15:15:41 -080018#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
19#include "av1/common/warped_motion.h"
20#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuf883b422016-08-30 14:01:10 -070021#include "aom/aom_integer.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070022
23#ifdef __cplusplus
24extern "C" {
25#endif
26
27static INLINE void inter_predictor(const uint8_t *src, int src_stride,
28 uint8_t *dst, int dst_stride,
29 const int subpel_x, const int subpel_y,
30 const struct scale_factors *sf, int w, int h,
Angie Chiang9f45bc42017-01-13 16:27:54 -080031 ConvolveParams *conv_params,
Yaowu Xuc27fc142016-08-22 16:08:15 -070032#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -070033 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -070034#else
James Zern7b9407a2016-05-18 23:48:05 -070035 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -070036#endif
37 int xs, int ys) {
38#if CONFIG_DUAL_FILTER
39 InterpFilterParams interp_filter_params_x =
Angie Chiang9f45bc42017-01-13 16:27:54 -080040 av1_get_interp_filter_params(interp_filter[1 + 2 * conv_params->ref]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070041 InterpFilterParams interp_filter_params_y =
Angie Chiang9f45bc42017-01-13 16:27:54 -080042 av1_get_interp_filter_params(interp_filter[0 + 2 * conv_params->ref]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070043#else
44 InterpFilterParams interp_filter_params =
Yaowu Xuf883b422016-08-30 14:01:10 -070045 av1_get_interp_filter_params(interp_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -070046#endif
47
48#if CONFIG_DUAL_FILTER
49 if (interp_filter_params_x.taps == SUBPEL_TAPS &&
Angie Chiang117aa0d2017-01-18 15:27:03 -080050 interp_filter_params_y.taps == SUBPEL_TAPS && w > 2 && h > 2 &&
51 conv_params->round == CONVOLVE_OPT_ROUND) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070052 const int16_t *kernel_x =
Yaowu Xuf883b422016-08-30 14:01:10 -070053 av1_get_interp_filter_subpel_kernel(interp_filter_params_x, subpel_x);
Yaowu Xuc27fc142016-08-22 16:08:15 -070054 const int16_t *kernel_y =
Yaowu Xuf883b422016-08-30 14:01:10 -070055 av1_get_interp_filter_subpel_kernel(interp_filter_params_y, subpel_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -070056#else
Angie Chiang117aa0d2017-01-18 15:27:03 -080057 if (interp_filter_params.taps == SUBPEL_TAPS && w > 2 && h > 2 &&
58 conv_params->round == CONVOLVE_OPT_ROUND) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070059 const int16_t *kernel_x =
Yaowu Xuf883b422016-08-30 14:01:10 -070060 av1_get_interp_filter_subpel_kernel(interp_filter_params, subpel_x);
Yaowu Xuc27fc142016-08-22 16:08:15 -070061 const int16_t *kernel_y =
Yaowu Xuf883b422016-08-30 14:01:10 -070062 av1_get_interp_filter_subpel_kernel(interp_filter_params, subpel_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -070063#endif
Angie Chiang9f45bc42017-01-13 16:27:54 -080064 sf->predict[subpel_x != 0][subpel_y != 0][conv_params->ref](
Yaowu Xuc27fc142016-08-22 16:08:15 -070065 src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h);
Yaowu Xuc27fc142016-08-22 16:08:15 -070066 } else {
67 // ref_idx > 0 means this is the second reference frame
68 // first reference frame's prediction result is already in dst
69 // therefore we need to average the first and second results
Yaowu Xuf883b422016-08-30 14:01:10 -070070 av1_convolve(src, src_stride, dst, dst_stride, w, h, interp_filter,
Angie Chiang9f45bc42017-01-13 16:27:54 -080071 subpel_x, xs, subpel_y, ys, conv_params);
Yaowu Xuc27fc142016-08-22 16:08:15 -070072 }
73}
74
Yaowu Xuf883b422016-08-30 14:01:10 -070075#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070076static INLINE void highbd_inter_predictor(const uint8_t *src, int src_stride,
77 uint8_t *dst, int dst_stride,
78 const int subpel_x,
79 const int subpel_y,
80 const struct scale_factors *sf, int w,
81 int h, int ref,
82#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -070083 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -070084#else
James Zern7b9407a2016-05-18 23:48:05 -070085 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -070086#endif
87 int xs, int ys, int bd) {
88#if CONFIG_DUAL_FILTER
89 InterpFilterParams interp_filter_params_x =
Yaowu Xuf883b422016-08-30 14:01:10 -070090 av1_get_interp_filter_params(interp_filter[1 + 2 * ref]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070091 InterpFilterParams interp_filter_params_y =
Yaowu Xuf883b422016-08-30 14:01:10 -070092 av1_get_interp_filter_params(interp_filter[0 + 2 * ref]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070093#else
94 InterpFilterParams interp_filter_params =
Yaowu Xuf883b422016-08-30 14:01:10 -070095 av1_get_interp_filter_params(interp_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -070096#endif
97
98#if CONFIG_DUAL_FILTER
99 if (interp_filter_params_x.taps == SUBPEL_TAPS &&
100 interp_filter_params_y.taps == SUBPEL_TAPS && w > 2 && h > 2) {
101 const int16_t *kernel_x =
Yaowu Xuf883b422016-08-30 14:01:10 -0700102 av1_get_interp_filter_subpel_kernel(interp_filter_params_x, subpel_x);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700103 const int16_t *kernel_y =
Yaowu Xuf883b422016-08-30 14:01:10 -0700104 av1_get_interp_filter_subpel_kernel(interp_filter_params_y, subpel_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700105#else
Jingning Hane29ea122016-06-21 17:47:30 -0700106 if (interp_filter_params.taps == SUBPEL_TAPS && w > 2 && h > 2) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700107 const int16_t *kernel_x =
Yaowu Xuf883b422016-08-30 14:01:10 -0700108 av1_get_interp_filter_subpel_kernel(interp_filter_params, subpel_x);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700109 const int16_t *kernel_y =
Yaowu Xuf883b422016-08-30 14:01:10 -0700110 av1_get_interp_filter_subpel_kernel(interp_filter_params, subpel_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700111#endif // CONFIG_DUAL_FILTER
Yaowu Xuc27fc142016-08-22 16:08:15 -0700112 sf->highbd_predict[subpel_x != 0][subpel_y != 0][ref](
113 src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h, bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700114 } else {
115 // ref > 0 means this is the second reference frame
116 // first reference frame's prediction result is already in dst
117 // therefore we need to average the first and second results
118 int avg = ref > 0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700119 av1_highbd_convolve(src, src_stride, dst, dst_stride, w, h, interp_filter,
120 subpel_x, xs, subpel_y, ys, avg, bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700121 }
122}
Yaowu Xuf883b422016-08-30 14:01:10 -0700123#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700124
125#if CONFIG_EXT_INTER
126// Set to one to use larger codebooks
127#define USE_LARGE_WEDGE_CODEBOOK 0
128
129#if USE_LARGE_WEDGE_CODEBOOK
130#define MAX_WEDGE_TYPES (1 << 5)
131#else
132#define MAX_WEDGE_TYPES (1 << 4)
133#endif
134
135#define MAX_WEDGE_SIZE_LOG2 5 // 32x32
136#define MAX_WEDGE_SIZE (1 << MAX_WEDGE_SIZE_LOG2)
137#define MAX_WEDGE_SQUARE (MAX_WEDGE_SIZE * MAX_WEDGE_SIZE)
138
139#define WEDGE_WEIGHT_BITS 6
140
141#define WEDGE_NONE -1
142
143// Angles are with respect to horizontal anti-clockwise
144typedef enum {
145 WEDGE_HORIZONTAL = 0,
146 WEDGE_VERTICAL = 1,
147 WEDGE_OBLIQUE27 = 2,
148 WEDGE_OBLIQUE63 = 3,
149 WEDGE_OBLIQUE117 = 4,
150 WEDGE_OBLIQUE153 = 5,
151 WEDGE_DIRECTIONS
152} WedgeDirectionType;
153
154// 3-tuple: {direction, x_offset, y_offset}
155typedef struct {
156 WedgeDirectionType direction;
157 int x_offset;
158 int y_offset;
159} wedge_code_type;
160
161typedef uint8_t *wedge_masks_type[MAX_WEDGE_TYPES];
162
163typedef struct {
164 int bits;
165 const wedge_code_type *codebook;
166 uint8_t *signflip;
167 int smoother;
168 wedge_masks_type *masks;
169} wedge_params_type;
170
171extern const wedge_params_type wedge_params_lookup[BLOCK_SIZES];
172
173static INLINE int get_wedge_bits_lookup(BLOCK_SIZE sb_type) {
174 return wedge_params_lookup[sb_type].bits;
175}
176
177static INLINE int is_interinter_wedge_used(BLOCK_SIZE sb_type) {
178 (void)sb_type;
179 return wedge_params_lookup[sb_type].bits > 0;
180}
181
182static INLINE int get_interinter_wedge_bits(BLOCK_SIZE sb_type) {
183 const int wbits = wedge_params_lookup[sb_type].bits;
184 return (wbits > 0) ? wbits + 1 : 0;
185}
186
187static INLINE int is_interintra_wedge_used(BLOCK_SIZE sb_type) {
188 (void)sb_type;
189 return wedge_params_lookup[sb_type].bits > 0;
190}
191
192static INLINE int get_interintra_wedge_bits(BLOCK_SIZE sb_type) {
193 return wedge_params_lookup[sb_type].bits;
194}
Sarah Parker569edda2016-12-14 14:57:38 -0800195
196#if CONFIG_COMPOUND_SEGMENT
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800197void build_compound_seg_mask(uint8_t *mask, SEG_MASK_TYPE mask_type,
Sarah Parker569edda2016-12-14 14:57:38 -0800198 const uint8_t *src0, int src0_stride,
199 const uint8_t *src1, int src1_stride,
200 BLOCK_SIZE sb_type, int h, int w);
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800201#if CONFIG_AOM_HIGHBITDEPTH
202void build_compound_seg_mask_highbd(uint8_t *mask, SEG_MASK_TYPE mask_type,
203 const uint8_t *src0, int src0_stride,
204 const uint8_t *src1, int src1_stride,
205 BLOCK_SIZE sb_type, int h, int w, int bd);
206#endif // CONFIG_AOM_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -0800207#endif // CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -0700208#endif // CONFIG_EXT_INTER
209
210void build_inter_predictors(MACROBLOCKD *xd, int plane,
Yue Chencb60b182016-10-13 15:18:22 -0700211#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700212 int mi_col_offset, int mi_row_offset,
Yue Chencb60b182016-10-13 15:18:22 -0700213#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700214 int block, int bw, int bh, int x, int y, int w,
215 int h,
216#if CONFIG_SUPERTX && CONFIG_EXT_INTER
217 int wedge_offset_x, int wedge_offset_y,
218#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
219 int mi_x, int mi_y);
220
Yaowu Xuf883b422016-08-30 14:01:10 -0700221static INLINE void av1_make_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700222 const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride,
223 const int subpel_x, const int subpel_y, const struct scale_factors *sf,
Angie Chiang9f45bc42017-01-13 16:27:54 -0800224 int w, int h, ConvolveParams *conv_params,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700225#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -0700226 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700227#else
James Zern7b9407a2016-05-18 23:48:05 -0700228 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700229#endif
Sarah Parkerc2d38712017-01-24 15:15:41 -0800230#if CONFIG_GLOBAL_MOTION
231 int is_global, int p_col, int p_row, int plane, int ref,
232#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -0700233 int xs, int ys, const MACROBLOCKD *xd) {
234 (void)xd;
Sarah Parkerc2d38712017-01-24 15:15:41 -0800235#if CONFIG_GLOBAL_MOTION
236 if (is_global) {
237 const MODE_INFO *mi = xd->mi[0];
238 const struct macroblockd_plane *const pd = &xd->plane[plane];
239 const struct buf_2d *const pre_buf = &pd->pre[ref];
240 WarpedMotionParams *gm = &xd->global_motion[mi->mbmi.ref_frame[ref]];
241
242 av1_warp_plane(gm,
Yaowu Xuf883b422016-08-30 14:01:10 -0700243#if CONFIG_AOM_HIGHBITDEPTH
Sarah Parkerc2d38712017-01-24 15:15:41 -0800244 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
245#endif // CONFIG_AOM_HIGHBITDEPTH
246 pre_buf->buf0, pre_buf->width, pre_buf->height,
247 pre_buf->stride, dst, p_col, p_row, w, h, dst_stride,
248 pd->subsampling_x, pd->subsampling_y, xs, ys, ref);
249 return;
250 }
251#endif // CONFIG_GLOBAL_MOTION
252#if CONFIG_AOM_HIGHBITDEPTH
253 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700254 highbd_inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y,
Angie Chiang9f45bc42017-01-13 16:27:54 -0800255 sf, w, h, conv_params->ref, interp_filter, xs, ys,
256 xd->bd);
Sarah Parkerc2d38712017-01-24 15:15:41 -0800257 return;
258 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700259#endif // CONFIG_AOM_HIGHBITDEPTH
Sarah Parkerc2d38712017-01-24 15:15:41 -0800260 inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y, sf, w,
261 h, conv_params, interp_filter, xs, ys);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700262}
263
264#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -0700265void av1_make_masked_inter_predictor(const uint8_t *pre, int pre_stride,
266 uint8_t *dst, int dst_stride,
267 const int subpel_x, const int subpel_y,
268 const struct scale_factors *sf, int w,
269 int h,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700270#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -0700271 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700272#else
James Zern7b9407a2016-05-18 23:48:05 -0700273 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700274#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700275 int xs, int ys,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700276#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -0700277 int wedge_offset_x, int wedge_offset_y,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700278#endif // CONFIG_SUPERTX
Sarah Parkerc2d38712017-01-24 15:15:41 -0800279#if CONFIG_COMPOUND_SEGMENT || CONFIG_GLOBAL_MOTION
Sarah Parker569edda2016-12-14 14:57:38 -0800280 int plane,
Sarah Parkerc2d38712017-01-24 15:15:41 -0800281#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_GLOBAL_MOTION
282#if CONFIG_GLOBAL_MOTION
283 int is_global, int p_col, int p_row,
284 int ref,
285#endif // CONFIG_GLOBAL_MOTION
Sarah Parker569edda2016-12-14 14:57:38 -0800286 MACROBLOCKD *xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700287#endif // CONFIG_EXT_INTER
288
289static INLINE int round_mv_comp_q4(int value) {
290 return (value < 0 ? value - 2 : value + 2) / 4;
291}
292
293static MV mi_mv_pred_q4(const MODE_INFO *mi, int idx) {
294 MV res = {
295 round_mv_comp_q4(
296 mi->bmi[0].as_mv[idx].as_mv.row + mi->bmi[1].as_mv[idx].as_mv.row +
297 mi->bmi[2].as_mv[idx].as_mv.row + mi->bmi[3].as_mv[idx].as_mv.row),
298 round_mv_comp_q4(
299 mi->bmi[0].as_mv[idx].as_mv.col + mi->bmi[1].as_mv[idx].as_mv.col +
300 mi->bmi[2].as_mv[idx].as_mv.col + mi->bmi[3].as_mv[idx].as_mv.col)
301 };
302 return res;
303}
304
305static INLINE int round_mv_comp_q2(int value) {
306 return (value < 0 ? value - 1 : value + 1) / 2;
307}
308
309static MV mi_mv_pred_q2(const MODE_INFO *mi, int idx, int block0, int block1) {
310 MV res = { round_mv_comp_q2(mi->bmi[block0].as_mv[idx].as_mv.row +
311 mi->bmi[block1].as_mv[idx].as_mv.row),
312 round_mv_comp_q2(mi->bmi[block0].as_mv[idx].as_mv.col +
313 mi->bmi[block1].as_mv[idx].as_mv.col) };
314 return res;
315}
316
317// TODO(jkoleszar): yet another mv clamping function :-(
318static INLINE MV clamp_mv_to_umv_border_sb(const MACROBLOCKD *xd,
319 const MV *src_mv, int bw, int bh,
320 int ss_x, int ss_y) {
321 // If the MV points so far into the UMV border that no visible pixels
322 // are used for reconstruction, the subpel part of the MV can be
323 // discarded and the MV limited to 16 pixels with equivalent results.
Yaowu Xuf883b422016-08-30 14:01:10 -0700324 const int spel_left = (AOM_INTERP_EXTEND + bw) << SUBPEL_BITS;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700325 const int spel_right = spel_left - SUBPEL_SHIFTS;
Yaowu Xuf883b422016-08-30 14:01:10 -0700326 const int spel_top = (AOM_INTERP_EXTEND + bh) << SUBPEL_BITS;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700327 const int spel_bottom = spel_top - SUBPEL_SHIFTS;
328 MV clamped_mv = { src_mv->row * (1 << (1 - ss_y)),
329 src_mv->col * (1 << (1 - ss_x)) };
330 assert(ss_x <= 1);
331 assert(ss_y <= 1);
332
333 clamp_mv(&clamped_mv, xd->mb_to_left_edge * (1 << (1 - ss_x)) - spel_left,
334 xd->mb_to_right_edge * (1 << (1 - ss_x)) + spel_right,
335 xd->mb_to_top_edge * (1 << (1 - ss_y)) - spel_top,
336 xd->mb_to_bottom_edge * (1 << (1 - ss_y)) + spel_bottom);
337
338 return clamped_mv;
339}
340
341static INLINE MV average_split_mvs(const struct macroblockd_plane *pd,
342 const MODE_INFO *mi, int ref, int block) {
343 const int ss_idx = ((pd->subsampling_x > 0) << 1) | (pd->subsampling_y > 0);
344 MV res = { 0, 0 };
345 switch (ss_idx) {
346 case 0: res = mi->bmi[block].as_mv[ref].as_mv; break;
347 case 1: res = mi_mv_pred_q2(mi, ref, block, block + 2); break;
348 case 2: res = mi_mv_pred_q2(mi, ref, block, block + 1); break;
349 case 3: res = mi_mv_pred_q4(mi, ref); break;
350 default: assert(ss_idx <= 3 && ss_idx >= 0);
351 }
352 return res;
353}
354
Yaowu Xuf883b422016-08-30 14:01:10 -0700355void av1_build_inter_predictor_sub8x8(MACROBLOCKD *xd, int plane, int i, int ir,
356 int ic, int mi_row, int mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700357
Yaowu Xuf883b422016-08-30 14:01:10 -0700358void av1_build_inter_predictors_sby(MACROBLOCKD *xd, int mi_row, int mi_col,
David Barkerac37fa32016-12-02 12:30:21 +0000359 BUFFER_SET *ctx, BLOCK_SIZE bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700360
Yaowu Xuf883b422016-08-30 14:01:10 -0700361void av1_build_inter_predictors_sbp(MACROBLOCKD *xd, int mi_row, int mi_col,
David Barkerac37fa32016-12-02 12:30:21 +0000362 BUFFER_SET *ctx, BLOCK_SIZE bsize,
363 int plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700364
Yaowu Xuf883b422016-08-30 14:01:10 -0700365void av1_build_inter_predictors_sbuv(MACROBLOCKD *xd, int mi_row, int mi_col,
David Barkerac37fa32016-12-02 12:30:21 +0000366 BUFFER_SET *ctx, BLOCK_SIZE bsize);
Yaowu Xuf883b422016-08-30 14:01:10 -0700367
368void av1_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col,
David Barkerac37fa32016-12-02 12:30:21 +0000369 BUFFER_SET *ctx, BLOCK_SIZE bsize);
Yaowu Xuf883b422016-08-30 14:01:10 -0700370
371#if CONFIG_SUPERTX
372void av1_build_inter_predictors_sb_sub8x8_extend(MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700373#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -0700374 int mi_row_ori, int mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700375#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -0700376 int mi_row, int mi_col,
377 BLOCK_SIZE bsize, int block);
378
379void av1_build_inter_predictors_sb_extend(MACROBLOCKD *xd,
380#if CONFIG_EXT_INTER
381 int mi_row_ori, int mi_col_ori,
382#endif // CONFIG_EXT_INTER
383 int mi_row, int mi_col,
384 BLOCK_SIZE bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700385struct macroblockd_plane;
Yaowu Xuf883b422016-08-30 14:01:10 -0700386void av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700387 MACROBLOCKD *xd, uint8_t *dst, int dst_stride, const uint8_t *pre,
388 int pre_stride, int mi_row, int mi_col, int mi_row_ori, int mi_col_ori,
389 BLOCK_SIZE bsize, BLOCK_SIZE top_bsize, PARTITION_TYPE partition,
390 int plane);
391#endif // CONFIG_SUPERTX
392
Yaowu Xuf883b422016-08-30 14:01:10 -0700393void av1_build_inter_predictor(const uint8_t *src, int src_stride, uint8_t *dst,
394 int dst_stride, const MV *mv_q3,
395 const struct scale_factors *sf, int w, int h,
Angie Chiang9f45bc42017-01-13 16:27:54 -0800396 ConvolveParams *conv_params,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700397#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -0700398 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700399#else
James Zern7b9407a2016-05-18 23:48:05 -0700400 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700401#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700402 enum mv_precision precision, int x, int y);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700403
Yaowu Xuf883b422016-08-30 14:01:10 -0700404#if CONFIG_AOM_HIGHBITDEPTH
405void av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700406 const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride,
407 const MV *mv_q3, const struct scale_factors *sf, int w, int h, int do_avg,
408#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -0700409 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700410#else
James Zern7b9407a2016-05-18 23:48:05 -0700411 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700412#endif
413 enum mv_precision precision, int x, int y, int bd);
414#endif
415
416static INLINE int scaled_buffer_offset(int x_offset, int y_offset, int stride,
417 const struct scale_factors *sf) {
418 const int x = sf ? sf->scale_value_x(x_offset, sf) : x_offset;
419 const int y = sf ? sf->scale_value_y(y_offset, sf) : y_offset;
420 return y * stride + x;
421}
422
423static INLINE void setup_pred_plane(struct buf_2d *dst, uint8_t *src, int width,
424 int height, int stride, int mi_row,
425 int mi_col,
426 const struct scale_factors *scale,
427 int subsampling_x, int subsampling_y) {
428 const int x = (MI_SIZE * mi_col) >> subsampling_x;
429 const int y = (MI_SIZE * mi_row) >> subsampling_y;
430 dst->buf = src + scaled_buffer_offset(x, y, stride, scale);
431 dst->buf0 = src;
432 dst->width = width;
433 dst->height = height;
434 dst->stride = stride;
435}
436
Yaowu Xuf883b422016-08-30 14:01:10 -0700437void av1_setup_dst_planes(struct macroblockd_plane planes[MAX_MB_PLANE],
438 const YV12_BUFFER_CONFIG *src, int mi_row,
439 int mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700440
Yaowu Xuf883b422016-08-30 14:01:10 -0700441void av1_setup_pre_planes(MACROBLOCKD *xd, int idx,
442 const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col,
443 const struct scale_factors *sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700444
Yaowu Xuc27fc142016-08-22 16:08:15 -0700445// Detect if the block have sub-pixel level motion vectors
446// per component.
447static INLINE int has_subpel_mv_component(const MODE_INFO *const mi,
448 const MACROBLOCKD *const xd,
449 int dir) {
450 const MB_MODE_INFO *const mbmi = &mi->mbmi;
451 const BLOCK_SIZE bsize = mbmi->sb_type;
452 int plane;
453 int ref = (dir >> 1);
Jingning Hanb46540c2016-12-14 10:59:20 -0800454#if CONFIG_CB4X4
455 const int unify_bsize = 1;
456#else
457 const int unify_bsize = 0;
458#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700459
Jingning Hanb46540c2016-12-14 10:59:20 -0800460 if (bsize >= BLOCK_8X8 || unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700461 if (dir & 0x01) {
462 if (mbmi->mv[ref].as_mv.col & SUBPEL_MASK) return 1;
463 } else {
464 if (mbmi->mv[ref].as_mv.row & SUBPEL_MASK) return 1;
465 }
466 } else {
467 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
468 const PARTITION_TYPE bp = BLOCK_8X8 - bsize;
469 const struct macroblockd_plane *const pd = &xd->plane[plane];
470 const int have_vsplit = bp != PARTITION_HORZ;
471 const int have_hsplit = bp != PARTITION_VERT;
472 const int num_4x4_w = 2 >> ((!have_vsplit) | pd->subsampling_x);
473 const int num_4x4_h = 2 >> ((!have_hsplit) | pd->subsampling_y);
474
475 int x, y;
476 for (y = 0; y < num_4x4_h; ++y) {
477 for (x = 0; x < num_4x4_w; ++x) {
478 const MV mv = average_split_mvs(pd, mi, ref, y * 2 + x);
479 if (dir & 0x01) {
480 if (mv.col & SUBPEL_MASK) return 1;
481 } else {
482 if (mv.row & SUBPEL_MASK) return 1;
483 }
484 }
485 }
486 }
487 }
488
489 return 0;
490}
Yaowu Xuc27fc142016-08-22 16:08:15 -0700491
Angie Chianga69ce1b2016-10-07 10:57:45 -0700492#define CHECK_SUBPEL 0
Yaowu Xuf883b422016-08-30 14:01:10 -0700493static INLINE int av1_is_interp_needed(const MACROBLOCKD *const xd) {
Angie Chianga69ce1b2016-10-07 10:57:45 -0700494#if CHECK_SUBPEL
Yaowu Xuc27fc142016-08-22 16:08:15 -0700495 MODE_INFO *const mi = xd->mi[0];
Angie Chiangb135deb2016-10-25 16:56:48 -0700496 const int is_compound = has_second_ref(&mi->mbmi);
497 int ref;
498 for (ref = 0; ref < 1 + is_compound; ++ref) {
499 int row_col;
500 for (row_col = 0; row_col < 2; ++row_col) {
501 const int dir = (ref << 1) + row_col;
502 if (has_subpel_mv_component(mi, xd, dir)) {
503 return 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700504 }
505 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700506 }
Angie Chiangb135deb2016-10-25 16:56:48 -0700507 return 0;
Angie Chianga69ce1b2016-10-07 10:57:45 -0700508#else
509 (void)xd;
510 return 1;
511#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700512}
Yaowu Xuc27fc142016-08-22 16:08:15 -0700513
Yue Chencb60b182016-10-13 15:18:22 -0700514#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -0700515const uint8_t *av1_get_obmc_mask(int length);
Urvang Joshi52648442016-10-13 17:27:51 -0700516void av1_build_obmc_inter_prediction(const AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700517 int mi_row, int mi_col,
518 uint8_t *above[MAX_MB_PLANE],
519 int above_stride[MAX_MB_PLANE],
520 uint8_t *left[MAX_MB_PLANE],
521 int left_stride[MAX_MB_PLANE]);
Urvang Joshi52648442016-10-13 17:27:51 -0700522void av1_build_prediction_by_above_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700523 int mi_row, int mi_col,
524 uint8_t *tmp_buf[MAX_MB_PLANE],
525 int tmp_width[MAX_MB_PLANE],
526 int tmp_height[MAX_MB_PLANE],
527 int tmp_stride[MAX_MB_PLANE]);
Urvang Joshi52648442016-10-13 17:27:51 -0700528void av1_build_prediction_by_left_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700529 int mi_row, int mi_col,
530 uint8_t *tmp_buf[MAX_MB_PLANE],
531 int tmp_width[MAX_MB_PLANE],
532 int tmp_height[MAX_MB_PLANE],
533 int tmp_stride[MAX_MB_PLANE]);
Yue Chen894fcce2016-10-21 16:50:52 -0700534void av1_build_obmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
535 int mi_row, int mi_col);
Yue Chen86ae7b12017-01-11 17:04:29 -0800536#if CONFIG_NCOBMC
537void av1_build_ncobmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
538 int mi_row, int mi_col);
539#endif
Yue Chencb60b182016-10-13 15:18:22 -0700540#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700541
542#if CONFIG_EXT_INTER
543#define MASK_MASTER_SIZE (2 * MAX_SB_SIZE)
544#define MASK_MASTER_STRIDE (2 * MAX_SB_SIZE)
545
Yaowu Xuf883b422016-08-30 14:01:10 -0700546void av1_init_wedge_masks();
Yaowu Xuc27fc142016-08-22 16:08:15 -0700547
Yaowu Xuf883b422016-08-30 14:01:10 -0700548static INLINE const uint8_t *av1_get_contiguous_soft_mask(int wedge_index,
549 int wedge_sign,
550 BLOCK_SIZE sb_type) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700551 return wedge_params_lookup[sb_type].masks[wedge_sign][wedge_index];
552}
553
Yaowu Xuf883b422016-08-30 14:01:10 -0700554const uint8_t *av1_get_soft_mask(int wedge_index, int wedge_sign,
555 BLOCK_SIZE sb_type, int wedge_offset_x,
556 int wedge_offset_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700557
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800558const uint8_t *av1_get_compound_type_mask_inverse(
559 const INTERINTER_COMPOUND_DATA *const comp_data,
560#if CONFIG_COMPOUND_SEGMENT
561 uint8_t *mask_buffer, int h, int w, int stride,
562#endif
563 BLOCK_SIZE sb_type);
564
565const uint8_t *av1_get_compound_type_mask(
566 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type);
Sarah Parker6fdc8532016-11-16 17:47:13 -0800567
Yaowu Xuf883b422016-08-30 14:01:10 -0700568void av1_build_interintra_predictors(MACROBLOCKD *xd, uint8_t *ypred,
569 uint8_t *upred, uint8_t *vpred,
570 int ystride, int ustride, int vstride,
David Barkerac37fa32016-12-02 12:30:21 +0000571 BUFFER_SET *ctx, BLOCK_SIZE bsize);
Yaowu Xuf883b422016-08-30 14:01:10 -0700572void av1_build_interintra_predictors_sby(MACROBLOCKD *xd, uint8_t *ypred,
David Barkerac37fa32016-12-02 12:30:21 +0000573 int ystride, BUFFER_SET *ctx,
Yaowu Xuf883b422016-08-30 14:01:10 -0700574 BLOCK_SIZE bsize);
David Barkerac37fa32016-12-02 12:30:21 +0000575void av1_build_interintra_predictors_sbc(MACROBLOCKD *xd, uint8_t *upred,
576 int ustride, BUFFER_SET *ctx,
577 int plane, BLOCK_SIZE bsize);
Yaowu Xuf883b422016-08-30 14:01:10 -0700578void av1_build_interintra_predictors_sbuv(MACROBLOCKD *xd, uint8_t *upred,
579 uint8_t *vpred, int ustride,
David Barkerac37fa32016-12-02 12:30:21 +0000580 int vstride, BUFFER_SET *ctx,
581 BLOCK_SIZE bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700582
Yaowu Xuf883b422016-08-30 14:01:10 -0700583void av1_build_intra_predictors_for_interintra(MACROBLOCKD *xd,
584 BLOCK_SIZE bsize, int plane,
David Barkerac37fa32016-12-02 12:30:21 +0000585 BUFFER_SET *ctx,
Yaowu Xuf883b422016-08-30 14:01:10 -0700586 uint8_t *intra_pred,
587 int intra_stride);
588void av1_combine_interintra(MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane,
589 const uint8_t *inter_pred, int inter_stride,
590 const uint8_t *intra_pred, int intra_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700591
592// Encoder only
Yaowu Xuf883b422016-08-30 14:01:10 -0700593void av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700594 MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane_from, int plane_to, int mi_row,
595 int mi_col, int ref, uint8_t *ext_dst[3], int ext_dst_stride[3]);
Yaowu Xuf883b422016-08-30 14:01:10 -0700596void av1_build_wedge_inter_predictor_from_buf(MACROBLOCKD *xd, BLOCK_SIZE bsize,
597 int plane_from, int plane_to,
598 uint8_t *ext_dst0[3],
599 int ext_dst_stride0[3],
600 uint8_t *ext_dst1[3],
601 int ext_dst_stride1[3]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700602#endif // CONFIG_EXT_INTER
603
604#ifdef __cplusplus
605} // extern "C"
606#endif
607
Yaowu Xuf883b422016-08-30 14:01:10 -0700608#endif // AV1_COMMON_RECONINTER_H_