reconinter.c 120 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
#define USE_SOFT_WEIGHTS_IN_WEDGE 1
32
static int get_masked_weight(int m, int smoothness) {
clang-format's avatar
clang-format committed
33 34
#define SMOOTHER_LEN 32
  static const uint8_t smoothfn[NSMOOTHERS][2 * SMOOTHER_LEN + 1] = { {
35
#if USE_SOFT_WEIGHTS_IN_WEDGE
clang-format's avatar
clang-format committed
36 37 38 39
      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,
40 41 42 43 44 45
#else
      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,  0,  64, 64, 32, 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, 64, 64, 64,
#endif  // USE_SOFT_WEIGHTS_IN_WEDGE
clang-format's avatar
clang-format committed
46
  } };
47 48 49 50 51
  if (m < -SMOOTHER_LEN)
    return 0;
  else if (m > SMOOTHER_LEN)
    return (1 << WEDGE_WEIGHT_BITS);
  else
52
    return smoothfn[smoothness][m + SMOOTHER_LEN];
53 54
}

55
// [smoother][negative][direction]
clang-format's avatar
clang-format committed
56 57 58
DECLARE_ALIGNED(16, static uint8_t,
                wedge_mask_obl[NSMOOTHERS][2][WEDGE_DIRECTIONS]
                              [MASK_MASTER_SIZE * MASK_MASTER_SIZE]);
59

clang-format's avatar
clang-format committed
60 61
DECLARE_ALIGNED(16, static uint8_t,
                wedge_signflip_lookup[BLOCK_SIZES][MAX_WEDGE_TYPES]);
62

63 64
// 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
65 66
DECLARE_ALIGNED(16, static uint8_t,
                wedge_mask_buf[2 * MAX_WEDGE_TYPES * 3 * MAX_WEDGE_SQUARE]);
67 68 69

static wedge_masks_type wedge_masks[BLOCK_SIZES][2];

70
// Some unused wedge codebooks left temporarily to facilitate experiments.
71 72
// To be removed when settled.
/*
73
static wedge_code_type wedge_codebook_8_hgtw[8] = {
clang-format's avatar
clang-format committed
74 75 76 77
  { 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 },
78 79
};

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

87
static wedge_code_type wedge_codebook_8_heqw[8] = {
clang-format's avatar
clang-format committed
88 89 90 91
  { 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 },
92
};
93
*/
94

95 96
#if !USE_LARGE_WEDGE_CODEBOOK
static const wedge_code_type wedge_codebook_16_hgtw[16] = {
clang-format's avatar
clang-format committed
97 98 99 100 101 102 103 104
  { 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
105
};
106

107
static const wedge_code_type wedge_codebook_16_hltw[16] = {
clang-format's avatar
clang-format committed
108 109 110 111 112 113 114 115
  { 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 },
116 117
};

118
static const wedge_code_type wedge_codebook_16_heqw[16] = {
clang-format's avatar
clang-format committed
119 120 121 122 123 124 125 126
  { 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 },
127 128
};

129
const wedge_params_type wedge_params_lookup[BLOCK_SIZES] = {
130 131 132 133
#if CONFIG_CB4X4
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
134 135 136 137
#endif  // CONFIG_CB4X4
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
138
#if CONFIG_WEDGE
139 140 141 142 143 144 145 146 147 148 149 150 151 152
  { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_8X8], 0,
    wedge_masks[BLOCK_8X8] },
  { 4, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_8X16], 0,
    wedge_masks[BLOCK_8X16] },
  { 4, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_16X8], 0,
    wedge_masks[BLOCK_16X8] },
  { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_16X16], 0,
    wedge_masks[BLOCK_16X16] },
  { 4, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_16X32], 0,
    wedge_masks[BLOCK_16X32] },
  { 4, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_32X16], 0,
    wedge_masks[BLOCK_32X16] },
  { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_32X32], 0,
    wedge_masks[BLOCK_32X32] },
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
  { 0, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_32X64], 0,
    wedge_masks[BLOCK_32X64] },
  { 0, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_64X32], 0,
    wedge_masks[BLOCK_64X32] },
  { 0, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_64X64], 0,
    wedge_masks[BLOCK_64X64] },
