reconinter.c 121 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 12 13
 */

#include <assert.h>

Yaowu Xu's avatar
Yaowu Xu committed
14 15 16
#include "./aom_scale_rtcd.h"
#include "./aom_dsp_rtcd.h"
#include "./aom_config.h"
Jingning Han's avatar
Jingning Han committed
17

Yaowu Xu's avatar
Yaowu Xu committed
18
#include "aom/aom_integer.h"
19
#include "aom_dsp/blend.h"
Jingning Han's avatar
Jingning Han committed
20

21 22 23
#include "av1/common/blockd.h"
#include "av1/common/reconinter.h"
#include "av1/common/reconintra.h"
Yue Chen's avatar
Yue Chen committed
24
#if CONFIG_MOTION_VAR
25
#include "av1/common/onyxc_int.h"
Yue Chen's avatar
Yue Chen committed
26
#endif  // CONFIG_MOTION_VAR
Jingning Han's avatar
Jingning Han committed
27

28
#if CONFIG_EXT_INTER
29

clang-format's avatar
clang-format committed
30
#define NSMOOTHERS 1
31

32
// [smoother][negative][direction]
clang-format's avatar
clang-format committed
33 34 35
DECLARE_ALIGNED(16, static uint8_t,
                wedge_mask_obl[NSMOOTHERS][2][WEDGE_DIRECTIONS]
                              [MASK_MASTER_SIZE * MASK_MASTER_SIZE]);
36

clang-format's avatar
clang-format committed
37 38
DECLARE_ALIGNED(16, static uint8_t,
                wedge_signflip_lookup[BLOCK_SIZES][MAX_WEDGE_TYPES]);
39

40 41
// 3 * MAX_WEDGE_SQUARE is an easy to compute and fairly tight upper bound
// on the sum of all mask sizes up to an including MAX_WEDGE_SQUARE.
clang-format's avatar
clang-format committed
42 43
DECLARE_ALIGNED(16, static uint8_t,
                wedge_mask_buf[2 * MAX_WEDGE_TYPES * 3 * MAX_WEDGE_SQUARE]);
44 45 46

static wedge_masks_type wedge_masks[BLOCK_SIZES][2];

47
// Some unused wedge codebooks left temporarily to facilitate experiments.
48 49
// To be removed when settled.
/*
50
static wedge_code_type wedge_codebook_8_hgtw[8] = {
clang-format's avatar
clang-format committed
51 52 53 54
  { WEDGE_OBLIQUE27, 4, 4 },  { WEDGE_OBLIQUE63, 4, 4 },
  { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
  { WEDGE_OBLIQUE27, 4, 2 },  { WEDGE_OBLIQUE27, 4, 6 },
  { WEDGE_OBLIQUE153, 4, 2 }, { WEDGE_OBLIQUE153, 4, 6 },
55 56
};

57
static wedge_code_type wedge_codebook_8_hltw[8] = {
clang-format's avatar
clang-format committed
58 59 60 61
  { WEDGE_OBLIQUE27, 4, 4 },  { WEDGE_OBLIQUE63, 4, 4 },
  { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
  { WEDGE_OBLIQUE63, 2, 4 },  { WEDGE_OBLIQUE63, 6, 4 },
  { WEDGE_OBLIQUE117, 2, 4 }, { WEDGE_OBLIQUE117, 6, 4 },
62 63
};

64
static wedge_code_type wedge_codebook_8_heqw[8] = {
clang-format's avatar
clang-format committed
65 66 67 68
  { WEDGE_OBLIQUE27, 4, 4 },  { WEDGE_OBLIQUE63, 4, 4 },
  { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
  { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 6 },
  { WEDGE_VERTICAL, 2, 4 },   { WEDGE_VERTICAL, 6, 4 },
69
};
70 71

static const wedge_code_type wedge_codebook_32_hgtw[32] = {
clang-format's avatar
clang-format committed
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
  { WEDGE_OBLIQUE27, 4, 4 },  { WEDGE_OBLIQUE63, 4, 4 },
  { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
  { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 4 },
  { WEDGE_HORIZONTAL, 4, 6 }, { WEDGE_VERTICAL, 4, 4 },
  { WEDGE_OBLIQUE27, 4, 1 },  { WEDGE_OBLIQUE27, 4, 2 },
  { WEDGE_OBLIQUE27, 4, 3 },  { WEDGE_OBLIQUE27, 4, 5 },
  { WEDGE_OBLIQUE27, 4, 6 },  { WEDGE_OBLIQUE27, 4, 7 },
  { WEDGE_OBLIQUE153, 4, 1 }, { WEDGE_OBLIQUE153, 4, 2 },
  { WEDGE_OBLIQUE153, 4, 3 }, { WEDGE_OBLIQUE153, 4, 5 },
  { WEDGE_OBLIQUE153, 4, 6 }, { WEDGE_OBLIQUE153, 4, 7 },
  { WEDGE_OBLIQUE63, 1, 4 },  { WEDGE_OBLIQUE63, 2, 4 },
  { WEDGE_OBLIQUE63, 3, 4 },  { WEDGE_OBLIQUE63, 5, 4 },
  { WEDGE_OBLIQUE63, 6, 4 },  { WEDGE_OBLIQUE63, 7, 4 },
  { WEDGE_OBLIQUE117, 1, 4 }, { WEDGE_OBLIQUE117, 2, 4 },
  { WEDGE_OBLIQUE117, 3, 4 }, { WEDGE_OBLIQUE117, 5, 4 },
  { WEDGE_OBLIQUE117, 6, 4 }, { WEDGE_OBLIQUE117, 7, 4 },
88 89
};

90
static const wedge_code_type wedge_codebook_32_hltw[32] = {
clang-format's avatar
clang-format committed
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
  { WEDGE_OBLIQUE27, 4, 4 },  { WEDGE_OBLIQUE63, 4, 4 },
  { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
  { WEDGE_VERTICAL, 2, 4 },   { WEDGE_VERTICAL, 4, 4 },
  { WEDGE_VERTICAL, 6, 4 },   { WEDGE_HORIZONTAL, 4, 4 },
  { WEDGE_OBLIQUE27, 4, 1 },  { WEDGE_OBLIQUE27, 4, 2 },
  { WEDGE_OBLIQUE27, 4, 3 },  { WEDGE_OBLIQUE27, 4, 5 },
  { WEDGE_OBLIQUE27, 4, 6 },  { WEDGE_OBLIQUE27, 4, 7 },
  { WEDGE_OBLIQUE153, 4, 1 }, { WEDGE_OBLIQUE153, 4, 2 },
  { WEDGE_OBLIQUE153, 4, 3 }, { WEDGE_OBLIQUE153, 4, 5 },
  { WEDGE_OBLIQUE153, 4, 6 }, { WEDGE_OBLIQUE153, 4, 7 },
  { WEDGE_OBLIQUE63, 1, 4 },  { WEDGE_OBLIQUE63, 2, 4 },
  { WEDGE_OBLIQUE63, 3, 4 },  { WEDGE_OBLIQUE63, 5, 4 },
  { WEDGE_OBLIQUE63, 6, 4 },  { WEDGE_OBLIQUE63, 7, 4 },
  { WEDGE_OBLIQUE117, 1, 4 }, { WEDGE_OBLIQUE117, 2, 4 },
  { WEDGE_OBLIQUE117, 3, 4 }, { WEDGE_OBLIQUE117, 5, 4 },
  { WEDGE_OBLIQUE117, 6, 4 }, { WEDGE_OBLIQUE117, 7, 4 },
107 108
};

109
static const wedge_code_type wedge_codebook_32_heqw[32] = {
clang-format's avatar
clang-format committed
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
  { WEDGE_OBLIQUE27, 4, 4 },  { WEDGE_OBLIQUE63, 4, 4 },
  { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
  { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 6 },
  { WEDGE_VERTICAL, 2, 4 },   { WEDGE_VERTICAL, 6, 4 },
  { WEDGE_OBLIQUE27, 4, 1 },  { WEDGE_OBLIQUE27, 4, 2 },
  { WEDGE_OBLIQUE27, 4, 3 },  { WEDGE_OBLIQUE27, 4, 5 },
  { WEDGE_OBLIQUE27, 4, 6 },  { WEDGE_OBLIQUE27, 4, 7 },
  { WEDGE_OBLIQUE153, 4, 1 }, { WEDGE_OBLIQUE153, 4, 2 },
  { WEDGE_OBLIQUE153, 4, 3 }, { WEDGE_OBLIQUE153, 4, 5 },
  { WEDGE_OBLIQUE153, 4, 6 }, { WEDGE_OBLIQUE153, 4, 7 },
  { WEDGE_OBLIQUE63, 1, 4 },  { WEDGE_OBLIQUE63, 2, 4 },
  { WEDGE_OBLIQUE63, 3, 4 },  { WEDGE_OBLIQUE63, 5, 4 },
  { WEDGE_OBLIQUE63, 6, 4 },  { WEDGE_OBLIQUE63, 7, 4 },
  { WEDGE_OBLIQUE117, 1, 4 }, { WEDGE_OBLIQUE117, 2, 4 },
  { WEDGE_OBLIQUE117, 3, 4 }, { WEDGE_OBLIQUE117, 5, 4 },
  { WEDGE_OBLIQUE117, 6, 4 }, { WEDGE_OBLIQUE117, 7, 4 },
126
};
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
*/

