reconinter.h 24.2 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"
18
#include "av1/common/warped_motion.h"
Yaowu Xu's avatar
Yaowu Xu committed
19
#include "aom/aom_integer.h"
Jingning Han's avatar
Jingning Han committed
20

21
#define WARP_WM_NEIGHBORS_WITH_OBMC 0
22

23
#define WARP_GM_NEIGHBORS_WITH_OBMC 0
24

25
26
27
#define AOM_LEFT_TOP_MARGIN_SCALED \
  ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << SCALE_SUBPEL_BITS)

Jingning Han's avatar
Jingning Han committed
28
29
30
31
#ifdef __cplusplus
extern "C" {
#endif

32
33
34
static INLINE int has_scale(int xs, int ys) {
  return xs != SCALE_SUBPEL_SHIFTS || ys != SCALE_SUBPEL_SHIFTS;
}
35

Jingning Han's avatar
Jingning Han committed
36
static INLINE void inter_predictor(const uint8_t *src, int src_stride,
37
38
39
                                   uint8_t *dst, int dst_stride, int subpel_x,
                                   int subpel_y, const struct scale_factors *sf,
                                   int w, int h, ConvolveParams *conv_params,
40
41
                                   InterpFilters interp_filters, int xs,
                                   int ys) {
42
  assert(conv_params->do_average == 0 || conv_params->do_average == 1);
Alex Converse's avatar
Alex Converse committed
43
  assert(sf);
44
  if (has_scale(xs, ys)) {
45
46
    // TODO(afergs, debargha): Use a different scale convolve function
    // that uses higher precision for subpel_x, subpel_y, xs, ys
47
48
49
    if (conv_params->round == CONVOLVE_OPT_NO_ROUND) {
#if CONFIG_CONVOLVE_ROUND
      av1_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
50
51
                             interp_filters, subpel_x, xs, subpel_y, ys, 1,
                             conv_params);
52
53
54
55
56
57
      conv_params->do_post_rounding = 1;
#else
      assert(0);
#endif  // CONFIG_CONVOLVE_ROUND
    } else {
      assert(conv_params->round == CONVOLVE_OPT_ROUND);
58
      av1_convolve_scale(src, src_stride, dst, dst_stride, w, h, interp_filters,
59
60
                         subpel_x, xs, subpel_y, ys, conv_params);
    }
61
62
63
64
65
66
67
68
69
70
  } else {
    subpel_x >>= SCALE_EXTRA_BITS;
    subpel_y >>= SCALE_EXTRA_BITS;
    xs >>= SCALE_EXTRA_BITS;
    ys >>= SCALE_EXTRA_BITS;
    assert(subpel_x < SUBPEL_SHIFTS);
    assert(subpel_y < SUBPEL_SHIFTS);
    assert(xs <= SUBPEL_SHIFTS);
    assert(ys <= SUBPEL_SHIFTS);
    if (conv_params->round == CONVOLVE_OPT_NO_ROUND) {
Angie Chiang's avatar
Angie Chiang committed
71
#if CONFIG_CONVOLVE_ROUND
72
      av1_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
73
74
                             interp_filters, subpel_x, xs, subpel_y, ys, 0,
                             conv_params);
75
      conv_params->do_post_rounding = 1;
76
#else
77
      assert(0);
78
79
#endif  // CONFIG_CONVOLVE_ROUND
    } else {
80
      assert(conv_params->round == CONVOLVE_OPT_ROUND);
81
82

      InterpFilterParams filter_params_x, filter_params_y;
Zhijie Yang's avatar
Zhijie Yang committed
83
84
85
86
#if CONFIG_SHORT_FILTER
      av1_get_convolve_filter_params(interp_filters, 0, &filter_params_x,
                                     &filter_params_y, w, h);
#else
87
88
89
      av1_get_convolve_filter_params(interp_filters, 0, &filter_params_x,
                                     &filter_params_y);

Zhijie Yang's avatar
Zhijie Yang committed
90
91
#endif

92
      if (w <= 2 || h <= 2) {
93
        av1_convolve_c(src, src_stride, dst, dst_stride, w, h, interp_filters,
94
                       subpel_x, xs, subpel_y, ys, conv_params);
95
96
97
98
99
100
      } else if (filter_params_x.taps == SUBPEL_TAPS &&
                 filter_params_y.taps == SUBPEL_TAPS) {
        const int16_t *kernel_x =
            av1_get_interp_filter_subpel_kernel(filter_params_x, subpel_x);
        const int16_t *kernel_y =
            av1_get_interp_filter_subpel_kernel(filter_params_y, subpel_y);
101
102
103
        sf->predict[subpel_x != 0][subpel_y != 0][conv_params->do_average](
            src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h);
      } else {
104
        av1_convolve(src, src_stride, dst, dst_stride, w, h, interp_filters,
105
106
                     subpel_x, xs, subpel_y, ys, conv_params);
      }
107
    }
108
  }
