reconinter.c 111 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
Yue Chen's avatar
Yue Chen committed
27
#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
28
#include "av1/common/warped_motion.h"
Yue Chen's avatar
Yue Chen committed
29
#endif  // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Jingning Han's avatar
Jingning Han committed
30

31
#if CONFIG_EXT_INTER
32

clang-format's avatar
clang-format committed
33
#define NSMOOTHERS 1
34
static int get_masked_weight(int m, int smoothness) {
clang-format's avatar
clang-format committed
35 36
#define SMOOTHER_LEN 32
  static const uint8_t smoothfn[NSMOOTHERS][2 * SMOOTHER_LEN + 1] = { {
clang-format's avatar
clang-format committed
37 38 39 40
      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,  4,  7,  13, 21, 32, 43,
      51, 57, 60, 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,
clang-format's avatar
clang-format committed
41
  } };
42 43 44 45 46
  if (m < -SMOOTHER_LEN)
    return 0;
  else if (m > SMOOTHER_LEN)
    return (1 << WEDGE_WEIGHT_BITS);
  else
47
    return smoothfn[smoothness][m + SMOOTHER_LEN];
48 49
}

50
// [smoother][negative][direction]
clang-format's avatar
clang-format committed
51 52 53
DECLARE_ALIGNED(16, static uint8_t,
                wedge_mask_obl[NSMOOTHERS][2][WEDGE_DIRECTIONS]
                              [MASK_MASTER_SIZE * MASK_MASTER_SIZE]);
54

clang-format's avatar
clang-format committed
55 56
DECLARE_ALIGNED(16, static uint8_t,
                wedge_signflip_lookup[BLOCK_SIZES][MAX_WEDGE_TYPES]);
57

58 59
// 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
60 61
DECLARE_ALIGNED(16, static uint8_t,
                wedge_mask_buf[2 * MAX_WEDGE_TYPES * 3 * MAX_WEDGE_SQUARE]);
62 63 64

static wedge_masks_type wedge_masks[BLOCK_SIZES][2];

65 66 67
// Some unused wedge codebooks left temporarily to facilitate experiments.
// To be removed when setteld.
static wedge_code_type wedge_codebook_8_hgtw[8] = {
clang-format's avatar
clang-format committed
68 69 70 71
  { 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 },
72 73
};

74
static wedge_code_type wedge_codebook_8_hltw[8] = {
clang-format's avatar
clang-format committed
75 76 77 78
  { 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 },
79 80
};

81
static wedge_code_type wedge_codebook_8_heqw[8] = {
clang-format's avatar
clang-format committed
82 83 84 85
  { 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 },
86 87
};

88 89
#if !USE_LARGE_WEDGE_CODEBOOK
static const wedge_code_type wedge_codebook_16_hgtw[16] = {
clang-format's avatar
clang-format committed
90 91 92 93 94 95 96 97
  { 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 },
Debargha Mukherjee's avatar
Debargha Mukherjee committed
98
};
99

100
static const wedge_code_type wedge_codebook_16_hltw[16] = {
clang-format's avatar
clang-format committed
101 102 103 104 105 106 107 108
  { 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 },
109 110
};

111
static const wedge_code_type wedge_codebook_16_heqw[16] = {
clang-format's avatar
clang-format committed
112 113 114 115 116 117 118 119
  { 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 },
120 121
};

122
const wedge_params_type wedge_params_lookup[BLOCK_SIZES] = {
clang-format's avatar
clang-format committed
123 124 125 126 127 128 129 130 131 132 133 134 135
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
  { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[3], 0, wedge_masks[3] },
  { 4, wedge_codebook_16_hgtw, wedge_signflip_lookup[4], 0, wedge_masks[4] },
  { 4, wedge_codebook_16_hltw, wedge_signflip_lookup[5], 0, wedge_masks[5] },
  { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[6], 0, wedge_masks[6] },
  { 4, wedge_codebook_16_hgtw, wedge_signflip_lookup[7], 0, wedge_masks[7] },
  { 4, wedge_codebook_16_hltw, wedge_signflip_lookup[8], 0, wedge_masks[8] },
  { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[9], 0, wedge_masks[9] },
  { 0, wedge_codebook_8_hgtw, wedge_signflip_lookup[10], 0, wedge_masks[10] },
  { 0, wedge_codebook_8_hltw, wedge_signflip_lookup[11], 0, wedge_masks[11] },
  { 0, wedge_codebook_8_heqw, wedge_signflip_lookup[12], 0, wedge_masks[12] },
136
#if CONFIG_EXT_PARTITION
clang-format's avatar
clang-format committed
137 138 139
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
140
#endif  // CONFIG_EXT_PARTITION
141 142
};

143 144 145
#else

static const wedge_code_type wedge_codebook_32_hgtw[32] = {
clang-format's avatar
clang-format committed
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
  { 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 },
162 163
};