static const wedge_code_type wedge_codebook_16_hgtw[16] = {
  { WEDGE_OBLIQUE27, 4, 4 },  { WEDGE_OBLIQUE63, 4, 4 },
  { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
  { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 4 },
  { WEDGE_HORIZONTAL, 4, 6 }, { WEDGE_VERTICAL, 4, 4 },
  { WEDGE_OBLIQUE27, 4, 2 },  { WEDGE_OBLIQUE27, 4, 6 },
  { WEDGE_OBLIQUE153, 4, 2 }, { WEDGE_OBLIQUE153, 4, 6 },
  { WEDGE_OBLIQUE63, 2, 4 },  { WEDGE_OBLIQUE63, 6, 4 },
  { WEDGE_OBLIQUE117, 2, 4 }, { WEDGE_OBLIQUE117, 6, 4 },
};

static const wedge_code_type wedge_codebook_16_hltw[16] = {
  { WEDGE_OBLIQUE27, 4, 4 },  { WEDGE_OBLIQUE63, 4, 4 },
  { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
  { WEDGE_VERTICAL, 2, 4 },   { WEDGE_VERTICAL, 4, 4 },
  { WEDGE_VERTICAL, 6, 4 },   { WEDGE_HORIZONTAL, 4, 4 },
  { WEDGE_OBLIQUE27, 4, 2 },  { WEDGE_OBLIQUE27, 4, 6 },
  { WEDGE_OBLIQUE153, 4, 2 }, { WEDGE_OBLIQUE153, 4, 6 },
  { WEDGE_OBLIQUE63, 2, 4 },  { WEDGE_OBLIQUE63, 6, 4 },
  { WEDGE_OBLIQUE117, 2, 4 }, { WEDGE_OBLIQUE117, 6, 4 },
};

static const wedge_code_type wedge_codebook_16_heqw[16] = {
  { WEDGE_OBLIQUE27, 4, 4 },  { WEDGE_OBLIQUE63, 4, 4 },
  { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
  { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 6 },
  { WEDGE_VERTICAL, 2, 4 },   { WEDGE_VERTICAL, 6, 4 },
  { WEDGE_OBLIQUE27, 4, 2 },  { WEDGE_OBLIQUE27, 4, 6 },
  { WEDGE_OBLIQUE153, 4, 2 }, { WEDGE_OBLIQUE153, 4, 6 },
  { WEDGE_OBLIQUE63, 2, 4 },  { WEDGE_OBLIQUE63, 6, 4 },
  { WEDGE_OBLIQUE117, 2, 4 }, { WEDGE_OBLIQUE117, 6, 4 },
};
161

162
const wedge_params_type wedge_params_lookup[BLOCK_SIZES] = {
163 164 165 166
#if CONFIG_CB4X4
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
167
#endif  // CONFIG_CB4X4
clang-format's avatar
clang-format committed
168 169 170
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
171
#if CONFIG_WEDGE
172
  { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_8X8], 0,
173
    wedge_masks[BLOCK_8X8] },
174
  { 4, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_8X16], 0,
175
    wedge_masks[BLOCK_8X16] },
176
  { 4, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_16X8], 0,
177
    wedge_masks[BLOCK_16X8] },
178
  { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_16X16], 0,
179
    wedge_masks[BLOCK_16X16] },
