reconinter.h 22.6 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
/*
Yaowu Xu's avatar
Yaowu Xu committed
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Jingning Han's avatar
Jingning Han committed
3
 *
Yaowu Xu's avatar
Yaowu Xu committed
4
5
6
7
8
9
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Jingning Han's avatar
Jingning Han committed
10
11
 */

Yaowu Xu's avatar
Yaowu Xu committed
12
13
#ifndef AV1_COMMON_RECONINTER_H_
#define AV1_COMMON_RECONINTER_H_
Jingning Han's avatar
Jingning Han committed
14

15
16
#include "av1/common/filter.h"
#include "av1/common/onyxc_int.h"
17
#include "av1/common/convolve.h"
Yaowu Xu's avatar
Yaowu Xu committed
18
#include "aom/aom_integer.h"
Jingning Han's avatar
Jingning Han committed
19
20
21
22
23
24
25

#ifdef __cplusplus
extern "C" {
#endif

static INLINE void inter_predictor(const uint8_t *src, int src_stride,
                                   uint8_t *dst, int dst_stride,
clang-format's avatar
clang-format committed
26
27
28
                                   const int subpel_x, const int subpel_y,
                                   const struct scale_factors *sf, int w, int h,
                                   int ref_idx,
29
#if CONFIG_DUAL_FILTER
James Zern's avatar
James Zern committed
30
                                   const InterpFilter *interp_filter,
31
#else
James Zern's avatar
James Zern committed
32
                                   const InterpFilter interp_filter,
33
#endif
Jingning Han's avatar
Jingning Han committed
34
                                   int xs, int ys) {
35
36
#if CONFIG_DUAL_FILTER
  InterpFilterParams interp_filter_params_x =
Yaowu Xu's avatar
Yaowu Xu committed
37
      av1_get_interp_filter_params(interp_filter[1 + 2 * ref_idx]);
38
  InterpFilterParams interp_filter_params_y =
Yaowu Xu's avatar
Yaowu Xu committed
39
      av1_get_interp_filter_params(interp_filter[0 + 2 * ref_idx]);
40
#else
41
  InterpFilterParams interp_filter_params =
Yaowu Xu's avatar
Yaowu Xu committed
42
      av1_get_interp_filter_params(interp_filter);
43
44
45
46
#endif

#if CONFIG_DUAL_FILTER
  if (interp_filter_params_x.taps == SUBPEL_TAPS &&
clang-format's avatar
clang-format committed
47
      interp_filter_params_y.taps == SUBPEL_TAPS && w > 2 && h > 2) {
48
    const int16_t *kernel_x =
Yaowu Xu's avatar
Yaowu Xu committed
49
        av1_get_interp_filter_subpel_kernel(interp_filter_params_x, subpel_x);
50
    const int16_t *kernel_y =
Yaowu Xu's avatar
Yaowu Xu committed
51
        av1_get_interp_filter_subpel_kernel(interp_filter_params_y, subpel_y);
52
#else
53
  if (interp_filter_params.taps == SUBPEL_TAPS && w > 2 && h > 2) {
54
    const int16_t *kernel_x =
Yaowu Xu's avatar
Yaowu Xu committed
55
        av1_get_interp_filter_subpel_kernel(interp_filter_params, subpel_x);
56
    const int16_t *kernel_y =
Yaowu Xu's avatar
Yaowu Xu committed
57
        av1_get_interp_filter_subpel_kernel(interp_filter_params, subpel_y);
58
#endif
59
#if CONFIG_EXT_INTERP && SUPPORT_NONINTERPOLATING_FILTERS
60
61
62
    if (IsInterpolatingFilter(interp_filter)) {
      // Interpolating filter
      sf->predict[subpel_x != 0][subpel_y != 0][ref](
clang-format's avatar
clang-format committed
63
          src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h);
64
65
    } else {
      sf->predict_ni[subpel_x != 0][subpel_y != 0][ref](
clang-format's avatar
clang-format committed
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](
clang-format's avatar
clang-format committed
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
75
    // first reference frame's prediction result is already in dst
    // therefore we need to average the first and second results
Yaowu Xu's avatar
Yaowu Xu committed
76
77
    av1_convolve(src, src_stride, dst, dst_stride, w, h, interp_filter,
                 subpel_x, xs, subpel_y, ys, ref_idx);
78
  }
Jingning Han's avatar
Jingning Han committed
79
80
}

Yaowu Xu's avatar
Yaowu Xu committed
81
#if CONFIG_AOM_HIGHBITDEPTH
82
83
84
85
static INLINE void highbd_inter_predictor(const uint8_t *src, int src_stride,
                                          uint8_t *dst, int dst_stride,
                                          const int subpel_x,
                                          const int subpel_y,
clang-format's avatar
clang-format committed
86
87
                                          const struct scale_factors *sf, int w,
                                          int h, int ref,
88
#if CONFIG_DUAL_FILTER
James Zern's avatar
James Zern committed
89
                                          const InterpFilter *interp_filter,
90
#else
James Zern's avatar
James Zern committed
91
                                          const InterpFilter interp_filter,
92
#endif
93
                                          int xs, int ys, int bd) {
94
95
#if CONFIG_DUAL_FILTER
  InterpFilterParams interp_filter_params_x =
Yaowu Xu's avatar
Yaowu Xu committed
96
      av1_get_interp_filter_params(interp_filter[1 + 2 * ref]);
97
  InterpFilterParams interp_filter_params_y =
Yaowu Xu's avatar
Yaowu Xu committed
98
      av1_get_interp_filter_params(interp_filter[0 + 2 * ref]);
99
#else
100
  InterpFilterParams interp_filter_params =
Yaowu Xu's avatar
Yaowu Xu committed
101
      av1_get_interp_filter_params(interp_filter);
102
103
104
105
#endif

#if CONFIG_DUAL_FILTER
  if (interp_filter_params_x.taps == SUBPEL_TAPS &&
clang-format's avatar
clang-format committed
106
      interp_filter_params_y.taps == SUBPEL_TAPS && w > 2 && h > 2) {
107
    const int16_t *kernel_x =
Yaowu Xu's avatar
Yaowu Xu committed
108
        av1_get_interp_filter_subpel_kernel(interp_filter_params_x, subpel_x);
109
    const int16_t *kernel_y =
Yaowu Xu's avatar
Yaowu Xu committed
110
        av1_get_interp_filter_subpel_kernel(interp_filter_params_y, subpel_y);
111
#else
112
  if (interp_filter_params.taps == SUBPEL_TAPS && w > 2 && h > 2) {
113
    const int16_t *kernel_x =
Yaowu Xu's avatar
Yaowu Xu committed
114
        av1_get_interp_filter_subpel_kernel(interp_filter_params, subpel_x);
115
    const int16_t *kernel_y =
Yaowu Xu's avatar
Yaowu Xu committed
116
        av1_get_interp_filter_subpel_kernel(interp_filter_params, subpel_y);
117
#endif  // CONFIG_DUAL_FILTER
118
#if CONFIG_EXT_INTERP && SUPPORT_NONINTERPOLATING_FILTERS
119
120
121
    if (IsInterpolatingFilter(interp_filter)) {
      // Interpolating filter
      sf->highbd_predict[subpel_x != 0][subpel_y != 0][ref](
clang-format's avatar
clang-format committed
122
123
          src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h,
          bd);
124
125
    } else {
      sf->highbd_predict_ni[subpel_x != 0][subpel_y != 0][ref](
clang-format's avatar
clang-format committed
126
127
          src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h,
          bd);
128
129
    }
#else
130
    sf->highbd_predict[subpel_x != 0][subpel_y != 0][ref](
clang-format's avatar
clang-format committed
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
135
136
137
    // ref > 0 means this is the second reference frame
    // first reference frame's prediction result is already in dst
    // therefore we need to average the first and second results
    int avg = ref > 0;
Yaowu Xu's avatar
Yaowu Xu committed
138
139
    av1_highbd_convolve(src, src_stride, dst, dst_stride, w, h, interp_filter,
                        subpel_x, xs, subpel_y, ys, avg, bd);
140
  }
Jingning Han's avatar
Jingning Han committed
141
}
Yaowu Xu's avatar
Yaowu Xu committed
142
#endif  // CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
143

144
#if CONFIG_EXT_INTER
145
// Set to one to use larger codebooks
clang-format's avatar
clang-format committed
146
#define USE_LARGE_WEDGE_CODEBOOK 0
147
148

#if USE_LARGE_WEDGE_CODEBOOK
clang-format's avatar
clang-format committed
149
#define MAX_WEDGE_TYPES (1 << 5)
150
#else
clang-format's avatar
clang-format committed
151
#define MAX_WEDGE_TYPES (1 << 4)
152
153
#endif

clang-format's avatar
clang-format committed
154
155
156
#define MAX_WEDGE_SIZE_LOG2 5  // 32x32
#define MAX_WEDGE_SIZE (1 << MAX_WEDGE_SIZE_LOG2)
#define MAX_WEDGE_SQUARE (MAX_WEDGE_SIZE * MAX_WEDGE_SIZE)
157

158
159
#define WEDGE_WEIGHT_BITS 6

clang-format's avatar
clang-format committed
160
#define WEDGE_NONE -1
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179

// Angles are with respect to horizontal anti-clockwise
typedef enum {
  WEDGE_HORIZONTAL = 0,
  WEDGE_VERTICAL = 1,
  WEDGE_OBLIQUE27 = 2,
  WEDGE_OBLIQUE63 = 3,
  WEDGE_OBLIQUE117 = 4,
  WEDGE_OBLIQUE153 = 5,
  WEDGE_DIRECTIONS
} WedgeDirectionType;

// 3-tuple: {direction, x_offset, y_offset}
typedef struct {
  WedgeDirectionType direction;
  int x_offset;
  int y_offset;
} wedge_code_type;

180
181
typedef uint8_t *wedge_masks_type[MAX_WEDGE_TYPES];

182
183
184
185
186
typedef struct {
  int bits;
  const wedge_code_type *codebook;
  uint8_t *signflip;
  int smoother;
187
  wedge_masks_type *masks;
188
189
190
191
192
193
194
} wedge_params_type;

extern const wedge_params_type wedge_params_lookup[BLOCK_SIZES];

static INLINE int get_wedge_bits_lookup(BLOCK_SIZE sb_type) {
  return wedge_params_lookup[sb_type].bits;
}
195
196

static INLINE int is_interinter_wedge_used(BLOCK_SIZE sb_type) {
clang-format's avatar
clang-format committed
197
  (void)sb_type;
198
  return wedge_params_lookup[sb_type].bits > 0;
199
200
201
}

static INLINE int get_interinter_wedge_bits(BLOCK_SIZE sb_type) {
202
  const int wbits = wedge_params_lookup[sb_type].bits;
203
204
205
206
  return (wbits > 0) ? wbits + 1 : 0;
}

static INLINE int is_interintra_wedge_used(BLOCK_SIZE sb_type) {
clang-format's avatar
clang-format committed
207
  (void)sb_type;
208
  return wedge_params_lookup[sb_type].bits > 0;
209
210
211
}

static INLINE int get_interintra_wedge_bits(BLOCK_SIZE sb_type) {
212
  return wedge_params_lookup[sb_type].bits;
213
214
215
}
#endif  // CONFIG_EXT_INTER

216
void build_inter_predictors(MACROBLOCKD *xd, int plane,
Yue Chen's avatar
Yue Chen committed
217
#if CONFIG_MOTION_VAR
218
                            int mi_col_offset, int mi_row_offset,
Yue Chen's avatar
Yue Chen committed
219
#endif  // CONFIG_MOTION_VAR
clang-format's avatar
clang-format committed
220
221
                            int block, int bw, int bh, int x, int y, int w,
                            int h,
222
223
224
225
226
#if CONFIG_SUPERTX && CONFIG_EXT_INTER
                            int wedge_offset_x, int wedge_offset_y,
#endif  // CONFIG_SUPERTX && CONFIG_EXT_INTER
                            int mi_x, int mi_y);

Yaowu Xu's avatar
Yaowu Xu committed
227
static INLINE void av1_make_inter_predictor(
clang-format's avatar
clang-format committed
228
229
    const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride,
    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 Zern's avatar
James Zern committed
232
    const InterpFilter *interp_filter,
233
#else
James Zern's avatar
James Zern committed
234
    const InterpFilter interp_filter,
235
#endif
clang-format's avatar
clang-format committed
236
237
    int xs, int ys, const MACROBLOCKD *xd) {
  (void)xd;
Yaowu Xu's avatar
Yaowu Xu committed
238
#if CONFIG_AOM_HIGHBITDEPTH
239
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
clang-format's avatar
clang-format committed
240
241
    highbd_inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y,
                           sf, w, h, ref, interp_filter, xs, ys, xd->bd);
242
  else
Yaowu Xu's avatar
Yaowu Xu committed
243
#endif  // CONFIG_AOM_HIGHBITDEPTH
clang-format's avatar
clang-format committed
244
245
    inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y, sf, w,
                    h, ref, interp_filter, xs, ys);
246
247
248
}

#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
249
250
251
252
253
void av1_make_masked_inter_predictor(const uint8_t *pre, int pre_stride,
                                     uint8_t *dst, int dst_stride,
                                     const int subpel_x, const int subpel_y,
                                     const struct scale_factors *sf, int w,
                                     int h,
254
#if CONFIG_DUAL_FILTER
James Zern's avatar
James Zern committed
255
                                     const InterpFilter *interp_filter,
256
#else
James Zern's avatar
James Zern committed
257
                                     const InterpFilter interp_filter,
258
#endif
Yaowu Xu's avatar
Yaowu Xu committed
259
                                     int xs, int ys,
260
#if CONFIG_SUPERTX
Yaowu Xu's avatar
Yaowu Xu committed
261
                                     int wedge_offset_x, int wedge_offset_y,
262
#endif  // CONFIG_SUPERTX
Yaowu Xu's avatar
Yaowu Xu committed
263
                                     const MACROBLOCKD *xd);
264
265
#endif  // CONFIG_EXT_INTER

Jingning Han's avatar
Jingning Han committed
266
267
268
269
270
static INLINE int round_mv_comp_q4(int value) {
  return (value < 0 ? value - 2 : value + 2) / 4;
}

static MV mi_mv_pred_q4(const MODE_INFO *mi, int idx) {
clang-format's avatar
clang-format committed
271
272
273
274
275
276
277
278
  MV res = {
    round_mv_comp_q4(
        mi->bmi[0].as_mv[idx].as_mv.row + mi->bmi[1].as_mv[idx].as_mv.row +
        mi->bmi[2].as_mv[idx].as_mv.row + mi->bmi[3].as_mv[idx].as_mv.row),
    round_mv_comp_q4(
        mi->bmi[0].as_mv[idx].as_mv.col + mi->bmi[1].as_mv[idx].as_mv.col +
        mi->bmi[2].as_mv[idx].as_mv.col + mi->bmi[3].as_mv[idx].as_mv.col)
  };
Jingning Han's avatar
Jingning Han committed
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
  return res;
}

static INLINE int round_mv_comp_q2(int value) {
  return (value < 0 ? value - 1 : value + 1) / 2;
}

static MV mi_mv_pred_q2(const MODE_INFO *mi, int idx, int block0, int block1) {
  MV res = { round_mv_comp_q2(mi->bmi[block0].as_mv[idx].as_mv.row +
                              mi->bmi[block1].as_mv[idx].as_mv.row),
             round_mv_comp_q2(mi->bmi[block0].as_mv[idx].as_mv.col +
                              mi->bmi[block1].as_mv[idx].as_mv.col) };
  return res;
}

// TODO(jkoleszar): yet another mv clamping function :-(
Johann's avatar
Johann committed
295
static INLINE MV clamp_mv_to_umv_border_sb(const MACROBLOCKD *xd,
clang-format's avatar
clang-format committed
296
297
                                           const MV *src_mv, int bw, int bh,
                                           int ss_x, int ss_y) {
Jingning Han's avatar
Jingning Han committed
298
299
300
  // If the MV points so far into the UMV border that no visible pixels
  // are used for reconstruction, the subpel part of the MV can be
  // discarded and the MV limited to 16 pixels with equivalent results.
Yaowu Xu's avatar
Yaowu Xu committed
301
  const int spel_left = (AOM_INTERP_EXTEND + bw) << SUBPEL_BITS;
Jingning Han's avatar
Jingning Han committed
302
  const int spel_right = spel_left - SUBPEL_SHIFTS;
Yaowu Xu's avatar
Yaowu Xu committed
303
  const int spel_top = (AOM_INTERP_EXTEND + bh) << SUBPEL_BITS;
Jingning Han's avatar
Jingning Han committed
304
  const int spel_bottom = spel_top - SUBPEL_SHIFTS;
clang-format's avatar
clang-format committed
305
306
  MV clamped_mv = { src_mv->row * (1 << (1 - ss_y)),
                    src_mv->col * (1 << (1 - ss_x)) };
Jingning Han's avatar
Jingning Han committed
307
308
309
  assert(ss_x <= 1);
  assert(ss_y <= 1);

clang-format's avatar
clang-format committed
310
  clamp_mv(&clamped_mv, xd->mb_to_left_edge * (1 << (1 - ss_x)) - spel_left,
Jingning Han's avatar
Jingning Han committed
311
312
313
314
315
316
317
           xd->mb_to_right_edge * (1 << (1 - ss_x)) + spel_right,
           xd->mb_to_top_edge * (1 << (1 - ss_y)) - spel_top,
           xd->mb_to_bottom_edge * (1 << (1 - ss_y)) + spel_bottom);

  return clamped_mv;
}

Johann's avatar
Johann committed
318
319
static INLINE MV average_split_mvs(const struct macroblockd_plane *pd,
                                   const MODE_INFO *mi, int ref, int block) {
Jingning Han's avatar
Jingning Han committed
320
  const int ss_idx = ((pd->subsampling_x > 0) << 1) | (pd->subsampling_y > 0);
clang-format's avatar
clang-format committed
321
  MV res = { 0, 0 };
Jingning Han's avatar
Jingning Han committed
322
  switch (ss_idx) {
clang-format's avatar
clang-format committed
323
324
325
326
327
    case 0: res = mi->bmi[block].as_mv[ref].as_mv; break;
    case 1: res = mi_mv_pred_q2(mi, ref, block, block + 2); break;
    case 2: res = mi_mv_pred_q2(mi, ref, block, block + 1); break;
    case 3: res = mi_mv_pred_q4(mi, ref); break;
    default: assert(ss_idx <= 3 && ss_idx >= 0);
Jingning Han's avatar
Jingning Han committed
328
329
330
331
  }
  return res;
}

Yaowu Xu's avatar
Yaowu Xu committed
332
333
void av1_build_inter_predictor_sub8x8(MACROBLOCKD *xd, int plane, int i, int ir,
                                      int ic, int mi_row, int mi_col);
334

Yaowu Xu's avatar
Yaowu Xu committed
335
336
void av1_build_inter_predictors_sby(MACROBLOCKD *xd, int mi_row, int mi_col,
                                    BLOCK_SIZE bsize);
Jingning Han's avatar
Jingning Han committed
337

Yaowu Xu's avatar
Yaowu Xu committed
338
339
void av1_build_inter_predictors_sbp(MACROBLOCKD *xd, int mi_row, int mi_col,
                                    BLOCK_SIZE bsize, int plane);
Jingning Han's avatar
Jingning Han committed
340

Yaowu Xu's avatar
Yaowu Xu committed
341
342
void av1_build_inter_predictors_sbuv(MACROBLOCKD *xd, int mi_row, int mi_col,
                                     BLOCK_SIZE bsize);
Jingning Han's avatar
Jingning Han committed
343

Yaowu Xu's avatar
Yaowu Xu committed
344
345
void av1_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col,
                                   BLOCK_SIZE bsize);
346
347

#if CONFIG_SUPERTX
Yaowu Xu's avatar
Yaowu Xu committed
348
void av1_build_inter_predictors_sb_sub8x8_extend(MACROBLOCKD *xd,
349
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
350
                                                 int mi_row_ori, int mi_col_ori,
351
#endif  // CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
352
353
                                                 int mi_row, int mi_col,
                                                 BLOCK_SIZE bsize, int block);
354

Yaowu Xu's avatar
Yaowu Xu committed
355
void av1_build_inter_predictors_sb_extend(MACROBLOCKD *xd,
356
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
357
                                          int mi_row_ori, int mi_col_ori,
358
#endif  // CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
359
360
                                          int mi_row, int mi_col,
                                          BLOCK_SIZE bsize);
361
struct macroblockd_plane;
Yaowu Xu's avatar
Yaowu Xu committed
362
void av1_build_masked_inter_predictor_complex(
clang-format's avatar
clang-format committed
363
364
365
366
    MACROBLOCKD *xd, uint8_t *dst, int dst_stride, const uint8_t *pre,
    int pre_stride, int mi_row, int mi_col, int mi_row_ori, int mi_col_ori,
    BLOCK_SIZE bsize, BLOCK_SIZE top_bsize, PARTITION_TYPE partition,
    int plane);
367
#endif  // CONFIG_SUPERTX
Jingning Han's avatar
Jingning Han committed
368

Yaowu Xu's avatar
Yaowu Xu committed
369
370
371
372
void av1_build_inter_predictor(const uint8_t *src, int src_stride, uint8_t *dst,
                               int dst_stride, const MV *mv_q3,
                               const struct scale_factors *sf, int w, int h,
                               int do_avg,
373
#if CONFIG_DUAL_FILTER
James Zern's avatar
James Zern committed
374
                               const InterpFilter *interp_filter,
375
#else
James Zern's avatar
James Zern committed
376
                               const InterpFilter interp_filter,
377
#endif
Yaowu Xu's avatar
Yaowu Xu committed
378
                               enum mv_precision precision, int x, int y);
Jingning Han's avatar
Jingning Han committed
379

Yaowu Xu's avatar
Yaowu Xu committed
380
381
#if CONFIG_AOM_HIGHBITDEPTH
void av1_highbd_build_inter_predictor(
clang-format's avatar
clang-format committed
382
383
    const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride,
    const MV *mv_q3, const struct scale_factors *sf, int w, int h, int do_avg,
384
#if CONFIG_DUAL_FILTER
James Zern's avatar
James Zern committed
385
    const InterpFilter *interp_filter,
386
#else
James Zern's avatar
James Zern committed
387
    const InterpFilter interp_filter,
388
#endif
clang-format's avatar
clang-format committed
389
    enum mv_precision precision, int x, int y, int bd);
Jingning Han's avatar
Jingning Han committed
390
391
392
393
394
395
396
397
398
#endif

static INLINE int scaled_buffer_offset(int x_offset, int y_offset, int stride,
                                       const struct scale_factors *sf) {
  const int x = sf ? sf->scale_value_x(x_offset, sf) : x_offset;
  const int y = sf ? sf->scale_value_y(y_offset, sf) : y_offset;
  return y * stride + x;
}

clang-format's avatar
clang-format committed
399
400
401
static INLINE void setup_pred_plane(struct buf_2d *dst, uint8_t *src, int width,
                                    int height, int stride, int mi_row,
                                    int mi_col,
Jingning Han's avatar
Jingning Han committed
402
403
404
405
406
                                    const struct scale_factors *scale,
                                    int subsampling_x, int subsampling_y) {
  const int x = (MI_SIZE * mi_col) >> subsampling_x;
  const int y = (MI_SIZE * mi_row) >> subsampling_y;
  dst->buf = src + scaled_buffer_offset(x, y, stride, scale);
407
408
409
  dst->buf0 = src;
  dst->width = width;
  dst->height = height;
Jingning Han's avatar
Jingning Han committed
410
411
412
  dst->stride = stride;
}

Yaowu Xu's avatar
Yaowu Xu committed
413
414
415
void av1_setup_dst_planes(struct macroblockd_plane planes[MAX_MB_PLANE],
                          const YV12_BUFFER_CONFIG *src, int mi_row,
                          int mi_col);
Jingning Han's avatar
Jingning Han committed
416

Yaowu Xu's avatar
Yaowu Xu committed
417
418
419
void av1_setup_pre_planes(MACROBLOCKD *xd, int idx,
                          const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col,
                          const struct scale_factors *sf);
420

421
422
// Detect if the block have sub-pixel level motion vectors
// per component.
423
424
static INLINE int has_subpel_mv_component(const MODE_INFO *const mi,
                                          const MACROBLOCKD *const xd,
425
                                          int dir) {
426
  const MB_MODE_INFO *const mbmi = &mi->mbmi;
427
428
429
430
431
432
  const BLOCK_SIZE bsize = mbmi->sb_type;
  int plane;
  int ref = (dir >> 1);

  if (bsize >= BLOCK_8X8) {
    if (dir & 0x01) {
clang-format's avatar
clang-format committed
433
      if (mbmi->mv[ref].as_mv.col & SUBPEL_MASK) return 1;
434
    } else {
clang-format's avatar
clang-format committed
435
      if (mbmi->mv[ref].as_mv.row & SUBPEL_MASK) return 1;
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
    }
  } else {
    for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
      const PARTITION_TYPE bp = BLOCK_8X8 - bsize;
      const struct macroblockd_plane *const pd = &xd->plane[plane];
      const int have_vsplit = bp != PARTITION_HORZ;
      const int have_hsplit = bp != PARTITION_VERT;
      const int num_4x4_w = 2 >> ((!have_vsplit) | pd->subsampling_x);
      const int num_4x4_h = 2 >> ((!have_hsplit) | pd->subsampling_y);

      int x, y;
      for (y = 0; y < num_4x4_h; ++y) {
        for (x = 0; x < num_4x4_w; ++x) {
          const MV mv = average_split_mvs(pd, mi, ref, y * 2 + x);
          if (dir & 0x01) {
clang-format's avatar
clang-format committed
451
            if (mv.col & SUBPEL_MASK) return 1;
452
          } else {
clang-format's avatar
clang-format committed
453
            if (mv.row & SUBPEL_MASK) return 1;
454
455
456
457
458
459
460
461
462
          }
        }
      }
    }
  }

  return 0;
}

463
#define CHECK_SUBPEL 0
Yaowu Xu's avatar
Yaowu Xu committed
464
static INLINE int av1_is_interp_needed(const MACROBLOCKD *const xd) {
465
#if CHECK_SUBPEL
466
  MODE_INFO *const mi = xd->mi[0];
467
468
469
470
471
472
473
474
  const int is_compound = has_second_ref(&mi->mbmi);
  int ref;
  for (ref = 0; ref < 1 + is_compound; ++ref) {
    int row_col;
    for (row_col = 0; row_col < 2; ++row_col) {
      const int dir = (ref << 1) + row_col;
      if (has_subpel_mv_component(mi, xd, dir)) {
        return 1;
475
476
477
      }
    }
  }
478
  return 0;
479
480
481
482
#else
  (void)xd;
  return 1;
#endif
483
}
484

Yue Chen's avatar
Yue Chen committed
485
#if CONFIG_MOTION_VAR
Yaowu Xu's avatar
Yaowu Xu committed
486
const uint8_t *av1_get_obmc_mask(int length);
487
void av1_build_obmc_inter_prediction(const AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xu's avatar
Yaowu Xu committed
488
489
490
491
492
                                     int mi_row, int mi_col,
                                     uint8_t *above[MAX_MB_PLANE],
                                     int above_stride[MAX_MB_PLANE],
                                     uint8_t *left[MAX_MB_PLANE],
                                     int left_stride[MAX_MB_PLANE]);
493
void av1_build_prediction_by_above_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
494
495
                                         int mi_row, int mi_col,
                                         uint8_t *tmp_buf[MAX_MB_PLANE],
496
497
                                         int tmp_width[MAX_MB_PLANE],
                                         int tmp_height[MAX_MB_PLANE],
498
                                         int tmp_stride[MAX_MB_PLANE]);
499
void av1_build_prediction_by_left_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xu's avatar
Yaowu Xu committed
500
501
502
503
504
                                        int mi_row, int mi_col,
                                        uint8_t *tmp_buf[MAX_MB_PLANE],
                                        int tmp_width[MAX_MB_PLANE],
                                        int tmp_height[MAX_MB_PLANE],
                                        int tmp_stride[MAX_MB_PLANE]);