164
static const wedge_code_type wedge_codebook_32_hltw[32] = {
clang-format's avatar
clang-format committed
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
  { 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 },
181 182
};

183
static const wedge_code_type wedge_codebook_32_heqw[32] = {
clang-format's avatar
clang-format committed
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
  { 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 },
200 201
};

202
const wedge_params_type wedge_params_lookup[BLOCK_SIZES] = {
clang-format's avatar
clang-format committed
203 204 205 206 207 208 209 210 211 212 213 214 215
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
  { 5, wedge_codebook_32_heqw, wedge_signflip_lookup[3], 0, wedge_masks[3] },
  { 5, wedge_codebook_32_hgtw, wedge_signflip_lookup[4], 0, wedge_masks[4] },
  { 5, wedge_codebook_32_hltw, wedge_signflip_lookup[5], 0, wedge_masks[5] },
  { 5, wedge_codebook_32_heqw, wedge_signflip_lookup[6], 0, wedge_masks[6] },
  { 5, wedge_codebook_32_hgtw, wedge_signflip_lookup[7], 0, wedge_masks[7] },
  { 5, wedge_codebook_32_hltw, wedge_signflip_lookup[8], 0, wedge_masks[8] },
  { 5, wedge_codebook_32_heqw, wedge_signflip_lookup[9], 0, wedge_masks[9] },
  { 0, wedge_codebook_8_hgtw, wedge_signflip_lookup[10], 0, wedge_masks[10] },
  { 0, wedge_codebook_8_hltw, wedge_signflip_lookup[11], 0, wedge_masks[11] },
  { 0, wedge_codebook_8_heqw, wedge_signflip_lookup[12], 0, wedge_masks[12] },
Debargha Mukherjee's avatar
Debargha Mukherjee committed
216
#if CONFIG_EXT_PARTITION
clang-format's avatar
clang-format committed
217 218 219
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
Debargha Mukherjee's avatar
Debargha Mukherjee committed
220
#endif  // CONFIG_EXT_PARTITION
221
};
222
#endif  // USE_LARGE_WEDGE_CODEBOOK
223

clang-format's avatar
clang-format committed
224
static const uint8_t *get_wedge_mask_inplace(int wedge_index, int neg,
225
                                             BLOCK_SIZE sb_type) {
Debargha Mukherjee's avatar
Debargha Mukherjee committed
226
  const uint8_t *master;
227 228
  const int bh = 4 << b_height_log2_lookup[sb_type];
  const int bw = 4 << b_width_log2_lookup[sb_type];
229 230 231
  const wedge_code_type *a =
      wedge_params_lookup[sb_type].codebook + wedge_index;
  const int smoother = wedge_params_lookup[sb_type].smoother;
232
  int woff, hoff;
233 234 235 236 237 238 239
  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
240 241
           MASK_MASTER_STRIDE * (MASK_MASTER_SIZE / 2 - hoff) +
           MASK_MASTER_SIZE / 2 - woff;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
242 243 244
  return master;
}

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

254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
#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) {
274 275 276
  assert(is_masked_compound_type(comp_data->type));
  switch (comp_data->type) {
    case COMPOUND_WEDGE:
277 278
      return av1_get_contiguous_soft_mask(comp_data->wedge_index,
                                          !comp_data->wedge_sign, sb_type);
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 289 290 291 292 293
const uint8_t *av1_get_compound_type_mask(
    const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type) {
  assert(is_masked_compound_type(comp_data->type));
  switch (comp_data->type) {
    case COMPOUND_WEDGE:
      return av1_get_contiguous_soft_mask(comp_data->wedge_index,
                                          comp_data->wedge_sign, sb_type);
294
#if CONFIG_COMPOUND_SEGMENT
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
    case COMPOUND_SEG: return comp_data->seg_mask;
#endif  // CONFIG_COMPOUND_SEGMENT
    default: assert(0); return NULL;
  }
}

#if CONFIG_COMPOUND_SEGMENT
void uniform_mask(uint8_t *mask, int which_inverse, BLOCK_SIZE sb_type, int h,
                  int w, int mask_val) {
  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,
314 315 316 317 318 319 320
                             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;
321 322 323 324 325 326 327
  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;
    case UNIFORM_55: uniform_mask(mask, 0, sb_type, h, w, 55); break;
    case UNIFORM_55_INV: uniform_mask(mask, 1, sb_type, h, w, 55); break;
    default: assert(0);
  }
328 329
}
#endif  // CONFIG_COMPOUND_SEGMENT
330

