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

#include <assert.h>

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

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

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

28
#if CONFIG_EXT_INTER
29

clang-format's avatar
clang-format committed
30
#define NSMOOTHERS 1
31
#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
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453

#if CONFIG_AOM_HIGHBITDEPTH
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);
  }
}
#endif  // CONFIG_AOM_HIGHBITDEPTH

#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
466
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
503
504
                   h, w);
      break;
    default: assert(0);
  }
}

#if CONFIG_AOM_HIGHBITDEPTH
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);
  }
}
#endif  // CONFIG_AOM_HIGHBITDEPTH
#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
}

Yaowu Xu's avatar
Yaowu Xu committed
632
#if CONFIG_AOM_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
}
Yaowu Xu's avatar
Yaowu Xu committed
660
#endif  // CONFIG_AOM_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
}

Yaowu Xu's avatar
Yaowu Xu committed
676
#if CONFIG_AOM_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
}
Yaowu Xu's avatar
Yaowu Xu committed
693
#endif  // CONFIG_AOM_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
                                     int is_global, int p_col, int p_row,
                                     int ref,
#endif  // CONFIG_GLOBAL_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

Yaowu Xu's avatar
Yaowu Xu committed
729
#if CONFIG_AOM_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
736
737
                           subpel_y, sf, w, h, &conv_params, tmp_ipf,
#if CONFIG_GLOBAL_MOTION
                           is_global, p_col, p_row, plane, ref,
738
739
740
#if CONFIG_MOTION_VAR
                           0, 0,
#endif
741
742
#endif  // CONFIG_GLOBAL_MOTION
                           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_AOM_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
779
780
                           subpel_y, sf, w, h, &conv_params, tmp_ipf,
#if CONFIG_GLOBAL_MOTION
                           is_global, p_col, p_row, plane, ref,
781
782
783
#if CONFIG_MOTION_VAR
                           0, 0,
#endif
784
785
#endif  // CONFIG_GLOBAL_MOTION
                           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
Yaowu Xu's avatar
Yaowu Xu committed
800
#endif  // CONFIG_AOM_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
Yaowu Xu's avatar
Yaowu Xu committed
810
#if CONFIG_AOM_HIGHBITDEPTH
811
812
813
814
815
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,
816
#if CONFIG_DUAL_FILTER
817
                                      const InterpFilter *interp_filter,
818
#else
819
                                      const InterpFilter interp_filter,
820
#endif
821
822
823
824
825
#if CONFIG_GLOBAL_MOTION
                                      int is_global, int p_col, int p_row,
#endif  // CONFIG_GLOBAL_MOTION
                                      int plane, enum mv_precision precision,
                                      int x, int y, const MACROBLOCKD *xd) {
Jingning Han's avatar
Jingning Han committed
826
827
828
  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
829
  MV32 mv = av1_scale_mv(&mv_q4, x, y, sf);
Jingning Han's avatar
Jingning Han committed
830
831
  const int subpel_x = mv.col & SUBPEL_MASK;
  const int subpel_y = mv.row & SUBPEL_MASK;
832
  ConvolveParams conv_params = get_conv_params(ref, plane);
Jingning Han's avatar
Jingning Han committed
833
834
835

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

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

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

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

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

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

919
920
921
922
#if CONFIG_CB4X4
  (void)block;
#endif

923
#if CONFIG_SUB8X8_MC
924
925
926
#if CONFIG_MOTION_VAR
  if (mi->mbmi.sb_type < BLOCK_8X8 && plane > 0 && !build_for_obmc) {
#else
927
  if (mi->mbmi.sb_type < BLOCK_8X8 && plane > 0) {
928
#endif  // CONFIG_MOTION_VAR
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
959
960
    // 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
961
          const int is_scaled = av1_is_scaled(sf);
962
          ConvolveParams conv_params = get_conv_params(ref, plane);
963
964
965
966
967
968
969
970
971

          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
972
            scaled_mv = av1_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf);
973
974
975
976
977
978
979
980
981
982
983
984
985
            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);
986

987
#if CONFIG_EXT_INTER
988
989
          if (ref &&
              is_masked_compound_type(mi->mbmi.interinter_compound_data.type))
Yaowu Xu's avatar
Yaowu Xu committed
990
            av1_make_masked_inter_predictor(
991
992
993
994
995
                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
996
                plane,
997
998
#if CONFIG_GLOBAL_MOTION
                is_global[ref], (mi_x >> pd->subsampling_x) + x,
999
                (mi_y >> pd->subsampling_y) + y, ref,
1000
#endif  // CONFIG_GLOBAL_MOTION
1001
                xd);
1002
1003
          else
#endif  // CONFIG_EXT_INTER
1004
1005
1006
1007
1008
1009
            av1_make_inter_predictor(
                pre, pre_buf->stride, dst, dst_buf->stride, subpel_x, subpel_y,
                sf, x_step, y_step, &conv_params, mi->mbmi.interp_filter,
#if CONFIG_GLOBAL_MOTION
                is_global[ref], (mi_x >> pd->subsampling_x) + x,
                (mi_y >> pd->subsampling_y) + y, plane, ref,
1010
1011
1012
#if CONFIG_MOTION_VAR
                mi_col_offset, mi_row_offset,
#endif
1013
1014
#endif  // CONFIG_GLOBAL_MOTION
                xs, ys, xd);
1015
        }
1016
1017
1018
1019
1020
1021
      }
    }
    return;
  }
#endif

Angie Chiang's avatar
Angie Chiang committed
1022
  {
Jingning Han's avatar
Jingning Han committed
1023
1024
    struct buf_2d *const dst_buf = &pd->dst;
    uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x;
Angie Chiang's avatar
Angie Chiang committed
1025
1026
1027
    uint8_t *pre[2];
    MV32 scaled_mv[2];
    SubpelParams subpel_params[2];
Angie Chiang's avatar
Angie Chiang committed
1028
#if CONFIG_CONVOLVE_ROUND
Angie Chiang's avatar
Angie Chiang committed
1029
1030
    DECLARE_ALIGNED(16, int32_t, tmp_dst[MAX_SB_SIZE * MAX_SB_SIZE]);
    av1_zero(tmp_dst);
Angie Chiang's avatar
Angie Chiang committed
1031
#endif  // CONFIG_CONVOLVE_ROUND
Angie Chiang's avatar
Angie Chiang committed
1032
1033
1034
1035

    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];
1036
#if CONFIG_CB4X4
Angie Chiang's avatar
Angie Chiang committed
1037
      const MV mv = mi->mbmi.mv[ref].as_mv;
1038
#else
Angie Chiang's avatar
Angie Chiang committed
1039
      const MV mv =
1040
#if CONFIG_MOTION_VAR
1041
1042
          (mi->mbmi.sb_type < BLOCK_8X8 && !build_for_obmc)
              ?
1043
#else
1044
1045
1046
          mi->mbmi.sb_type < BLOCK_8X8 ?
#endif
              average_split_mvs(pd, mi, ref, block)
Angie Chiang's avatar
Angie Chiang committed
1047
              : mi->mbmi.mv[ref].as_mv;
1048
#endif
Jingning Han's avatar
Jingning Han committed
1049

Angie Chiang's avatar
Angie Chiang committed
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
      // 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.
      const MV mv_q4 = clamp_mv_to_umv_border_sb(
          xd, &mv, bw, bh, pd->subsampling_x, pd->subsampling_y);

      const int is_scaled = av1_is_scaled(sf);

      if (is_scaled) {
        pre[ref] =
            pre_buf->buf + scaled_buffer_offset(x, y, pre_buf->stride, sf</