#else
  { 0, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_8X8], 0,
    wedge_masks[BLOCK_8X8] },
  { 0, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_8X16], 0,
    wedge_masks[BLOCK_8X16] },
  { 0, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_16X8], 0,
    wedge_masks[BLOCK_16X8] },
  { 0, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_16X16], 0,
    wedge_masks[BLOCK_16X16] },
  { 0, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_16X32], 0,
    wedge_masks[BLOCK_16X32] },
  { 0, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_32X16], 0,
    wedge_masks[BLOCK_32X16] },
  { 0, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_32X32], 0,
    wedge_masks[BLOCK_32X32] },
  { 0, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_32X64], 0,
175
    wedge_masks[BLOCK_32X64] },
176
  { 0, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_64X32], 0,
177
    wedge_masks[BLOCK_64X32] },
178
  { 0, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_64X64], 0,
179
    wedge_masks[BLOCK_64X64] },
180
#endif  // CONFIG_WEDGE
181
#if CONFIG_EXT_PARTITION
clang-format's avatar
clang-format committed
182 183 184
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
185
#endif  // CONFIG_EXT_PARTITION
186 187
};

188 189 190
#else

static const wedge_code_type wedge_codebook_32_hgtw[32] = {
clang-format's avatar
clang-format committed
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
  { 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 },
207 208
};

209
static const wedge_code_type wedge_codebook_32_hltw[32] = {
clang-format's avatar
clang-format committed
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
  { 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 },
226 227
};

228
static const wedge_code_type wedge_codebook_32_heqw[32] = {
clang-format's avatar
clang-format committed
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
  { 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 },
245 246
};

247
const wedge_params_type wedge_params_lookup[BLOCK_SIZES] = {
248 249 250 251 252
#if CONFIG_CB4X4
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
#endif
clang-format's avatar
clang-format committed
253 254 255
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
256
#if CONFIG_WEDGE
257 258 259 260 261 262 263 264 265 266 267 268 269 270
  { 5, wedge_codebook_32_heqw, wedge_signflip_lookup[BLOCK_8X8], 0,
    wedge_masks[BLOCK_8X8] },
  { 5, wedge_codebook_32_hgtw, wedge_signflip_lookup[BLOCK_8X16], 0,
    wedge_masks[BLOCK_8X16] },
  { 5, wedge_codebook_32_hltw, wedge_signflip_lookup[BLOCK_16X8], 0,
    wedge_masks[BLOCK_16X8] },
  { 5, wedge_codebook_32_heqw, wedge_signflip_lookup[BLOCK_16X16], 0,
    wedge_masks[BLOCK_16X16] },
  { 5, wedge_codebook_32_hgtw, wedge_signflip_lookup[BLOCK_16X32], 0,
    wedge_masks[BLOCK_16X32] },
  { 5, wedge_codebook_32_hltw, wedge_signflip_lookup[BLOCK_32X16], 0,
    wedge_masks[BLOCK_32X16] },
  { 5, wedge_codebook_32_heqw, wedge_signflip_lookup[BLOCK_32X32], 0,
    wedge_masks[BLOCK_32X32] },
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
  { 0, wedge_codebook_32_hgtw, wedge_signflip_lookup[BLOCK_32X64], 0,
    wedge_masks[BLOCK_32X64] },
  { 0, wedge_codebook_32_hltw, wedge_signflip_lookup[BLOCK_64X32], 0,
    wedge_masks[BLOCK_64X32] },
  { 0, wedge_codebook_32_heqw, wedge_signflip_lookup[BLOCK_64X64], 0,
    wedge_masks[BLOCK_64X64] },
#else
  { 0, wedge_codebook_32_heqw, wedge_signflip_lookup[BLOCK_8X8], 0,
    wedge_masks[BLOCK_8X8] },
  { 0, wedge_codebook_32_hgtw, wedge_signflip_lookup[BLOCK_8X16], 0,
    wedge_masks[BLOCK_8X16] },
  { 0, wedge_codebook_32_hltw, wedge_signflip_lookup[BLOCK_16X8], 0,
    wedge_masks[BLOCK_16X8] },
  { 0, wedge_codebook_32_heqw, wedge_signflip_lookup[BLOCK_16X16], 0,
    wedge_masks[BLOCK_16X16] },
  { 0, wedge_codebook_32_hgtw, wedge_signflip_lookup[BLOCK_16X32], 0,
    wedge_masks[BLOCK_16X32] },
  { 0, wedge_codebook_32_hltw, wedge_signflip_lookup[BLOCK_32X16], 0,
    wedge_masks[BLOCK_32X16] },
  { 0, wedge_codebook_32_heqw, wedge_signflip_lookup[BLOCK_32X32], 0,
    wedge_masks[BLOCK_32X32] },
  { 0, wedge_codebook_32_hgtw, wedge_signflip_lookup[BLOCK_32X64], 0,
293
    wedge_masks[BLOCK_32X64] },
294
  { 0, wedge_codebook_32_hltw, wedge_signflip_lookup[BLOCK_64X32], 0,
295
    wedge_masks[BLOCK_64X32] },
296
  { 0, wedge_codebook_32_heqw, wedge_signflip_lookup[BLOCK_64X64], 0,
297
    wedge_masks[BLOCK_64X64] },
298
#endif  // CONFIG_WEDGE
Debargha Mukherjee's avatar
Debargha Mukherjee committed
299
#if CONFIG_EXT_PARTITION
clang-format's avatar
clang-format committed
300 301 302
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
  { 0, NULL, NULL, 0, NULL },
Debargha Mukherjee's avatar
Debargha Mukherjee committed
303
#endif  // CONFIG_EXT_PARTITION
304
};
305
#endif  // USE_LARGE_WEDGE_CODEBOOK
306