331
static void init_wedge_master_masks() {
332 333 334 335
  int i, j, s;
  const int w = MASK_MASTER_SIZE;
  const int h = MASK_MASTER_SIZE;
  const int stride = MASK_MASTER_STRIDE;
clang-format's avatar
clang-format committed
336
  const int a[2] = { 2, 1 };
337 338 339 340 341 342 343 344
  const double asqrt = sqrt(a[0] * a[0] + a[1] * a[1]);
  for (s = 0; s < NSMOOTHERS; s++) {
    for (i = 0; i < h; ++i)
      for (j = 0; j < w; ++j) {
        int x = (2 * j + 1 - w);
        int y = (2 * i + 1 - h);
        int m = (int)rint((a[0] * x + a[1] * y) / asqrt);
        wedge_mask_obl[s][1][WEDGE_OBLIQUE63][i * stride + j] =
clang-format's avatar
clang-format committed
345 346
            wedge_mask_obl[s][1][WEDGE_OBLIQUE27][j * stride + i] =
                get_masked_weight(m, s);
347
        wedge_mask_obl[s][1][WEDGE_OBLIQUE117][i * stride + w - 1 - j] =
clang-format's avatar
clang-format committed
348 349
            wedge_mask_obl[s][1][WEDGE_OBLIQUE153][(w - 1 - j) * stride + i] =
                (1 << WEDGE_WEIGHT_BITS) - get_masked_weight(m, s);
350
        wedge_mask_obl[s][0][WEDGE_OBLIQUE63][i * stride + j] =
clang-format's avatar
clang-format committed
351 352
            wedge_mask_obl[s][0][WEDGE_OBLIQUE27][j * stride + i] =
                (1 << WEDGE_WEIGHT_BITS) - get_masked_weight(m, s);
353
        wedge_mask_obl[s][0][WEDGE_OBLIQUE117][i * stride + w - 1 - j] =
clang-format's avatar
clang-format committed
354 355
            wedge_mask_obl[s][0][WEDGE_OBLIQUE153][(w - 1 - j) * stride + i] =
                get_masked_weight(m, s);
356
        wedge_mask_obl[s][1][WEDGE_VERTICAL][i * stride + j] =
clang-format's avatar
clang-format committed
357 358
            wedge_mask_obl[s][1][WEDGE_HORIZONTAL][j * stride + i] =
                get_masked_weight(x, s);
359
        wedge_mask_obl[s][0][WEDGE_VERTICAL][i * stride + j] =
clang-format's avatar
clang-format committed
360 361
            wedge_mask_obl[s][0][WEDGE_HORIZONTAL][j * stride + i] =
                (1 << WEDGE_WEIGHT_BITS) - get_masked_weight(x, s);
362 363
      }
  }
364 365 366 367 368 369 370 371 372
}

// 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) {
373 374
    const int bw = block_size_wide[sb_type];
    const int bh = block_size_high[sb_type];
375 376 377 378 379 380 381 382
    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
383 384
      for (i = 0; i < bw; ++i) sum += mask[i];
      for (i = 0; i < bh; ++i) sum += mask[i * MASK_MASTER_STRIDE];
385 386 387 388 389 390 391 392 393 394 395 396
      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;
397 398
    const int bw = block_size_wide[bsize];
    const int bh = block_size_high[bsize];
399 400 401 402 403 404 405
    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
406
      aom_convolve_copy(mask, MASK_MASTER_STRIDE, dst, bw, NULL, 0, NULL, 0, bw,
clang-format's avatar
clang-format committed
407
                        bh);
408 409 410 411
      wedge_params->masks[0][w] = dst;
      dst += bw * bh;

      mask = get_wedge_mask_inplace(w, 1, bsize);
Yaowu Xu's avatar
Yaowu Xu committed
412
      aom_convolve_copy(mask, MASK_MASTER_STRIDE, dst, bw, NULL, 0, NULL, 0, bw,
clang-format's avatar
clang-format committed
413
                        bh);
414 415 416 417 418 419 420 421
      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
422
void av1_init_wedge_masks() {
423
  init_wedge_master_masks();
424
  init_wedge_signs();
425
  init_wedge_masks();
426 427
}

428 429
#if CONFIG_SUPERTX
static void build_masked_compound_wedge_extend(
clang-format's avatar
clang-format committed
430 431 432
    uint8_t *dst, int dst_stride, const uint8_t *src0, int src0_stride,
    const uint8_t *src1, int src1_stride, int wedge_index, int wedge_sign,
    BLOCK_SIZE sb_type, int wedge_offset_x, int wedge_offset_y, int h, int w) {
433 434
  const int subh = (2 << b_height_log2_lookup[sb_type]) == h;
  const int subw = (2 << b_width_log2_lookup[sb_type]) == w;
Yaowu Xu's avatar
Yaowu Xu committed
435 436 437
  const uint8_t *mask = av1_get_soft_mask(wedge_index, wedge_sign, sb_type,
                                          wedge_offset_x, wedge_offset_y);
  aom_blend_a64_mask(dst, dst_stride, src0, src0_stride, src1, src1_stride,
clang-format's avatar
clang-format committed
438
                     mask, MASK_MASTER_STRIDE, h, w, subh, subw);
439 440
}