505
506
void av1_build_obmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
                                        int mi_row, int mi_col);
Yue Chen's avatar
Yue Chen committed
507
#endif  // CONFIG_MOTION_VAR
508

509
#if CONFIG_EXT_INTER
clang-format's avatar
clang-format committed
510
#define MASK_MASTER_SIZE (2 * MAX_SB_SIZE)
511
#define MASK_MASTER_STRIDE (2 * MAX_SB_SIZE)
512

Yaowu Xu's avatar
Yaowu Xu committed
513
void av1_init_wedge_masks();
514

Yaowu Xu's avatar
Yaowu Xu committed
515
516
517
static INLINE const uint8_t *av1_get_contiguous_soft_mask(int wedge_index,
                                                          int wedge_sign,
                                                          BLOCK_SIZE sb_type) {
518
519
520
  return wedge_params_lookup[sb_type].masks[wedge_sign][wedge_index];
}

Yaowu Xu's avatar
Yaowu Xu committed
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
const uint8_t *av1_get_soft_mask(int wedge_index, int wedge_sign,
                                 BLOCK_SIZE sb_type, int wedge_offset_x,
                                 int wedge_offset_y);

void av1_build_interintra_predictors(MACROBLOCKD *xd, uint8_t *ypred,
                                     uint8_t *upred, uint8_t *vpred,
                                     int ystride, int ustride, int vstride,
                                     BLOCK_SIZE bsize);