clang-format's avatar
clang-format committed
307
static const uint8_t *get_wedge_mask_inplace(int wedge_index, int neg,
308
                                             BLOCK_SIZE sb_type) {
Debargha Mukherjee's avatar
Debargha Mukherjee committed
309
  const uint8_t *master;
310 311
  const int bh = block_size_high[sb_type];
  const int bw = block_size_wide[sb_type];
312 313 314
  const wedge_code_type *a =
      wedge_params_lookup[sb_type].codebook + wedge_index;
  const int smoother = wedge_params_lookup[sb_type].smoother;
315
  int woff, hoff;
316 317 318 319 320 321 322
  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
323 324
           MASK_MASTER_STRIDE * (MASK_MASTER_SIZE / 2 - hoff) +
           MASK_MASTER_SIZE / 2 - woff;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
325 326 327
  return master;
}

Yaowu Xu's avatar
Yaowu Xu committed
328 329 330
const uint8_t *av1_get_soft_mask(int wedge_index, int wedge_sign,
                                 BLOCK_SIZE sb_type, int offset_x,
                                 int offset_y) {
331
  const uint8_t *mask =
332
      get_wedge_mask_inplace(wedge_index, wedge_sign, sb_type);
clang-format's avatar
clang-format committed
333
  if (mask) mask -= (offset_x + offset_y * MASK_MASTER_STRIDE);
334
  return mask;
335 336
}

337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
#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) {
357 358 359
  assert(is_masked_compound_type(comp_data->type));
  switch (comp_data->type) {
    case COMPOUND_WEDGE:
360 361
      return av1_get_contiguous_soft_mask(comp_data->wedge_index,
                                          !comp_data->wedge_sign, sb_type);
362 363
#if CONFIG_COMPOUND_SEGMENT
    case COMPOUND_SEG:
364
      return invert_mask(mask_buffer, comp_data->seg_mask, h, w, stride);
365
#endif  // CONFIG_COMPOUND_SEGMENT
366 367 368
    default: assert(0); return NULL;
  }
}
369

370 371 372 373 374 375 376
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);
377
#if CONFIG_COMPOUND_SEGMENT
378 379 380 381 382 383 384
    case COMPOUND_SEG: return comp_data->seg_mask;
#endif  // CONFIG_COMPOUND_SEGMENT
    default: assert(0); return NULL;
  }
}