180
  { 4, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_16X32], 0,
181
    wedge_masks[BLOCK_16X32] },
182
  { 4, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_32X16], 0,
183
    wedge_masks[BLOCK_32X16] },
184
  { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_32X32], 0,
185
    wedge_masks[BLOCK_32X32] },
186
  { 0, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_32X64], 0,
187
    wedge_masks[BLOCK_32X64] },
188
  { 0, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_64X32], 0,
189
    wedge_masks[BLOCK_64X32] },
190
  { 0, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_64X64], 0,
191 192
    wedge_masks[BLOCK_64X64] },
#else
193
  { 0, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_8X8], 0,
194
    wedge_masks[BLOCK_8X8] },
195
  { 0, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_8X16], 0,
196
    wedge_masks[BLOCK_8X16] },
197
  { 0, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_16X8], 0,
198
    wedge_masks[BLOCK_16X8] },
199
  { 0, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_16X16], 0,
200
    wedge_masks[BLOCK_16X16] },
201
  { 0, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_16X32], 0,
202
    wedge_masks[BLOCK_16X32] },
203
  { 0, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_32X16], 0,
204
    wedge_masks[BLOCK_32X16] },
205
  { 0, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_32X32], 0,
206
    wedge_masks[BLOCK_32X32] },
207
  { 0, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_32X64], 0,
208
    wedge_masks[BLOCK_32X64] },
209
  { 0, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_64X32], 0,
210
    wedge_masks[BLOCK_64X32] },
211
  { 0, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_64X64], 0,
212
    wedge_masks[BLOCK_64X64] },
213
#endif  // CONFIG_WEDGE
Debargha Mukherjee's avatar
Debargha Mukherjee committed
214
#if CONFIG_EXT_PARTITION
clang-format's avatar
clang-format committed
215 216 217
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
Debargha Mukherjee's avatar
Debargha Mukherjee committed
218
#endif  // CONFIG_EXT_PARTITION
219
};
220

clang-format's avatar
clang-format committed
221
static const uint8_t *get_wedge_mask_inplace(int wedge_index, int neg,
222
                                             BLOCK_SIZE sb_type) {
Debargha Mukherjee's avatar
Debargha Mukherjee committed
223
  const uint8_t *master;
224 225
  const int bh = block_size_high[sb_type];
  const int bw = block_size_wide[sb_type];
226 227 228
  const wedge_code_type *a =
      wedge_params_lookup[sb_type].codebook + wedge_index;
  const int smoother = wedge_params_lookup[sb_type].smoother;
229
  int woff, hoff;
230 231 232 233 234 235 236
  const uint8_t wsignflip = wedge_params_lookup[sb_type].signflip[wedge_index];

  assert(wedge_index >= 0 &&
         wedge_index < (1 << get_wedge_bits_lookup(sb_type)));
  woff = (a->x_offset * bw) >> 3;
  hoff = (a->y_offset * bh) >> 3;
  master = wedge_mask_obl[smoother][neg ^ wsignflip][a->direction] +
clang-format's avatar
clang-format committed
237 238
           MASK_MASTER_STRIDE * (MASK_MASTER_SIZE / 2 - hoff) +
           MASK_MASTER_SIZE / 2 - woff;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
239 240 241
  return master;
}

Yaowu Xu's avatar
Yaowu Xu committed
242 243 244
const uint8_t *av1_get_soft_mask(int wedge_index, int wedge_sign,
                                 BLOCK_SIZE sb_type, int offset_x,
                                 int offset_y) {
245
  const uint8_t *mask =
246
      get_wedge_mask_inplace(wedge_index, wedge_sign, sb_type);
clang-format's avatar
clang-format committed
247
  if (mask) mask -= (offset_x + offset_y * MASK_MASTER_STRIDE);
248
  return mask;
249 250
}

251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
#if CONFIG_COMPOUND_SEGMENT
static uint8_t *invert_mask(uint8_t *mask_inv_buffer, const uint8_t *const mask,
                            int h, int w, int stride) {
  int i, j;

  for (i = 0; i < h; ++i)
    for (j = 0; j < w; ++j) {
      mask_inv_buffer[i * stride + j] =
          AOM_BLEND_A64_MAX_ALPHA - mask[i * stride + j];
    }
  return mask_inv_buffer;
}
#endif  // CONFIG_COMPOUND_SEGMENT

const uint8_t *av1_get_compound_type_mask_inverse(
    const INTERINTER_COMPOUND_DATA *const comp_data,
#if CONFIG_COMPOUND_SEGMENT
    uint8_t *mask_buffer, int h, int w, int stride,
#endif
    BLOCK_SIZE sb_type) {
271
  assert(is_masked_compound_type(comp_data->interinter_compound_type));
272
  (void)sb_type;
273
  switch (comp_data->interinter_compound_type) {
274
#if CONFIG_WEDGE
275
    case COMPOUND_WEDGE:
276 277
      return av1_get_contiguous_soft_mask(comp_data->wedge_index,
                                          !comp_data->wedge_sign, sb_type);
278
#endif  // CONFIG_WEDGE
279 280
#if CONFIG_COMPOUND_SEGMENT
    case COMPOUND_SEG:
281
      return invert_mask(mask_buffer, comp_data->seg_mask, h, w, stride);
282
#endif  // CONFIG_COMPOUND_SEGMENT
283 284 285
    default: assert(0); return NULL;
  }
}
286

