blob: d3863ee8eaeeb6ae708c5c6a96bcc59143b27aa1 [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 Xuf883b422016-08-30 14:01:10 -070017#include "av1/common/av1_convolve.h"
18#include "aom/aom_integer.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070019
20#ifdef __cplusplus
21extern "C" {
22#endif
23
24static INLINE void inter_predictor(const uint8_t *src, int src_stride,
25 uint8_t *dst, int dst_stride,
26 const int subpel_x, const int subpel_y,
27 const struct scale_factors *sf, int w, int h,
28 int ref_idx,
29#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -070030 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -070031#else
James Zern7b9407a2016-05-18 23:48:05 -070032 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -070033#endif
34 int xs, int ys) {
35#if CONFIG_DUAL_FILTER
36 InterpFilterParams interp_filter_params_x =
Yaowu Xuf883b422016-08-30 14:01:10 -070037 av1_get_interp_filter_params(interp_filter[1 + 2 * ref_idx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070038 InterpFilterParams interp_filter_params_y =
Yaowu Xuf883b422016-08-30 14:01:10 -070039 av1_get_interp_filter_params(interp_filter[0 + 2 * ref_idx]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070040#else
41 InterpFilterParams interp_filter_params =
Yaowu Xuf883b422016-08-30 14:01:10 -070042 av1_get_interp_filter_params(interp_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -070043#endif
44
45#if CONFIG_DUAL_FILTER
46 if (interp_filter_params_x.taps == SUBPEL_TAPS &&
47 interp_filter_params_y.taps == SUBPEL_TAPS && w > 2 && h > 2) {
48 const int16_t *kernel_x =
Yaowu Xuf883b422016-08-30 14:01:10 -070049 av1_get_interp_filter_subpel_kernel(interp_filter_params_x, subpel_x);
Yaowu Xuc27fc142016-08-22 16:08:15 -070050 const int16_t *kernel_y =
Yaowu Xuf883b422016-08-30 14:01:10 -070051 av1_get_interp_filter_subpel_kernel(interp_filter_params_y, subpel_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -070052#else
Jingning Hane29ea122016-06-21 17:47:30 -070053 if (interp_filter_params.taps == SUBPEL_TAPS && w > 2 && h > 2) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070054 const int16_t *kernel_x =
Yaowu Xuf883b422016-08-30 14:01:10 -070055 av1_get_interp_filter_subpel_kernel(interp_filter_params, subpel_x);
Yaowu Xuc27fc142016-08-22 16:08:15 -070056 const int16_t *kernel_y =
Yaowu Xuf883b422016-08-30 14:01:10 -070057 av1_get_interp_filter_subpel_kernel(interp_filter_params, subpel_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -070058#endif
59#if CONFIG_EXT_INTERP && SUPPORT_NONINTERPOLATING_FILTERS
60 if (IsInterpolatingFilter(interp_filter)) {
61 // Interpolating filter
62 sf->predict[subpel_x != 0][subpel_y != 0][ref](
63 src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h);
64 } else {
65 sf->predict_ni[subpel_x != 0][subpel_y != 0][ref](
66 src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h);
67 }
68#else
69 sf->predict[subpel_x != 0][subpel_y != 0][ref_idx](
70 src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h);
71#endif // CONFIG_EXT_INTERP && SUPPORT_NONINTERPOLATING_FILTERS
72 } else {
73 // ref_idx > 0 means this is the second reference frame
74 // first reference frame's prediction result is already in dst
75 // therefore we need to average the first and second results
Yaowu Xuf883b422016-08-30 14:01:10 -070076 av1_convolve(src, src_stride, dst, dst_stride, w, h, interp_filter,
77 subpel_x, xs, subpel_y, ys, ref_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -070078 }
79}
80
Yaowu Xuf883b422016-08-30 14:01:10 -070081#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070082static INLINE void highbd_inter_predictor(const uint8_t *src, int src_stride,
83 uint8_t *dst, int dst_stride,
84 const int subpel_x,
85 const int subpel_y,
86 const struct scale_factors *sf, int w,
87 int h, int ref,
88#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -070089 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -070090#else
James Zern7b9407a2016-05-18 23:48:05 -070091 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -070092#endif
93 int xs, int ys, int bd) {
94#if CONFIG_DUAL_FILTER
95 InterpFilterParams interp_filter_params_x =
Yaowu Xuf883b422016-08-30 14:01:10 -070096 av1_get_interp_filter_params(interp_filter[1 + 2 * ref]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070097 InterpFilterParams interp_filter_params_y =
Yaowu Xuf883b422016-08-30 14:01:10 -070098 av1_get_interp_filter_params(interp_filter[0 + 2 * ref]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070099#else
100 InterpFilterParams interp_filter_params =
Yaowu Xuf883b422016-08-30 14:01:10 -0700101 av1_get_interp_filter_params(interp_filter);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700102#endif
103
104#if CONFIG_DUAL_FILTER
105 if (interp_filter_params_x.taps == SUBPEL_TAPS &&
106 interp_filter_params_y.taps == SUBPEL_TAPS && w > 2 && h > 2) {
107 const int16_t *kernel_x =
Yaowu Xuf883b422016-08-30 14:01:10 -0700108 av1_get_interp_filter_subpel_kernel(interp_filter_params_x, 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_y, subpel_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700111#else
Jingning Hane29ea122016-06-21 17:47:30 -0700112 if (interp_filter_params.taps == SUBPEL_TAPS && w > 2 && h > 2) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700113 const int16_t *kernel_x =
Yaowu Xuf883b422016-08-30 14:01:10 -0700114 av1_get_interp_filter_subpel_kernel(interp_filter_params, subpel_x);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700115 const int16_t *kernel_y =
Yaowu Xuf883b422016-08-30 14:01:10 -0700116 av1_get_interp_filter_subpel_kernel(interp_filter_params, subpel_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700117#endif // CONFIG_DUAL_FILTER
118#if CONFIG_EXT_INTERP && SUPPORT_NONINTERPOLATING_FILTERS
119 if (IsInterpolatingFilter(interp_filter)) {
120 // Interpolating filter
121 sf->highbd_predict[subpel_x != 0][subpel_y != 0][ref](
122 src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h,
123 bd);
124 } else {
125 sf->highbd_predict_ni[subpel_x != 0][subpel_y != 0][ref](
126 src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h,
127 bd);
128 }
129#else
130 sf->highbd_predict[subpel_x != 0][subpel_y != 0][ref](
131 src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h, bd);
132#endif // CONFIG_EXT_INTERP && SUPPORT_NONINTERPOLATING_FILTERS
133 } else {
134 // ref > 0 means this is the second reference frame
135 // first reference frame's prediction result is already in dst
136 // therefore we need to average the first and second results
137 int avg = ref > 0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700138 av1_highbd_convolve(src, src_stride, dst, dst_stride, w, h, interp_filter,
139 subpel_x, xs, subpel_y, ys, avg, bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700140 }
141}
Yaowu Xuf883b422016-08-30 14:01:10 -0700142#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700143
144#if CONFIG_EXT_INTER
145// Set to one to use larger codebooks
146#define USE_LARGE_WEDGE_CODEBOOK 0
147
148#if USE_LARGE_WEDGE_CODEBOOK
149#define MAX_WEDGE_TYPES (1 << 5)
150#else
151#define MAX_WEDGE_TYPES (1 << 4)
152#endif
153
154#define MAX_WEDGE_SIZE_LOG2 5 // 32x32
155#define MAX_WEDGE_SIZE (1 << MAX_WEDGE_SIZE_LOG2)
156#define MAX_WEDGE_SQUARE (MAX_WEDGE_SIZE * MAX_WEDGE_SIZE)
157
158#define WEDGE_WEIGHT_BITS 6
159
160#define WEDGE_NONE -1
161
162// Angles are with respect to horizontal anti-clockwise
163typedef enum {
164 WEDGE_HORIZONTAL = 0,
165 WEDGE_VERTICAL = 1,
166 WEDGE_OBLIQUE27 = 2,
167 WEDGE_OBLIQUE63 = 3,
168 WEDGE_OBLIQUE117 = 4,
169 WEDGE_OBLIQUE153 = 5,
170 WEDGE_DIRECTIONS
171} WedgeDirectionType;
172
173// 3-tuple: {direction, x_offset, y_offset}
174typedef struct {
175 WedgeDirectionType direction;
176 int x_offset;
177 int y_offset;
178} wedge_code_type;
179
180typedef uint8_t *wedge_masks_type[MAX_WEDGE_TYPES];
181
182typedef struct {
183 int bits;
184 const wedge_code_type *codebook;
185 uint8_t *signflip;
186 int smoother;
187 wedge_masks_type *masks;
188} wedge_params_type;
189
190extern const wedge_params_type wedge_params_lookup[BLOCK_SIZES];
191
192static INLINE int get_wedge_bits_lookup(BLOCK_SIZE sb_type) {
193 return wedge_params_lookup[sb_type].bits;
194}
195
196static INLINE int is_interinter_wedge_used(BLOCK_SIZE sb_type) {
197 (void)sb_type;
198 return wedge_params_lookup[sb_type].bits > 0;
199}
200
201static INLINE int get_interinter_wedge_bits(BLOCK_SIZE sb_type) {
202 const int wbits = wedge_params_lookup[sb_type].bits;
203 return (wbits > 0) ? wbits + 1 : 0;
204}
205
206static INLINE int is_interintra_wedge_used(BLOCK_SIZE sb_type) {
207 (void)sb_type;
208 return wedge_params_lookup[sb_type].bits > 0;
209}
210
211static INLINE int get_interintra_wedge_bits(BLOCK_SIZE sb_type) {
212 return wedge_params_lookup[sb_type].bits;
213}
214#endif // CONFIG_EXT_INTER
215
216void build_inter_predictors(MACROBLOCKD *xd, int plane,
Yue Chencb60b182016-10-13 15:18:22 -0700217#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700218 int mi_col_offset, int mi_row_offset,
Yue Chencb60b182016-10-13 15:18:22 -0700219#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700220 int block, int bw, int bh, int x, int y, int w,
221 int h,
222#if CONFIG_SUPERTX && CONFIG_EXT_INTER
223 int wedge_offset_x, int wedge_offset_y,
224#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
225 int mi_x, int mi_y);
226
Yaowu Xuf883b422016-08-30 14:01:10 -0700227static INLINE void av1_make_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700228 const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride,
229 const int subpel_x, const int subpel_y, const struct scale_factors *sf,
230 int w, int h, int ref,
231#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -0700232 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700233#else
James Zern7b9407a2016-05-18 23:48:05 -0700234 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700235#endif
236 int xs, int ys, const MACROBLOCKD *xd) {
237 (void)xd;
Yaowu Xuf883b422016-08-30 14:01:10 -0700238#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700239 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
240 highbd_inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y,
241 sf, w, h, ref, interp_filter, xs, ys, xd->bd);
242 else
Yaowu Xuf883b422016-08-30 14:01:10 -0700243#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700244 inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y, sf, w,
245 h, ref, interp_filter, xs, ys);
246}
247
248#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -0700249void av1_make_masked_inter_predictor(const uint8_t *pre, int pre_stride,
250 uint8_t *dst, int dst_stride,
251 const int subpel_x, const int subpel_y,
252 const struct scale_factors *sf, int w,
253 int h,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700254#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -0700255 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700256#else
James Zern7b9407a2016-05-18 23:48:05 -0700257 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700258#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700259 int xs, int ys,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700260#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -0700261 int wedge_offset_x, int wedge_offset_y,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700262#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -0700263 const MACROBLOCKD *xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700264#endif // CONFIG_EXT_INTER
265
266static INLINE int round_mv_comp_q4(int value) {
267 return (value < 0 ? value - 2 : value + 2) / 4;
268}
269
270static MV mi_mv_pred_q4(const MODE_INFO *mi, int idx) {
271 MV res = {
272 round_mv_comp_q4(
273 mi->bmi[0].as_mv[idx].as_mv.row + mi->bmi[1].as_mv[idx].as_mv.row +
274 mi->bmi[2].as_mv[idx].as_mv.row + mi->bmi[3].as_mv[idx].as_mv.row),
275 round_mv_comp_q4(
276 mi->bmi[0].as_mv[idx].as_mv.col + mi->bmi[1].as_mv[idx].as_mv.col +
277 mi->bmi[2].as_mv[idx].as_mv.col + mi->bmi[3].as_mv[idx].as_mv.col)
278 };
279 return res;
280}
281
282static INLINE int round_mv_comp_q2(int value) {
283 return (value < 0 ? value - 1 : value + 1) / 2;
284}
285
286static MV mi_mv_pred_q2(const MODE_INFO *mi, int idx, int block0, int block1) {
287 MV res = { round_mv_comp_q2(mi->bmi[block0].as_mv[idx].as_mv.row +
288 mi->bmi[block1].as_mv[idx].as_mv.row),
289 round_mv_comp_q2(mi->bmi[block0].as_mv[idx].as_mv.col +
290 mi->bmi[block1].as_mv[idx].as_mv.col) };
291 return res;
292}
293
294// TODO(jkoleszar): yet another mv clamping function :-(
295static INLINE MV clamp_mv_to_umv_border_sb(const MACROBLOCKD *xd,
296 const MV *src_mv, int bw, int bh,
297 int ss_x, int ss_y) {
298 // If the MV points so far into the UMV border that no visible pixels
299 // are used for reconstruction, the subpel part of the MV can be
300 // discarded and the MV limited to 16 pixels with equivalent results.
Yaowu Xuf883b422016-08-30 14:01:10 -0700301 const int spel_left = (AOM_INTERP_EXTEND + bw) << SUBPEL_BITS;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700302 const int spel_right = spel_left - SUBPEL_SHIFTS;
Yaowu Xuf883b422016-08-30 14:01:10 -0700303 const int spel_top = (AOM_INTERP_EXTEND + bh) << SUBPEL_BITS;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700304 const int spel_bottom = spel_top - SUBPEL_SHIFTS;
305 MV clamped_mv = { src_mv->row * (1 << (1 - ss_y)),
306 src_mv->col * (1 << (1 - ss_x)) };
307 assert(ss_x <= 1);
308 assert(ss_y <= 1);
309
310 clamp_mv(&clamped_mv, xd->mb_to_left_edge * (1 << (1 - ss_x)) - spel_left,
311 xd->mb_to_right_edge * (1 << (1 - ss_x)) + spel_right,
312 xd->mb_to_top_edge * (1 << (1 - ss_y)) - spel_top,
313 xd->mb_to_bottom_edge * (1 << (1 - ss_y)) + spel_bottom);
314
315 return clamped_mv;
316}
317
318static INLINE MV average_split_mvs(const struct macroblockd_plane *pd,
319 const MODE_INFO *mi, int ref, int block) {
320 const int ss_idx = ((pd->subsampling_x > 0) << 1) | (pd->subsampling_y > 0);
321 MV res = { 0, 0 };
322 switch (ss_idx) {
323 case 0: res = mi->bmi[block].as_mv[ref].as_mv; break;
324 case 1: res = mi_mv_pred_q2(mi, ref, block, block + 2); break;
325 case 2: res = mi_mv_pred_q2(mi, ref, block, block + 1); break;
326 case 3: res = mi_mv_pred_q4(mi, ref); break;
327 default: assert(ss_idx <= 3 && ss_idx >= 0);
328 }
329 return res;
330}
331
Yaowu Xuf883b422016-08-30 14:01:10 -0700332void av1_build_inter_predictor_sub8x8(MACROBLOCKD *xd, int plane, int i, int ir,
333 int ic, int mi_row, int mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700334
Yaowu Xuf883b422016-08-30 14:01:10 -0700335void av1_build_inter_predictors_sby(MACROBLOCKD *xd, int mi_row, int mi_col,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700336 BLOCK_SIZE bsize);
337
Yaowu Xuf883b422016-08-30 14:01:10 -0700338void av1_build_inter_predictors_sbp(MACROBLOCKD *xd, int mi_row, int mi_col,
339 BLOCK_SIZE bsize, int plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700340
Yaowu Xuf883b422016-08-30 14:01:10 -0700341void av1_build_inter_predictors_sbuv(MACROBLOCKD *xd, int mi_row, int mi_col,
342 BLOCK_SIZE bsize);
343
344void av1_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col,
345 BLOCK_SIZE bsize);
346
347#if CONFIG_SUPERTX
348void av1_build_inter_predictors_sb_sub8x8_extend(MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700349#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -0700350 int mi_row_ori, int mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700351#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -0700352 int mi_row, int mi_col,
353 BLOCK_SIZE bsize, int block);
354
355void av1_build_inter_predictors_sb_extend(MACROBLOCKD *xd,
356#if CONFIG_EXT_INTER
357 int mi_row_ori, int mi_col_ori,
358#endif // CONFIG_EXT_INTER
359 int mi_row, int mi_col,
360 BLOCK_SIZE bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700361struct macroblockd_plane;
Yaowu Xuf883b422016-08-30 14:01:10 -0700362void av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700363 MACROBLOCKD *xd, uint8_t *dst, int dst_stride, const uint8_t *pre,
364 int pre_stride, int mi_row, int mi_col, int mi_row_ori, int mi_col_ori,
365 BLOCK_SIZE bsize, BLOCK_SIZE top_bsize, PARTITION_TYPE partition,
366 int plane);
367#endif // CONFIG_SUPERTX
368
Yaowu Xuf883b422016-08-30 14:01:10 -0700369void av1_build_inter_predictor(const uint8_t *src, int src_stride, uint8_t *dst,
370 int dst_stride, const MV *mv_q3,
371 const struct scale_factors *sf, int w, int h,
372 int do_avg,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700373#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -0700374 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700375#else
James Zern7b9407a2016-05-18 23:48:05 -0700376 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700377#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700378 enum mv_precision precision, int x, int y);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700379
Yaowu Xuf883b422016-08-30 14:01:10 -0700380#if CONFIG_AOM_HIGHBITDEPTH
381void av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700382 const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride,
383 const MV *mv_q3, const struct scale_factors *sf, int w, int h, int do_avg,
384#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -0700385 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700386#else
James Zern7b9407a2016-05-18 23:48:05 -0700387 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700388#endif
389 enum mv_precision precision, int x, int y, int bd);
390#endif
391
392static INLINE int scaled_buffer_offset(int x_offset, int y_offset, int stride,
393 const struct scale_factors *sf) {
394 const int x = sf ? sf->scale_value_x(x_offset, sf) : x_offset;
395 const int y = sf ? sf->scale_value_y(y_offset, sf) : y_offset;
396 return y * stride + x;
397}
398
399static INLINE void setup_pred_plane(struct buf_2d *dst, uint8_t *src, int width,
400 int height, int stride, int mi_row,
401 int mi_col,
402 const struct scale_factors *scale,
403 int subsampling_x, int subsampling_y) {
404 const int x = (MI_SIZE * mi_col) >> subsampling_x;
405 const int y = (MI_SIZE * mi_row) >> subsampling_y;
406 dst->buf = src + scaled_buffer_offset(x, y, stride, scale);
407 dst->buf0 = src;
408 dst->width = width;
409 dst->height = height;
410 dst->stride = stride;
411}
412
Yaowu Xuf883b422016-08-30 14:01:10 -0700413void av1_setup_dst_planes(struct macroblockd_plane planes[MAX_MB_PLANE],
414 const YV12_BUFFER_CONFIG *src, int mi_row,
415 int mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700416
Yaowu Xuf883b422016-08-30 14:01:10 -0700417void av1_setup_pre_planes(MACROBLOCKD *xd, int idx,
418 const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col,
419 const struct scale_factors *sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700420
Yaowu Xuc27fc142016-08-22 16:08:15 -0700421// Detect if the block have sub-pixel level motion vectors
422// per component.
423static INLINE int has_subpel_mv_component(const MODE_INFO *const mi,
424 const MACROBLOCKD *const xd,
425 int dir) {
426 const MB_MODE_INFO *const mbmi = &mi->mbmi;
427 const BLOCK_SIZE bsize = mbmi->sb_type;
428 int plane;
429 int ref = (dir >> 1);
430
431 if (bsize >= BLOCK_8X8) {
432 if (dir & 0x01) {
433 if (mbmi->mv[ref].as_mv.col & SUBPEL_MASK) return 1;
434 } else {
435 if (mbmi->mv[ref].as_mv.row & SUBPEL_MASK) return 1;
436 }
437 } else {
438 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
439 const PARTITION_TYPE bp = BLOCK_8X8 - bsize;
440 const struct macroblockd_plane *const pd = &xd->plane[plane];
441 const int have_vsplit = bp != PARTITION_HORZ;
442 const int have_hsplit = bp != PARTITION_VERT;
443 const int num_4x4_w = 2 >> ((!have_vsplit) | pd->subsampling_x);
444 const int num_4x4_h = 2 >> ((!have_hsplit) | pd->subsampling_y);
445
446 int x, y;
447 for (y = 0; y < num_4x4_h; ++y) {
448 for (x = 0; x < num_4x4_w; ++x) {
449 const MV mv = average_split_mvs(pd, mi, ref, y * 2 + x);
450 if (dir & 0x01) {
451 if (mv.col & SUBPEL_MASK) return 1;
452 } else {
453 if (mv.row & SUBPEL_MASK) return 1;
454 }
455 }
456 }
457 }
458 }
459
460 return 0;
461}
Yaowu Xuc27fc142016-08-22 16:08:15 -0700462
Angie Chianga69ce1b2016-10-07 10:57:45 -0700463#define CHECK_SUBPEL 0
Yaowu Xuf883b422016-08-30 14:01:10 -0700464static INLINE int av1_is_interp_needed(const MACROBLOCKD *const xd) {
Angie Chianga69ce1b2016-10-07 10:57:45 -0700465#if CHECK_SUBPEL
Yaowu Xuc27fc142016-08-22 16:08:15 -0700466 MODE_INFO *const mi = xd->mi[0];
Angie Chiangb135deb2016-10-25 16:56:48 -0700467 const int is_compound = has_second_ref(&mi->mbmi);
468 int ref;
469 for (ref = 0; ref < 1 + is_compound; ++ref) {
470 int row_col;
471 for (row_col = 0; row_col < 2; ++row_col) {
472 const int dir = (ref << 1) + row_col;
473 if (has_subpel_mv_component(mi, xd, dir)) {
474 return 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700475 }
476 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700477 }
Angie Chiangb135deb2016-10-25 16:56:48 -0700478 return 0;
Angie Chianga69ce1b2016-10-07 10:57:45 -0700479#else
480 (void)xd;
481 return 1;
482#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700483}
Yaowu Xuc27fc142016-08-22 16:08:15 -0700484
Yue Chencb60b182016-10-13 15:18:22 -0700485#if CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -0700486const uint8_t *av1_get_obmc_mask(int length);
Urvang Joshi52648442016-10-13 17:27:51 -0700487void av1_build_obmc_inter_prediction(const AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700488 int mi_row, int mi_col,
489 uint8_t *above[MAX_MB_PLANE],
490 int above_stride[MAX_MB_PLANE],
491 uint8_t *left[MAX_MB_PLANE],
492 int left_stride[MAX_MB_PLANE]);
Urvang Joshi52648442016-10-13 17:27:51 -0700493void av1_build_prediction_by_above_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700494 int mi_row, int mi_col,
495 uint8_t *tmp_buf[MAX_MB_PLANE],
496 int tmp_width[MAX_MB_PLANE],
497 int tmp_height[MAX_MB_PLANE],
498 int tmp_stride[MAX_MB_PLANE]);
Urvang Joshi52648442016-10-13 17:27:51 -0700499void av1_build_prediction_by_left_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700500 int mi_row, int mi_col,
501 uint8_t *tmp_buf[MAX_MB_PLANE],
502 int tmp_width[MAX_MB_PLANE],
503 int tmp_height[MAX_MB_PLANE],
504 int tmp_stride[MAX_MB_PLANE]);
Yue Chen894fcce2016-10-21 16:50:52 -0700505void av1_build_obmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
506 int mi_row, int mi_col);
Yue Chencb60b182016-10-13 15:18:22 -0700507#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700508
509#if CONFIG_EXT_INTER
510#define MASK_MASTER_SIZE (2 * MAX_SB_SIZE)
511#define MASK_MASTER_STRIDE (2 * MAX_SB_SIZE)
512
Yaowu Xuf883b422016-08-30 14:01:10 -0700513void av1_init_wedge_masks();
Yaowu Xuc27fc142016-08-22 16:08:15 -0700514
Yaowu Xuf883b422016-08-30 14:01:10 -0700515static INLINE const uint8_t *av1_get_contiguous_soft_mask(int wedge_index,
516 int wedge_sign,
517 BLOCK_SIZE sb_type) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700518 return wedge_params_lookup[sb_type].masks[wedge_sign][wedge_index];
519}
520
Yaowu Xuf883b422016-08-30 14:01:10 -0700521const uint8_t *av1_get_soft_mask(int wedge_index, int wedge_sign,
522 BLOCK_SIZE sb_type, int wedge_offset_x,
523 int wedge_offset_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700524
Yaowu Xuf883b422016-08-30 14:01:10 -0700525void av1_build_interintra_predictors(MACROBLOCKD *xd, uint8_t *ypred,
526 uint8_t *upred, uint8_t *vpred,
527 int ystride, int ustride, int vstride,
528 BLOCK_SIZE bsize);
529void av1_build_interintra_predictors_sby(MACROBLOCKD *xd, uint8_t *ypred,
530 int ystride, BLOCK_SIZE bsize);
531void av1_build_interintra_predictors_sbc(MACROBLOCKD *xd, uint8_t *upred,
532 int ustride, int plane,
533 BLOCK_SIZE bsize);
534void av1_build_interintra_predictors_sbuv(MACROBLOCKD *xd, uint8_t *upred,
535 uint8_t *vpred, int ustride,
536 int vstride, BLOCK_SIZE bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700537
Yaowu Xuf883b422016-08-30 14:01:10 -0700538void av1_build_intra_predictors_for_interintra(MACROBLOCKD *xd,
539 BLOCK_SIZE bsize, int plane,
540 uint8_t *intra_pred,
541 int intra_stride);
542void av1_combine_interintra(MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane,
543 const uint8_t *inter_pred, int inter_stride,
544 const uint8_t *intra_pred, int intra_stride);
545void av1_build_interintra_predictors_sbuv(MACROBLOCKD *xd, uint8_t *upred,
546 uint8_t *vpred, int ustride,
547 int vstride, BLOCK_SIZE bsize);
548void av1_build_interintra_predictors_sby(MACROBLOCKD *xd, uint8_t *ypred,
549 int ystride, BLOCK_SIZE bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700550
551// Encoder only
Yaowu Xuf883b422016-08-30 14:01:10 -0700552void av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700553 MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane_from, int plane_to, int mi_row,
554 int mi_col, int ref, uint8_t *ext_dst[3], int ext_dst_stride[3]);
Yaowu Xuf883b422016-08-30 14:01:10 -0700555void av1_build_wedge_inter_predictor_from_buf(MACROBLOCKD *xd, BLOCK_SIZE bsize,
556 int plane_from, int plane_to,
557 uint8_t *ext_dst0[3],
558 int ext_dst_stride0[3],
559 uint8_t *ext_dst1[3],
560 int ext_dst_stride1[3]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700561#endif // CONFIG_EXT_INTER
562
563#ifdef __cplusplus
564} // extern "C"
565#endif
566
Yaowu Xuf883b422016-08-30 14:01:10 -0700567#endif // AV1_COMMON_RECONINTER_H_