Jingning Han's avatar
Jingning Han committed
109
110
}

111
#if CONFIG_HIGHBITDEPTH
112
113
static INLINE void highbd_inter_predictor(const uint8_t *src, int src_stride,
                                          uint8_t *dst, int dst_stride,
114
                                          int subpel_x, int subpel_y,
clang-format's avatar
clang-format committed
115
                                          const struct scale_factors *sf, int w,
116
                                          int h, ConvolveParams *conv_params,
117
118
                                          InterpFilters interp_filters, int xs,
                                          int ys, int bd) {
119
120
  const int avg = conv_params->do_average;
  assert(avg == 0 || avg == 1);
121

122
  if (has_scale(xs, ys)) {
123
124
125
    if (conv_params->round == CONVOLVE_OPT_NO_ROUND) {
#if CONFIG_CONVOLVE_ROUND
      av1_highbd_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
126
127
                                    interp_filters, subpel_x, xs, subpel_y, ys,
                                    1, conv_params, bd);
128
129
130
131
132
133
      conv_params->do_post_rounding = 1;
#else
      assert(0);
#endif  // CONFIG_CONVOLVE_ROUND
    } else {
      av1_highbd_convolve_scale(src, src_stride, dst, dst_stride, w, h,
134
                                interp_filters, subpel_x, xs, subpel_y, ys, avg,
135
136
                                bd);
    }
137
138
139
140
141
142
143
144
145
146
  } else {
    subpel_x >>= SCALE_EXTRA_BITS;
    subpel_y >>= SCALE_EXTRA_BITS;
    xs >>= SCALE_EXTRA_BITS;
    ys >>= SCALE_EXTRA_BITS;
    assert(subpel_x < SUBPEL_SHIFTS);
    assert(subpel_y < SUBPEL_SHIFTS);
    assert(xs <= SUBPEL_SHIFTS);
    assert(ys <= SUBPEL_SHIFTS);
    if (conv_params->round == CONVOLVE_OPT_NO_ROUND) {
147
#if CONFIG_CONVOLVE_ROUND
148
      av1_highbd_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
149
150
                                    interp_filters, subpel_x, xs, subpel_y, ys,
                                    0, conv_params, bd);
151
      conv_params->do_post_rounding = 1;
152
#else
153
      assert(0);
154
155
#endif  // CONFIG_CONVOLVE_ROUND
    } else {
156
      InterpFilterParams filter_params_x, filter_params_y;
Zhijie Yang's avatar
Zhijie Yang committed
157
158
159
160
#if CONFIG_SHORT_FILTER
      av1_get_convolve_filter_params(interp_filters, 0, &filter_params_x,
                                     &filter_params_y, w, h);
#else
161
162
      av1_get_convolve_filter_params(interp_filters, 0, &filter_params_x,
                                     &filter_params_y);
Zhijie Yang's avatar
Zhijie Yang committed
163
#endif
164
165
166
167
168
169
170

      if (filter_params_x.taps == SUBPEL_TAPS &&
          filter_params_y.taps == SUBPEL_TAPS && w > 2 && h > 2) {
        const int16_t *kernel_x =
            av1_get_interp_filter_subpel_kernel(filter_params_x, subpel_x);
        const int16_t *kernel_y =
            av1_get_interp_filter_subpel_kernel(filter_params_y, subpel_y);
171
172
173
174
175
        sf->highbd_predict[subpel_x != 0][subpel_y != 0][avg](
            src, src_stride, dst, dst_stride, kernel_x, xs, kernel_y, ys, w, h,
            bd);
      } else {
        av1_highbd_convolve(src, src_stride, dst, dst_stride, w, h,
176
177
                            interp_filters, subpel_x, xs, subpel_y, ys, avg,
                            bd);
178
      }
179
    }
180
  }
Jingning Han's avatar
Jingning Han committed
181
}
182
#endif  // CONFIG_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
183