#if CONFIG_COMPOUND_SEGMENT
385 386 387
#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) {
388 389 390 391 392 393 394 395 396 397
  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,
398 399 400 401 402 403 404
                             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;
405 406 407 408 409
  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);
  }
410
}
411

412
#if CONFIG_HIGHBITDEPTH
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
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);
  }
}
428
#endif  // CONFIG_HIGHBITDEPTH
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

#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
454 455
    case DIFFWTD_42:
      diffwtd_mask(mask, 0, 42, src0, src0_stride, src1, src1_stride, sb_type,
456 457
                   h, w);
      break;
Yaowu Xu's avatar
Yaowu Xu committed
458 459
    case DIFFWTD_42_INV:
      diffwtd_mask(mask, 1, 42, src0, src0_stride, src1, src1_stride, sb_type,
460 461 462 463 464 465
                   h, w);
      break;
    default: assert(0);
  }
}

466
#if CONFIG_HIGHBITDEPTH
467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502
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);
  }
}
503
#endif  // CONFIG_HIGHBITDEPTH
504
#endif  // COMPOUND_SEGMENT_TYPE
505
#endif  // CONFIG_COMPOUND_SEGMENT
506

507
static void init_wedge_master_masks() {
508 509 510 511
  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
512
  const int a[2] = { 2, 1 };
513 514 515 516 517 518 519 520
  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
521 522
            wedge_mask_obl[s][1][WEDGE_OBLIQUE27][j * stride + i] =
                get_masked_weight(m, s);
523
        wedge_mask_obl[s][1][WEDGE_OBLIQUE117][i * stride + w - 1 - j] =
clang-format's avatar
clang-format committed
524 525
            wedge_mask_obl[s][1][WEDGE_OBLIQUE153][(w - 1 - j) * stride + i] =
                (1 << WEDGE_WEIGHT_BITS) - get_masked_weight(m, s);
526
        wedge_mask_obl[s][0][WEDGE_OBLIQUE63][i * stride + j] =
clang-format's avatar
clang-format committed
527 528
            wedge_mask_obl[s][0][WEDGE_OBLIQUE27][j * stride + i] =
                (1 << WEDGE_WEIGHT_BITS) - get_masked_weight(m, s);
529
        wedge_mask_obl[s][0][WEDGE_OBLIQUE117][i * stride + w - 1 - j] =
clang-format's avatar
clang-format committed
530 531
            wedge_mask_obl[s][0][WEDGE_OBLIQUE153][(w - 1 - j) * stride + i] =
                get_masked_weight(m, s);
532
        wedge_mask_obl[s][1][WEDGE_VERTICAL][i * stride + j] =
clang-format's avatar
clang-format committed
533 534
            wedge_mask_obl[s][1][WEDGE_HORIZONTAL][j * stride + i] =
                get_masked_weight(x, s);
535
        wedge_mask_obl[s][0][WEDGE_VERTICAL][i * stride + j] =
clang-format's avatar
clang-format committed
536 537
            wedge_mask_obl[s][0][WEDGE_HORIZONTAL][j * stride + i] =
                (1 << WEDGE_WEIGHT_BITS) - get_masked_weight(x, s);
538 539
      }
  }
540 541 542 543 544 545 546 547 548
}

// 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) {
549 550
    const int bw = block_size_wide[sb_type];
    const int bh = block_size_high[sb_type];
551 552 553 554 555 556 557 558
    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
559 560
      for (i = 0; i < bw; ++i) sum += mask[i];
      for (i = 0; i < bh; ++i) sum += mask[i * MASK_MASTER_STRIDE];
561 562 563 564 565 566 567 568 569 570 571 572
      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;
573 574
    const int bw = block_size_wide[bsize];
    const int bh = block_size_high[bsize];
575 576 577 578 579 580 581
    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
582
      aom_convolve_copy(mask, MASK_MASTER_STRIDE, dst, bw, NULL, 0, NULL, 0, bw,
clang-format's avatar
clang-format committed
583
                        bh);
584 585 586 587
      wedge_params->masks[0][w] = dst;
      dst += bw * bh;

      mask = get_wedge_mask_inplace(w, 1, bsize);