Yaowu Xu's avatar
Yaowu Xu committed
441
#if CONFIG_AOM_HIGHBITDEPTH
442
static void build_masked_compound_wedge_extend_highbd(
clang-format's avatar
clang-format committed
443 444 445 446
    uint8_t *dst_8, int dst_stride, const uint8_t *src0_8, int src0_stride,
    const uint8_t *src1_8, int src1_stride, int wedge_index, int wedge_sign,
    BLOCK_SIZE sb_type, int wedge_offset_x, int wedge_offset_y, int h, int w,
    int bd) {
447 448
  const int subh = (2 << b_height_log2_lookup[sb_type]) == h;
  const int subw = (2 << b_width_log2_lookup[sb_type]) == w;
Yaowu Xu's avatar
Yaowu Xu committed
449 450 451
  const uint8_t *mask = av1_get_soft_mask(wedge_index, wedge_sign, sb_type,
                                          wedge_offset_x, wedge_offset_y);
  aom_highbd_blend_a64_mask(dst_8, dst_stride, src0_8, src0_stride, src1_8,
clang-format's avatar
clang-format committed
452 453
                            src1_stride, mask, MASK_MASTER_STRIDE, h, w, subh,
                            subw, bd);
454
}
Yaowu Xu's avatar
Yaowu Xu committed
455
#endif  // CONFIG_AOM_HIGHBITDEPTH
456
#endif  // CONFIG_SUPERTX
457

458 459 460 461 462
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) {
463 464 465 466
  // 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;
467
  const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type);
Yaowu Xu's avatar
Yaowu Xu committed
468
  aom_blend_a64_mask(dst, dst_stride, src0, src0_stride, src1, src1_stride,
469
                     mask, block_size_wide[sb_type], h, w, subh, subw);
470 471
}

Yaowu Xu's avatar
Yaowu Xu committed
472
#if CONFIG_AOM_HIGHBITDEPTH
Geza Lore's avatar
Geza Lore committed
473
static void build_masked_compound_wedge_highbd(
clang-format's avatar
clang-format committed
474 475 476
    uint8_t *dst_8, int dst_stride, const uint8_t *src0_8, int src0_stride,
    const uint8_t *src1_8, int src1_stride, int wedge_index, int wedge_sign,
    BLOCK_SIZE sb_type, int h, int w, int bd) {
477 478 479 480
  // 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;
481 482
  const uint8_t *mask =
      av1_get_contiguous_soft_mask(wedge_index, wedge_sign, sb_type);
483 484 485
  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);
486
}
Yaowu Xu's avatar
Yaowu Xu committed
487
#endif  // CONFIG_AOM_HIGHBITDEPTH
488

Yaowu Xu's avatar
Yaowu Xu committed
489 490 491 492 493
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,
494
#if CONFIG_DUAL_FILTER
James Zern's avatar
James Zern committed
495
                                     const InterpFilter *interp_filter,
496
#else
James Zern's avatar
James Zern committed
497
                                     const InterpFilter interp_filter,
498
#endif
Yaowu Xu's avatar
Yaowu Xu committed
499
                                     int xs, int ys,
500
#if CONFIG_SUPERTX
Yaowu Xu's avatar
Yaowu Xu committed
501
                                     int wedge_offset_x, int wedge_offset_y,
502
#endif  // CONFIG_SUPERTX
503 504 505 506 507 508
#if CONFIG_COMPOUND_SEGMENT
                                     int plane,