184
// Set to (1 << 5) if the 32-ary codebooks are used for any bock size
clang-format's avatar
clang-format committed
185
#define MAX_WEDGE_TYPES (1 << 4)
186

clang-format's avatar
clang-format committed
187
188
189
#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)
190

191
192
#define WEDGE_WEIGHT_BITS 6

clang-format's avatar
clang-format committed
193
#define WEDGE_NONE -1
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212

// 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;

213
214
typedef uint8_t *wedge_masks_type[MAX_WEDGE_TYPES];

215
216
217
218
219
typedef struct {
  int bits;
  const wedge_code_type *codebook;
  uint8_t *signflip;
  int smoother;
220
  wedge_masks_type *masks;
221
222
} wedge_params_type;

223
extern const wedge_params_type wedge_params_lookup[BLOCK_SIZES_ALL];
224

225
226
static INLINE int is_interinter_compound_used(COMPOUND_TYPE type,
                                              BLOCK_SIZE sb_type) {
227
  (void)sb_type;
228
  switch (type) {
229
    case COMPOUND_AVERAGE: return sb_type >= BLOCK_4X4;
230
    case COMPOUND_WEDGE: return wedge_params_lookup[sb_type].bits > 0;
231
232
    case COMPOUND_SEG:
      return AOMMIN(block_size_wide[sb_type], block_size_high[sb_type]) >= 8;
233
234
    default: assert(0); return 0;
  }
235
}
236

237
238
static INLINE int is_any_masked_compound_used(BLOCK_SIZE sb_type) {
  COMPOUND_TYPE comp_type;
239
  if (sb_type < BLOCK_4X4) return 0;
240
241
242
243
244
245
246
247
248
249
  for (comp_type = 0; comp_type < COMPOUND_TYPES; comp_type++) {
    if (is_masked_compound_type(comp_type) &&
        is_interinter_compound_used(comp_type, sb_type))
      return 1;
  }
  return 0;
}

static INLINE int get_wedge_bits_lookup(BLOCK_SIZE sb_type) {
  return wedge_params_lookup[sb_type].bits;
250
251
252
}

static INLINE int get_interinter_wedge_bits(BLOCK_SIZE sb_type) {
253
  const int wbits = wedge_params_lookup[sb_type].bits;
254
255
256
257
  return (wbits > 0) ? wbits + 1 : 0;
}

static INLINE int is_interintra_wedge_used(BLOCK_SIZE sb_type) {
clang-format's avatar
clang-format committed
258
  (void)sb_type;
259
  return wedge_params_lookup[sb_type].bits > 0;
260
261
262
}

static INLINE int get_interintra_wedge_bits(BLOCK_SIZE sb_type) {
263
  return wedge_params_lookup[sb_type].bits;
264
}
265

266
void build_compound_seg_mask(uint8_t *mask, SEG_MASK_TYPE mask_type,
267
268
269
                             const uint8_t *src0, int src0_stride,
                             const uint8_t *src1, int src1_stride,
                             BLOCK_SIZE sb_type, int h, int w);
270
#if CONFIG_HIGHBITDEPTH
271
272
273
274
void build_compound_seg_mask_highbd(uint8_t *mask, SEG_MASK_TYPE mask_type,
                                    const uint8_t *src0, int src0_stride,
                                    const uint8_t *src1, int src1_stride,
                                    BLOCK_SIZE sb_type, int h, int w, int bd);
275
#endif  // CONFIG_HIGHBITDEPTH
276

277
278
279
280
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, ConvolveParams *conv_params, InterpFilters interp_filters,
281
282
    int xs, int ys, int plane, const WarpTypesAllowed *warp_types, int p_col,
    int p_row, int ref, MACROBLOCKD *xd);
283

Jingning Han's avatar
Jingning Han committed
284
285
286
287
288
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
289
290
291
292
293
294
295
296
  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
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
  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