Yaowu Xu's avatar
Yaowu Xu committed
588
      aom_convolve_copy(mask, MASK_MASTER_STRIDE, dst, bw, NULL, 0, NULL, 0, bw,
clang-format's avatar
clang-format committed
589
                        bh);
590 591 592 593 594 595 596 597
      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
598
void av1_init_wedge_masks() {
599
  init_wedge_master_masks();
600
  init_wedge_signs();
601
  init_wedge_masks();
602 603
}

604 605
#if CONFIG_SUPERTX
static void build_masked_compound_wedge_extend(
clang-format's avatar
clang-format committed
606
    uint8_t *dst, int dst_stride, const uint8_t *src0, int src0_stride,
607 608 609
    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) {
610 611
  const int subh = (2 << b_height_log2_lookup[sb_type]) == h;
  const int subw = (2 << b_width_log2_lookup[sb_type]) == w;
612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
  const uint8_t *mask;
  size_t mask_stride;
  switch (comp_data->type) {
    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
628
  aom_blend_a64_mask(dst, dst_stride, src0, src0_stride, src1, src1_stride,
629
                     mask, mask_stride, h, w, subh, subw);
630 631
}

632
#if CONFIG_HIGHBITDEPTH
633
static void build_masked_compound_wedge_extend_highbd(
clang-format's avatar
clang-format committed
634
    uint8_t *dst_8, int dst_stride, const uint8_t *src0_8, int src0_stride,
635 636 637
    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) {
638 639
  const int subh = (2 << b_height_log2_lookup[sb_type]) == h;
  const int subw = (2 << b_width_log2_lookup[sb_type]) == w;
640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655
  const uint8_t *mask;
  size_t mask_stride;
  switch (comp_data->type) {
    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
656
  aom_highbd_blend_a64_mask(dst_8, dst_stride, src0_8, src0_stride, src1_8,
657 658
                            src1_stride, mask, mask_stride, h, w, subh, subw,
                            bd);
659
}
660
#endif  // CONFIG_HIGHBITDEPTH
661
#else
662 663 664 665 666
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) {
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
  const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type);
Yaowu Xu's avatar
Yaowu Xu committed
672
  aom_blend_a64_mask(dst, dst_stride, src0, src0_stride, src1, src1_stride,
673
                     mask, block_size_wide[sb_type], h, w, subh, subw);
674 675
}

676
#if CONFIG_HIGHBITDEPTH
677
static void build_masked_compound_highbd(
clang-format's avatar
clang-format committed
678
    uint8_t *dst_8, int dst_stride, const uint8_t *src0_8, int src0_stride,
679 680 681
    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) {
682 683 684 685
  // 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;
686 687 688
  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);
689 690 691
  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);
692
}
693
#endif  // CONFIG_HIGHBITDEPTH
694
#endif  // CONFIG_SUPERTX
695

Yaowu Xu's avatar
Yaowu Xu committed
696 697 698 699 700
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,
701
#if CONFIG_DUAL_FILTER
James Zern's avatar
James Zern committed
702
                                     const InterpFilter *interp_filter,
703
#else
James Zern's avatar
James Zern committed
704
                                     const InterpFilter interp_filter,
705
#endif
Yaowu Xu's avatar
Yaowu Xu committed
706
                                     int xs, int ys,
707
#if CONFIG_SUPERTX
Yaowu Xu's avatar
Yaowu Xu committed
708
                                     int wedge_offset_x, int wedge_offset_y,
709
#endif  // CONFIG_SUPERTX
710
                                     int plane,
711 712 713 714
#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
715 716 717
                                     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
718 719
// The prediction filter types used here should be those for
// the second reference block.
Geza Lore's avatar
Geza Lore committed
720
#if CONFIG_DUAL_FILTER
James Zern's avatar
James Zern committed
721
  InterpFilter tmp_ipf[4] = {
Geza Lore's avatar
Geza Lore committed
722
    interp_filter[2], interp_filter[3], interp_filter[2], interp_filter[3],
723
  };
Geza Lore's avatar
Geza Lore committed
724
#else
James Zern's avatar
James Zern committed
725
  InterpFilter tmp_ipf = interp_filter;