#endif  // CONFIG_COMPOUND_SEGMENT
                                     MACROBLOCKD *xd) {
  MODE_INFO *mi = xd->mi[0];
  INTERINTER_COMPOUND_DATA *comp_data = &mi->mbmi.interinter_compound_data;
clang-format's avatar
clang-format committed
509 510
// The prediction filter types used here should be those for
// the second reference block.
Geza Lore's avatar
Geza Lore committed
511
#if CONFIG_DUAL_FILTER
James Zern's avatar
James Zern committed
512
  InterpFilter tmp_ipf[4] = {
Geza Lore's avatar
Geza Lore committed
513
    interp_filter[2], interp_filter[3], interp_filter[2], interp_filter[3],
514
  };
Geza Lore's avatar
Geza Lore committed
515
#else
James Zern's avatar
James Zern committed
516
  InterpFilter tmp_ipf = interp_filter;
Geza Lore's avatar
Geza Lore committed
517
#endif  // CONFIG_DUAL_FILTER
Yaowu Xu's avatar
Yaowu Xu committed
518
#if CONFIG_AOM_HIGHBITDEPTH
519
  DECLARE_ALIGNED(16, uint8_t, tmp_dst_[2 * MAX_SB_SQUARE]);
clang-format's avatar
clang-format committed
520 521 522
  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
523 524
  av1_make_inter_predictor(pre, pre_stride, tmp_dst, MAX_SB_SIZE, subpel_x,
                           subpel_y, sf, w, h, 0, tmp_ipf, xs, ys, xd);
525 526
#if CONFIG_SUPERTX
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
527
    build_masked_compound_wedge_extend_highbd(
clang-format's avatar
clang-format committed
528
        dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE,
529 530
        comp_data->wedge_index, comp_data->wedge_sign, mi->mbmi.sb_type,
        wedge_offset_x, wedge_offset_y, h, w, xd->bd);
531
  else
532
    build_masked_compound_wedge_extend(
clang-format's avatar
clang-format committed
533
        dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE,
534 535
        comp_data->wedge_index, comp_data->wedge_sign, mi->mbmi.sb_type,
        wedge_offset_x, wedge_offset_y, h, w);
536 537
#else
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
538
    build_masked_compound_wedge_highbd(
clang-format's avatar
clang-format committed
539
        dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE,
540 541
        comp_data->wedge_index, comp_data->wedge_sign, mi->mbmi.sb_type, h, w,
        xd->bd);
542
  else
543 544
    build_masked_compound(dst, dst_stride, dst, dst_stride, tmp_dst,
                          MAX_SB_SIZE, comp_data, mi->mbmi.sb_type, h, w);
545
#endif  // CONFIG_SUPERTX
Yaowu Xu's avatar
Yaowu Xu committed
546
#else   // CONFIG_AOM_HIGHBITDEPTH
547
  DECLARE_ALIGNED(16, uint8_t, tmp_dst[MAX_SB_SQUARE]);
Yaowu Xu's avatar
Yaowu Xu committed
548 549
  av1_make_inter_predictor(pre, pre_stride, tmp_dst, MAX_SB_SIZE, subpel_x,
                           subpel_y, sf, w, h, 0, tmp_ipf, xs, ys, xd);
550
#if CONFIG_SUPERTX
551 552 553 554
  build_masked_compound_wedge_extend(dst, dst_stride, dst, dst_stride, tmp_dst,
                                     MAX_SB_SIZE, comp_data->wedge_index,
                                     comp_data->wedge_sign, mi->mbmi.sb_type,
                                     wedge_offset_x, wedge_offset_y, h, w);
555
#else
556 557
#if CONFIG_COMPOUND_SEGMENT
  if (!plane && comp_data->type == COMPOUND_SEG)
558 559 560
    build_compound_seg_mask(comp_data->seg_mask, comp_data->mask_type, dst,
                            dst_stride, tmp_dst, MAX_SB_SIZE, mi->mbmi.sb_type,
                            h, w);
561
#endif  // CONFIG_COMPOUND_SEGMENT
562 563
  build_masked_compound(dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE,
                        comp_data, mi->mbmi.sb_type, h, w);
564
#endif  // CONFIG_SUPERTX
Yaowu Xu's avatar
Yaowu Xu committed
565
#endif  // CONFIG_AOM_HIGHBITDEPTH
566 567
}
#endif  // CONFIG_EXT_INTER
568

Yaowu Xu's avatar
Yaowu Xu committed
569 570
#if CONFIG_AOM_HIGHBITDEPTH
void av1_highbd_build_inter_predictor(
clang-format's avatar
clang-format committed
571 572
    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,
573
#if CONFIG_DUAL_FILTER
James Zern's avatar
James Zern committed
574
    const InterpFilter *interp_filter,
575
#else
James Zern's avatar
James Zern committed
576
    const InterpFilter interp_filter,
577
#endif
clang-format's avatar
clang-format committed
578
    enum mv_precision precision, int x, int y, int bd) {
Jingning Han's avatar
Jingning Han committed
579 580 581
  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
582
  MV32 mv = av1_scale_mv(&mv_q4, x, y, sf);
Jingning Han's avatar
Jingning Han committed
583 584 585 586 587
  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);

588
  highbd_inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y,
589 590
                         sf, w, h, ref, interp_filter, sf->x_step_q4,
                         sf->y_step_q4, bd);
Jingning Han's avatar
Jingning Han committed
591
}
Yaowu Xu's avatar
Yaowu Xu committed
592
#endif  // CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
593

Yaowu Xu's avatar
Yaowu Xu committed
594 595 596 597
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,
                               int ref,
598
#if CONFIG_DUAL_FILTER
James Zern's avatar
James Zern committed
599
                               const InterpFilter *interp_filter,
600
#else
James Zern's avatar
James Zern committed
601
                               const InterpFilter interp_filter,