287 288
const uint8_t *av1_get_compound_type_mask(
    const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type) {
289
  assert(is_masked_compound_type(comp_data->interinter_compound_type));
290
  (void)sb_type;
291
  switch (comp_data->interinter_compound_type) {
292
#if CONFIG_WEDGE
293 294 295
    case COMPOUND_WEDGE:
      return av1_get_contiguous_soft_mask(comp_data->wedge_index,
                                          comp_data->wedge_sign, sb_type);
296
#endif  // CONFIG_WEDGE
297
#if CONFIG_COMPOUND_SEGMENT
298 299 300 301 302 303 304
    case COMPOUND_SEG: return comp_data->seg_mask;
#endif  // CONFIG_COMPOUND_SEGMENT
    default: assert(0); return NULL;
  }
}

#if CONFIG_COMPOUND_SEGMENT
305 306 307
#if COMPOUND_SEGMENT_TYPE == 0
static void uniform_mask(uint8_t *mask, int which_inverse, BLOCK_SIZE sb_type,
                         int h, int w, int mask_val) {
308 309 310 311 312 313 314 315 316 317
  int i, j;
  int block_stride = block_size_wide[sb_type];
  for (i = 0; i < h; ++i)
    for (j = 0; j < w; ++j) {
      mask[i * block_stride + j] =
          which_inverse ? AOM_BLEND_A64_MAX_ALPHA - mask_val : mask_val;
    }
}

void build_compound_seg_mask(uint8_t *mask, SEG_MASK_TYPE mask_type,
318 319 320 321 322 323 324
                             const uint8_t *src0, int src0_stride,
                             const uint8_t *src1, int src1_stride,
                             BLOCK_SIZE sb_type, int h, int w) {
  (void)src0;
  (void)src1;
  (void)src0_stride;
  (void)src1_stride;
325 326 327 328 329
  switch (mask_type) {
    case UNIFORM_45: uniform_mask(mask, 0, sb_type, h, w, 45); break;
    case UNIFORM_45_INV: uniform_mask(mask, 1, sb_type, h, w, 45); break;
    default: assert(0);
  }
330
}
331

332
#if CONFIG_HIGHBITDEPTH
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
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) {
  (void)src0;
  (void)src1;
  (void)src0_stride;
  (void)src1_stride;
  (void)bd;
  switch (mask_type) {
    case UNIFORM_45: uniform_mask(mask, 0, sb_type, h, w, 45); break;
    case UNIFORM_45_INV: uniform_mask(mask, 1, sb_type, h, w, 45); break;
    default: assert(0);
  }
}
348
#endif  // CONFIG_HIGHBITDEPTH
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373

#elif COMPOUND_SEGMENT_TYPE == 1
#define DIFF_FACTOR 16
static void diffwtd_mask(uint8_t *mask, int which_inverse, int mask_base,
                         const uint8_t *src0, int src0_stride,
                         const uint8_t *src1, int src1_stride,
                         BLOCK_SIZE sb_type, int h, int w) {
  int i, j, m, diff;
  int block_stride = block_size_wide[sb_type];
  for (i = 0; i < h; ++i) {
    for (j = 0; j < w; ++j) {
      diff =
          abs((int)src0[i * src0_stride + j] - (int)src1[i * src1_stride + j]);
      m = clamp(mask_base + (diff / DIFF_FACTOR), 0, AOM_BLEND_A64_MAX_ALPHA);
      mask[i * block_stride + j] =
          which_inverse ? AOM_BLEND_A64_MAX_ALPHA - m : m;
    }
  }
}

void build_compound_seg_mask(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) {
  switch (mask_type) {
Yaowu Xu's avatar
Yaowu Xu committed
374 375
    case DIFFWTD_42:
      diffwtd_mask(mask, 0, 42, src0, src0_stride, src1, src1_stride, sb_type,
376 377
                   h, w);
      break;
Yaowu Xu's avatar
Yaowu Xu committed
378 379
    case DIFFWTD_42_INV:
      diffwtd_mask(mask, 1, 42, src0, src0_stride, src1, src1_stride, sb_type,
380 381 382 383 384 385
                   h, w);
      break;
    default: assert(0);
  }
}

386
#if CONFIG_HIGHBITDEPTH
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422
static void diffwtd_mask_highbd(uint8_t *mask, int which_inverse, int mask_base,
                                const uint16_t *src0, int src0_stride,
                                const uint16_t *src1, int src1_stride,
                                BLOCK_SIZE sb_type, int h, int w, int bd) {
  int i, j, m, diff;
  int block_stride = block_size_wide[sb_type];
  for (i = 0; i < h; ++i) {
    for (j = 0; j < w; ++j) {
      diff = abs((int)src0[i * src0_stride + j] -
                 (int)src1[i * src1_stride + j]) >>
             (bd - 8);
      m = clamp(mask_base + (diff / DIFF_FACTOR), 0, AOM_BLEND_A64_MAX_ALPHA);
      mask[i * block_stride + j] =
          which_inverse ? AOM_BLEND_A64_MAX_ALPHA - m : m;
    }
  }
}

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) {
  switch (mask_type) {
    case DIFFWTD_42:
      diffwtd_mask_highbd(mask, 0, 42, CONVERT_TO_SHORTPTR(src0), src0_stride,
                          CONVERT_TO_SHORTPTR(src1), src1_stride, sb_type, h, w,
                          bd);
      break;
    case DIFFWTD_42_INV:
      diffwtd_mask_highbd(mask, 1, 42, CONVERT_TO_SHORTPTR(src0), src0_stride,
                          CONVERT_TO_SHORTPTR(src1), src1_stride, sb_type, h, w,
                          bd);
      break;
    default: assert(0);
  }
}
423
#endif  // CONFIG_HIGHBITDEPTH
424
#endif  // COMPOUND_SEGMENT_TYPE
425
#endif  // CONFIG_COMPOUND_SEGMENT
426