313
static INLINE MV clamp_mv_to_umv_border_sb(const MACROBLOCKD *xd,
clang-format's avatar
clang-format committed
314
315
                                           const MV *src_mv, int bw, int bh,
                                           int ss_x, int ss_y) {
Jingning Han's avatar
Jingning Han committed
316
317
318
  // 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
319
  const int spel_left = (AOM_INTERP_EXTEND + bw) << SUBPEL_BITS;
Jingning Han's avatar
Jingning Han committed
320
  const int spel_right = spel_left - SUBPEL_SHIFTS;
Yaowu Xu's avatar
Yaowu Xu committed
321
  const int spel_top = (AOM_INTERP_EXTEND + bh) << SUBPEL_BITS;
Jingning Han's avatar
Jingning Han committed
322
  const int spel_bottom = spel_top - SUBPEL_SHIFTS;
clang-format's avatar
clang-format committed
323
324
  MV clamped_mv = { src_mv->row * (1 << (1 - ss_y)),
                    src_mv->col * (1 << (1 - ss_x)) };
Jingning Han's avatar
Jingning Han committed
325
326
327
  assert(ss_x <= 1);
  assert(ss_y <= 1);

clang-format's avatar
clang-format committed
328
  clamp_mv(&clamped_mv, xd->mb_to_left_edge * (1 << (1 - ss_x)) - spel_left,
Jingning Han's avatar
Jingning Han committed
329
330
331
332
333
334
335
           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
336
337
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
338
  const int ss_idx = ((pd->subsampling_x > 0) << 1) | (pd->subsampling_y > 0);
clang-format's avatar
clang-format committed
339
  MV res = { 0, 0 };
Jingning Han's avatar
Jingning Han committed
340
  switch (ss_idx) {
clang-format's avatar
clang-format committed
341
342
343
344
345
    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
346
347
348
349
  }
  return res;
}

350
351
352
void av1_build_inter_predictors_sby(const AV1_COMMON *cm, MACROBLOCKD *xd,
                                    int mi_row, int mi_col, BUFFER_SET *ctx,
                                    BLOCK_SIZE bsize);
Jingning Han's avatar
Jingning Han committed
353

354
355
356
void av1_build_inter_predictors_sbuv(const AV1_COMMON *cm, MACROBLOCKD *xd,
                                     int mi_row, int mi_col, BUFFER_SET *ctx,
                                     BLOCK_SIZE bsize);
Jingning Han's avatar
Jingning Han committed
357

358
359
360
void av1_build_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
                                   int mi_row, int mi_col, BUFFER_SET *ctx,
                                   BLOCK_SIZE bsize);
361

362
363
364
365
366
367
void av1_build_inter_predictor(
    const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride,
    const MV *src_mv, const struct scale_factors *sf, int w, int h,
    ConvolveParams *conv_params, InterpFilters interp_filters,
    const WarpTypesAllowed *warp_types, int p_col, int p_row, int plane,
    int ref, enum mv_precision precision, int x, int y, const MACROBLOCKD *xd);
Jingning Han's avatar
Jingning Han committed
368

369
#if CONFIG_HIGHBITDEPTH
370
371
372
void av1_highbd_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
374
    InterpFilters interp_filters, const WarpTypesAllowed *warp_types, int p_col,
    int p_row, int plane, enum mv_precision precision, int x, int y,
375
    const MACROBLOCKD *xd);
Jingning Han's avatar
Jingning Han committed
376
377
378
379
#endif

static INLINE int scaled_buffer_offset(int x_offset, int y_offset, int stride,
                                       const struct scale_factors *sf) {
380
381
382
383
  const int x =
      sf ? sf->scale_value_x(x_offset, sf) >> SCALE_EXTRA_BITS : x_offset;
  const int y =
      sf ? sf->scale_value_y(y_offset, sf) >> SCALE_EXTRA_BITS : y_offset;
Jingning Han's avatar
Jingning Han committed
384
385
386
  return y * stride + x;
}

387
388
389
static INLINE void 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,
Jingning Han's avatar
Jingning Han committed
390
391
                                    const struct scale_factors *scale,
                                    int subsampling_x, int subsampling_y) {
392
393
394
395
396
  // Offset the buffer pointer
  if (subsampling_y && (mi_row & 0x01) && (mi_size_high[bsize] == 1))
    mi_row -= 1;
  if (subsampling_x && (mi_col & 0x01) && (mi_size_wide[bsize] == 1))
    mi_col -= 1;
397

Jingning Han's avatar
Jingning Han committed
398
399
400
  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);
401
402
403
  dst->buf0 = src;
  dst->width = width;
  dst->height = height;
Jingning Han's avatar
Jingning Han committed
404
405
406
  dst->stride = stride;
}

Yaowu Xu's avatar
Yaowu Xu committed
407
408
409
void av1_setup_dst_planes(struct macroblockd_plane *planes, BLOCK_SIZE bsize,
                          const YV12_BUFFER_CONFIG *src, int mi_row,
                          int mi_col);