602
#endif
Yaowu Xu's avatar
Yaowu Xu committed
603
                               enum mv_precision precision, int x, int y) {
Jingning Han's avatar
Jingning Han committed
604 605 606
  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
607
  MV32 mv = av1_scale_mv(&mv_q4, x, y, sf);
Jingning Han's avatar
Jingning Han committed
608 609 610 611 612
  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);

clang-format's avatar
clang-format committed
613 614
  inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y, sf, w,
                  h, ref, interp_filter, sf->x_step_q4, sf->y_step_q4);
Jingning Han's avatar
Jingning Han committed
615 616
}

617
void build_inter_predictors(MACROBLOCKD *xd, int plane,
Yue Chen's avatar
Yue Chen committed
618
#if CONFIG_MOTION_VAR
619
                            int mi_col_offset, int mi_row_offset,
Yue Chen's avatar
Yue Chen committed
620
#endif  // CONFIG_MOTION_VAR
clang-format's avatar
clang-format committed
621 622
                            int block, int bw, int bh, int x, int y, int w,
                            int h,
623 624 625
#if CONFIG_SUPERTX && CONFIG_EXT_INTER
                            int wedge_offset_x, int wedge_offset_y,
#endif  // CONFIG_SUPERTX && CONFIG_EXT_INTER
626
                            int mi_x, int mi_y) {
Jingning Han's avatar
Jingning Han committed
627
  struct macroblockd_plane *const pd = &xd->plane[plane];
Yue Chen's avatar
Yue Chen committed
628
#if CONFIG_MOTION_VAR
629
  const MODE_INFO *mi = xd->mi[mi_col_offset + xd->mi_stride * mi_row_offset];
630
  const int build_for_obmc = !(mi_col_offset == 0 && mi_row_offset == 0);
631
#else
Jingning Han's avatar
Jingning Han committed
632
  const MODE_INFO *mi = xd->mi[0];
Yue Chen's avatar
Yue Chen committed
633
#endif  // CONFIG_MOTION_VAR
Jingning Han's avatar
Jingning Han committed
634 635
  const int is_compound = has_second_ref(&mi->mbmi);
  int ref;
636
#if CONFIG_GLOBAL_MOTION
637
  WarpedMotionParams *gm[2];
638 639 640
  int is_global[2];
  for (ref = 0; ref < 1 + is_compound; ++ref) {
    gm[ref] = &xd->global_motion[mi->mbmi.ref_frame[ref]];
clang-format's avatar
clang-format committed
641
    is_global[ref] =
642
        (get_y_mode(mi, block) == ZEROMV && gm[ref]->wmtype > TRANSLATION);
643 644
  }
  // TODO(sarahparker) remove these once gm works with all experiments
clang-format's avatar
clang-format committed
645 646
  (void)gm;
  (void)is_global;
647
#endif  // CONFIG_GLOBAL_MOTION
Jingning Han's avatar
Jingning Han committed
648

649 650 651 652
#if CONFIG_CB4X4
  (void)block;
#endif

653 654
// TODO(sarahparker) enable the use of DUAL_FILTER in warped motion functions
// in order to allow GLOBAL_MOTION and DUAL_FILTER to work together
655
#if CONFIG_SUB8X8_MC
656 657 658
#if CONFIG_MOTION_VAR
  if (mi->mbmi.sb_type < BLOCK_8X8 && plane > 0 && !build_for_obmc) {
#else
659
  if (mi->mbmi.sb_type < BLOCK_8X8 && plane > 0) {
660
#endif  // CONFIG_MOTION_VAR
661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692
    // block size in log2
    const int b4_wl = b_width_log2_lookup[mi->mbmi.sb_type];
    const int b4_hl = b_height_log2_lookup[mi->mbmi.sb_type];
    const int b8_sl = b_width_log2_lookup[BLOCK_8X8];

    // block size
    const int b4_w = 1 << b4_wl;
    const int b4_h = 1 << b4_hl;
    const int b8_s = 1 << b8_sl;
    int idx, idy;

    const int x_base = x;
    const int y_base = y;

    // processing unit size
    const int x_step = w >> (b8_sl - b4_wl);
    const int y_step = h >> (b8_sl - b4_hl);

    for (idy = 0; idy < b8_s; idy += b4_h) {
      for (idx = 0; idx < b8_s; idx += b4_w) {
        const int chr_idx = (idy * 2) + idx;
        for (ref = 0; ref < 1 + is_compound; ++ref) {
          const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
          struct buf_2d *const pre_buf = &pd->pre[ref];
          struct buf_2d *const dst_buf = &pd->dst;
          uint8_t *dst = dst_buf->buf;
          const MV mv = mi->bmi[chr_idx].as_mv[ref].as_mv;
          const MV mv_q4 = clamp_mv_to_umv_border_sb(
              xd, &mv, bw, bh, pd->subsampling_x, pd->subsampling_y);
          uint8_t *pre;
          MV32 scaled_mv;
          int xs, ys, subpel_x, subpel_y;
Yaowu Xu's avatar
Yaowu Xu committed
693
          const int is_scaled = av1_is_scaled(sf);
694 695 696 697 698 699 700 701 702

          x = x_base + idx * x_step;
          y = y_base + idy * y_step;

          dst += dst_buf->stride * y + x;

          if (is_scaled) {
            pre =
                pre_buf->buf + scaled_buffer_offset(x, y, pre_buf->stride, sf);
Yaowu Xu's avatar
Yaowu Xu committed
703
            scaled_mv = av1_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf);
704 705 706 707 708 709 710 711 712 713 714 715 716
            xs = sf->x_step_q4;
            ys = sf->y_step_q4;
          } else {
            pre = pre_buf->buf + y * pre_buf->stride + x;
            scaled_mv.row = mv_q4.row;
            scaled_mv.col = mv_q4.col;
            xs = ys = 16;
          }

          subpel_x = scaled_mv.col & SUBPEL_MASK;
          subpel_y = scaled_mv.row & SUBPEL_MASK;
          pre += (scaled_mv.row >> SUBPEL_BITS) * pre_buf->stride +
                 (scaled_mv.col >> SUBPEL_BITS);
717

718
#if CONFIG_EXT_INTER
719 720
          if (ref &&
              is_masked_compound_type(mi->mbmi.interinter_compound_data.type))
Yaowu Xu's avatar
Yaowu Xu committed
721
            av1_make_masked_inter_predictor(
722 723 724 725 726
                pre, pre_buf->stride, dst, dst_buf->stride, subpel_x, subpel_y,
                sf, w, h, mi->mbmi.interp_filter, xs, ys,
#if CONFIG_SUPERTX
                wedge_offset_x, wedge_offset_y,
#endif  // CONFIG_SUPERTX
727 728 729
#if CONFIG_COMPOUND_SEGMENT
                plane,
#endif  // CONFIG_COMPOUND_SEGMENT
730 731 732
                xd);
          else
#endif  // CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
733 734 735
            av1_make_inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride,
                                     subpel_x, subpel_y, sf, x_step, y_step,
                                     ref, mi->mbmi.interp_filter, xs, ys, xd);
736
        }
737 738 739 740 741 742
      }
    }
    return;
  }