void av1_build_interintra_predictors_sby(MACROBLOCKD *xd, uint8_t *ypred,
                                         int ystride, BLOCK_SIZE bsize);
void av1_build_interintra_predictors_sbc(MACROBLOCKD *xd, uint8_t *upred,
                                         int ustride, int plane,
                                         BLOCK_SIZE bsize);
void av1_build_interintra_predictors_sbuv(MACROBLOCKD *xd, uint8_t *upred,
                                          uint8_t *vpred, int ustride,
                                          int vstride, BLOCK_SIZE bsize);

void av1_build_intra_predictors_for_interintra(MACROBLOCKD *xd,
                                               BLOCK_SIZE bsize, int plane,
                                               uint8_t *intra_pred,
                                               int intra_stride);
void av1_combine_interintra(MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane,
                            const uint8_t *inter_pred, int inter_stride,
                            const uint8_t *intra_pred, int intra_stride);
void av1_build_interintra_predictors_sbuv(MACROBLOCKD *xd, uint8_t *upred,
                                          uint8_t *vpred, int ustride,
                                          int vstride, BLOCK_SIZE bsize);
void av1_build_interintra_predictors_sby(MACROBLOCKD *xd, uint8_t *ypred,
                                         int ystride, BLOCK_SIZE bsize);
550

551
// Encoder only
Yaowu Xu's avatar
Yaowu Xu committed
552
void av1_build_inter_predictors_for_planes_single_buf(
clang-format's avatar
clang-format committed
553
554
    MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane_from, int plane_to, int mi_row,
    int mi_col, int ref, uint8_t *ext_dst[3], int ext_dst_stride[3]);
Yaowu Xu's avatar
Yaowu Xu committed
555
556
557
558
559
560
void av1_build_wedge_inter_predictor_from_buf(MACROBLOCKD *xd, BLOCK_SIZE bsize,
                                              int plane_from, int plane_to,
                                              uint8_t *ext_dst0[3],
                                              int ext_dst_stride0[3],
                                              uint8_t *ext_dst1[3],
                                              int ext_dst_stride1[3]);
561
562
#endif  // CONFIG_EXT_INTER

Jingning Han's avatar
Jingning Han committed
563
564
565
566
#ifdef __cplusplus
}  // extern "C"
#endif

Yaowu Xu's avatar
Yaowu Xu committed
567
#endif  // AV1_COMMON_RECONINTER_H_