Geza Lore's avatar
Geza Lore committed
726
#endif  // CONFIG_DUAL_FILTER
727
  ConvolveParams conv_params = get_conv_params(0, plane);
728

729
#if CONFIG_HIGHBITDEPTH
730
  DECLARE_ALIGNED(16, uint8_t, tmp_dst_[2 * MAX_SB_SQUARE]);
clang-format's avatar
clang-format committed
731 732 733
  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
734
  av1_make_inter_predictor(pre, pre_stride, tmp_dst, MAX_SB_SIZE, subpel_x,
735
                           subpel_y, sf, w, h, &conv_params, tmp_ipf,
736 737 738
#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
                           warp_types, p_col, p_row, plane, ref,
#endif  // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
739 740 741
#if CONFIG_MOTION_VAR
                           0, 0,
#endif
742
                           xs, ys, xd);
743 744 745 746 747 748 749 750 751 752 753 754
#if CONFIG_COMPOUND_SEGMENT
  if (!plane && comp_data->type == COMPOUND_SEG) {
    if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
      build_compound_seg_mask_highbd(comp_data->seg_mask, comp_data->mask_type,
                                     dst, dst_stride, tmp_dst, MAX_SB_SIZE,
                                     mi->mbmi.sb_type, h, w, xd->bd);
    else
      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);
  }
#endif  // CONFIG_COMPOUND_SEGMENT
755 756 757 758 759 760 761 762 763 764 765

#if CONFIG_SUPERTX
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
    build_masked_compound_wedge_extend_highbd(
        dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE, comp_data,
        mi->mbmi.sb_type, wedge_offset_x, wedge_offset_y, h, w, xd->bd);
  else
    build_masked_compound_wedge_extend(
        dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE, comp_data,
        mi->mbmi.sb_type, wedge_offset_x, wedge_offset_y, h, w);
#else
766
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
767 768 769
    build_masked_compound_highbd(dst, dst_stride, dst, dst_stride, tmp_dst,
                                 MAX_SB_SIZE, comp_data, mi->mbmi.sb_type, h, w,
                                 xd->bd);
770
  else
771 772
    build_masked_compound(dst, dst_stride, dst, dst_stride, tmp_dst,
                          MAX_SB_SIZE, comp_data, mi->mbmi.sb_type, h, w);
773
#endif  // CONFIG_SUPERTX
774

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

807 808 809
// TODO(sarahparker) av1_highbd_build_inter_predictor and
// av1_build_inter_predictor should be combined with
// av1_make_inter_predictor
810
#if CONFIG_HIGHBITDEPTH
811 812 813
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,
814
#if CONFIG_DUAL_FILTER
815
    const InterpFilter *interp_filter,
816
#else
817
    const InterpFilter interp_filter,
818
#endif
819 820 821 822 823
#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
824 825 826
  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
827
  MV32 mv = av1_scale_mv(&mv_q4, x, y, sf);
Jingning Han's avatar
Jingning Han committed
828 829
  const int subpel_x = mv.col & SUBPEL_MASK;
  const int subpel_y = mv.row & SUBPEL_MASK;
830
  ConvolveParams conv_params = get_conv_params(ref, plane);
Jingning Han's avatar
Jingning Han committed
831 832 833

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

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

Yaowu Xu's avatar
Yaowu Xu committed
846 847 848
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,
849
                               ConvolveParams *conv_params,
850
#if CONFIG_DUAL_FILTER
James Zern's avatar
James Zern committed
851
                               const InterpFilter *interp_filter,
852
#else
James Zern's avatar
James Zern committed
853
                               const InterpFilter interp_filter,
854
#endif
855 856 857 858
#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
859 860
                               enum mv_precision precision, int x, int y,
                               const MACROBLOCKD *xd) {
Jingning Han's avatar
Jingning Han committed
861 862 863
  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
864
  MV32 mv = av1_scale_mv(&mv_q4, x, y, sf);
Jingning Han's avatar
Jingning Han committed
865 866 867 868 869
  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);

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