#endif

Jingning Han's avatar
Jingning Han committed
743 744 745 746 747
  for (ref = 0; ref < 1 + is_compound; ++ref) {
    const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
    struct buf_2d *const pre_buf = &pd->pre[ref];
    struct buf_2d *const dst_buf = &pd->dst;
    uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x;
748 749 750
#if CONFIG_CB4X4
    const MV mv = mi->mbmi.mv[ref].as_mv;
#else
Jingning Han's avatar
Jingning Han committed
751
    const MV mv = mi->mbmi.sb_type < BLOCK_8X8
752 753 754 755
#if CONFIG_MOTION_VAR
                      ? (build_for_obmc ? mi->bmi[block].as_mv[ref].as_mv
                                        : average_split_mvs(pd, mi, ref, block))
#else
clang-format's avatar
clang-format committed
756
                      ? average_split_mvs(pd, mi, ref, block)
757
#endif  // CONFIG_MOTION_VAR
clang-format's avatar
clang-format committed
758
                      : mi->mbmi.mv[ref].as_mv;
759
#endif
Jingning Han's avatar
Jingning Han committed
760 761 762 763 764 765

    // TODO(jkoleszar): This clamping is done in the incorrect place for the
    // scaling case. It needs to be done on the scaled MV, not the pre-scaling
    // MV. Note however that it performs the subsampling aware scaling so
    // that the result is always q4.
    // mv_precision precision is MV_PRECISION_Q4.
clang-format's avatar
clang-format committed
766 767
    const MV mv_q4 = clamp_mv_to_umv_border_sb(
        xd, &mv, bw, bh, pd->subsampling_x, pd->subsampling_y);
Jingning Han's avatar
Jingning Han committed
768 769 770 771

    uint8_t *pre;
    MV32 scaled_mv;
    int xs, ys, subpel_x, subpel_y;
Yaowu Xu's avatar
Yaowu Xu committed
772
    const int is_scaled = av1_is_scaled(sf);
Jingning Han's avatar
Jingning Han committed
773 774 775

    if (is_scaled) {
      pre = pre_buf->buf + scaled_buffer_offset(x, y, pre_buf->stride, sf);
Yaowu Xu's avatar
Yaowu Xu committed
776
      scaled_mv = av1_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf);
Jingning Han's avatar
Jingning Han committed
777 778 779 780 781 782 783 784
      xs = sf->x_step_q4;
      ys = sf->y_step_q4;
    } else {
      pre = pre_buf->buf + (y * pre_buf->stride + x);
      scaled_mv.row = mv_q4.row;
      scaled_mv.col = mv_q4.col;
      xs = ys = 16;
    }