427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
#if MASK_MASTER_SIZE == 64
static const uint8_t wedge_master_oblique_odd[NSMOOTHERS][MASK_MASTER_SIZE] = {
  {
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  6,  18,
      37, 53, 60, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
      64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  }
};
static const uint8_t wedge_master_oblique_even[NSMOOTHERS][MASK_MASTER_SIZE] = {
  {
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  4,  11, 27,
      46, 58, 62, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
      64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
  }
};
static const uint8_t wedge_master_vertical[NSMOOTHERS][MASK_MASTER_SIZE] = { {
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  7,  21,
    43, 57, 62, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
    64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
} };

static void shift_copy(const uint8_t *src, uint8_t *dst, int shift, int width) {
  if (shift >= 0) {
    memcpy(dst + shift, src, width - shift);
    memset(dst, src[0], shift);
  } else {
    shift = -shift;
    memcpy(dst, src + shift, width - shift);
    memset(dst + width - shift, src[width - 1], shift);
  }
}
#else
static const double smoother_param[NSMOOTHERS] = { 2.83 };
#endif  // MASK_MASTER_SIZE == 64

465
static void init_wedge_master_masks() {
466 467 468 469 470
  int i, j, s;
  const int w = MASK_MASTER_SIZE;
  const int h = MASK_MASTER_SIZE;
  const int stride = MASK_MASTER_STRIDE;
  for (s = 0; s < NSMOOTHERS; s++) {
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492
#if MASK_MASTER_SIZE == 64
    // Generate prototype by shifting the masters
    int shift = h / 4;
    for (i = 0; i < h; i += 2) {
      shift_copy(wedge_master_oblique_even[s],
                 &wedge_mask_obl[s][1][WEDGE_OBLIQUE63][i * stride], shift,
                 MASK_MASTER_SIZE);
      shift--;
      shift_copy(wedge_master_oblique_odd[s],
                 &wedge_mask_obl[s][1][WEDGE_OBLIQUE63][(i + 1) * stride],
                 shift, MASK_MASTER_SIZE);
      memcpy(&wedge_mask_obl[s][1][WEDGE_VERTICAL][i * stride],
             wedge_master_vertical[s],
             MASK_MASTER_SIZE * sizeof(wedge_master_vertical[s][0]));
      memcpy(&wedge_mask_obl[s][1][WEDGE_VERTICAL][(i + 1) * stride],
             wedge_master_vertical[s],
             MASK_MASTER_SIZE * sizeof(wedge_master_vertical[s][0]));
    }
#else
    const int a[2] = { 2, 1 };
    const double asqrt = sqrt(a[0] * a[0] + a[1] * a[1]);
    for (i = 0; i < h; i++) {
493 494 495
      for (j = 0; j < w; ++j) {
        int x = (2 * j + 1 - w);
        int y = (2 * i + 1 - h);
496 497 498 499 500 501 502 503 504 505 506 507
        double d = (a[0] * x + a[1] * y) / asqrt;
        const int msk = (int)rint((1.0 + tanh(d / smoother_param[s])) * 32);
        wedge_mask_obl[s][1][WEDGE_OBLIQUE63][i * stride + j] = msk;
        const int mskx = (int)rint((1.0 + tanh(x / smoother_param[s])) * 32);
        wedge_mask_obl[s][1][WEDGE_VERTICAL][i * stride + j] = mskx;
      }
    }
#endif  // MASK_MASTER_SIZE == 64
    for (i = 0; i < h; ++i) {
      for (j = 0; j < w; ++j) {
        const int msk = wedge_mask_obl[s][1][WEDGE_OBLIQUE63][i * stride + j];
        wedge_mask_obl[s][1][WEDGE_OBLIQUE27][j * stride + i] = msk;
508
        wedge_mask_obl[s][1][WEDGE_OBLIQUE117][i * stride + w - 1 - j] =
clang-format's avatar
clang-format committed
509
            wedge_mask_obl[s][1][WEDGE_OBLIQUE153][(w - 1 - j) * stride + i] =
510
                (1 << WEDGE_WEIGHT_BITS) - msk;
511
        wedge_mask_obl[s][0][WEDGE_OBLIQUE63][i * stride + j] =
clang-format's avatar
clang-format committed
512
            wedge_mask_obl[s][0][WEDGE_OBLIQUE27][j * stride + i] =
513
                (1 << WEDGE_WEIGHT_BITS) - msk;
514
        wedge_mask_obl[s][0][WEDGE_OBLIQUE117][i * stride + w - 1 - j] =
clang-format's avatar
clang-format committed
515
            wedge_mask_obl[s][0][WEDGE_OBLIQUE153][(w - 1 - j) * stride + i] =
516 517 518
                msk;
        const int mskx = wedge_mask_obl[s][1][WEDGE_VERTICAL][i * stride + j];
        wedge_mask_obl[s][1][WEDGE_HORIZONTAL][j * stride + i] = mskx;
519
        wedge_mask_obl[s][0][WEDGE_VERTICAL][i * stride + j] =
clang-format's avatar
clang-format committed
520
            wedge_mask_obl[s][0][WEDGE_HORIZONTAL][j * stride + i] =
521
                (1 << WEDGE_WEIGHT_BITS) - mskx;
522
      }
523
    }
524
  }
525 526 527 528 529 530 531 532 533
}

// If the signs for the wedges for various blocksizes are
// inconsistent flip the sign flag. Do it only once for every
// wedge codebook.
static void init_wedge_signs() {
  BLOCK_SIZE sb_type;
  memset(wedge_signflip_lookup, 0, sizeof(wedge_signflip_lookup));
  for (sb_type = BLOCK_4X4; sb_type < BLOCK_SIZES; ++sb_type) {
534 535
    const int bw = block_size_wide[sb_type];
    const int bh = block_size_high[sb_type];
536 537 538 539 540 541 542 543
    const wedge_params_type wedge_params = wedge_params_lookup[sb_type];
    const int wbits = wedge_params.bits;
    const int wtypes = 1 << wbits;
    int i, w;
    if (wbits == 0) continue;
    for (w = 0; w < wtypes; ++w) {
      const uint8_t *mask = get_wedge_mask_inplace(w, 0, sb_type);
      int sum = 0;
clang-format's avatar
clang-format committed
544 545
      for (i = 0; i < bw; ++i) sum += mask[i];
      for (i = 0; i < bh; ++i) sum += mask[i * MASK_MASTER_STRIDE];
546 547 548 549 550 551 552 553 554 555 556 557
      sum = (sum + (bw + bh) / 2) / (bw + bh);
      wedge_params.signflip[w] = (sum < 32);
    }
  }
}