Angie Chiang's avatar
Angie Chiang committed
881 882 883 884 885 886 887
typedef struct SubpelParams {
  int xs;
  int ys;
  int subpel_x;
  int subpel_y;
} SubpelParams;

888
void build_inter_predictors(MACROBLOCKD *xd, int plane,
Yue Chen's avatar
Yue Chen committed
889
#if CONFIG_MOTION_VAR
890
                            int mi_col_offset, int mi_row_offset,
Yue Chen's avatar
Yue Chen committed
891
#endif  // CONFIG_MOTION_VAR
clang-format's avatar
clang-format committed
892 893
                            int block, int bw, int bh, int x, int y, int w,
                            int h,
894 895 896
#if CONFIG_SUPERTX && CONFIG_EXT_INTER
                            int wedge_offset_x, int wedge_offset_y,
#endif  // CONFIG_SUPERTX && CONFIG_EXT_INTER
897
                            int mi_x, int mi_y) {
Jingning Han's avatar
Jingning Han committed
898
  struct macroblockd_plane *const pd = &xd->plane[plane];
Yue Chen's avatar
Yue Chen committed
899
#if CONFIG_MOTION_VAR
900
  const MODE_INFO *mi = xd->mi[mi_col_offset + xd->mi_stride * mi_row_offset];
Jingning Han's avatar
Jingning Han committed
901
#if !CONFIG_CB4X4 || CONFIG_SUB8X8_MC
902
  const int build_for_obmc = !(mi_col_offset == 0 && mi_row_offset == 0);
Jingning Han's avatar
Jingning Han committed
903
#endif  // !CONFIG_CB4X4 || CONFIG_SUB8X8_MC
904
#else
Jingning Han's avatar
Jingning Han committed
905
  const MODE_INFO *mi = xd->mi[0];
Yue Chen's avatar
Yue Chen committed
906
#endif  // CONFIG_MOTION_VAR
Jingning Han's avatar
Jingning Han committed
907 908
  const int is_compound = has_second_ref(&mi->mbmi);
  int ref;
909 910 911
#if CONFIG_GLOBAL_MOTION
  int is_global[2];
  for (ref = 0; ref < 1 + is_compound; ++ref) {
912
    WarpedMotionParams *const wm = &xd->global_motion[mi->mbmi.ref_frame[ref]];
913
    is_global[ref] = is_global_mv_block(mi, block, wm->wmtype);
914 915
  }
#endif  // CONFIG_GLOBAL_MOTION
Jingning Han's avatar
Jingning Han committed
916

917 918 919 920
#if CONFIG_CB4X4
  (void)block;
#endif

921
#if CONFIG_SUB8X8_MC
922 923 924
#if CONFIG_MOTION_VAR
  if (mi->mbmi.sb_type < BLOCK_8X8 && plane > 0 && !build_for_obmc) {
#else
925
  if (mi->mbmi.sb_type < BLOCK_8X8 && plane > 0) {
926
#endif  // CONFIG_MOTION_VAR
927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958
    // 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
959
          const int is_scaled = av1_is_scaled(sf);
960
          ConvolveParams conv_params = get_conv_params(ref, plane);
961 962 963 964 965 966 967 968 969
#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
          WarpTypesAllowed warp_types;
#if CONFIG_GLOBAL_MOTION
          warp_types.global_warp_allowed = is_global[ref];
#endif  // CONFIG_GLOBAL_MOTION
#if CONFIG_WARPED_MOTION
          warp_types.local_warp_allowed = mi->mbmi.motion_mode == WARPED_CAUSAL;
#endif  // CONFIG_WARPED_MOTION
#endif  // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
970 971 972 973 974 975 976 977 978

          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
979
            scaled_mv = av1_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf);
980 981 982 983 984 985 986 987 988 989 990 991 992
            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);
993

994
#if CONFIG_EXT_INTER
995 996
          if (ref &&
              is_masked_compound_type(mi->mbmi.interinter_compound_data.type))
Yaowu Xu's avatar
Yaowu Xu committed
997
            av1_make_masked_inter_predictor(
998 999 1000 1001 1002
                pre, pre_buf->stride, dst, dst_buf->stride, subpel_x, subpel_y