785

Jingning Han's avatar
Jingning Han committed
786 787
    subpel_x = scaled_mv.col & SUBPEL_MASK;
    subpel_y = scaled_mv.row & SUBPEL_MASK;
clang-format's avatar
clang-format committed
788 789
    pre += (scaled_mv.row >> SUBPEL_BITS) * pre_buf->stride +
           (scaled_mv.col >> SUBPEL_BITS);
Jingning Han's avatar
Jingning Han committed
790

791
#if CONFIG_EXT_INTER
792
    if (ref && is_masked_compound_type(mi->mbmi.interinter_compound_data.type))
Yaowu Xu's avatar
Yaowu Xu committed
793 794 795
      av1_make_masked_inter_predictor(pre, pre_buf->stride, dst,
                                      dst_buf->stride, subpel_x, subpel_y, sf,
                                      w, h, mi->mbmi.interp_filter, xs, ys,
796
#if CONFIG_SUPERTX
Yaowu Xu's avatar
Yaowu Xu committed
797
                                      wedge_offset_x, wedge_offset_y,
798
#endif  // CONFIG_SUPERTX
799 800 801
#if CONFIG_COMPOUND_SEGMENT
                                      plane,
#endif  // CONFIG_COMPOUND_SEGMENT
Yaowu Xu's avatar
Yaowu Xu committed
802
                                      xd);
803
    else
804 805 806
#else  // CONFIG_EXT_INTER
#if CONFIG_GLOBAL_MOTION
    if (is_global[ref])
807
      av1_warp_plane(gm[ref],
Yaowu Xu's avatar
Yaowu Xu committed
808 809 810 811 812 813
#if CONFIG_AOM_HIGHBITDEPTH
                     xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
#endif  // CONFIG_AOM_HIGHBITDEPTH
                     pre_buf->buf0, pre_buf->width, pre_buf->height,
                     pre_buf->stride, dst, (mi_x >> pd->subsampling_x) + x,
                     (mi_y >> pd->subsampling_y) + y, w, h, dst_buf->stride,
814
                     pd->subsampling_x, pd->subsampling_y, xs, ys, ref);
815 816
    else
#endif  // CONFIG_GLOBAL_MOTION
817
#endif  // CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
818 819 820
      av1_make_inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride,
                               subpel_x, subpel_y, sf, w, h, ref,
                               mi->mbmi.interp_filter, xs, ys, xd);
Jingning Han's avatar
Jingning Han committed
821 822 823
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
824 825
void av1_build_inter_predictor_sub8x8(MACROBLOCKD *xd, int plane, int i, int ir,
                                      int ic, int mi_row, int mi_col) {
826 827 828
  struct macroblockd_plane *const pd = &xd->plane[plane];
  MODE_INFO *const mi = xd->mi[0];
  const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
829 830
  const int width = block_size_wide[plane_bsize];
  const int height = block_size_high[plane_bsize];
831 832 833 834 835 836 837
  uint8_t *const dst = &pd->dst.buf[(ir * pd->dst.stride + ic) << 2];
  int ref;
  const int is_compound = has_second_ref(&mi->mbmi);

  for (ref = 0; ref < 1 + is_compound; ++ref) {
    const uint8_t *pre =
        &pd->pre[ref].buf[(ir * pd->pre[ref].stride + ic) << 2];
Yaowu Xu's avatar
Yaowu Xu committed
838
#if CONFIG_AOM_HIGHBITDEPTH
clang-format's avatar
clang-format committed
839
    if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xu's avatar
Yaowu Xu committed
840
      av1_highbd_build_inter_predictor(
clang-format's avatar
clang-format committed
841 842 843 844 845
          pre, pd->pre[ref].stride, dst, pd->dst.stride,
          &mi->bmi[i].as_mv[ref].as_mv, &xd->block_refs[ref]->sf, width, height,
          ref, mi->mbmi.interp_filter, MV_PRECISION_Q3,
          mi_col * MI_SIZE + 4 * ic, mi_row * MI_SIZE + 4 * ir, xd->bd);
    } else {
Yaowu Xu's avatar
Yaowu Xu committed
846
      av1_build_inter_predictor(
clang-format's avatar
clang-format committed
847 848 849 850 851
          pre, pd->pre[ref].stride, dst, pd->dst.stride,
          &mi->bmi[i].as_mv[ref].as_mv, &xd->block_refs[ref]->sf, width, height,
          ref, mi->mbmi.interp_filter, MV_PRECISION_Q3,
          mi_col * MI_SIZE + 4 * ic, mi_row * MI_SIZE + 4 * ir);
    }