static void init_wedge_masks() {
  uint8_t *dst = wedge_mask_buf;
  BLOCK_SIZE bsize;
  memset(wedge_masks, 0, sizeof(wedge_masks));
  for (bsize = BLOCK_4X4; bsize < BLOCK_SIZES; ++bsize) {
    const uint8_t *mask;
558 559
    const int bw = block_size_wide[bsize];
    const int bh = block_size_high[bsize];
560 561 562 563 564 565 566
    const wedge_params_type *wedge_params = &wedge_params_lookup[bsize];
    const int wbits = wedge_params->bits;
    const int wtypes = 1 << wbits;
    int w;
    if (wbits == 0) continue;
    for (w = 0; w < wtypes; ++w) {
      mask = get_wedge_mask_inplace(w, 0, bsize);
Yaowu Xu's avatar
Yaowu Xu committed
567
      aom_convolve_copy(mask, MASK_MASTER_STRIDE, dst, bw, NULL, 0, NULL, 0, bw,
clang-format's avatar
clang-format committed
568
                        bh);
569 570 571 572
      wedge_params->masks[0][w] = dst;
      dst += bw * bh;

      mask = get_wedge_mask_inplace(w, 1, bsize);
Yaowu Xu's avatar
Yaowu Xu committed
573
      aom_convolve_copy(mask, MASK_MASTER_STRIDE, dst, bw, NULL, 0, NULL, 0, bw,
clang-format's avatar
clang-format committed
574
                        bh);
575 576 577 578 579 580 581 582
      wedge_params->masks[1][w] = dst;
      dst += bw * bh;
    }
    assert(sizeof(wedge_mask_buf) >= (size_t)(dst - wedge_mask_buf));
  }
}

// Equation of line: f(x, y) = a[0]*(x - a[2]*w/8) + a[1]*(y - a[3]*h/8) = 0
Yaowu Xu's avatar
Yaowu Xu committed
583
void av1_init_wedge_masks() {
584
  init_wedge_master_masks();
585
  init_wedge_signs();
586
  init_wedge_masks();
587 588
}

589 590
#if CONFIG_SUPERTX
static void build_masked_compound_wedge_extend(
clang-format's avatar
clang-format committed
591
    uint8_t *dst, int dst_stride, const uint8_t *src0, int src0_stride,
592 593 594
    const uint8_t *src1, int src1_stride,
    const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type,
    int wedge_offset_x, int wedge_offset_y, int h, int w) {
595 596
  const int subh = (2 << b_height_log2_lookup[sb_type]) == h;
  const int subw = (2 << b_width_log2_lookup[sb_type]) == w;
597 598
  const uint8_t *mask;
  size_t mask_stride;
599
  switch (comp_data->interinter_compound_type) {
600 601 602 603 604 605 606 607 608 609 610 611 612
    case COMPOUND_WEDGE:
      mask = av1_get_soft_mask(comp_data->wedge_index, comp_data->wedge_sign,
                               sb_type, wedge_offset_x, wedge_offset_y);
      mask_stride = MASK_MASTER_STRIDE;
      break;
#if CONFIG_COMPOUND_SEGMENT
    case COMPOUND_SEG:
      mask = comp_data->seg_mask;
      mask_stride = block_size_wide[sb_type];
      break;
#endif
    default: assert(0); return;
  }
Yaowu Xu's avatar
Yaowu Xu committed
613
  aom_blend_a64_mask(dst, dst_stride, src0, src0_stride, src1, src1_stride,
614
                     mask, (int)mask_stride, h, w, subh, subw);
615 616
}

617
#if CONFIG_HIGHBITDEPTH
618
static void build_masked_compound_wedge_extend_highbd(
clang-format's avatar
clang-format committed
619
    uint8_t *dst_8, int dst_stride, const uint8_t *src0_8, int src0_stride,
620 621 622
    const uint8_t *src1_8, int src1_stride,
    const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type,
    int wedge_offset_x, int wedge_offset_y, int h, int w, int bd) {
623 624
  const int subh = (2 << b_height_log2_lookup[sb_type]) == h;
  const int subw = (2 << b_width_log2_lookup[sb_type]) == w;
625 626
  const uint8_t *mask;
  size_t mask_stride;
627
  switch (comp_data->interinter_compound_type) {
628 629 630 631 632 633 634 635 636 637 638 639 640
    case COMPOUND_WEDGE:
      mask = av1_get_soft_mask(comp_data->wedge_index, comp_data->wedge_sign,
                               sb_type, wedge_offset_x, wedge_offset_y);
      mask_stride = MASK_MASTER_STRIDE;
      break;
#if CONFIG_COMPOUND_SEGMENT
    case COMPOUND_SEG:
      mask = comp_data->seg_mask;
      mask_stride = block_size_wide[sb_type];
      break;
#endif
    default: assert(0); return;
  }
Yaowu Xu's avatar
Yaowu Xu committed
641
  aom_highbd_blend_a64_mask(dst_8, dst_stride, src0_8, src0_stride, src1_8,
642 643
                            src1_stride, mask, (int)mask_stride, h, w, subh,
                            subw, bd);
644
}
645
#endif  // CONFIG_HIGHBITDEPTH
646
#else
647 648 649 650 651
static void build_masked_compound(
    uint8_t *dst, int dst_stride, const uint8_t *src0, int src0_stride,
    const uint8_t *src1, int src1_stride,
    const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type, int h,
    int w) {
652 653 654 655
  // Derive subsampling from h and w passed in. May be refactored to
  // pass in subsampling factors directly.
  const int subh = (2 << b_height_log2_lookup[sb_type]) == h;
  const int subw = (2 << b_width_log2_lookup[sb_type]) == w;
656
  const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type);