Jingning Han's avatar
Jingning Han committed
410

Yaowu Xu's avatar
Yaowu Xu committed
411
412
413
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);
414

415
416
// Detect if the block have sub-pixel level motion vectors
// per component.
417
#define CHECK_SUBPEL 0
418
419
static INLINE int has_subpel_mv_component(const MODE_INFO *const mi,
                                          const MACROBLOCKD *const xd,
420
                                          int dir) {
421
#if CHECK_SUBPEL
422
  const MB_MODE_INFO *const mbmi = &mi->mbmi;
423
424
425
426
  const BLOCK_SIZE bsize = mbmi->sb_type;
  int plane;
  int ref = (dir >> 1);

427
428
  if (dir & 0x01) {
    if (mbmi->mv[ref].as_mv.col & SUBPEL_MASK) return 1;
429
  } else {
430
    if (mbmi->mv[ref].as_mv.row & SUBPEL_MASK) return 1;
431
432
433
  }

  return 0;
434
435
436
437
438
439
#else
  (void)mi;
  (void)xd;
  (void)dir;
  return 1;
#endif
440
441
}

442
443
static INLINE void set_default_interp_filters(
    MB_MODE_INFO *const mbmi, InterpFilter frame_interp_filter) {
444
445
  mbmi->interp_filters =
      av1_broadcast_interp_filter(av1_unswitchable_filter(frame_interp_filter));
446
447
}

Yaowu Xu's avatar
Yaowu Xu committed
448
static INLINE int av1_is_interp_needed(const MACROBLOCKD *const xd) {
449
450
451
  (void)xd;
  const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
  if (mbmi->motion_mode == WARPED_CAUSAL) return 0;
Zoe Liu's avatar
Zoe Liu committed
452
453
454
#if CONFIG_EXT_SKIP
  if (mbmi->skip_mode) return 0;
#endif  // CONFIG_EXT_SKIP
455
456
457
458
459
  if (is_nontrans_global_motion(xd)) return 0;
  return 1;
}

static INLINE int av1_is_interp_search_needed(const MACROBLOCKD *const xd) {
460
  MODE_INFO *const mi = xd->mi[0];
461
462
463
464
465
466
467
468
  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;
469
470
471
      }
    }
  }
472
  return 0;
473
}
474

Yaowu Xu's avatar
Yaowu Xu committed
475
const uint8_t *av1_get_obmc_mask(int length);
476
477
void av1_count_overlappable_neighbors(const AV1_COMMON *cm, MACROBLOCKD *xd,
                                      int mi_row, int mi_col);
478
void av1_build_obmc_inter_prediction(const AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xu's avatar
Yaowu Xu committed
479
480
481
482
483
                                     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]);
484
void av1_build_prediction_by_above_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
485
486
                                         int mi_row, int mi_col,
                                         uint8_t *tmp_buf[MAX_MB_PLANE],
487
488
                                         int tmp_width[MAX_MB_PLANE],
                                         int tmp_height[MAX_MB_PLANE],
489
                                         int tmp_stride[MAX_MB_PLANE]);
490
void av1_build_prediction_by_left_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xu's avatar
Yaowu Xu committed
491
492
493
494
495
                                        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]);
496
497
void av1_build_obmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
                                        int mi_row, int mi_col);
498
499
500
501
#if CONFIG_NCOBMC
void av1_build_ncobmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
                                          int mi_row, int mi_col);
#endif
502

503
504
#define MASK_MASTER_SIZE ((MAX_WEDGE_SIZE) << 1)
#define MASK_MASTER_STRIDE (MASK_MASTER_SIZE)
505

Yaowu Xu's avatar
Yaowu Xu committed
506
void av1_init_wedge_masks();
507

Yaowu Xu's avatar
Yaowu Xu committed
508
509
510
static INLINE const uint8_t *av1_get_contiguous_soft_mask(int wedge_index,
                                                          int wedge_sign,
                                                          BLOCK_SIZE sb_type) {
511
512
513
  return wedge_params_lookup[sb_type].masks[wedge_sign][wedge_index];
}

Yaowu Xu's avatar
Yaowu Xu committed
514
515
516
517
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);

518
const uint8_t *av1_get_compound_type_mask_inverse(
519
520
    const INTERINTER_COMPOUND_DATA *const comp_data, uint8_t *mask_buffer,
    int h, int w, int stride, BLOCK_SIZE sb_type);