Yaowu Xu's avatar
Yaowu Xu committed
657
  aom_blend_a64_mask(dst, dst_stride, src0, src0_stride, src1, src1_stride,
658
                     mask, block_size_wide[sb_type], h, w, subh, subw);
659 660
}

661
#if CONFIG_HIGHBITDEPTH
662
static void build_masked_compound_highbd(
clang-format's avatar
clang-format committed
663
    uint8_t *dst_8, int dst_stride, const uint8_t *src0_8, int src0_stride,
664 665 666
    const uint8_t *src1_8, int src1_stride,
    const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type, int h,
    int w, int bd) {
667 668 669 670
  // Derive subsampling from h and w passed in. May be refactored to
  // pass in subsampling factors directly.
  const int subh = (2 << b_height_log2_lookup[sb_type]) == h;
  const int subw = (2 << b_width_log2_lookup[sb_type]) == w;
671 672 673
  const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type);
  // const uint8_t *mask =
  //     av1_get_contiguous_soft_mask(wedge_index, wedge_sign, sb_type);
674 675 676
  aom_highbd_blend_a64_mask(dst_8, dst_stride, src0_8, src0_stride, src1_8,
                            src1_stride, mask, block_size_wide[sb_type], h, w,
                            subh, subw, bd);
677
}
678
#endif  // CONFIG_HIGHBITDEPTH
679
#endif  // CONFIG_SUPERTX
680

Yaowu Xu's avatar
Yaowu Xu committed
681 682 683 684 685
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,
686
#if CONFIG_DUAL_FILTER
James Zern's avatar
James Zern committed
687
                                     const InterpFilter *interp_filter,
688
#else
James Zern's avatar
James Zern committed
689
                                     const InterpFilter interp_filter,
690
#endif
Yaowu Xu's avatar
Yaowu Xu committed
691
                                     int xs, int ys,
692
#if CONFIG_SUPERTX
Yaowu Xu's avatar
Yaowu Xu committed
693
                                     int wedge_offset_x, int wedge_offset_y,
694
#endif  // CONFIG_SUPERTX
695
                                     int plane,
696 697 698 699
#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
                                     const WarpTypesAllowed *warp_types,
                                     int p_col, int p_row, int ref,
#endif  // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
700 701
                                     MACROBLOCKD *xd) {
  MODE_INFO *mi = xd->mi[0];
702 703 704 705 706 707 708 709 710 711 712
  const INTERINTER_COMPOUND_DATA comp_data = {
#if CONFIG_WEDGE
    mi->mbmi.wedge_index,
    mi->mbmi.wedge_sign,
#endif  // CONFIG_WEDGE
#if CONFIG_COMPOUND_SEGMENT
    mi->mbmi.mask_type,
    xd->seg_mask,
#endif  // CONFIG_COMPOUND_SEGMENT
    mi->mbmi.interinter_compound_type
  };
clang-format's avatar
clang-format committed
713 714
// The prediction filter types used here should be those for
// the second reference block.
Geza Lore's avatar
Geza Lore committed
715
#if CONFIG_DUAL_FILTER
James Zern's avatar
James Zern committed
716
  InterpFilter tmp_ipf[4] = {
Geza Lore's avatar
Geza Lore committed
717
    interp_filter[2], interp_filter[3], interp_filter[2], interp_filter[3],
718
  };
Geza Lore's avatar
Geza Lore committed
719
#else
James Zern's avatar
James Zern committed
720
  InterpFilter tmp_ipf = interp_filter;
Geza Lore's avatar
Geza Lore committed
721
#endif  // CONFIG_DUAL_FILTER
722
  ConvolveParams conv_params = get_conv_params(0, plane);
723

724
#if CONFIG_HIGHBITDEPTH
725
  DECLARE_ALIGNED(16, uint8_t, tmp_dst_[2 * MAX_SB_SQUARE]);
clang-format's avatar
clang-format committed
726 727 728
  uint8_t *tmp_dst = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
                         ? CONVERT_TO_BYTEPTR(tmp_dst_)
                         : tmp_dst_;
Yaowu Xu's avatar
Yaowu Xu committed
729
  av1_make_inter_predictor(pre, pre_stride, tmp_dst, MAX_SB_SIZE, subpel_x,
730
                           subpel_y, sf, w, h, &conv_params, tmp_ipf,
731 732 733
#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
                           warp_types, p_col, p_row, plane, ref,
#endif  // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
734 735 736
#if CONFIG_MOTION_VAR
                           0, 0,
#endif
737
                           xs, ys, xd);
738
#if CONFIG_COMPOUND_SEGMENT
739
  if (!plane && comp_data.interinter_compound_type == COMPOUND_SEG) {
740
    if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
741
      build_compound_seg_mask_highbd(comp_data.seg_mask, comp_data.mask_type,
742 743 744
                                     dst, dst_stride, tmp_dst, MAX_SB_SIZE,
                                     mi->mbmi.sb_type, h, w, xd->bd);
    else
745
      build_compound_seg_mask(comp_data.seg_mask, comp_data.mask_type, dst,
746 747 748 749
                              dst_stride, tmp_dst, MAX_SB_SIZE,
                              mi->mbmi.sb_type, h, w);
  }
#endif  // CONFIG_COMPOUND_SEGMENT
750 751 752 753

#if CONFIG_SUPERTX
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
    build_masked_compound_wedge_extend_highbd(
754
        dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE, &comp_data,
755 756 757
        mi->mbmi.sb_type, wedge_offset_x, wedge_offset_y, h, w, xd->bd);
  else
    build_masked_compound_wedge_extend(
758
        dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE, &comp_data,
759 760
        mi->mbmi.sb_type, wedge_offset_x, wedge_offset_y, h, w);
#else
761
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
762
    build_masked_compound_highbd(dst, dst_stride, dst, dst_stride, tmp_dst,
763 764
                                 MAX_SB_SIZE, &comp_data, mi->mbmi.sb_type, h,
                                 w, xd->bd);
765
  else
766
    build_masked_compound(dst, dst_stride, dst, dst_stride, tmp_dst,
767
                          MAX_SB_SIZE, &comp_data, mi->mbmi.sb_type, h, w);
768
#endif  // CONFIG_SUPERTX
769

770
#else  // CONFIG_HIGHBITDEPTH
771
  DECLARE_ALIGNED(16, uint8_t, tmp_dst[MAX_SB_SQUARE]);
Yaowu Xu's avatar
Yaowu Xu committed
772
  av1_make_inter_predictor(pre, pre_stride, tmp_dst, MAX_SB_SIZE, subpel_x,
773
                           subpel_y, sf, w, h, &conv_params, tmp_ipf,
774 775 776
#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
                           warp_types, p_col, p_row, plane, ref,
#endif  // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
777 778 779
#if CONFIG_MOTION_VAR
                           0, 0,
#endif
780
                           xs, ys, xd);
781
#if CONFIG_COMPOUND_SEGMENT
782 783
  if (!plane && comp_data.interinter_compound_type == COMPOUND_SEG)
    build_compound_seg_mask(comp_data.seg_mask, comp_data.mask_type, dst,
784 785
                            dst_stride, tmp_dst, MAX_SB_SIZE, mi->mbmi.sb_type,
                            h, w);
786
#endif  // CONFIG_COMPOUND_SEGMENT
787 788
#if CONFIG_SUPERTX
  build_masked_compound_wedge_extend(dst, dst_stride, dst, dst_stride, tmp_dst,
789
                                     MAX_SB_SIZE, &comp_data, mi->mbmi.sb_type,
790 791
                                     wedge_offset_x, wedge_offset_y, h, w);
#else
792
  build_masked_compound(dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE,
793
                        &comp_data, mi->mbmi.sb_type, h, w);
794
#endif  // CONFIG_SUPERTX
795
#endif  // CONFIG_HIGHBITDEPTH
796 797 798
#if CONFIG_COMPOUND_SEGMENT
  (void)plane;
#endif  // CONFIG_COMPOUND_SEGMENT
799 800
}
#endif  // CONFIG_EXT_INTER
801