521
522
523

const uint8_t *av1_get_compound_type_mask(
    const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type);
524
#if CONFIG_INTERINTRA
525
526
527
528
529
530
531
532
533
534
535
void av1_build_interintra_predictors(const AV1_COMMON *cm, MACROBLOCKD *xd,
                                     uint8_t *ypred, uint8_t *upred,
                                     uint8_t *vpred, int ystride, int ustride,
                                     int vstride, BUFFER_SET *ctx,
                                     BLOCK_SIZE bsize);
void av1_build_interintra_predictors_sby(const AV1_COMMON *cm, MACROBLOCKD *xd,
                                         uint8_t *ypred, int ystride,
                                         BUFFER_SET *ctx, BLOCK_SIZE bsize);
void av1_build_interintra_predictors_sbc(const AV1_COMMON *cm, MACROBLOCKD *xd,
                                         uint8_t *upred, int ustride,
                                         BUFFER_SET *ctx, int plane,
Yaowu Xu's avatar
Yaowu Xu committed
536
                                         BLOCK_SIZE bsize);
537
538
539
540
541
542
543
544
void av1_build_interintra_predictors_sbuv(const AV1_COMMON *cm, MACROBLOCKD *xd,
                                          uint8_t *upred, uint8_t *vpred,
                                          int ustride, int vstride,
                                          BUFFER_SET *ctx, BLOCK_SIZE bsize);

void av1_build_intra_predictors_for_interintra(
    const AV1_COMMON *cm, MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane,
    BUFFER_SET *ctx, uint8_t *intra_pred, int intra_stride);
Yaowu Xu's avatar
Yaowu Xu committed
545
546
547
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);
548
#endif  // CONFIG_INTERINTRA
549
// Encoder only
Yaowu Xu's avatar
Yaowu Xu committed
550
void av1_build_inter_predictors_for_planes_single_buf(
clang-format's avatar
clang-format committed
551
552
    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]);
553
554
555
556
557
558
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]);
559

560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
#if CONFIG_NCOBMC_ADAPT_WEIGHT
#define ASSIGN_ALIGNED_PTRS(p, a, s) \
  p[0] = a;                          \
  p[1] = a + s;                      \
  p[2] = a + 2 * s;

#define ASSIGN_ALIGNED_PTRS_HBD(p, a, s, l) \
  p[0] = CONVERT_TO_BYTEPTR(a);             \
  p[1] = CONVERT_TO_BYTEPTR(a + s * l);     \
  p[2] = CONVERT_TO_BYTEPTR(a + 2 * s * l);

void alloc_ncobmc_pred_buffer(MACROBLOCKD *const xd);
void free_ncobmc_pred_buffer(MACROBLOCKD *const xd);
void set_sb_mi_boundaries(const AV1_COMMON *const cm, MACROBLOCKD *const xd,
                          const int mi_row, const int mi_col);

void reset_xd_boundary(MACROBLOCKD *xd, int mi_row, int bh, int mi_col, int bw,
                       int mi_rows, int mi_cols);

void get_pred_from_intrpl_buf(MACROBLOCKD *xd, int mi_row, int mi_col,
                              BLOCK_SIZE bsize, int plane);

void build_ncobmc_intrpl_pred(const AV1_COMMON *const cm, MACROBLOCKD *xd,
                              int plane, int pxl_row, int pxl_col,
                              BLOCK_SIZE bsize, uint8_t *preds[][MAX_MB_PLANE],
                              int ps[MAX_MB_PLANE],  // pred buffer strides
                              int mode);

void av1_get_ext_blk_preds(const AV1_COMMON *cm, MACROBLOCKD *xd, int bsize,
                           int mi_row, int mi_col,
                           uint8_t *dst_buf[][MAX_MB_PLANE],
                           int dst_stride[MAX_MB_PLANE]);

void av1_get_ori_blk_pred(const AV1_COMMON *cm, MACROBLOCKD *xd, int bsize,
                          int mi_row, int mi_col,
                          uint8_t *dst_buf[MAX_MB_PLANE],
                          int dst_stride[MAX_MB_PLANE]);
#endif  // CONFIG_NCOBMC_ADAPT_WEIGHT

Jingning Han's avatar
Jingning Han committed
599
600
601
602
#ifdef __cplusplus
}  // extern "C"
#endif

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