802 803 804
// TODO(sarahparker) av1_highbd_build_inter_predictor and
// av1_build_inter_predictor should be combined with
// av1_make_inter_predictor
805
#if CONFIG_HIGHBITDEPTH
806 807 808
void av1_highbd_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, int ref,
809
#if CONFIG_DUAL_FILTER
810
    const InterpFilter *interp_filter,
811
#else
812
    const InterpFilter interp_filter,
813
#endif
814 815 816 817 818
#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
    const WarpTypesAllowed *warp_types, int p_col, int p_row,
#endif  // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
    int plane, enum mv_precision precision, int x, int y,
    const MACROBLOCKD *xd) {
Jingning Han's avatar
Jingning Han committed
819 820 821
  const int is_q4 = precision == MV_PRECISION_Q4;
  const MV mv_q4 = { is_q4 ? src_mv->row : src_mv->row * 2,
                     is_q4 ? src_mv->col : src_mv->col * 2 };
Yaowu Xu's avatar
Yaowu Xu committed
822
  MV32 mv = av1_scale_mv(&mv_q4, x, y, sf);
Jingning Han's avatar
Jingning Han committed
823 824
  const int subpel_x = mv.col & SUBPEL_MASK;
  const int subpel_y = mv.row & SUBPEL_MASK;
825
  ConvolveParams conv_params = get_conv_params(ref, plane);
Jingning Han's avatar
Jingning Han committed
826 827 828

  src += (mv.row >> SUBPEL_BITS) * src_stride + (mv.col >> SUBPEL_BITS);

829 830
  av1_make_inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y,
                           sf, w, h, &conv_params, interp_filter,
831 832 833
#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
                           warp_types, p_col, p_row, plane, ref,
#endif  // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
834 835 836
#if CONFIG_MOTION_VAR
                           0, 0,
#endif
837 838
                           sf->x_step_q4, sf->y_step_q4, xd);
}
839
#endif  // CONFIG_HIGHBITDEPTH
840

Yaowu Xu's avatar
Yaowu Xu committed
841 842 843
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,
844
                               ConvolveParams *conv_params,
845
#if CONFIG_DUAL_FILTER
James Zern's avatar
James Zern committed
846
                               const InterpFilter *interp_filter,
847
#else
James Zern's avatar
James Zern committed
848
                               const InterpFilter interp_filter,
849
#endif
850 851 852 853
#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
                               const WarpTypesAllowed *warp_types, int p_col,
                               int p_row, int plane, int ref,
#endif  // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
854 855
                               enum mv_precision precision, int x, int y,
                               const MACROBLOCKD *xd) {
Jingning Han's avatar
Jingning Han committed
856 857 858
  const int is_q4 = precision == MV_PRECISION_Q4;
  const MV mv_q4 = { is_q4 ? src_mv->row : src_mv->row * 2,
                     is_q4 ? src_mv->col : src_mv->col * 2 };
Yaowu Xu's avatar
Yaowu Xu committed
859
  MV32 mv = av1_scale_mv(&mv_q4, x, y, sf);
Jingning Han's avatar
Jingning Han committed
860 861 862 863 864
  const int subpel_x = mv.col & SUBPEL_MASK;
  const int subpel_y = mv.row & SUBPEL_MASK;

  src += (mv.row >> SUBPEL_BITS) * src_stride + (mv.col >> SUBPEL_BITS);

865 866
  av1_make_inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y,
                           sf, w, h, conv_params, interp_filter,
867 868 869
#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
                           warp_types, p_col, p_row, plane, ref,
#endif  // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
870 871 872
#if CONFIG_MOTION_VAR
                           0, 0,
#endif
873
                           sf->x_step_q4, sf->y_step_q4, xd);
Jingning Han's avatar
Jingning Han committed
874 875
}

Angie Chiang's avatar
Angie Chiang committed
876 877 878 879 880 881 882
typedef struct SubpelParams {
  int xs;
  int ys;
  int subpel_x;
  int subpel_y;
} SubpelParams;

883