blob: c0c21ce7bf7248c5285dbbd53ccb8c5cad125c87 [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
12#include <assert.h>
13
Yaowu Xuf883b422016-08-30 14:01:10 -070014#include "./aom_scale_rtcd.h"
15#include "./aom_dsp_rtcd.h"
16#include "./aom_config.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070017
Yaowu Xuf883b422016-08-30 14:01:10 -070018#include "aom/aom_integer.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070019#include "aom_dsp/blend.h"
20
21#include "av1/common/blockd.h"
22#include "av1/common/reconinter.h"
23#include "av1/common/reconintra.h"
Yue Chencb60b182016-10-13 15:18:22 -070024#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -070025#include "av1/common/onyxc_int.h"
Yue Chencb60b182016-10-13 15:18:22 -070026#endif // CONFIG_MOTION_VAR
Yue Chen69f18e12016-09-08 14:48:15 -070027#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070028#include "av1/common/warped_motion.h"
Yue Chen69f18e12016-09-08 14:48:15 -070029#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -070030
31#if CONFIG_EXT_INTER
32
33#define NSMOOTHERS 1
34static int get_masked_weight(int m, int smoothness) {
35#define SMOOTHER_LEN 32
36 static const uint8_t smoothfn[NSMOOTHERS][2 * SMOOTHER_LEN + 1] = { {
clang-format67948d32016-09-07 22:40:40 -070037 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
38 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 7, 13, 21, 32, 43,
39 51, 57, 60, 62, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
40 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
Yaowu Xuc27fc142016-08-22 16:08:15 -070041 } };
42 if (m < -SMOOTHER_LEN)
43 return 0;
44 else if (m > SMOOTHER_LEN)
45 return (1 << WEDGE_WEIGHT_BITS);
46 else
47 return smoothfn[smoothness][m + SMOOTHER_LEN];
48}
49
50// [smoother][negative][direction]
clang-format67948d32016-09-07 22:40:40 -070051DECLARE_ALIGNED(16, static uint8_t,
52 wedge_mask_obl[NSMOOTHERS][2][WEDGE_DIRECTIONS]
53 [MASK_MASTER_SIZE * MASK_MASTER_SIZE]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070054
55DECLARE_ALIGNED(16, static uint8_t,
56 wedge_signflip_lookup[BLOCK_SIZES][MAX_WEDGE_TYPES]);
57
58// 3 * MAX_WEDGE_SQUARE is an easy to compute and fairly tight upper bound
59// on the sum of all mask sizes up to an including MAX_WEDGE_SQUARE.
60DECLARE_ALIGNED(16, static uint8_t,
61 wedge_mask_buf[2 * MAX_WEDGE_TYPES * 3 * MAX_WEDGE_SQUARE]);
62
63static wedge_masks_type wedge_masks[BLOCK_SIZES][2];
64
65// Some unused wedge codebooks left temporarily to facilitate experiments.
66// To be removed when setteld.
67static wedge_code_type wedge_codebook_8_hgtw[8] = {
68 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
69 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
70 { WEDGE_OBLIQUE27, 4, 2 }, { WEDGE_OBLIQUE27, 4, 6 },
71 { WEDGE_OBLIQUE153, 4, 2 }, { WEDGE_OBLIQUE153, 4, 6 },
72};
73
74static wedge_code_type wedge_codebook_8_hltw[8] = {
75 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
76 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
77 { WEDGE_OBLIQUE63, 2, 4 }, { WEDGE_OBLIQUE63, 6, 4 },
78 { WEDGE_OBLIQUE117, 2, 4 }, { WEDGE_OBLIQUE117, 6, 4 },
79};
80
81static wedge_code_type wedge_codebook_8_heqw[8] = {
82 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
83 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
84 { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 6 },
85 { WEDGE_VERTICAL, 2, 4 }, { WEDGE_VERTICAL, 6, 4 },
86};
87
88#if !USE_LARGE_WEDGE_CODEBOOK
89static const wedge_code_type wedge_codebook_16_hgtw[16] = {
90 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
91 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
92 { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 4 },
93 { WEDGE_HORIZONTAL, 4, 6 }, { WEDGE_VERTICAL, 4, 4 },
94 { WEDGE_OBLIQUE27, 4, 2 }, { WEDGE_OBLIQUE27, 4, 6 },
95 { WEDGE_OBLIQUE153, 4, 2 }, { WEDGE_OBLIQUE153, 4, 6 },
96 { WEDGE_OBLIQUE63, 2, 4 }, { WEDGE_OBLIQUE63, 6, 4 },
97 { WEDGE_OBLIQUE117, 2, 4 }, { WEDGE_OBLIQUE117, 6, 4 },
98};
99
100static const wedge_code_type wedge_codebook_16_hltw[16] = {
101 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
102 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
103 { WEDGE_VERTICAL, 2, 4 }, { WEDGE_VERTICAL, 4, 4 },
104 { WEDGE_VERTICAL, 6, 4 }, { WEDGE_HORIZONTAL, 4, 4 },
105 { WEDGE_OBLIQUE27, 4, 2 }, { WEDGE_OBLIQUE27, 4, 6 },
106 { WEDGE_OBLIQUE153, 4, 2 }, { WEDGE_OBLIQUE153, 4, 6 },
107 { WEDGE_OBLIQUE63, 2, 4 }, { WEDGE_OBLIQUE63, 6, 4 },
108 { WEDGE_OBLIQUE117, 2, 4 }, { WEDGE_OBLIQUE117, 6, 4 },
109};
110
111static const wedge_code_type wedge_codebook_16_heqw[16] = {
112 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
113 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
114 { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 6 },
115 { WEDGE_VERTICAL, 2, 4 }, { WEDGE_VERTICAL, 6, 4 },
116 { WEDGE_OBLIQUE27, 4, 2 }, { WEDGE_OBLIQUE27, 4, 6 },
117 { WEDGE_OBLIQUE153, 4, 2 }, { WEDGE_OBLIQUE153, 4, 6 },
118 { WEDGE_OBLIQUE63, 2, 4 }, { WEDGE_OBLIQUE63, 6, 4 },
119 { WEDGE_OBLIQUE117, 2, 4 }, { WEDGE_OBLIQUE117, 6, 4 },
120};
121
122const wedge_params_type wedge_params_lookup[BLOCK_SIZES] = {
Jingning Han61418bb2017-01-23 17:12:48 -0800123#if CONFIG_CB4X4
124 { 0, NULL, NULL, 0, NULL },
125 { 0, NULL, NULL, 0, NULL },
126 { 0, NULL, NULL, 0, NULL },
127#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700128 { 0, NULL, NULL, 0, NULL },
129 { 0, NULL, NULL, 0, NULL },
130 { 0, NULL, NULL, 0, NULL },
131 { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[3], 0, wedge_masks[3] },
132 { 4, wedge_codebook_16_hgtw, wedge_signflip_lookup[4], 0, wedge_masks[4] },
133 { 4, wedge_codebook_16_hltw, wedge_signflip_lookup[5], 0, wedge_masks[5] },
134 { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[6], 0, wedge_masks[6] },
135 { 4, wedge_codebook_16_hgtw, wedge_signflip_lookup[7], 0, wedge_masks[7] },
136 { 4, wedge_codebook_16_hltw, wedge_signflip_lookup[8], 0, wedge_masks[8] },
137 { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[9], 0, wedge_masks[9] },
138 { 0, wedge_codebook_8_hgtw, wedge_signflip_lookup[10], 0, wedge_masks[10] },
139 { 0, wedge_codebook_8_hltw, wedge_signflip_lookup[11], 0, wedge_masks[11] },
140 { 0, wedge_codebook_8_heqw, wedge_signflip_lookup[12], 0, wedge_masks[12] },
141#if CONFIG_EXT_PARTITION
142 { 0, NULL, NULL, 0, NULL },
143 { 0, NULL, NULL, 0, NULL },
144 { 0, NULL, NULL, 0, NULL },
145#endif // CONFIG_EXT_PARTITION
146};
147
148#else
149
150static const wedge_code_type wedge_codebook_32_hgtw[32] = {
151 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
152 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
153 { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 4 },
154 { WEDGE_HORIZONTAL, 4, 6 }, { WEDGE_VERTICAL, 4, 4 },
155 { WEDGE_OBLIQUE27, 4, 1 }, { WEDGE_OBLIQUE27, 4, 2 },
156 { WEDGE_OBLIQUE27, 4, 3 }, { WEDGE_OBLIQUE27, 4, 5 },
157 { WEDGE_OBLIQUE27, 4, 6 }, { WEDGE_OBLIQUE27, 4, 7 },
158 { WEDGE_OBLIQUE153, 4, 1 }, { WEDGE_OBLIQUE153, 4, 2 },
159 { WEDGE_OBLIQUE153, 4, 3 }, { WEDGE_OBLIQUE153, 4, 5 },
160 { WEDGE_OBLIQUE153, 4, 6 }, { WEDGE_OBLIQUE153, 4, 7 },
161 { WEDGE_OBLIQUE63, 1, 4 }, { WEDGE_OBLIQUE63, 2, 4 },
162 { WEDGE_OBLIQUE63, 3, 4 }, { WEDGE_OBLIQUE63, 5, 4 },
163 { WEDGE_OBLIQUE63, 6, 4 }, { WEDGE_OBLIQUE63, 7, 4 },
164 { WEDGE_OBLIQUE117, 1, 4 }, { WEDGE_OBLIQUE117, 2, 4 },
165 { WEDGE_OBLIQUE117, 3, 4 }, { WEDGE_OBLIQUE117, 5, 4 },
166 { WEDGE_OBLIQUE117, 6, 4 }, { WEDGE_OBLIQUE117, 7, 4 },
167};
168
169static const wedge_code_type wedge_codebook_32_hltw[32] = {
170 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
171 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
172 { WEDGE_VERTICAL, 2, 4 }, { WEDGE_VERTICAL, 4, 4 },
173 { WEDGE_VERTICAL, 6, 4 }, { WEDGE_HORIZONTAL, 4, 4 },
174 { WEDGE_OBLIQUE27, 4, 1 }, { WEDGE_OBLIQUE27, 4, 2 },
175 { WEDGE_OBLIQUE27, 4, 3 }, { WEDGE_OBLIQUE27, 4, 5 },
176 { WEDGE_OBLIQUE27, 4, 6 }, { WEDGE_OBLIQUE27, 4, 7 },
177 { WEDGE_OBLIQUE153, 4, 1 }, { WEDGE_OBLIQUE153, 4, 2 },
178 { WEDGE_OBLIQUE153, 4, 3 }, { WEDGE_OBLIQUE153, 4, 5 },
179 { WEDGE_OBLIQUE153, 4, 6 }, { WEDGE_OBLIQUE153, 4, 7 },
180 { WEDGE_OBLIQUE63, 1, 4 }, { WEDGE_OBLIQUE63, 2, 4 },
181 { WEDGE_OBLIQUE63, 3, 4 }, { WEDGE_OBLIQUE63, 5, 4 },
182 { WEDGE_OBLIQUE63, 6, 4 }, { WEDGE_OBLIQUE63, 7, 4 },
183 { WEDGE_OBLIQUE117, 1, 4 }, { WEDGE_OBLIQUE117, 2, 4 },
184 { WEDGE_OBLIQUE117, 3, 4 }, { WEDGE_OBLIQUE117, 5, 4 },
185 { WEDGE_OBLIQUE117, 6, 4 }, { WEDGE_OBLIQUE117, 7, 4 },
186};
187
188static const wedge_code_type wedge_codebook_32_heqw[32] = {
189 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
190 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
191 { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 6 },
192 { WEDGE_VERTICAL, 2, 4 }, { WEDGE_VERTICAL, 6, 4 },
193 { WEDGE_OBLIQUE27, 4, 1 }, { WEDGE_OBLIQUE27, 4, 2 },
194 { WEDGE_OBLIQUE27, 4, 3 }, { WEDGE_OBLIQUE27, 4, 5 },
195 { WEDGE_OBLIQUE27, 4, 6 }, { WEDGE_OBLIQUE27, 4, 7 },
196 { WEDGE_OBLIQUE153, 4, 1 }, { WEDGE_OBLIQUE153, 4, 2 },
197 { WEDGE_OBLIQUE153, 4, 3 }, { WEDGE_OBLIQUE153, 4, 5 },
198 { WEDGE_OBLIQUE153, 4, 6 }, { WEDGE_OBLIQUE153, 4, 7 },
199 { WEDGE_OBLIQUE63, 1, 4 }, { WEDGE_OBLIQUE63, 2, 4 },
200 { WEDGE_OBLIQUE63, 3, 4 }, { WEDGE_OBLIQUE63, 5, 4 },
201 { WEDGE_OBLIQUE63, 6, 4 }, { WEDGE_OBLIQUE63, 7, 4 },
202 { WEDGE_OBLIQUE117, 1, 4 }, { WEDGE_OBLIQUE117, 2, 4 },
203 { WEDGE_OBLIQUE117, 3, 4 }, { WEDGE_OBLIQUE117, 5, 4 },
204 { WEDGE_OBLIQUE117, 6, 4 }, { WEDGE_OBLIQUE117, 7, 4 },
205};
206
207const wedge_params_type wedge_params_lookup[BLOCK_SIZES] = {
Jingning Han61418bb2017-01-23 17:12:48 -0800208#if CONFIG_CB4X4
209 { 0, NULL, NULL, 0, NULL },
210 { 0, NULL, NULL, 0, NULL },
211 { 0, NULL, NULL, 0, NULL },
212#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700213 { 0, NULL, NULL, 0, NULL },
214 { 0, NULL, NULL, 0, NULL },
215 { 0, NULL, NULL, 0, NULL },
216 { 5, wedge_codebook_32_heqw, wedge_signflip_lookup[3], 0, wedge_masks[3] },
217 { 5, wedge_codebook_32_hgtw, wedge_signflip_lookup[4], 0, wedge_masks[4] },
218 { 5, wedge_codebook_32_hltw, wedge_signflip_lookup[5], 0, wedge_masks[5] },
219 { 5, wedge_codebook_32_heqw, wedge_signflip_lookup[6], 0, wedge_masks[6] },
220 { 5, wedge_codebook_32_hgtw, wedge_signflip_lookup[7], 0, wedge_masks[7] },
221 { 5, wedge_codebook_32_hltw, wedge_signflip_lookup[8], 0, wedge_masks[8] },
222 { 5, wedge_codebook_32_heqw, wedge_signflip_lookup[9], 0, wedge_masks[9] },
223 { 0, wedge_codebook_8_hgtw, wedge_signflip_lookup[10], 0, wedge_masks[10] },
224 { 0, wedge_codebook_8_hltw, wedge_signflip_lookup[11], 0, wedge_masks[11] },
225 { 0, wedge_codebook_8_heqw, wedge_signflip_lookup[12], 0, wedge_masks[12] },
226#if CONFIG_EXT_PARTITION
227 { 0, NULL, NULL, 0, NULL },
228 { 0, NULL, NULL, 0, NULL },
229 { 0, NULL, NULL, 0, NULL },
230#endif // CONFIG_EXT_PARTITION
231};
232#endif // USE_LARGE_WEDGE_CODEBOOK
233
234static const uint8_t *get_wedge_mask_inplace(int wedge_index, int neg,
235 BLOCK_SIZE sb_type) {
236 const uint8_t *master;
Jingning Han61418bb2017-01-23 17:12:48 -0800237 const int bh = block_size_high[sb_type];
238 const int bw = block_size_wide[sb_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700239 const wedge_code_type *a =
240 wedge_params_lookup[sb_type].codebook + wedge_index;
241 const int smoother = wedge_params_lookup[sb_type].smoother;
242 int woff, hoff;
243 const uint8_t wsignflip = wedge_params_lookup[sb_type].signflip[wedge_index];
244
245 assert(wedge_index >= 0 &&
246 wedge_index < (1 << get_wedge_bits_lookup(sb_type)));
247 woff = (a->x_offset * bw) >> 3;
248 hoff = (a->y_offset * bh) >> 3;
249 master = wedge_mask_obl[smoother][neg ^ wsignflip][a->direction] +
250 MASK_MASTER_STRIDE * (MASK_MASTER_SIZE / 2 - hoff) +
251 MASK_MASTER_SIZE / 2 - woff;
252 return master;
253}
254
Yaowu Xuf883b422016-08-30 14:01:10 -0700255const uint8_t *av1_get_soft_mask(int wedge_index, int wedge_sign,
256 BLOCK_SIZE sb_type, int offset_x,
257 int offset_y) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700258 const uint8_t *mask =
259 get_wedge_mask_inplace(wedge_index, wedge_sign, sb_type);
260 if (mask) mask -= (offset_x + offset_y * MASK_MASTER_STRIDE);
261 return mask;
262}
263
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800264#if CONFIG_COMPOUND_SEGMENT
265static uint8_t *invert_mask(uint8_t *mask_inv_buffer, const uint8_t *const mask,
266 int h, int w, int stride) {
267 int i, j;
268
269 for (i = 0; i < h; ++i)
270 for (j = 0; j < w; ++j) {
271 mask_inv_buffer[i * stride + j] =
272 AOM_BLEND_A64_MAX_ALPHA - mask[i * stride + j];
273 }
274 return mask_inv_buffer;
275}
276#endif // CONFIG_COMPOUND_SEGMENT
277
278const uint8_t *av1_get_compound_type_mask_inverse(
279 const INTERINTER_COMPOUND_DATA *const comp_data,
280#if CONFIG_COMPOUND_SEGMENT
281 uint8_t *mask_buffer, int h, int w, int stride,
282#endif
283 BLOCK_SIZE sb_type) {
Sarah Parker6fdc8532016-11-16 17:47:13 -0800284 assert(is_masked_compound_type(comp_data->type));
285 switch (comp_data->type) {
286 case COMPOUND_WEDGE:
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800287 return av1_get_contiguous_soft_mask(comp_data->wedge_index,
288 !comp_data->wedge_sign, sb_type);
Sarah Parker569edda2016-12-14 14:57:38 -0800289#if CONFIG_COMPOUND_SEGMENT
290 case COMPOUND_SEG:
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800291 return invert_mask(mask_buffer, comp_data->seg_mask, h, w, stride);
292#endif // CONFIG_COMPOUND_SEGMENT
293 default: assert(0); return NULL;
294 }
295}
296
297const uint8_t *av1_get_compound_type_mask(
298 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type) {
299 assert(is_masked_compound_type(comp_data->type));
300 switch (comp_data->type) {
301 case COMPOUND_WEDGE:
302 return av1_get_contiguous_soft_mask(comp_data->wedge_index,
303 comp_data->wedge_sign, sb_type);
304#if CONFIG_COMPOUND_SEGMENT
305 case COMPOUND_SEG: return comp_data->seg_mask;
Sarah Parker569edda2016-12-14 14:57:38 -0800306#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -0800307 default: assert(0); return NULL;
308 }
309}
Sarah Parker569edda2016-12-14 14:57:38 -0800310
311#if CONFIG_COMPOUND_SEGMENT
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800312#if COMPOUND_SEGMENT_TYPE == 0
313static void uniform_mask(uint8_t *mask, int which_inverse, BLOCK_SIZE sb_type,
314 int h, int w, int mask_val) {
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800315 int i, j;
316 int block_stride = block_size_wide[sb_type];
317 for (i = 0; i < h; ++i)
318 for (j = 0; j < w; ++j) {
319 mask[i * block_stride + j] =
320 which_inverse ? AOM_BLEND_A64_MAX_ALPHA - mask_val : mask_val;
321 }
322}
323
324void build_compound_seg_mask(uint8_t *mask, SEG_MASK_TYPE mask_type,
Sarah Parker569edda2016-12-14 14:57:38 -0800325 const uint8_t *src0, int src0_stride,
326 const uint8_t *src1, int src1_stride,
327 BLOCK_SIZE sb_type, int h, int w) {
Sarah Parker569edda2016-12-14 14:57:38 -0800328 (void)src0;
329 (void)src1;
330 (void)src0_stride;
331 (void)src1_stride;
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800332 switch (mask_type) {
333 case UNIFORM_45: uniform_mask(mask, 0, sb_type, h, w, 45); break;
334 case UNIFORM_45_INV: uniform_mask(mask, 1, sb_type, h, w, 45); break;
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800335 default: assert(0);
336 }
Sarah Parker569edda2016-12-14 14:57:38 -0800337}
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800338
339#if CONFIG_AOM_HIGHBITDEPTH
340void build_compound_seg_mask_highbd(uint8_t *mask, SEG_MASK_TYPE mask_type,
341 const uint8_t *src0, int src0_stride,
342 const uint8_t *src1, int src1_stride,
343 BLOCK_SIZE sb_type, int h, int w, int bd) {
344 (void)src0;
345 (void)src1;
346 (void)src0_stride;
347 (void)src1_stride;
348 (void)bd;
349 switch (mask_type) {
350 case UNIFORM_45: uniform_mask(mask, 0, sb_type, h, w, 45); break;
351 case UNIFORM_45_INV: uniform_mask(mask, 1, sb_type, h, w, 45); break;
352 default: assert(0);
353 }
354}
355#endif // CONFIG_AOM_HIGHBITDEPTH
356
357#elif COMPOUND_SEGMENT_TYPE == 1
358#define DIFF_FACTOR 16
359static void diffwtd_mask(uint8_t *mask, int which_inverse, int mask_base,
360 const uint8_t *src0, int src0_stride,
361 const uint8_t *src1, int src1_stride,
362 BLOCK_SIZE sb_type, int h, int w) {
363 int i, j, m, diff;
364 int block_stride = block_size_wide[sb_type];
365 for (i = 0; i < h; ++i) {
366 for (j = 0; j < w; ++j) {
367 diff =
368 abs((int)src0[i * src0_stride + j] - (int)src1[i * src1_stride + j]);
369 m = clamp(mask_base + (diff / DIFF_FACTOR), 0, AOM_BLEND_A64_MAX_ALPHA);
370 mask[i * block_stride + j] =
371 which_inverse ? AOM_BLEND_A64_MAX_ALPHA - m : m;
372 }
373 }
374}
375
376void build_compound_seg_mask(uint8_t *mask, SEG_MASK_TYPE mask_type,
377 const uint8_t *src0, int src0_stride,
378 const uint8_t *src1, int src1_stride,
379 BLOCK_SIZE sb_type, int h, int w) {
380 switch (mask_type) {
Yaowu Xua93e65e2017-01-24 10:58:48 -0800381 case DIFFWTD_42:
382 diffwtd_mask(mask, 0, 42, src0, src0_stride, src1, src1_stride, sb_type,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800383 h, w);
384 break;
Yaowu Xua93e65e2017-01-24 10:58:48 -0800385 case DIFFWTD_42_INV:
386 diffwtd_mask(mask, 1, 42, src0, src0_stride, src1, src1_stride, sb_type,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800387 h, w);
388 break;
389 default: assert(0);
390 }
391}
392
393#if CONFIG_AOM_HIGHBITDEPTH
394static void diffwtd_mask_highbd(uint8_t *mask, int which_inverse, int mask_base,
395 const uint16_t *src0, int src0_stride,
396 const uint16_t *src1, int src1_stride,
397 BLOCK_SIZE sb_type, int h, int w, int bd) {
398 int i, j, m, diff;
399 int block_stride = block_size_wide[sb_type];
400 for (i = 0; i < h; ++i) {
401 for (j = 0; j < w; ++j) {
402 diff = abs((int)src0[i * src0_stride + j] -
403 (int)src1[i * src1_stride + j]) >>
404 (bd - 8);
405 m = clamp(mask_base + (diff / DIFF_FACTOR), 0, AOM_BLEND_A64_MAX_ALPHA);
406 mask[i * block_stride + j] =
407 which_inverse ? AOM_BLEND_A64_MAX_ALPHA - m : m;
408 }
409 }
410}
411
412void build_compound_seg_mask_highbd(uint8_t *mask, SEG_MASK_TYPE mask_type,
413 const uint8_t *src0, int src0_stride,
414 const uint8_t *src1, int src1_stride,
415 BLOCK_SIZE sb_type, int h, int w, int bd) {
416 switch (mask_type) {
417 case DIFFWTD_42:
418 diffwtd_mask_highbd(mask, 0, 42, CONVERT_TO_SHORTPTR(src0), src0_stride,
419 CONVERT_TO_SHORTPTR(src1), src1_stride, sb_type, h, w,
420 bd);
421 break;
422 case DIFFWTD_42_INV:
423 diffwtd_mask_highbd(mask, 1, 42, CONVERT_TO_SHORTPTR(src0), src0_stride,
424 CONVERT_TO_SHORTPTR(src1), src1_stride, sb_type, h, w,
425 bd);
426 break;
427 default: assert(0);
428 }
429}
430#endif // CONFIG_AOM_HIGHBITDEPTH
431#endif // COMPOUND_SEGMENT_TYPE
Sarah Parker569edda2016-12-14 14:57:38 -0800432#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -0800433
Yaowu Xuc27fc142016-08-22 16:08:15 -0700434static void init_wedge_master_masks() {
435 int i, j, s;
436 const int w = MASK_MASTER_SIZE;
437 const int h = MASK_MASTER_SIZE;
438 const int stride = MASK_MASTER_STRIDE;
439 const int a[2] = { 2, 1 };
440 const double asqrt = sqrt(a[0] * a[0] + a[1] * a[1]);
441 for (s = 0; s < NSMOOTHERS; s++) {
442 for (i = 0; i < h; ++i)
443 for (j = 0; j < w; ++j) {
444 int x = (2 * j + 1 - w);
445 int y = (2 * i + 1 - h);
446 int m = (int)rint((a[0] * x + a[1] * y) / asqrt);
447 wedge_mask_obl[s][1][WEDGE_OBLIQUE63][i * stride + j] =
448 wedge_mask_obl[s][1][WEDGE_OBLIQUE27][j * stride + i] =
449 get_masked_weight(m, s);
450 wedge_mask_obl[s][1][WEDGE_OBLIQUE117][i * stride + w - 1 - j] =
451 wedge_mask_obl[s][1][WEDGE_OBLIQUE153][(w - 1 - j) * stride + i] =
452 (1 << WEDGE_WEIGHT_BITS) - get_masked_weight(m, s);
453 wedge_mask_obl[s][0][WEDGE_OBLIQUE63][i * stride + j] =
454 wedge_mask_obl[s][0][WEDGE_OBLIQUE27][j * stride + i] =
455 (1 << WEDGE_WEIGHT_BITS) - get_masked_weight(m, s);
456 wedge_mask_obl[s][0][WEDGE_OBLIQUE117][i * stride + w - 1 - j] =
457 wedge_mask_obl[s][0][WEDGE_OBLIQUE153][(w - 1 - j) * stride + i] =
458 get_masked_weight(m, s);
459 wedge_mask_obl[s][1][WEDGE_VERTICAL][i * stride + j] =
460 wedge_mask_obl[s][1][WEDGE_HORIZONTAL][j * stride + i] =
461 get_masked_weight(x, s);
462 wedge_mask_obl[s][0][WEDGE_VERTICAL][i * stride + j] =
463 wedge_mask_obl[s][0][WEDGE_HORIZONTAL][j * stride + i] =
464 (1 << WEDGE_WEIGHT_BITS) - get_masked_weight(x, s);
465 }
466 }
467}
468
469// If the signs for the wedges for various blocksizes are
470// inconsistent flip the sign flag. Do it only once for every
471// wedge codebook.
472static void init_wedge_signs() {
473 BLOCK_SIZE sb_type;
474 memset(wedge_signflip_lookup, 0, sizeof(wedge_signflip_lookup));
475 for (sb_type = BLOCK_4X4; sb_type < BLOCK_SIZES; ++sb_type) {
Jingning Hanae5cfde2016-11-30 12:01:44 -0800476 const int bw = block_size_wide[sb_type];
477 const int bh = block_size_high[sb_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700478 const wedge_params_type wedge_params = wedge_params_lookup[sb_type];
479 const int wbits = wedge_params.bits;
480 const int wtypes = 1 << wbits;
481 int i, w;
482 if (wbits == 0) continue;
483 for (w = 0; w < wtypes; ++w) {
484 const uint8_t *mask = get_wedge_mask_inplace(w, 0, sb_type);
485 int sum = 0;
486 for (i = 0; i < bw; ++i) sum += mask[i];
487 for (i = 0; i < bh; ++i) sum += mask[i * MASK_MASTER_STRIDE];
488 sum = (sum + (bw + bh) / 2) / (bw + bh);
489 wedge_params.signflip[w] = (sum < 32);
490 }
491 }
492}
493
494static void init_wedge_masks() {
495 uint8_t *dst = wedge_mask_buf;
496 BLOCK_SIZE bsize;
497 memset(wedge_masks, 0, sizeof(wedge_masks));
498 for (bsize = BLOCK_4X4; bsize < BLOCK_SIZES; ++bsize) {
499 const uint8_t *mask;
Jingning Hanae5cfde2016-11-30 12:01:44 -0800500 const int bw = block_size_wide[bsize];
501 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700502 const wedge_params_type *wedge_params = &wedge_params_lookup[bsize];
503 const int wbits = wedge_params->bits;
504 const int wtypes = 1 << wbits;
505 int w;
506 if (wbits == 0) continue;
507 for (w = 0; w < wtypes; ++w) {
508 mask = get_wedge_mask_inplace(w, 0, bsize);
Yaowu Xuf883b422016-08-30 14:01:10 -0700509 aom_convolve_copy(mask, MASK_MASTER_STRIDE, dst, bw, NULL, 0, NULL, 0, bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700510 bh);
511 wedge_params->masks[0][w] = dst;
512 dst += bw * bh;
513
514 mask = get_wedge_mask_inplace(w, 1, bsize);
Yaowu Xuf883b422016-08-30 14:01:10 -0700515 aom_convolve_copy(mask, MASK_MASTER_STRIDE, dst, bw, NULL, 0, NULL, 0, bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700516 bh);
517 wedge_params->masks[1][w] = dst;
518 dst += bw * bh;
519 }
520 assert(sizeof(wedge_mask_buf) >= (size_t)(dst - wedge_mask_buf));
521 }
522}
523
524// Equation of line: f(x, y) = a[0]*(x - a[2]*w/8) + a[1]*(y - a[3]*h/8) = 0
Yaowu Xuf883b422016-08-30 14:01:10 -0700525void av1_init_wedge_masks() {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700526 init_wedge_master_masks();
527 init_wedge_signs();
528 init_wedge_masks();
529}
530
531#if CONFIG_SUPERTX
532static void build_masked_compound_wedge_extend(
533 uint8_t *dst, int dst_stride, const uint8_t *src0, int src0_stride,
534 const uint8_t *src1, int src1_stride, int wedge_index, int wedge_sign,
535 BLOCK_SIZE sb_type, int wedge_offset_x, int wedge_offset_y, int h, int w) {
536 const int subh = (2 << b_height_log2_lookup[sb_type]) == h;
537 const int subw = (2 << b_width_log2_lookup[sb_type]) == w;
Yaowu Xuf883b422016-08-30 14:01:10 -0700538 const uint8_t *mask = av1_get_soft_mask(wedge_index, wedge_sign, sb_type,
539 wedge_offset_x, wedge_offset_y);
540 aom_blend_a64_mask(dst, dst_stride, src0, src0_stride, src1, src1_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700541 mask, MASK_MASTER_STRIDE, h, w, subh, subw);
542}
543
Yaowu Xuf883b422016-08-30 14:01:10 -0700544#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700545static void build_masked_compound_wedge_extend_highbd(
546 uint8_t *dst_8, int dst_stride, const uint8_t *src0_8, int src0_stride,
547 const uint8_t *src1_8, int src1_stride, int wedge_index, int wedge_sign,
548 BLOCK_SIZE sb_type, int wedge_offset_x, int wedge_offset_y, int h, int w,
549 int bd) {
550 const int subh = (2 << b_height_log2_lookup[sb_type]) == h;
551 const int subw = (2 << b_width_log2_lookup[sb_type]) == w;
Yaowu Xuf883b422016-08-30 14:01:10 -0700552 const uint8_t *mask = av1_get_soft_mask(wedge_index, wedge_sign, sb_type,
553 wedge_offset_x, wedge_offset_y);
554 aom_highbd_blend_a64_mask(dst_8, dst_stride, src0_8, src0_stride, src1_8,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700555 src1_stride, mask, MASK_MASTER_STRIDE, h, w, subh,
556 subw, bd);
557}
Yaowu Xuf883b422016-08-30 14:01:10 -0700558#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700559#endif // CONFIG_SUPERTX
560
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800561static void build_masked_compound(
562 uint8_t *dst, int dst_stride, const uint8_t *src0, int src0_stride,
563 const uint8_t *src1, int src1_stride,
564 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type, int h,
565 int w) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700566 // Derive subsampling from h and w passed in. May be refactored to
567 // pass in subsampling factors directly.
568 const int subh = (2 << b_height_log2_lookup[sb_type]) == h;
569 const int subw = (2 << b_width_log2_lookup[sb_type]) == w;
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800570 const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type);
Yaowu Xuf883b422016-08-30 14:01:10 -0700571 aom_blend_a64_mask(dst, dst_stride, src0, src0_stride, src1, src1_stride,
Jingning Hanae5cfde2016-11-30 12:01:44 -0800572 mask, block_size_wide[sb_type], h, w, subh, subw);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700573}
574
Yaowu Xuf883b422016-08-30 14:01:10 -0700575#if CONFIG_AOM_HIGHBITDEPTH
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800576static void build_masked_compound_highbd(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700577 uint8_t *dst_8, int dst_stride, const uint8_t *src0_8, int src0_stride,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800578 const uint8_t *src1_8, int src1_stride,
579 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type, int h,
580 int w, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700581 // Derive subsampling from h and w passed in. May be refactored to
582 // pass in subsampling factors directly.
583 const int subh = (2 << b_height_log2_lookup[sb_type]) == h;
584 const int subw = (2 << b_width_log2_lookup[sb_type]) == w;
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800585 const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type);
586 // const uint8_t *mask =
587 // av1_get_contiguous_soft_mask(wedge_index, wedge_sign, sb_type);
Jingning Hanae5cfde2016-11-30 12:01:44 -0800588 aom_highbd_blend_a64_mask(dst_8, dst_stride, src0_8, src0_stride, src1_8,
589 src1_stride, mask, block_size_wide[sb_type], h, w,
590 subh, subw, bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700591}
Yaowu Xuf883b422016-08-30 14:01:10 -0700592#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700593
Yaowu Xuf883b422016-08-30 14:01:10 -0700594void av1_make_masked_inter_predictor(const uint8_t *pre, int pre_stride,
595 uint8_t *dst, int dst_stride,
596 const int subpel_x, const int subpel_y,
597 const struct scale_factors *sf, int w,
598 int h,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700599#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -0700600 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700601#else
James Zern7b9407a2016-05-18 23:48:05 -0700602 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700603#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700604 int xs, int ys,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700605#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -0700606 int wedge_offset_x, int wedge_offset_y,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700607#endif // CONFIG_SUPERTX
Sarah Parker569edda2016-12-14 14:57:38 -0800608#if CONFIG_COMPOUND_SEGMENT
609 int plane,
610#endif // CONFIG_COMPOUND_SEGMENT
611 MACROBLOCKD *xd) {
612 MODE_INFO *mi = xd->mi[0];
613 INTERINTER_COMPOUND_DATA *comp_data = &mi->mbmi.interinter_compound_data;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700614// The prediction filter types used here should be those for
615// the second reference block.
616#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -0700617 InterpFilter tmp_ipf[4] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700618 interp_filter[2], interp_filter[3], interp_filter[2], interp_filter[3],
619 };
620#else
James Zern7b9407a2016-05-18 23:48:05 -0700621 InterpFilter tmp_ipf = interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700622#endif // CONFIG_DUAL_FILTER
Angie Chiang9f45bc42017-01-13 16:27:54 -0800623 ConvolveParams conv_params = get_conv_params(0);
Yaowu Xuf883b422016-08-30 14:01:10 -0700624#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700625 DECLARE_ALIGNED(16, uint8_t, tmp_dst_[2 * MAX_SB_SQUARE]);
626 uint8_t *tmp_dst = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
627 ? CONVERT_TO_BYTEPTR(tmp_dst_)
628 : tmp_dst_;
Yaowu Xuf883b422016-08-30 14:01:10 -0700629 av1_make_inter_predictor(pre, pre_stride, tmp_dst, MAX_SB_SIZE, subpel_x,
Angie Chiang9f45bc42017-01-13 16:27:54 -0800630 subpel_y, sf, w, h, &conv_params, tmp_ipf, xs, ys,
631 xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700632#if CONFIG_SUPERTX
633 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
634 build_masked_compound_wedge_extend_highbd(
635 dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE,
Sarah Parker6fdc8532016-11-16 17:47:13 -0800636 comp_data->wedge_index, comp_data->wedge_sign, mi->mbmi.sb_type,
637 wedge_offset_x, wedge_offset_y, h, w, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700638 else
639 build_masked_compound_wedge_extend(
640 dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE,
Sarah Parker6fdc8532016-11-16 17:47:13 -0800641 comp_data->wedge_index, comp_data->wedge_sign, mi->mbmi.sb_type,
642 wedge_offset_x, wedge_offset_y, h, w);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700643#else
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800644#if CONFIG_COMPOUND_SEGMENT
645 if (!plane && comp_data->type == COMPOUND_SEG) {
646 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
647 build_compound_seg_mask_highbd(comp_data->seg_mask, comp_data->mask_type,
648 dst, dst_stride, tmp_dst, MAX_SB_SIZE,
649 mi->mbmi.sb_type, h, w, xd->bd);
650 else
651 build_compound_seg_mask(comp_data->seg_mask, comp_data->mask_type, dst,
652 dst_stride, tmp_dst, MAX_SB_SIZE,
653 mi->mbmi.sb_type, h, w);
654 }
655#endif // CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -0700656 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800657 build_masked_compound_highbd(dst, dst_stride, dst, dst_stride, tmp_dst,
658 MAX_SB_SIZE, comp_data, mi->mbmi.sb_type, h, w,
659 xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700660 else
Sarah Parker6fdc8532016-11-16 17:47:13 -0800661 build_masked_compound(dst, dst_stride, dst, dst_stride, tmp_dst,
662 MAX_SB_SIZE, comp_data, mi->mbmi.sb_type, h, w);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700663#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -0700664#else // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700665 DECLARE_ALIGNED(16, uint8_t, tmp_dst[MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -0700666 av1_make_inter_predictor(pre, pre_stride, tmp_dst, MAX_SB_SIZE, subpel_x,
Angie Chiang9f45bc42017-01-13 16:27:54 -0800667 subpel_y, sf, w, h, &conv_params, tmp_ipf, xs, ys,
668 xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700669#if CONFIG_SUPERTX
Sarah Parker6fdc8532016-11-16 17:47:13 -0800670 build_masked_compound_wedge_extend(dst, dst_stride, dst, dst_stride, tmp_dst,
671 MAX_SB_SIZE, comp_data->wedge_index,
672 comp_data->wedge_sign, mi->mbmi.sb_type,
673 wedge_offset_x, wedge_offset_y, h, w);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700674#else
Sarah Parker569edda2016-12-14 14:57:38 -0800675#if CONFIG_COMPOUND_SEGMENT
676 if (!plane && comp_data->type == COMPOUND_SEG)
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800677 build_compound_seg_mask(comp_data->seg_mask, comp_data->mask_type, dst,
678 dst_stride, tmp_dst, MAX_SB_SIZE, mi->mbmi.sb_type,
679 h, w);
Sarah Parker569edda2016-12-14 14:57:38 -0800680#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -0800681 build_masked_compound(dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE,
682 comp_data, mi->mbmi.sb_type, h, w);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700683#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -0700684#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700685}
686#endif // CONFIG_EXT_INTER
687
Yaowu Xuf883b422016-08-30 14:01:10 -0700688#if CONFIG_AOM_HIGHBITDEPTH
689void av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700690 const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride,
691 const MV *src_mv, const struct scale_factors *sf, int w, int h, int ref,
692#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -0700693 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700694#else
James Zern7b9407a2016-05-18 23:48:05 -0700695 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700696#endif
697 enum mv_precision precision, int x, int y, int bd) {
698 const int is_q4 = precision == MV_PRECISION_Q4;
699 const MV mv_q4 = { is_q4 ? src_mv->row : src_mv->row * 2,
700 is_q4 ? src_mv->col : src_mv->col * 2 };
Yaowu Xuf883b422016-08-30 14:01:10 -0700701 MV32 mv = av1_scale_mv(&mv_q4, x, y, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700702 const int subpel_x = mv.col & SUBPEL_MASK;
703 const int subpel_y = mv.row & SUBPEL_MASK;
704
705 src += (mv.row >> SUBPEL_BITS) * src_stride + (mv.col >> SUBPEL_BITS);
706
707 highbd_inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y,
708 sf, w, h, ref, interp_filter, sf->x_step_q4,
709 sf->y_step_q4, bd);
710}
Yaowu Xuf883b422016-08-30 14:01:10 -0700711#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700712
Yaowu Xuf883b422016-08-30 14:01:10 -0700713void av1_build_inter_predictor(const uint8_t *src, int src_stride, uint8_t *dst,
714 int dst_stride, const MV *src_mv,
715 const struct scale_factors *sf, int w, int h,
Angie Chiang9f45bc42017-01-13 16:27:54 -0800716 ConvolveParams *conv_params,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700717#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -0700718 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700719#else
James Zern7b9407a2016-05-18 23:48:05 -0700720 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700721#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700722 enum mv_precision precision, int x, int y) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700723 const int is_q4 = precision == MV_PRECISION_Q4;
724 const MV mv_q4 = { is_q4 ? src_mv->row : src_mv->row * 2,
725 is_q4 ? src_mv->col : src_mv->col * 2 };
Yaowu Xuf883b422016-08-30 14:01:10 -0700726 MV32 mv = av1_scale_mv(&mv_q4, x, y, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700727 const int subpel_x = mv.col & SUBPEL_MASK;
728 const int subpel_y = mv.row & SUBPEL_MASK;
729
730 src += (mv.row >> SUBPEL_BITS) * src_stride + (mv.col >> SUBPEL_BITS);
731
732 inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y, sf, w,
Angie Chiang9f45bc42017-01-13 16:27:54 -0800733 h, conv_params, interp_filter, sf->x_step_q4, sf->y_step_q4);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700734}
735
Angie Chiang907230e2017-01-17 17:39:14 -0800736typedef struct SubpelParams {
737 int xs;
738 int ys;
739 int subpel_x;
740 int subpel_y;
741} SubpelParams;
742
Yaowu Xuc27fc142016-08-22 16:08:15 -0700743void build_inter_predictors(MACROBLOCKD *xd, int plane,
Yue Chencb60b182016-10-13 15:18:22 -0700744#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700745 int mi_col_offset, int mi_row_offset,
Yue Chencb60b182016-10-13 15:18:22 -0700746#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700747 int block, int bw, int bh, int x, int y, int w,
748 int h,
749#if CONFIG_SUPERTX && CONFIG_EXT_INTER
750 int wedge_offset_x, int wedge_offset_y,
751#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
752 int mi_x, int mi_y) {
753 struct macroblockd_plane *const pd = &xd->plane[plane];
Yue Chencb60b182016-10-13 15:18:22 -0700754#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700755 const MODE_INFO *mi = xd->mi[mi_col_offset + xd->mi_stride * mi_row_offset];
Yue Chenf27b1602017-01-13 11:11:43 -0800756#if !CONFIG_CB4X4
Yue Chen894fcce2016-10-21 16:50:52 -0700757 const int build_for_obmc = !(mi_col_offset == 0 && mi_row_offset == 0);
Yue Chenf27b1602017-01-13 11:11:43 -0800758#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700759#else
760 const MODE_INFO *mi = xd->mi[0];
Yue Chencb60b182016-10-13 15:18:22 -0700761#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700762 const int is_compound = has_second_ref(&mi->mbmi);
763 int ref;
764#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +0000765 WarpedMotionParams *gm[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700766 int is_global[2];
767 for (ref = 0; ref < 1 + is_compound; ++ref) {
768 gm[ref] = &xd->global_motion[mi->mbmi.ref_frame[ref]];
769 is_global[ref] =
Debargha Mukherjeee3e00792016-11-13 11:35:44 -0800770 (get_y_mode(mi, block) == ZEROMV && gm[ref]->wmtype > TRANSLATION);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700771 }
772 // TODO(sarahparker) remove these once gm works with all experiments
773 (void)gm;
774 (void)is_global;
775#endif // CONFIG_GLOBAL_MOTION
776
Jingning Hanb46540c2016-12-14 10:59:20 -0800777#if CONFIG_CB4X4
778 (void)block;
779#endif
780
Yaowu Xuc27fc142016-08-22 16:08:15 -0700781// TODO(sarahparker) enable the use of DUAL_FILTER in warped motion functions
782// in order to allow GLOBAL_MOTION and DUAL_FILTER to work together
Jingning Han46003142016-11-02 14:57:11 -0700783#if CONFIG_SUB8X8_MC
Yue Chen894fcce2016-10-21 16:50:52 -0700784#if CONFIG_MOTION_VAR
785 if (mi->mbmi.sb_type < BLOCK_8X8 && plane > 0 && !build_for_obmc) {
786#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700787 if (mi->mbmi.sb_type < BLOCK_8X8 && plane > 0) {
Yue Chen894fcce2016-10-21 16:50:52 -0700788#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700789 // block size in log2
790 const int b4_wl = b_width_log2_lookup[mi->mbmi.sb_type];
791 const int b4_hl = b_height_log2_lookup[mi->mbmi.sb_type];
792 const int b8_sl = b_width_log2_lookup[BLOCK_8X8];
793
794 // block size
795 const int b4_w = 1 << b4_wl;
796 const int b4_h = 1 << b4_hl;
797 const int b8_s = 1 << b8_sl;
798 int idx, idy;
799
800 const int x_base = x;
801 const int y_base = y;
802
803 // processing unit size
804 const int x_step = w >> (b8_sl - b4_wl);
805 const int y_step = h >> (b8_sl - b4_hl);
806
807 for (idy = 0; idy < b8_s; idy += b4_h) {
808 for (idx = 0; idx < b8_s; idx += b4_w) {
809 const int chr_idx = (idy * 2) + idx;
810 for (ref = 0; ref < 1 + is_compound; ++ref) {
811 const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
812 struct buf_2d *const pre_buf = &pd->pre[ref];
813 struct buf_2d *const dst_buf = &pd->dst;
814 uint8_t *dst = dst_buf->buf;
815 const MV mv = mi->bmi[chr_idx].as_mv[ref].as_mv;
816 const MV mv_q4 = clamp_mv_to_umv_border_sb(
817 xd, &mv, bw, bh, pd->subsampling_x, pd->subsampling_y);
818 uint8_t *pre;
819 MV32 scaled_mv;
820 int xs, ys, subpel_x, subpel_y;
Yaowu Xuf883b422016-08-30 14:01:10 -0700821 const int is_scaled = av1_is_scaled(sf);
Angie Chiang9f45bc42017-01-13 16:27:54 -0800822 ConvolveParams conv_params = get_conv_params(ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700823
824 x = x_base + idx * x_step;
825 y = y_base + idy * y_step;
826
827 dst += dst_buf->stride * y + x;
828
829 if (is_scaled) {
830 pre =
831 pre_buf->buf + scaled_buffer_offset(x, y, pre_buf->stride, sf);
Yaowu Xuf883b422016-08-30 14:01:10 -0700832 scaled_mv = av1_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700833 xs = sf->x_step_q4;
834 ys = sf->y_step_q4;
835 } else {
836 pre = pre_buf->buf + y * pre_buf->stride + x;
837 scaled_mv.row = mv_q4.row;
838 scaled_mv.col = mv_q4.col;
839 xs = ys = 16;
840 }
841
842 subpel_x = scaled_mv.col & SUBPEL_MASK;
843 subpel_y = scaled_mv.row & SUBPEL_MASK;
844 pre += (scaled_mv.row >> SUBPEL_BITS) * pre_buf->stride +
845 (scaled_mv.col >> SUBPEL_BITS);
846
847#if CONFIG_EXT_INTER
Sarah Parker6fdc8532016-11-16 17:47:13 -0800848 if (ref &&
849 is_masked_compound_type(mi->mbmi.interinter_compound_data.type))
Yaowu Xuf883b422016-08-30 14:01:10 -0700850 av1_make_masked_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700851 pre, pre_buf->stride, dst, dst_buf->stride, subpel_x, subpel_y,
852 sf, w, h, mi->mbmi.interp_filter, xs, ys,
853#if CONFIG_SUPERTX
854 wedge_offset_x, wedge_offset_y,
855#endif // CONFIG_SUPERTX
Sarah Parker569edda2016-12-14 14:57:38 -0800856#if CONFIG_COMPOUND_SEGMENT
857 plane,
858#endif // CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -0700859 xd);
860 else
861#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -0700862 av1_make_inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride,
863 subpel_x, subpel_y, sf, x_step, y_step,
Angie Chiang9f45bc42017-01-13 16:27:54 -0800864 &conv_params, mi->mbmi.interp_filter, xs,
865 ys, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700866 }
867 }
868 }
869 return;
870 }
871#endif
872
Angie Chiang907230e2017-01-17 17:39:14 -0800873 {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700874 struct buf_2d *const dst_buf = &pd->dst;
875 uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x;
Angie Chiang907230e2017-01-17 17:39:14 -0800876 uint8_t *pre[2];
877 MV32 scaled_mv[2];
878 SubpelParams subpel_params[2];
Angie Chiang117aa0d2017-01-18 15:27:03 -0800879#if CONVOLVE_POST_ROUNDING
880 int32_t tmp_dst[MAX_SB_SIZE * MAX_SB_SIZE];
881#endif // CONVOLVE_POST_ROUNDING
Angie Chiang907230e2017-01-17 17:39:14 -0800882
883 for (ref = 0; ref < 1 + is_compound; ++ref) {
884 const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
885 struct buf_2d *const pre_buf = &pd->pre[ref];
Jingning Hanb46540c2016-12-14 10:59:20 -0800886#if CONFIG_CB4X4
Angie Chiang907230e2017-01-17 17:39:14 -0800887 const MV mv = mi->mbmi.mv[ref].as_mv;
Jingning Hanb46540c2016-12-14 10:59:20 -0800888#else
Angie Chiang907230e2017-01-17 17:39:14 -0800889 const MV mv =
890 mi->mbmi.sb_type < BLOCK_8X8
Yue Chen894fcce2016-10-21 16:50:52 -0700891#if CONFIG_MOTION_VAR
Angie Chiang907230e2017-01-17 17:39:14 -0800892 ? (build_for_obmc ? mi->bmi[block].as_mv[ref].as_mv
893 : average_split_mvs(pd, mi, ref, block))
Yue Chen894fcce2016-10-21 16:50:52 -0700894#else
Angie Chiang907230e2017-01-17 17:39:14 -0800895 ? average_split_mvs(pd, mi, ref, block)
Yue Chen894fcce2016-10-21 16:50:52 -0700896#endif // CONFIG_MOTION_VAR
Angie Chiang907230e2017-01-17 17:39:14 -0800897 : mi->mbmi.mv[ref].as_mv;
Jingning Hanb46540c2016-12-14 10:59:20 -0800898#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700899
Angie Chiang907230e2017-01-17 17:39:14 -0800900 // TODO(jkoleszar): This clamping is done in the incorrect place for the
901 // scaling case. It needs to be done on the scaled MV, not the pre-scaling
902 // MV. Note however that it performs the subsampling aware scaling so
903 // that the result is always q4.
904 // mv_precision precision is MV_PRECISION_Q4.
905 const MV mv_q4 = clamp_mv_to_umv_border_sb(
906 xd, &mv, bw, bh, pd->subsampling_x, pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700907
Angie Chiang907230e2017-01-17 17:39:14 -0800908 const int is_scaled = av1_is_scaled(sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700909
Angie Chiang907230e2017-01-17 17:39:14 -0800910 if (is_scaled) {
911 pre[ref] =
912 pre_buf->buf + scaled_buffer_offset(x, y, pre_buf->stride, sf);
913 scaled_mv[ref] = av1_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf);
914 subpel_params[ref].xs = sf->x_step_q4;
915 subpel_params[ref].ys = sf->y_step_q4;
916 } else {
917 pre[ref] = pre_buf->buf + (y * pre_buf->stride + x);
918 scaled_mv[ref].row = mv_q4.row;
919 scaled_mv[ref].col = mv_q4.col;
920 subpel_params[ref].xs = 16;
921 subpel_params[ref].ys = 16;
922 }
923
924 subpel_params[ref].subpel_x = scaled_mv[ref].col & SUBPEL_MASK;
925 subpel_params[ref].subpel_y = scaled_mv[ref].row & SUBPEL_MASK;
926 pre[ref] += (scaled_mv[ref].row >> SUBPEL_BITS) * pre_buf->stride +
927 (scaled_mv[ref].col >> SUBPEL_BITS);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700928 }
929
Angie Chiang907230e2017-01-17 17:39:14 -0800930 for (ref = 0; ref < 1 + is_compound; ++ref) {
931 const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
Angie Chiang907230e2017-01-17 17:39:14 -0800932 struct buf_2d *const pre_buf = &pd->pre[ref];
Angie Chiang117aa0d2017-01-18 15:27:03 -0800933#if CONVOLVE_POST_ROUNDING
934 ConvolveParams conv_params =
935 get_conv_params_no_round(ref, tmp_dst, MAX_SB_SIZE);
936#else
937 ConvolveParams conv_params = get_conv_params(ref);
938#endif // CONVOLVE_POST_ROUNDING
Yaowu Xuc27fc142016-08-22 16:08:15 -0700939#if CONFIG_EXT_INTER
Angie Chiang907230e2017-01-17 17:39:14 -0800940 if (ref &&
941 is_masked_compound_type(mi->mbmi.interinter_compound_data.type))
942 av1_make_masked_inter_predictor(
943 pre[ref], pre_buf->stride, dst, dst_buf->stride,
944 subpel_params[ref].subpel_x, subpel_params[ref].subpel_y, sf, w, h,
945 mi->mbmi.interp_filter, subpel_params[ref].xs,
946 subpel_params[ref].ys,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700947#if CONFIG_SUPERTX
Angie Chiang907230e2017-01-17 17:39:14 -0800948 wedge_offset_x, wedge_offset_y,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700949#endif // CONFIG_SUPERTX
Sarah Parker569edda2016-12-14 14:57:38 -0800950#if CONFIG_COMPOUND_SEGMENT
Angie Chiang907230e2017-01-17 17:39:14 -0800951 plane,
Sarah Parker569edda2016-12-14 14:57:38 -0800952#endif // CONFIG_COMPOUND_SEGMENT
Angie Chiang907230e2017-01-17 17:39:14 -0800953 xd);
954 else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700955#else // CONFIG_EXT_INTER
956#if CONFIG_GLOBAL_MOTION
Angie Chiang907230e2017-01-17 17:39:14 -0800957 if (is_global[ref])
958 av1_warp_plane(gm[ref],
Yaowu Xuf883b422016-08-30 14:01:10 -0700959#if CONFIG_AOM_HIGHBITDEPTH
Angie Chiang907230e2017-01-17 17:39:14 -0800960 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
Yaowu Xuf883b422016-08-30 14:01:10 -0700961#endif // CONFIG_AOM_HIGHBITDEPTH
Angie Chiang907230e2017-01-17 17:39:14 -0800962 pre_buf->buf0, pre_buf->width, pre_buf->height,
963 pre_buf->stride, dst, (mi_x >> pd->subsampling_x) + x,
964 (mi_y >> pd->subsampling_y) + y, w, h, dst_buf->stride,
965 pd->subsampling_x, pd->subsampling_y,
966 subpel_params[ref].xs, subpel_params[ref].ys, ref);
967 else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700968#endif // CONFIG_GLOBAL_MOTION
969#endif // CONFIG_EXT_INTER
Angie Chiang907230e2017-01-17 17:39:14 -0800970 av1_make_inter_predictor(
971 pre[ref], pre_buf->stride, dst, dst_buf->stride,
972 subpel_params[ref].subpel_x, subpel_params[ref].subpel_y, sf, w, h,
973 &conv_params, mi->mbmi.interp_filter, subpel_params[ref].xs,
974 subpel_params[ref].ys, xd);
975 }
Angie Chiang117aa0d2017-01-18 15:27:03 -0800976
977#if CONVOLVE_POST_ROUNDING
Angie Chiang54294192017-01-20 17:27:13 -0800978// TODO(angiebird): This part needs optimization
979#if CONFIG_AOM_HIGHBITDEPTH
980 if (!(xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH))
981 av1_convolve_rounding(tmp_dst, MAX_SB_SIZE, dst, dst_buf->stride, w, h);
982#else
Angie Chiang117aa0d2017-01-18 15:27:03 -0800983 av1_convolve_rounding(tmp_dst, MAX_SB_SIZE, dst, dst_buf->stride, w, h);
Angie Chiang54294192017-01-20 17:27:13 -0800984#endif
Angie Chiang117aa0d2017-01-18 15:27:03 -0800985#endif // CONVOLVE_POST_ROUNDING
Yaowu Xuc27fc142016-08-22 16:08:15 -0700986 }
987}
988
Yaowu Xuf883b422016-08-30 14:01:10 -0700989void av1_build_inter_predictor_sub8x8(MACROBLOCKD *xd, int plane, int i, int ir,
990 int ic, int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700991 struct macroblockd_plane *const pd = &xd->plane[plane];
992 MODE_INFO *const mi = xd->mi[0];
993 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
Jingning Hanae5cfde2016-11-30 12:01:44 -0800994 const int width = block_size_wide[plane_bsize];
995 const int height = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700996 uint8_t *const dst = &pd->dst.buf[(ir * pd->dst.stride + ic) << 2];
997 int ref;
998 const int is_compound = has_second_ref(&mi->mbmi);
999
1000 for (ref = 0; ref < 1 + is_compound; ++ref) {
Angie Chiang9f45bc42017-01-13 16:27:54 -08001001 ConvolveParams conv_params = get_conv_params(ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001002 const uint8_t *pre =
1003 &pd->pre[ref].buf[(ir * pd->pre[ref].stride + ic) << 2];
Yaowu Xuf883b422016-08-30 14:01:10 -07001004#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001005 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001006 av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001007 pre, pd->pre[ref].stride, dst, pd->dst.stride,
1008 &mi->bmi[i].as_mv[ref].as_mv, &xd->block_refs[ref]->sf, width, height,
1009 ref, mi->mbmi.interp_filter, MV_PRECISION_Q3,
1010 mi_col * MI_SIZE + 4 * ic, mi_row * MI_SIZE + 4 * ir, xd->bd);
1011 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001012 av1_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001013 pre, pd->pre[ref].stride, dst, pd->dst.stride,
1014 &mi->bmi[i].as_mv[ref].as_mv, &xd->block_refs[ref]->sf, width, height,
Angie Chiang9f45bc42017-01-13 16:27:54 -08001015 &conv_params, mi->mbmi.interp_filter, MV_PRECISION_Q3,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001016 mi_col * MI_SIZE + 4 * ic, mi_row * MI_SIZE + 4 * ir);
1017 }
1018#else
Yaowu Xuf883b422016-08-30 14:01:10 -07001019 av1_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001020 pre, pd->pre[ref].stride, dst, pd->dst.stride,
1021 &mi->bmi[i].as_mv[ref].as_mv, &xd->block_refs[ref]->sf, width, height,
Angie Chiang9f45bc42017-01-13 16:27:54 -08001022 &conv_params, mi->mbmi.interp_filter, MV_PRECISION_Q3,
1023 mi_col * MI_SIZE + 4 * ic, mi_row * MI_SIZE + 4 * ir);
Yaowu Xuf883b422016-08-30 14:01:10 -07001024#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001025 }
1026}
1027
1028static void build_inter_predictors_for_planes(MACROBLOCKD *xd, BLOCK_SIZE bsize,
1029 int mi_row, int mi_col,
1030 int plane_from, int plane_to) {
1031 int plane;
1032 const int mi_x = mi_col * MI_SIZE;
1033 const int mi_y = mi_row * MI_SIZE;
Jingning Hanb46540c2016-12-14 10:59:20 -08001034#if CONFIG_CB4X4
1035 const int unify_bsize = 1;
1036#else
1037 const int unify_bsize = 0;
1038#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001039 for (plane = plane_from; plane <= plane_to; ++plane) {
1040 const struct macroblockd_plane *pd = &xd->plane[plane];
Jingning Hanae5cfde2016-11-30 12:01:44 -08001041 const int bw = block_size_wide[bsize] >> pd->subsampling_x;
1042 const int bh = block_size_high[bsize] >> pd->subsampling_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001043
Jingning Hanb46540c2016-12-14 10:59:20 -08001044 if (xd->mi[0]->mbmi.sb_type < BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001045 const PARTITION_TYPE bp = bsize - xd->mi[0]->mbmi.sb_type;
1046 const int have_vsplit = bp != PARTITION_HORZ;
1047 const int have_hsplit = bp != PARTITION_VERT;
1048 const int num_4x4_w = 2 >> ((!have_vsplit) | pd->subsampling_x);
1049 const int num_4x4_h = 2 >> ((!have_hsplit) | pd->subsampling_y);
1050 const int pw = 8 >> (have_vsplit | pd->subsampling_x);
1051 const int ph = 8 >> (have_hsplit | pd->subsampling_y);
1052 int x, y;
1053 assert(bp != PARTITION_NONE && bp < PARTITION_TYPES);
1054 assert(bsize == BLOCK_8X8);
1055 assert(pw * num_4x4_w == bw && ph * num_4x4_h == bh);
1056 for (y = 0; y < num_4x4_h; ++y)
1057 for (x = 0; x < num_4x4_w; ++x)
1058 build_inter_predictors(xd, plane,
Yue Chencb60b182016-10-13 15:18:22 -07001059#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001060 0, 0,
Yue Chencb60b182016-10-13 15:18:22 -07001061#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001062 y * 2 + x, bw, bh, 4 * x, 4 * y, pw, ph,
1063#if CONFIG_SUPERTX && CONFIG_EXT_INTER
1064 0, 0,
1065#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
1066 mi_x, mi_y);
1067 } else {
1068 build_inter_predictors(xd, plane,
Yue Chencb60b182016-10-13 15:18:22 -07001069#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001070 0, 0,
Yue Chencb60b182016-10-13 15:18:22 -07001071#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001072 0, bw, bh, 0, 0, bw, bh,
1073#if CONFIG_SUPERTX && CONFIG_EXT_INTER
1074 0, 0,
1075#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
1076 mi_x, mi_y);
1077 }
1078 }
1079}
1080
Yaowu Xuf883b422016-08-30 14:01:10 -07001081void av1_build_inter_predictors_sby(MACROBLOCKD *xd, int mi_row, int mi_col,
David Barkerac37fa32016-12-02 12:30:21 +00001082 BUFFER_SET *ctx, BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001083 build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 0, 0);
1084#if CONFIG_EXT_INTER
David Barkerac37fa32016-12-02 12:30:21 +00001085 if (is_interintra_pred(&xd->mi[0]->mbmi)) {
1086 BUFFER_SET default_ctx = { { xd->plane[0].dst.buf, NULL, NULL },
1087 { xd->plane[0].dst.stride, 0, 0 } };
1088 if (!ctx) ctx = &default_ctx;
Yaowu Xuf883b422016-08-30 14:01:10 -07001089 av1_build_interintra_predictors_sby(xd, xd->plane[0].dst.buf,
David Barkerac37fa32016-12-02 12:30:21 +00001090 xd->plane[0].dst.stride, ctx, bsize);
1091 }
1092#else
1093 (void)ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001094#endif // CONFIG_EXT_INTER
1095}
1096
Yaowu Xuf883b422016-08-30 14:01:10 -07001097void av1_build_inter_predictors_sbp(MACROBLOCKD *xd, int mi_row, int mi_col,
David Barkerac37fa32016-12-02 12:30:21 +00001098 BUFFER_SET *ctx, BLOCK_SIZE bsize,
1099 int plane) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001100 build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, plane, plane);
1101#if CONFIG_EXT_INTER
1102 if (is_interintra_pred(&xd->mi[0]->mbmi)) {
David Barkerac37fa32016-12-02 12:30:21 +00001103 BUFFER_SET default_ctx = {
1104 { xd->plane[0].dst.buf, xd->plane[1].dst.buf, xd->plane[2].dst.buf },
1105 { xd->plane[0].dst.stride, xd->plane[1].dst.stride,
1106 xd->plane[2].dst.stride }
1107 };
1108 if (!ctx) ctx = &default_ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001109 if (plane == 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001110 av1_build_interintra_predictors_sby(xd, xd->plane[0].dst.buf,
David Barkerac37fa32016-12-02 12:30:21 +00001111 xd->plane[0].dst.stride, ctx, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001112 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001113 av1_build_interintra_predictors_sbc(xd, xd->plane[plane].dst.buf,
David Barkerac37fa32016-12-02 12:30:21 +00001114 xd->plane[plane].dst.stride, ctx,
1115 plane, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001116 }
1117 }
David Barkerac37fa32016-12-02 12:30:21 +00001118#else
1119 (void)ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001120#endif // CONFIG_EXT_INTER
1121}
1122
Yaowu Xuf883b422016-08-30 14:01:10 -07001123void av1_build_inter_predictors_sbuv(MACROBLOCKD *xd, int mi_row, int mi_col,
David Barkerac37fa32016-12-02 12:30:21 +00001124 BUFFER_SET *ctx, BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001125 build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 1,
1126 MAX_MB_PLANE - 1);
1127#if CONFIG_EXT_INTER
David Barkerac37fa32016-12-02 12:30:21 +00001128 if (is_interintra_pred(&xd->mi[0]->mbmi)) {
1129 BUFFER_SET default_ctx = {
1130 { NULL, xd->plane[1].dst.buf, xd->plane[2].dst.buf },
1131 { 0, xd->plane[1].dst.stride, xd->plane[2].dst.stride }
1132 };
1133 if (!ctx) ctx = &default_ctx;
Yaowu Xuf883b422016-08-30 14:01:10 -07001134 av1_build_interintra_predictors_sbuv(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001135 xd, xd->plane[1].dst.buf, xd->plane[2].dst.buf, xd->plane[1].dst.stride,
David Barkerac37fa32016-12-02 12:30:21 +00001136 xd->plane[2].dst.stride, ctx, bsize);
1137 }
1138#else
1139 (void)ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001140#endif // CONFIG_EXT_INTER
1141}
1142
Yaowu Xuf883b422016-08-30 14:01:10 -07001143void av1_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col,
David Barkerac37fa32016-12-02 12:30:21 +00001144 BUFFER_SET *ctx, BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001145 build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 0,
1146 MAX_MB_PLANE - 1);
1147#if CONFIG_EXT_INTER
David Barkerac37fa32016-12-02 12:30:21 +00001148 if (is_interintra_pred(&xd->mi[0]->mbmi)) {
1149 BUFFER_SET default_ctx = {
1150 { xd->plane[0].dst.buf, xd->plane[1].dst.buf, xd->plane[2].dst.buf },
1151 { xd->plane[0].dst.stride, xd->plane[1].dst.stride,
1152 xd->plane[2].dst.stride }
1153 };
1154 if (!ctx) ctx = &default_ctx;
Yaowu Xuf883b422016-08-30 14:01:10 -07001155 av1_build_interintra_predictors(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001156 xd, xd->plane[0].dst.buf, xd->plane[1].dst.buf, xd->plane[2].dst.buf,
1157 xd->plane[0].dst.stride, xd->plane[1].dst.stride,
David Barkerac37fa32016-12-02 12:30:21 +00001158 xd->plane[2].dst.stride, ctx, bsize);
1159 }
1160#else
1161 (void)ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001162#endif // CONFIG_EXT_INTER
1163}
1164
Yaowu Xuf883b422016-08-30 14:01:10 -07001165void av1_setup_dst_planes(struct macroblockd_plane planes[MAX_MB_PLANE],
1166 const YV12_BUFFER_CONFIG *src, int mi_row,
1167 int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001168 uint8_t *const buffers[MAX_MB_PLANE] = { src->y_buffer, src->u_buffer,
1169 src->v_buffer };
1170 const int widths[MAX_MB_PLANE] = { src->y_crop_width, src->uv_crop_width,
1171 src->uv_crop_width };
1172 const int heights[MAX_MB_PLANE] = { src->y_crop_height, src->uv_crop_height,
1173 src->uv_crop_height };
1174 const int strides[MAX_MB_PLANE] = { src->y_stride, src->uv_stride,
1175 src->uv_stride };
1176 int i;
1177
1178 for (i = 0; i < MAX_MB_PLANE; ++i) {
1179 struct macroblockd_plane *const pd = &planes[i];
1180 setup_pred_plane(&pd->dst, buffers[i], widths[i], heights[i], strides[i],
1181 mi_row, mi_col, NULL, pd->subsampling_x,
1182 pd->subsampling_y);
1183 }
1184}
1185
Yaowu Xuf883b422016-08-30 14:01:10 -07001186void av1_setup_pre_planes(MACROBLOCKD *xd, int idx,
1187 const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col,
1188 const struct scale_factors *sf) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001189 if (src != NULL) {
1190 int i;
1191 uint8_t *const buffers[MAX_MB_PLANE] = { src->y_buffer, src->u_buffer,
1192 src->v_buffer };
1193 const int widths[MAX_MB_PLANE] = { src->y_crop_width, src->uv_crop_width,
1194 src->uv_crop_width };
1195 const int heights[MAX_MB_PLANE] = { src->y_crop_height, src->uv_crop_height,
1196 src->uv_crop_height };
1197 const int strides[MAX_MB_PLANE] = { src->y_stride, src->uv_stride,
1198 src->uv_stride };
1199 for (i = 0; i < MAX_MB_PLANE; ++i) {
1200 struct macroblockd_plane *const pd = &xd->plane[i];
1201 setup_pred_plane(&pd->pre[idx], buffers[i], widths[i], heights[i],
1202 strides[i], mi_row, mi_col, sf, pd->subsampling_x,
1203 pd->subsampling_y);
1204 }
1205 }
1206}
1207
1208#if CONFIG_SUPERTX
Jingning Hanfeb517c2016-12-21 16:02:07 -08001209#if CONFIG_CB4X4
Jingning Han9e0976a2016-12-27 17:52:42 -08001210static const uint8_t mask_4[4] = { 64, 52, 12, 0 };
1211static const uint8_t mask_4_uv[4] = { 64, 52, 12, 0 };
Jingning Hanfeb517c2016-12-21 16:02:07 -08001212#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07001213static const uint8_t mask_8[8] = { 64, 64, 62, 52, 12, 2, 0, 0 };
1214
1215static const uint8_t mask_16[16] = { 63, 62, 60, 58, 55, 50, 43, 36,
1216 28, 21, 14, 9, 6, 4, 2, 1 };
1217
1218static const uint8_t mask_32[32] = { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 63,
1219 61, 57, 52, 45, 36, 28, 19, 12, 7, 3, 1,
1220 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1221
1222static const uint8_t mask_8_uv[8] = { 64, 64, 62, 52, 12, 2, 0, 0 };
1223
1224static const uint8_t mask_16_uv[16] = { 64, 64, 64, 64, 61, 53, 45, 36,
1225 28, 19, 11, 3, 0, 0, 0, 0 };
1226
1227static const uint8_t mask_32_uv[32] = { 64, 64, 64, 64, 64, 64, 64, 64,
1228 64, 64, 64, 64, 60, 54, 46, 36,
1229 28, 18, 10, 4, 0, 0, 0, 0,
1230 0, 0, 0, 0, 0, 0, 0, 0 };
1231
1232static const uint8_t *get_supertx_mask(int length, int plane) {
1233 switch (length) {
Jingning Hanfeb517c2016-12-21 16:02:07 -08001234#if CONFIG_CB4X4
1235 case 4: return plane ? mask_4_uv : mask_4;
1236#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07001237 case 8: return plane ? mask_8_uv : mask_8;
1238 case 16: return plane ? mask_16_uv : mask_16;
1239 case 32: return plane ? mask_32_uv : mask_32;
1240 default: assert(0);
1241 }
1242 return NULL;
1243}
1244
Yaowu Xuf883b422016-08-30 14:01:10 -07001245void av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001246 MACROBLOCKD *xd, uint8_t *dst, int dst_stride, const uint8_t *pre,
1247 int pre_stride, int mi_row, int mi_col, int mi_row_ori, int mi_col_ori,
1248 BLOCK_SIZE bsize, BLOCK_SIZE top_bsize, PARTITION_TYPE partition,
1249 int plane) {
1250 const struct macroblockd_plane *pd = &xd->plane[plane];
1251 const int ssx = pd->subsampling_x;
1252 const int ssy = pd->subsampling_y;
Jingning Han93531242016-12-20 11:54:36 -08001253 const int top_w = block_size_wide[top_bsize] >> ssx;
1254 const int top_h = block_size_high[top_bsize] >> ssy;
1255 const int w = block_size_wide[bsize] >> ssx;
1256 const int h = block_size_high[bsize] >> ssy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001257 const int w_offset = ((mi_col - mi_col_ori) * MI_SIZE) >> ssx;
1258 const int h_offset = ((mi_row - mi_row_ori) * MI_SIZE) >> ssy;
1259
1260 int w_remain, h_remain;
1261
Yaowu Xuf883b422016-08-30 14:01:10 -07001262#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001263 const int is_hdb = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07001264#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001265
1266 assert(bsize <= BLOCK_32X32);
1267 assert(IMPLIES(plane == 0, ssx == 0));
1268 assert(IMPLIES(plane == 0, ssy == 0));
1269
1270 switch (partition) {
1271 case PARTITION_HORZ: {
1272 const uint8_t *const mask = get_supertx_mask(h, ssy);
1273
1274 w_remain = top_w;
1275 h_remain = top_h - h_offset - h;
1276 dst += h_offset * dst_stride;
1277 pre += h_offset * pre_stride;
1278
Yaowu Xuf883b422016-08-30 14:01:10 -07001279#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001280 if (is_hdb)
Yaowu Xuf883b422016-08-30 14:01:10 -07001281 aom_highbd_blend_a64_vmask(dst, dst_stride, dst, dst_stride, pre,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001282 pre_stride, mask, h, top_w, xd->bd);
1283 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001284#endif // CONFIG_AOM_HIGHBITDEPTH
1285 aom_blend_a64_vmask(dst, dst_stride, dst, dst_stride, pre, pre_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001286 mask, h, top_w);
1287
1288 dst += h * dst_stride;
1289 pre += h * pre_stride;
1290 break;
1291 }
1292 case PARTITION_VERT: {
1293 const uint8_t *const mask = get_supertx_mask(w, ssx);
1294
1295 w_remain = top_w - w_offset - w;
1296 h_remain = top_h;
1297 dst += w_offset;
1298 pre += w_offset;
1299
Yaowu Xuf883b422016-08-30 14:01:10 -07001300#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001301 if (is_hdb)
Yaowu Xuf883b422016-08-30 14:01:10 -07001302 aom_highbd_blend_a64_hmask(dst, dst_stride, dst, dst_stride, pre,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001303 pre_stride, mask, top_h, w, xd->bd);
1304 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001305#endif // CONFIG_AOM_HIGHBITDEPTH
1306 aom_blend_a64_hmask(dst, dst_stride, dst, dst_stride, pre, pre_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001307 mask, top_h, w);
1308
1309 dst += w;
1310 pre += w;
1311 break;
1312 }
1313 default: {
1314 assert(0);
1315 return;
1316 }
1317 }
1318
1319 if (w_remain == 0 || h_remain == 0) {
1320 return;
1321 }
1322
Yaowu Xuf883b422016-08-30 14:01:10 -07001323#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001324 if (is_hdb) {
1325 dst = (uint8_t *)CONVERT_TO_SHORTPTR(dst);
1326 pre = (const uint8_t *)CONVERT_TO_SHORTPTR(pre);
1327 dst_stride *= 2;
1328 pre_stride *= 2;
1329 w_remain *= 2;
1330 }
Yaowu Xuf883b422016-08-30 14:01:10 -07001331#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001332
1333 do {
1334 memcpy(dst, pre, w_remain * sizeof(uint8_t));
1335 dst += dst_stride;
1336 pre += pre_stride;
1337 } while (--h_remain);
1338}
1339
Yaowu Xuf883b422016-08-30 14:01:10 -07001340void av1_build_inter_predictors_sb_sub8x8_extend(MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001341#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07001342 int mi_row_ori, int mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001343#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07001344 int mi_row, int mi_col,
1345 BLOCK_SIZE bsize, int block) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001346 // Prediction function used in supertx:
1347 // Use the mv at current block (which is less than 8x8)
1348 // to get prediction of a block located at (mi_row, mi_col) at size of bsize
1349 // bsize can be larger than 8x8.
1350 // block (0-3): the sub8x8 location of current block
1351 int plane;
1352 const int mi_x = mi_col * MI_SIZE;
1353 const int mi_y = mi_row * MI_SIZE;
1354#if CONFIG_EXT_INTER
1355 const int wedge_offset_x = (mi_col_ori - mi_col) * MI_SIZE;
1356 const int wedge_offset_y = (mi_row_ori - mi_row) * MI_SIZE;
1357#endif // CONFIG_EXT_INTER
1358
1359 // For sub8x8 uv:
1360 // Skip uv prediction in supertx except the first block (block = 0)
1361 int max_plane = block ? 1 : MAX_MB_PLANE;
1362
1363 for (plane = 0; plane < max_plane; plane++) {
1364 const BLOCK_SIZE plane_bsize =
1365 get_plane_block_size(bsize, &xd->plane[plane]);
1366 const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize];
1367 const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize];
1368 const int bw = 4 * num_4x4_w;
1369 const int bh = 4 * num_4x4_h;
1370
1371 build_inter_predictors(xd, plane,
Yue Chencb60b182016-10-13 15:18:22 -07001372#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001373 0, 0,
Yue Chencb60b182016-10-13 15:18:22 -07001374#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001375 block, bw, bh, 0, 0, bw, bh,
1376#if CONFIG_EXT_INTER
1377 wedge_offset_x, wedge_offset_y,
1378#endif // CONFIG_EXT_INTER
1379 mi_x, mi_y);
1380 }
1381#if CONFIG_EXT_INTER
Yaowu Xuf4c904c2016-12-07 11:18:27 -08001382 if (is_interintra_pred(&xd->mi[0]->mbmi)) {
1383 BUFFER_SET ctx = { { xd->plane[0].dst.buf, xd->plane[1].dst.buf,
1384 xd->plane[2].dst.buf },
1385 { xd->plane[0].dst.stride, xd->plane[1].dst.stride,
1386 xd->plane[2].dst.stride } };
Yaowu Xuf883b422016-08-30 14:01:10 -07001387 av1_build_interintra_predictors(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001388 xd, xd->plane[0].dst.buf, xd->plane[1].dst.buf, xd->plane[2].dst.buf,
1389 xd->plane[0].dst.stride, xd->plane[1].dst.stride,
David Barkerac37fa32016-12-02 12:30:21 +00001390 xd->plane[2].dst.stride, &ctx, bsize);
Yaowu Xuf4c904c2016-12-07 11:18:27 -08001391 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001392#endif // CONFIG_EXT_INTER
1393}
1394
Yaowu Xuf883b422016-08-30 14:01:10 -07001395void av1_build_inter_predictors_sb_extend(MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001396#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07001397 int mi_row_ori, int mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001398#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07001399 int mi_row, int mi_col,
1400 BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001401 int plane;
1402 const int mi_x = mi_col * MI_SIZE;
1403 const int mi_y = mi_row * MI_SIZE;
1404#if CONFIG_EXT_INTER
1405 const int wedge_offset_x = (mi_col_ori - mi_col) * MI_SIZE;
1406 const int wedge_offset_y = (mi_row_ori - mi_row) * MI_SIZE;
1407#endif // CONFIG_EXT_INTER
1408 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
1409 const BLOCK_SIZE plane_bsize =
1410 get_plane_block_size(bsize, &xd->plane[plane]);
Jingning Hanae5cfde2016-11-30 12:01:44 -08001411 const int bw = block_size_wide[plane_bsize];
1412 const int bh = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001413
Jingning Han002c8142016-12-20 15:07:58 -08001414 build_inter_predictors(xd, plane,
Yue Chencb60b182016-10-13 15:18:22 -07001415#if CONFIG_MOTION_VAR
Jingning Han002c8142016-12-20 15:07:58 -08001416 0, 0,
Yue Chencb60b182016-10-13 15:18:22 -07001417#endif // CONFIG_MOTION_VAR
Jingning Han002c8142016-12-20 15:07:58 -08001418 0, bw, bh, 0, 0, bw, bh,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001419#if CONFIG_EXT_INTER
Jingning Han002c8142016-12-20 15:07:58 -08001420 wedge_offset_x, wedge_offset_y,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001421#endif // CONFIG_EXT_INTER
Jingning Han002c8142016-12-20 15:07:58 -08001422 mi_x, mi_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001423 }
1424}
1425#endif // CONFIG_SUPERTX
1426
Yue Chencb60b182016-10-13 15:18:22 -07001427#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001428// obmc_mask_N[overlap_position]
1429static const uint8_t obmc_mask_1[1] = { 55 };
1430
1431static const uint8_t obmc_mask_2[2] = { 45, 62 };
1432
1433static const uint8_t obmc_mask_4[4] = { 39, 50, 59, 64 };
1434
1435static const uint8_t obmc_mask_8[8] = { 36, 42, 48, 53, 57, 61, 63, 64 };
1436
1437static const uint8_t obmc_mask_16[16] = { 34, 37, 40, 43, 46, 49, 52, 54,
1438 56, 58, 60, 61, 63, 64, 64, 64 };
1439
1440static const uint8_t obmc_mask_32[32] = { 33, 35, 36, 38, 40, 41, 43, 44,
1441 45, 47, 48, 50, 51, 52, 53, 55,
1442 56, 57, 58, 59, 60, 60, 61, 62,
1443 62, 63, 63, 64, 64, 64, 64, 64 };
1444
1445#if CONFIG_EXT_PARTITION
1446static const uint8_t obmc_mask_64[64] = {
1447 33, 34, 35, 35, 36, 37, 38, 39, 40, 40, 41, 42, 43, 44, 44, 44,
1448 45, 46, 47, 47, 48, 49, 50, 51, 51, 51, 52, 52, 53, 54, 55, 56,
1449 56, 56, 57, 57, 58, 58, 59, 60, 60, 60, 60, 60, 61, 62, 62, 62,
1450 62, 62, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
1451};
1452#endif // CONFIG_EXT_PARTITION
1453
Yaowu Xuf883b422016-08-30 14:01:10 -07001454const uint8_t *av1_get_obmc_mask(int length) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001455 switch (length) {
1456 case 1: return obmc_mask_1;
1457 case 2: return obmc_mask_2;
1458 case 4: return obmc_mask_4;
1459 case 8: return obmc_mask_8;
1460 case 16: return obmc_mask_16;
1461 case 32: return obmc_mask_32;
1462#if CONFIG_EXT_PARTITION
1463 case 64: return obmc_mask_64;
1464#endif // CONFIG_EXT_PARTITION
1465 default: assert(0); return NULL;
1466 }
1467}
1468
Yue Chen86ae7b12017-01-11 17:04:29 -08001469#if CONFIG_NCOBMC
1470// obmc_mask_flipN[overlap_position]
1471static const uint8_t obmc_mask_flip1[1] = { 55 };
1472
1473static const uint8_t obmc_mask_flip2[2] = { 62, 45 };
1474
1475static const uint8_t obmc_mask_flip4[4] = { 64, 59, 50, 39 };
1476
1477static const uint8_t obmc_mask_flip8[8] = { 64, 63, 61, 57, 53, 48, 42, 36 };
1478
1479static const uint8_t obmc_mask_flip16[16] = { 64, 64, 64, 63, 61, 60, 58, 56,
1480 54, 52, 49, 46, 43, 40, 37, 34 };
1481
1482static const uint8_t obmc_mask_flip32[32] = { 64, 64, 64, 64, 64, 63, 63, 62,
1483 62, 61, 60, 60, 59, 58, 57, 56,
1484 55, 53, 52, 51, 50, 48, 47, 45,
1485 44, 43, 41, 40, 38, 36, 35, 33 };
1486
1487#if CONFIG_EXT_PARTITION
1488static const uint8_t obmc_mask_flip64[64] = {
1489 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 63, 63, 63, 63, 62, 62,
1490 62, 62, 62, 61, 60, 60, 60, 60, 60, 59, 58, 58, 57, 57, 56, 56,
1491 56, 55, 54, 53, 52, 52, 51, 51, 51, 50, 49, 48, 47, 47, 46, 45,
1492 44, 44, 44, 43, 42, 41, 40, 40, 39, 38, 37, 36, 35, 35, 34, 33,
1493};
1494#endif // CONFIG_EXT_PARTITION
1495
1496const uint8_t *av1_get_obmc_mask_flipped(int length) {
1497 switch (length) {
1498 case 1: return obmc_mask_flip1;
1499 case 2: return obmc_mask_flip2;
1500 case 4: return obmc_mask_flip4;
1501 case 8: return obmc_mask_flip8;
1502 case 16: return obmc_mask_flip16;
1503 case 32: return obmc_mask_flip32;
1504#if CONFIG_EXT_PARTITION
1505 case 64: return obmc_mask_flip64;
1506#endif // CONFIG_EXT_PARTITION
1507 default: assert(0); return NULL;
1508 }
1509}
1510#endif // CONFIG_NCOBMC
1511
Yaowu Xuc27fc142016-08-22 16:08:15 -07001512// This function combines motion compensated predictions that is generated by
1513// top/left neighboring blocks' inter predictors with the regular inter
1514// prediction. We assume the original prediction (bmc) is stored in
1515// xd->plane[].dst.buf
Urvang Joshi52648442016-10-13 17:27:51 -07001516void av1_build_obmc_inter_prediction(const AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xuf883b422016-08-30 14:01:10 -07001517 int mi_row, int mi_col,
1518 uint8_t *above[MAX_MB_PLANE],
1519 int above_stride[MAX_MB_PLANE],
1520 uint8_t *left[MAX_MB_PLANE],
1521 int left_stride[MAX_MB_PLANE]) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001522 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
1523 int plane, i;
Yaowu Xuf883b422016-08-30 14:01:10 -07001524#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001525 const int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07001526#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001527
1528 // handle above row
1529 if (xd->up_available) {
1530 const int overlap = num_4x4_blocks_high_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -07001531 const int miw = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001532 const int mi_row_offset = -1;
1533
1534 assert(miw > 0);
1535
1536 i = 0;
1537 do { // for each mi in the above row
1538 const int mi_col_offset = i;
1539 const MB_MODE_INFO *const above_mbmi =
1540 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
Jingning Han51ec5052017-01-18 16:27:57 -08001541 const int mi_step = AOMMIN(xd->n8_w, mi_size_wide[above_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001542
1543 if (is_neighbor_overlappable(above_mbmi)) {
1544 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
1545 const struct macroblockd_plane *pd = &xd->plane[plane];
1546 const int bw = (mi_step * MI_SIZE) >> pd->subsampling_x;
1547 const int bh = overlap >> pd->subsampling_y;
1548 const int dst_stride = pd->dst.stride;
1549 uint8_t *const dst = &pd->dst.buf[(i * MI_SIZE) >> pd->subsampling_x];
1550 const int tmp_stride = above_stride[plane];
1551 const uint8_t *const tmp =
1552 &above[plane][(i * MI_SIZE) >> pd->subsampling_x];
Yaowu Xuf883b422016-08-30 14:01:10 -07001553 const uint8_t *const mask = av1_get_obmc_mask(bh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001554
Yaowu Xuf883b422016-08-30 14:01:10 -07001555#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001556 if (is_hbd)
Yaowu Xuf883b422016-08-30 14:01:10 -07001557 aom_highbd_blend_a64_vmask(dst, dst_stride, dst, dst_stride, tmp,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001558 tmp_stride, mask, bh, bw, xd->bd);
1559 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001560#endif // CONFIG_AOM_HIGHBITDEPTH
1561 aom_blend_a64_vmask(dst, dst_stride, dst, dst_stride, tmp,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001562 tmp_stride, mask, bh, bw);
1563 }
1564 }
1565 i += mi_step;
1566 } while (i < miw);
1567 }
1568
1569 // handle left column
1570 if (xd->left_available) {
1571 const int overlap = num_4x4_blocks_wide_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -07001572 const int mih = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001573 const int mi_col_offset = -1;
1574
1575 assert(mih > 0);
1576
1577 i = 0;
1578 do { // for each mi in the left column
1579 const int mi_row_offset = i;
1580 const MB_MODE_INFO *const left_mbmi =
1581 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
Jingning Han51ec5052017-01-18 16:27:57 -08001582 const int mi_step = AOMMIN(xd->n8_h, mi_size_high[left_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001583
1584 if (is_neighbor_overlappable(left_mbmi)) {
1585 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
1586 const struct macroblockd_plane *pd = &xd->plane[plane];
1587 const int bw = overlap >> pd->subsampling_x;
1588 const int bh = (mi_step * MI_SIZE) >> pd->subsampling_y;
1589 const int dst_stride = pd->dst.stride;
1590 uint8_t *const dst =
1591 &pd->dst.buf[(i * MI_SIZE * dst_stride) >> pd->subsampling_y];
1592 const int tmp_stride = left_stride[plane];
1593 const uint8_t *const tmp =
1594 &left[plane][(i * MI_SIZE * tmp_stride) >> pd->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07001595 const uint8_t *const mask = av1_get_obmc_mask(bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001596
Yaowu Xuf883b422016-08-30 14:01:10 -07001597#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001598 if (is_hbd)
Yaowu Xuf883b422016-08-30 14:01:10 -07001599 aom_highbd_blend_a64_hmask(dst, dst_stride, dst, dst_stride, tmp,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001600 tmp_stride, mask, bh, bw, xd->bd);
1601 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001602#endif // CONFIG_AOM_HIGHBITDEPTH
1603 aom_blend_a64_hmask(dst, dst_stride, dst, dst_stride, tmp,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001604 tmp_stride, mask, bh, bw);
1605 }
1606 }
1607 i += mi_step;
1608 } while (i < mih);
1609 }
1610}
1611
1612#if CONFIG_EXT_INTER
1613void modify_neighbor_predictor_for_obmc(MB_MODE_INFO *mbmi) {
1614 if (is_interintra_pred(mbmi)) {
Emil Keyder01770b32017-01-20 18:03:11 -05001615 mbmi->ref_frame[1] = NONE_FRAME;
Sarah Parker6fdc8532016-11-16 17:47:13 -08001616 } else if (has_second_ref(mbmi) &&
1617 is_masked_compound_type(mbmi->interinter_compound_data.type)) {
1618 mbmi->interinter_compound_data.type = COMPOUND_AVERAGE;
Emil Keyder01770b32017-01-20 18:03:11 -05001619 mbmi->ref_frame[1] = NONE_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001620 }
1621 return;
1622}
1623#endif // CONFIG_EXT_INTER
1624
Urvang Joshi52648442016-10-13 17:27:51 -07001625void av1_build_prediction_by_above_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xuf883b422016-08-30 14:01:10 -07001626 int mi_row, int mi_col,
1627 uint8_t *tmp_buf[MAX_MB_PLANE],
1628 int tmp_width[MAX_MB_PLANE],
1629 int tmp_height[MAX_MB_PLANE],
1630 int tmp_stride[MAX_MB_PLANE]) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001631 const TileInfo *const tile = &xd->tile;
1632 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
1633 int i, j, mi_step, ref;
Yue Chen894fcce2016-10-21 16:50:52 -07001634 int mb_to_right_edge_base = xd->mb_to_right_edge;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001635
1636 if (mi_row <= tile->mi_row_start) return;
1637
Yue Chen894fcce2016-10-21 16:50:52 -07001638 xd->mb_to_bottom_edge += xd->n8_h * 32;
Yaowu Xuf883b422016-08-30 14:01:10 -07001639 for (i = 0; i < AOMMIN(xd->n8_w, cm->mi_cols - mi_col); i += mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001640 int mi_row_offset = -1;
1641 int mi_col_offset = i;
1642 int mi_x, mi_y, bw, bh;
1643 MODE_INFO *above_mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
1644 MB_MODE_INFO *above_mbmi = &above_mi->mbmi;
1645#if CONFIG_EXT_INTER
1646 MB_MODE_INFO backup_mbmi;
1647#endif // CONFIG_EXT_INTER
1648
Jingning Han51ec5052017-01-18 16:27:57 -08001649 mi_step = AOMMIN(xd->n8_w, mi_size_wide[above_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001650
1651 if (!is_neighbor_overlappable(above_mbmi)) continue;
1652
1653#if CONFIG_EXT_INTER
1654 backup_mbmi = *above_mbmi;
1655 modify_neighbor_predictor_for_obmc(above_mbmi);
1656#endif // CONFIG_EXT_INTER
1657
1658 for (j = 0; j < MAX_MB_PLANE; ++j) {
1659 struct macroblockd_plane *const pd = &xd->plane[j];
1660 setup_pred_plane(&pd->dst, tmp_buf[j], tmp_width[j], tmp_height[j],
1661 tmp_stride[j], 0, i, NULL, pd->subsampling_x,
1662 pd->subsampling_y);
1663 }
1664 for (ref = 0; ref < 1 + has_second_ref(above_mbmi); ++ref) {
Urvang Joshi52648442016-10-13 17:27:51 -07001665 const MV_REFERENCE_FRAME frame = above_mbmi->ref_frame[ref];
1666 const RefBuffer *const ref_buf = &cm->frame_refs[frame - LAST_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001667
1668 xd->block_refs[ref] = ref_buf;
Yaowu Xuf883b422016-08-30 14:01:10 -07001669 if ((!av1_is_valid_scale(&ref_buf->sf)))
1670 aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001671 "Reference frame has invalid dimensions");
Yaowu Xuf883b422016-08-30 14:01:10 -07001672 av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col + i,
1673 &ref_buf->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001674 }
1675
1676 xd->mb_to_left_edge = -(((mi_col + i) * MI_SIZE) * 8);
Yue Chen894fcce2016-10-21 16:50:52 -07001677 xd->mb_to_right_edge =
1678 mb_to_right_edge_base + (xd->n8_w - i - mi_step) * 64;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001679 mi_x = (mi_col + i) << MI_SIZE_LOG2;
1680 mi_y = mi_row << MI_SIZE_LOG2;
1681
1682 for (j = 0; j < MAX_MB_PLANE; ++j) {
1683 const struct macroblockd_plane *pd = &xd->plane[j];
Jingning Han51ec5052017-01-18 16:27:57 -08001684 bw = (mi_step * MI_SIZE) >> pd->subsampling_x;
Yaowu Xuf883b422016-08-30 14:01:10 -07001685 bh = AOMMAX((num_4x4_blocks_high_lookup[bsize] * 2) >> pd->subsampling_y,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001686 4);
1687
Jingning Han51ec5052017-01-18 16:27:57 -08001688 if (above_mbmi->sb_type < BLOCK_8X8 && !CONFIG_CB4X4) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001689 const PARTITION_TYPE bp = BLOCK_8X8 - above_mbmi->sb_type;
1690 const int have_vsplit = bp != PARTITION_HORZ;
1691 const int have_hsplit = bp != PARTITION_VERT;
Yue Chen894fcce2016-10-21 16:50:52 -07001692 const int num_4x4_w = 2 >> !have_vsplit;
1693 const int num_4x4_h = 2 >> !have_hsplit;
1694 const int pw = 8 >> (have_vsplit + pd->subsampling_x);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001695 int x, y;
1696
1697 for (y = 0; y < num_4x4_h; ++y)
1698 for (x = 0; x < num_4x4_w; ++x) {
Yue Chen894fcce2016-10-21 16:50:52 -07001699 if ((bp == PARTITION_HORZ || bp == PARTITION_SPLIT) && y == 0)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001700 continue;
1701
1702 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset,
Yue Chen894fcce2016-10-21 16:50:52 -07001703 y * 2 + x, bw, bh,
1704 (4 * x) >> pd->subsampling_x, 0, pw, bh,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001705#if CONFIG_SUPERTX && CONFIG_EXT_INTER
1706 0, 0,
1707#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
1708 mi_x, mi_y);
1709 }
1710 } else {
Yue Chen69f18e12016-09-08 14:48:15 -07001711#if CONFIG_WARPED_MOTION
1712 if (above_mbmi->motion_mode == WARPED_CAUSAL) {
1713 av1_warp_plane(&above_mbmi->wm_params[0],
1714#if CONFIG_AOM_HIGHBITDEPTH
1715 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
1716#endif // CONFIG_AOM_HIGHBITDEPTH
1717 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
1718 pd->pre[0].stride, pd->dst.buf,
1719 (((mi_col + i) * MI_SIZE) >> pd->subsampling_x),
1720 ((mi_row * MI_SIZE) >> pd->subsampling_y), bw, bh,
1721 pd->dst.stride, pd->subsampling_x, pd->subsampling_y,
1722 16, 16, 0);
1723
1724 } else {
1725#endif // CONFIG_WARPED_MOTION
1726 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0, bw, bh,
1727 0, 0, bw, bh,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001728#if CONFIG_SUPERTX && CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07001729 0, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001730#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07001731 mi_x, mi_y);
1732#if CONFIG_WARPED_MOTION
1733 }
1734#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07001735 }
1736 }
1737#if CONFIG_EXT_INTER
1738 *above_mbmi = backup_mbmi;
1739#endif // CONFIG_EXT_INTER
1740 }
1741 xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8);
Yue Chen894fcce2016-10-21 16:50:52 -07001742 xd->mb_to_right_edge = mb_to_right_edge_base;
1743 xd->mb_to_bottom_edge -= xd->n8_h * 32;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001744}
1745
Urvang Joshi52648442016-10-13 17:27:51 -07001746void av1_build_prediction_by_left_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xuf883b422016-08-30 14:01:10 -07001747 int mi_row, int mi_col,
1748 uint8_t *tmp_buf[MAX_MB_PLANE],
1749 int tmp_width[MAX_MB_PLANE],
1750 int tmp_height[MAX_MB_PLANE],
1751 int tmp_stride[MAX_MB_PLANE]) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001752 const TileInfo *const tile = &xd->tile;
1753 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
1754 int i, j, mi_step, ref;
Yue Chen894fcce2016-10-21 16:50:52 -07001755 int mb_to_bottom_edge_base = xd->mb_to_bottom_edge;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001756
1757 if (mi_col == 0 || (mi_col - 1 < tile->mi_col_start)) return;
1758
Yue Chen894fcce2016-10-21 16:50:52 -07001759 xd->mb_to_right_edge += xd->n8_w * 32;
Yaowu Xuf883b422016-08-30 14:01:10 -07001760 for (i = 0; i < AOMMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001761 int mi_row_offset = i;
1762 int mi_col_offset = -1;
1763 int mi_x, mi_y, bw, bh;
1764 MODE_INFO *left_mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
1765 MB_MODE_INFO *left_mbmi = &left_mi->mbmi;
1766#if CONFIG_EXT_INTER
1767 MB_MODE_INFO backup_mbmi;
1768#endif // CONFIG_EXT_INTER
1769
Jingning Han51ec5052017-01-18 16:27:57 -08001770 mi_step = AOMMIN(xd->n8_h, mi_size_high[left_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001771
1772 if (!is_neighbor_overlappable(left_mbmi)) continue;
1773
1774#if CONFIG_EXT_INTER
1775 backup_mbmi = *left_mbmi;
1776 modify_neighbor_predictor_for_obmc(left_mbmi);
1777#endif // CONFIG_EXT_INTER
1778
1779 for (j = 0; j < MAX_MB_PLANE; ++j) {
1780 struct macroblockd_plane *const pd = &xd->plane[j];
1781 setup_pred_plane(&pd->dst, tmp_buf[j], tmp_width[j], tmp_height[j],
1782 tmp_stride[j], i, 0, NULL, pd->subsampling_x,
1783 pd->subsampling_y);
1784 }
1785 for (ref = 0; ref < 1 + has_second_ref(left_mbmi); ++ref) {
Urvang Joshi52648442016-10-13 17:27:51 -07001786 const MV_REFERENCE_FRAME frame = left_mbmi->ref_frame[ref];
1787 const RefBuffer *const ref_buf = &cm->frame_refs[frame - LAST_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001788
1789 xd->block_refs[ref] = ref_buf;
Yaowu Xuf883b422016-08-30 14:01:10 -07001790 if ((!av1_is_valid_scale(&ref_buf->sf)))
1791 aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001792 "Reference frame has invalid dimensions");
Yaowu Xuf883b422016-08-30 14:01:10 -07001793 av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row + i, mi_col,
1794 &ref_buf->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001795 }
1796
1797 xd->mb_to_top_edge = -(((mi_row + i) * MI_SIZE) * 8);
Yue Chen894fcce2016-10-21 16:50:52 -07001798 xd->mb_to_bottom_edge =
1799 mb_to_bottom_edge_base + (xd->n8_h - i - mi_step) * 64;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001800 mi_x = mi_col << MI_SIZE_LOG2;
1801 mi_y = (mi_row + i) << MI_SIZE_LOG2;
1802
1803 for (j = 0; j < MAX_MB_PLANE; ++j) {
1804 const struct macroblockd_plane *pd = &xd->plane[j];
Yaowu Xuf883b422016-08-30 14:01:10 -07001805 bw = AOMMAX((num_4x4_blocks_wide_lookup[bsize] * 2) >> pd->subsampling_x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001806 4);
1807 bh = (mi_step << MI_SIZE_LOG2) >> pd->subsampling_y;
1808
Jingning Han51ec5052017-01-18 16:27:57 -08001809 if (left_mbmi->sb_type < BLOCK_8X8 && !CONFIG_CB4X4) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001810 const PARTITION_TYPE bp = BLOCK_8X8 - left_mbmi->sb_type;
1811 const int have_vsplit = bp != PARTITION_HORZ;
1812 const int have_hsplit = bp != PARTITION_VERT;
Yue Chen894fcce2016-10-21 16:50:52 -07001813 const int num_4x4_w = 2 >> !have_vsplit;
1814 const int num_4x4_h = 2 >> !have_hsplit;
1815 const int ph = 8 >> (have_hsplit + pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001816 int x, y;
1817
1818 for (y = 0; y < num_4x4_h; ++y)
1819 for (x = 0; x < num_4x4_w; ++x) {
Yue Chen894fcce2016-10-21 16:50:52 -07001820 if ((bp == PARTITION_VERT || bp == PARTITION_SPLIT) && x == 0)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001821 continue;
1822
1823 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset,
Yue Chen894fcce2016-10-21 16:50:52 -07001824 y * 2 + x, bw, bh, 0,
1825 (4 * y) >> pd->subsampling_y, bw, ph,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001826#if CONFIG_SUPERTX && CONFIG_EXT_INTER
1827 0, 0,
1828#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
1829 mi_x, mi_y);
1830 }
1831 } else {
Yue Chen69f18e12016-09-08 14:48:15 -07001832#if CONFIG_WARPED_MOTION
1833 if (left_mbmi->motion_mode == WARPED_CAUSAL) {
1834 av1_warp_plane(&left_mbmi->wm_params[0],
1835#if CONFIG_AOM_HIGHBITDEPTH
1836 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
1837#endif // CONFIG_AOM_HIGHBITDEPTH
1838 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
1839 pd->pre[0].stride, pd->dst.buf,
1840 ((mi_col * MI_SIZE) >> pd->subsampling_x),
1841 (((mi_row + i) * MI_SIZE) >> pd->subsampling_y), bw,
1842 bh, pd->dst.stride, pd->subsampling_x,
1843 pd->subsampling_y, 16, 16, 0);
1844
1845 } else {
1846#endif // CONFIG_WARPED_MOTION
1847 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0, bw, bh,
1848 0, 0, bw, bh,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001849#if CONFIG_SUPERTX && CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07001850 0, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001851#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07001852 mi_x, mi_y);
1853#if CONFIG_WARPED_MOTION
1854 }
1855#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07001856 }
1857 }
1858#if CONFIG_EXT_INTER
1859 *left_mbmi = backup_mbmi;
1860#endif // CONFIG_EXT_INTER
1861 }
1862 xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8);
Yue Chen894fcce2016-10-21 16:50:52 -07001863 xd->mb_to_bottom_edge = mb_to_bottom_edge_base;
1864 xd->mb_to_right_edge -= xd->n8_w * 32;
1865}
1866
1867void av1_build_obmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
1868 int mi_row, int mi_col) {
1869#if CONFIG_AOM_HIGHBITDEPTH
1870 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
1871 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
1872#else
1873 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
1874 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
1875#endif // CONFIG_AOM_HIGHBITDEPTH
1876 uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
1877 int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
1878 int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
1879 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
1880 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
1881 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
1882 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
1883
1884#if CONFIG_AOM_HIGHBITDEPTH
1885 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1886 int len = sizeof(uint16_t);
1887 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
1888 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
1889 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * 2 * len);
1890 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
1891 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
1892 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * 2 * len);
1893 } else {
1894#endif // CONFIG_AOM_HIGHBITDEPTH
1895 dst_buf1[0] = tmp_buf1;
1896 dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE;
1897 dst_buf1[2] = tmp_buf1 + MAX_SB_SQUARE * 2;
1898 dst_buf2[0] = tmp_buf2;
1899 dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE;
1900 dst_buf2[2] = tmp_buf2 + MAX_SB_SQUARE * 2;
1901#if CONFIG_AOM_HIGHBITDEPTH
1902 }
1903#endif // CONFIG_AOM_HIGHBITDEPTH
1904 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col, dst_buf1,
1905 dst_width1, dst_height1, dst_stride1);
1906 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col, dst_buf2,
1907 dst_width2, dst_height2, dst_stride2);
1908 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
1909 av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, dst_buf1, dst_stride1,
1910 dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001911}
Yue Chen86ae7b12017-01-11 17:04:29 -08001912
1913#if CONFIG_NCOBMC
1914void av1_build_prediction_by_bottom_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
1915 int mi_row, int mi_col,
1916 uint8_t *tmp_buf[MAX_MB_PLANE],
1917 int tmp_width[MAX_MB_PLANE],
1918 int tmp_height[MAX_MB_PLANE],
1919 int tmp_stride[MAX_MB_PLANE]) {
1920 const TileInfo *const tile = &xd->tile;
1921 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
1922 int i, j, mi_step, ref;
1923 int mb_to_right_edge_base = xd->mb_to_right_edge;
1924
Jingning Han91f01fd2017-01-18 17:16:40 -08001925 if (mi_row + xd->n8_h >= tile->mi_row_end ||
1926 (mi_row + xd->n8_h) % MI_SIZE == 0 || (mi_row + xd->n8_h) >= cm->mi_rows)
Yue Chen86ae7b12017-01-11 17:04:29 -08001927 return;
1928 assert(bsize >= BLOCK_8X8);
1929
1930 xd->mb_to_top_edge -= xd->n8_h * 32;
1931 for (i = 0; i < AOMMIN(xd->n8_w, cm->mi_cols - mi_col); i += mi_step) {
1932 int mi_row_offset = xd->n8_h;
1933 int mi_col_offset = i;
1934 int mi_x, mi_y, bw, bh;
1935 MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
1936 MB_MODE_INFO *mbmi = &mi->mbmi;
1937#if CONFIG_EXT_INTER
1938 MB_MODE_INFO backup_mbmi;
1939#endif // CONFIG_EXT_INTER
1940
Jingning Han91f01fd2017-01-18 17:16:40 -08001941 mi_step = AOMMIN(xd->n8_w, mi_size_wide[mbmi->sb_type]);
Yue Chen86ae7b12017-01-11 17:04:29 -08001942
1943 if (!is_neighbor_overlappable(mbmi)) continue;
1944
1945#if CONFIG_EXT_INTER
1946 backup_mbmi = *mbmi;
1947 modify_neighbor_predictor_for_obmc(mbmi);
1948#endif // CONFIG_EXT_INTER
1949
1950 for (j = 0; j < MAX_MB_PLANE; ++j) {
1951 struct macroblockd_plane *const pd = &xd->plane[j];
1952 setup_pred_plane(&pd->dst, tmp_buf[j], tmp_width[j], tmp_height[j],
1953 tmp_stride[j], (xd->n8_h >> 1), i, NULL,
1954 pd->subsampling_x, pd->subsampling_y);
1955 }
1956 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
1957 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
1958 const RefBuffer *const ref_buf = &cm->frame_refs[frame - LAST_FRAME];
1959
1960 xd->block_refs[ref] = ref_buf;
1961 if ((!av1_is_valid_scale(&ref_buf->sf)))
1962 aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
1963 "Reference frame has invalid dimensions");
1964 av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row + (xd->n8_h >> 1),
1965 mi_col + i, &ref_buf->sf);
1966 }
1967
1968 xd->mb_to_left_edge = -(((mi_col + i) * MI_SIZE) * 8);
1969 xd->mb_to_right_edge =
1970 mb_to_right_edge_base + (xd->n8_w - i - mi_step) * 64;
1971 mi_x = (mi_col + i) << MI_SIZE_LOG2;
1972 mi_y = (mi_row << MI_SIZE_LOG2) + xd->n8_h * 4;
1973
1974 for (j = 0; j < MAX_MB_PLANE; ++j) {
1975 const struct macroblockd_plane *pd = &xd->plane[j];
1976 bw = (mi_step << MI_SIZE_LOG2) >> pd->subsampling_x;
1977 bh = (num_4x4_blocks_high_lookup[bsize] << 1) >> pd->subsampling_y;
1978
Jingning Han91f01fd2017-01-18 17:16:40 -08001979 if (mbmi->sb_type < BLOCK_8X8 && !CONFIG_CB4X4) {
Yue Chen86ae7b12017-01-11 17:04:29 -08001980 const PARTITION_TYPE bp = BLOCK_8X8 - mbmi->sb_type;
1981 const int have_vsplit = bp != PARTITION_HORZ;
1982 const int have_hsplit = bp != PARTITION_VERT;
1983 const int num_4x4_w = 2 >> (!have_vsplit);
1984 const int num_4x4_h = 2 >> (!have_hsplit);
1985 const int pw = 8 >> (have_vsplit + pd->subsampling_x);
1986 int x, y;
1987
1988 for (y = 0; y < num_4x4_h; ++y)
1989 for (x = 0; x < num_4x4_w; ++x) {
1990 if ((bp == PARTITION_HORZ || bp == PARTITION_SPLIT) && y != 0)
1991 continue;
1992
1993 build_inter_predictors(
1994 xd, j, mi_col_offset, mi_row_offset, y * 2 + x, bw, bh,
1995 (4 * x) >> pd->subsampling_x,
1996 xd->n8_h == 1 ? (4 >> pd->subsampling_y) : 0, pw, bh,
1997#if CONFIG_SUPERTX && CONFIG_EXT_INTER
1998 0, 0,
1999#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
2000 mi_x, mi_y);
2001 }
2002 } else {
2003#if CONFIG_WARPED_MOTION
2004 if (mbmi->motion_mode == WARPED_CAUSAL) {
2005 av1_warp_plane(&mbmi->wm_params[0],
2006#if CONFIG_AOM_HIGHBITDEPTH
2007 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
2008#endif // CONFIG_AOM_HIGHBITDEPTH
2009 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
2010 pd->pre[0].stride, pd->dst.buf,
2011 (((mi_col + i) * MI_SIZE) >> pd->subsampling_x),
2012 ((mi_row * MI_SIZE) >> pd->subsampling_y), bw, bh,
2013 pd->dst.stride, pd->subsampling_x, pd->subsampling_y,
2014 16, 16, 0);
2015
2016 } else {
2017#endif // CONFIG_WARPED_MOTION
2018 build_inter_predictors(
2019 xd, j, mi_col_offset, mi_row_offset, 0, bw, bh, 0,
2020 xd->n8_h == 1 ? (4 >> pd->subsampling_y) : 0, bw, bh,
2021#if CONFIG_SUPERTX && CONFIG_EXT_INTER
2022 0, 0,
2023#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
2024 mi_x, mi_y);
2025#if CONFIG_WARPED_MOTION
2026 }
2027#endif // CONFIG_WARPED_MOTION
2028 }
2029 }
2030#if CONFIG_EXT_INTER
2031 *mbmi = backup_mbmi;
2032#endif // CONFIG_EXT_INTER
2033 }
2034 xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8);
2035 xd->mb_to_right_edge = mb_to_right_edge_base;
2036 xd->mb_to_top_edge += xd->n8_h * 32;
2037}
2038
2039void av1_build_prediction_by_right_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
2040 int mi_row, int mi_col,
2041 uint8_t *tmp_buf[MAX_MB_PLANE],
2042 int tmp_width[MAX_MB_PLANE],
2043 int tmp_height[MAX_MB_PLANE],
2044 const int tmp_stride[MAX_MB_PLANE]) {
2045 const TileInfo *const tile = &xd->tile;
2046 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
2047 int i, j, mi_step, ref;
2048 int mb_to_bottom_edge_base = xd->mb_to_bottom_edge;
2049
Jingning Han91f01fd2017-01-18 17:16:40 -08002050 if (mi_col + xd->n8_w >= tile->mi_col_end ||
2051 (mi_col + xd->n8_w) % MI_SIZE == 0 || (mi_col + xd->n8_w) >= cm->mi_cols)
Yue Chen86ae7b12017-01-11 17:04:29 -08002052 return;
2053
2054 xd->mb_to_left_edge -= xd->n8_w * 32;
2055 for (i = 0; i < AOMMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) {
2056 int mi_row_offset = i;
2057 int mi_col_offset = xd->n8_w;
2058 int mi_x, mi_y, bw, bh;
2059 MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
2060 MB_MODE_INFO *mbmi = &mi->mbmi;
2061#if CONFIG_EXT_INTER
2062 MB_MODE_INFO backup_mbmi;
2063#endif // CONFIG_EXT_INTER
2064
Jingning Han91f01fd2017-01-18 17:16:40 -08002065 mi_step = AOMMIN(xd->n8_h, mi_size_high[mbmi->sb_type]);
Yue Chen86ae7b12017-01-11 17:04:29 -08002066
2067 if (!is_neighbor_overlappable(mbmi)) continue;
2068
2069#if CONFIG_EXT_INTER
2070 backup_mbmi = *mbmi;
2071 modify_neighbor_predictor_for_obmc(mbmi);
2072#endif // CONFIG_EXT_INTER
2073
2074 for (j = 0; j < MAX_MB_PLANE; ++j) {
2075 struct macroblockd_plane *const pd = &xd->plane[j];
2076 setup_pred_plane(&pd->dst, tmp_buf[j], tmp_width[j], tmp_height[j],
2077 tmp_stride[j], i, xd->n8_w >> 1, NULL, pd->subsampling_x,
2078 pd->subsampling_y);
2079 }
2080 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
2081 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
2082 const RefBuffer *const ref_buf = &cm->frame_refs[frame - LAST_FRAME];
2083
2084 xd->block_refs[ref] = ref_buf;
2085 if ((!av1_is_valid_scale(&ref_buf->sf)))
2086 aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
2087 "Reference frame has invalid dimensions");
2088 av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row + i,
2089 mi_col + (xd->n8_w >> 1), &ref_buf->sf);
2090 }
2091
2092 xd->mb_to_top_edge = -(((mi_row + i) * MI_SIZE) * 8);
2093 xd->mb_to_bottom_edge =
2094 mb_to_bottom_edge_base + (xd->n8_h - i - mi_step) * 64;
2095 mi_x = (mi_col << MI_SIZE_LOG2) + xd->n8_w * 4;
2096 mi_y = (mi_row + i) << MI_SIZE_LOG2;
2097
2098 for (j = 0; j < MAX_MB_PLANE; ++j) {
2099 const struct macroblockd_plane *pd = &xd->plane[j];
2100 bw = (num_4x4_blocks_wide_lookup[bsize] << 1) >> pd->subsampling_x;
2101 bh = (mi_step << MI_SIZE_LOG2) >> pd->subsampling_y;
2102
Jingning Han91f01fd2017-01-18 17:16:40 -08002103 if (mbmi->sb_type < BLOCK_8X8 && !CONFIG_CB4X4) {
Yue Chen86ae7b12017-01-11 17:04:29 -08002104 const PARTITION_TYPE bp = BLOCK_8X8 - mbmi->sb_type;
2105 const int have_vsplit = bp != PARTITION_HORZ;
2106 const int have_hsplit = bp != PARTITION_VERT;
2107 const int num_4x4_w = 2 >> (!have_vsplit);
2108 const int num_4x4_h = 2 >> (!have_hsplit);
2109 const int ph = 8 >> (have_hsplit + pd->subsampling_y);
2110 int x, y;
2111
2112 for (y = 0; y < num_4x4_h; ++y)
2113 for (x = 0; x < num_4x4_w; ++x) {
2114 if ((bp == PARTITION_VERT || bp == PARTITION_SPLIT) && x != 0)
2115 continue;
2116
2117 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset,
2118 y * 2 + x, bw, bh,
2119 xd->n8_w == 1 ? 4 >> pd->subsampling_x : 0,
2120 (4 * y) >> pd->subsampling_y, bw, ph,
2121#if CONFIG_SUPERTX && CONFIG_EXT_INTER
2122 0, 0,
2123#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
2124 mi_x, mi_y);
2125 }
2126 } else {
2127#if CONFIG_WARPED_MOTION
2128 if (mbmi->motion_mode == WARPED_CAUSAL) {
2129 av1_warp_plane(&mbmi->wm_params[0],
2130#if CONFIG_AOM_HIGHBITDEPTH
2131 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
2132#endif // CONFIG_AOM_HIGHBITDEPTH
2133 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
2134 pd->pre[0].stride, pd->dst.buf,
2135 ((mi_col * MI_SIZE) >> pd->subsampling_x),
2136 (((mi_row + i) * MI_SIZE) >> pd->subsampling_y), bw,
2137 bh, pd->dst.stride, pd->subsampling_x,
2138 pd->subsampling_y, 16, 16, 0);
2139
2140 } else {
2141#endif // CONFIG_WARPED_MOTION
2142 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0, bw, bh,
2143 xd->n8_w == 1 ? 4 >> pd->subsampling_x : 0, 0,
2144 bw, bh,
2145#if CONFIG_SUPERTX && CONFIG_EXT_INTER
2146 0, 0,
2147#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
2148 mi_x, mi_y);
2149#if CONFIG_WARPED_MOTION
2150 }
2151#endif // CONFIG_WARPED_MOTION
2152 }
2153 }
2154#if CONFIG_EXT_INTER
2155 *mbmi = backup_mbmi;
2156#endif // CONFIG_EXT_INTER
2157 }
2158 xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8);
2159 xd->mb_to_bottom_edge = mb_to_bottom_edge_base;
2160 xd->mb_to_left_edge += xd->n8_w * 32;
2161}
2162
2163// This function combines motion compensated predictions that is generated by
2164// bottom/right neighboring blocks' inter predictors with prediction in dst
2165// buffer.
2166void av1_merge_dst_bottom_right_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
2167 int mi_row, int mi_col,
2168 uint8_t *bottom[MAX_MB_PLANE],
2169 const int bottom_stride[MAX_MB_PLANE],
2170 uint8_t *right[MAX_MB_PLANE],
2171 const int right_stride[MAX_MB_PLANE]) {
2172 const TileInfo *const tile = &xd->tile;
2173 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
2174 int plane, i, mi_step;
2175 const int bottom_available = mi_row + xd->n8_h < tile->mi_row_end &&
Jingning Han91f01fd2017-01-18 17:16:40 -08002176 (mi_row + xd->n8_h) % MI_SIZE != 0 &&
Yue Chen86ae7b12017-01-11 17:04:29 -08002177 (mi_row + xd->n8_h) < cm->mi_rows;
2178#if CONFIG_AOM_HIGHBITDEPTH
2179 int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
2180#endif // CONFIG_AOM_HIGHBITDEPTH
2181
2182 // handle bottom row
2183 for (i = 0; bottom_available && i < AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
2184 i += mi_step) {
2185 int mi_row_offset = xd->n8_h;
2186 int mi_col_offset = i;
2187 MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
2188 MB_MODE_INFO *mbmi = &mi->mbmi;
2189 int overlap;
2190
Jingning Han91f01fd2017-01-18 17:16:40 -08002191 mi_step = AOMMIN(xd->n8_w, mi_size_wide[mbmi->sb_type]);
Yue Chen86ae7b12017-01-11 17:04:29 -08002192
2193 if (!is_neighbor_overlappable(mbmi)) continue;
2194
2195 overlap = num_4x4_blocks_high_lookup[bsize] << 1;
2196
2197 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
2198 const struct macroblockd_plane *pd = &xd->plane[plane];
2199 const int bw = (mi_step * MI_SIZE) >> pd->subsampling_x;
2200 const int bh = overlap >> pd->subsampling_y;
2201 const int dst_stride = pd->dst.stride;
Jingning Han91f01fd2017-01-18 17:16:40 -08002202 uint8_t *dst =
2203 &pd->dst.buf[((i * MI_SIZE) >> pd->subsampling_x) +
2204 (((xd->n8_h * MI_SIZE - overlap) * dst_stride) >>
2205 pd->subsampling_y)];
Yue Chen86ae7b12017-01-11 17:04:29 -08002206 const int tmp_stride = bottom_stride[plane];
2207 const uint8_t *const tmp =
2208 &bottom[plane][((i * MI_SIZE) >> pd->subsampling_x) +
Jingning Han91f01fd2017-01-18 17:16:40 -08002209 (((xd->n8_h * MI_SIZE - overlap) * tmp_stride) >>
Yue Chen86ae7b12017-01-11 17:04:29 -08002210 pd->subsampling_y)];
2211 const uint8_t *const mask = av1_get_obmc_mask_flipped(bh);
2212
2213#if CONFIG_AOM_HIGHBITDEPTH
2214 if (is_hbd)
2215 aom_highbd_blend_a64_vmask(dst, dst_stride, dst, dst_stride, tmp,
2216 tmp_stride, mask, bh, bw, xd->bd);
2217 else
2218#endif // CONFIG_AOM_HIGHBITDEPTH
2219 aom_blend_a64_vmask(dst, dst_stride, dst, dst_stride, tmp, tmp_stride,
2220 mask, bh, bw);
2221 }
2222 } // each mi in the bottom row
2223
2224 // handle right column
Jingning Han91f01fd2017-01-18 17:16:40 -08002225 if (mi_col + xd->n8_w >= tile->mi_col_end ||
2226 (mi_col + xd->n8_w) % MI_SIZE == 0 || (mi_col + xd->n8_w) >= cm->mi_cols)
Yue Chen86ae7b12017-01-11 17:04:29 -08002227 return;
2228
2229 for (i = 0; i < AOMMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) {
2230 int mi_row_offset = i;
2231 int mi_col_offset = xd->n8_w;
2232 int overlap;
2233 MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
2234 MB_MODE_INFO *mbmi = &mi->mbmi;
2235
Jingning Han91f01fd2017-01-18 17:16:40 -08002236 mi_step = AOMMIN(xd->n8_h, mi_size_high[mbmi->sb_type]);
Yue Chen86ae7b12017-01-11 17:04:29 -08002237
2238 if (!is_neighbor_overlappable(mbmi)) continue;
2239
2240 overlap = num_4x4_blocks_wide_lookup[bsize] << 1;
2241
2242 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
2243 const struct macroblockd_plane *pd = &xd->plane[plane];
2244 const int bw = overlap >> pd->subsampling_x;
2245 const int bh = (mi_step * MI_SIZE) >> pd->subsampling_y;
2246 const int dst_stride = pd->dst.stride;
2247 uint8_t *dst =
2248 &pd->dst.buf[((i * MI_SIZE * dst_stride) >> pd->subsampling_y) +
Jingning Han91f01fd2017-01-18 17:16:40 -08002249 ((xd->n8_w * MI_SIZE - overlap) >> pd->subsampling_x)];
Yue Chen86ae7b12017-01-11 17:04:29 -08002250 const int tmp_stride = right_stride[plane];
2251 const uint8_t *const tmp =
2252 &right[plane][((i * MI_SIZE * tmp_stride) >> pd->subsampling_y) +
Jingning Han91f01fd2017-01-18 17:16:40 -08002253 ((xd->n8_w * MI_SIZE - overlap) >> pd->subsampling_x)];
Yue Chen86ae7b12017-01-11 17:04:29 -08002254 const uint8_t *const mask = av1_get_obmc_mask_flipped(bw);
2255
2256#if CONFIG_AOM_HIGHBITDEPTH
2257 if (is_hbd)
2258 aom_highbd_blend_a64_hmask(dst, dst_stride, dst, dst_stride, tmp,
2259 tmp_stride, mask, bh, bw, xd->bd);
2260 else
2261#endif // CONFIG_AOM_HIGHBITDEPTH
2262 aom_blend_a64_hmask(dst, dst_stride, dst, dst_stride, tmp, tmp_stride,
2263 mask, bh, bw);
2264 }
2265 } // each mi in the right column
2266}
2267
2268// This function generates 4 sided obmc. (1) Prediction blocks generated by
2269// bottom and right motion vectors are calculated. (2) Combine them with the
2270// original prediction block (which should be pre-stored in xd->plane[].dst.buf
2271// before calling this function). The results is updated in xd->plane[].dst.buf
2272// (3) Call causal obmc prediction function, which will generate left and above
2273// preds, and then merge them and xd->plane[].dst.buf.
2274void av1_build_ncobmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
2275 int mi_row, int mi_col) {
2276#if CONFIG_AOM_HIGHBITDEPTH
2277 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
2278 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
2279#else
2280 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
2281 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
2282#endif // CONFIG_AOM_HIGHBITDEPTH
2283 uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
2284 int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2285 int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2286 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2287 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2288 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2289 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2290
2291#if CONFIG_AOM_HIGHBITDEPTH
2292 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2293 int len = sizeof(uint16_t);
2294 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
2295 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
2296 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * 2 * len);
2297 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
2298 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
2299 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * 2 * len);
2300 } else {
2301#endif // CONFIG_AOM_HIGHBITDEPTH
2302 dst_buf1[0] = tmp_buf1;
2303 dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE;
2304 dst_buf1[2] = tmp_buf1 + MAX_SB_SQUARE * 2;
2305 dst_buf2[0] = tmp_buf2;
2306 dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE;
2307 dst_buf2[2] = tmp_buf2 + MAX_SB_SQUARE * 2;
2308#if CONFIG_AOM_HIGHBITDEPTH
2309 }
2310#endif // CONFIG_AOM_HIGHBITDEPTH
Yue Chen86ae7b12017-01-11 17:04:29 -08002311
Yue Chen86ae7b12017-01-11 17:04:29 -08002312 av1_build_prediction_by_bottom_preds(cm, xd, mi_row, mi_col, dst_buf1,
2313 dst_width1, dst_height1, dst_stride1);
2314 av1_build_prediction_by_right_preds(cm, xd, mi_row, mi_col, dst_buf2,
2315 dst_width2, dst_height2, dst_stride2);
2316 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
2317 av1_merge_dst_bottom_right_preds(cm, xd, mi_row, mi_col, dst_buf1,
2318 dst_stride1, dst_buf2, dst_stride2);
2319 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
2320 av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
2321 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
2322}
2323#endif // CONFIG_NCOBMC
Yue Chencb60b182016-10-13 15:18:22 -07002324#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07002325
2326#if CONFIG_EXT_INTER
Jingning Han61418bb2017-01-23 17:12:48 -08002327/* clang-format off */
Yaowu Xuc27fc142016-08-22 16:08:15 -07002328#if CONFIG_EXT_PARTITION
2329static const int ii_weights1d[MAX_SB_SIZE] = {
2330 102, 100, 97, 95, 92, 90, 88, 86, 84, 82, 80, 78, 76, 74, 73, 71, 69, 68, 67,
2331 65, 64, 62, 61, 60, 59, 58, 57, 55, 54, 53, 52, 52, 51, 50, 49, 48, 47, 47,
2332 46, 45, 45, 44, 43, 43, 42, 41, 41, 40, 40, 39, 39, 38, 38, 38, 37, 37, 36,
2333 36, 36, 35, 35, 35, 34, 34, 34, 33, 33, 33, 33, 32, 32, 32, 32, 32, 31, 31,
2334 31, 31, 31, 30, 30, 30, 30, 30, 30, 30, 29, 29, 29, 29, 29, 29, 29, 29, 28,
2335 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 27, 27, 27, 27, 27, 27, 27, 27,
2336 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
2337};
Jingning Han61418bb2017-01-23 17:12:48 -08002338static int ii_size_scales[BLOCK_SIZES] = {
2339#if CONFIG_CB4X4
2340 32, 32, 32,
2341#endif
2342 32, 16, 16, 16, 8, 8, 8, 4,
2343 4, 4, 2, 2, 2, 1, 1, 1,
2344};
Yaowu Xuc27fc142016-08-22 16:08:15 -07002345#else
2346static const int ii_weights1d[MAX_SB_SIZE] = {
2347 102, 100, 97, 95, 92, 90, 88, 86, 84, 82, 80, 78, 76, 74, 73, 71,
2348 69, 68, 67, 65, 64, 62, 61, 60, 59, 58, 57, 55, 54, 53, 52, 52,
2349 51, 50, 49, 48, 47, 47, 46, 45, 45, 44, 43, 43, 42, 41, 41, 40,
2350 40, 39, 39, 38, 38, 38, 37, 37, 36, 36, 36, 35, 35, 35, 34, 34,
2351};
Jingning Han61418bb2017-01-23 17:12:48 -08002352static int ii_size_scales[BLOCK_SIZES] = {
2353#if CONFIG_CB4X4
2354 16, 16, 16,
2355#endif
2356 16, 8, 8, 8, 4, 4, 4,
2357 2, 2, 2, 1, 1, 1,
2358};
2359/* clang-format on */
Yaowu Xuc27fc142016-08-22 16:08:15 -07002360#endif // CONFIG_EXT_PARTITION
2361
2362static void combine_interintra(INTERINTRA_MODE mode, int use_wedge_interintra,
2363 int wedge_index, int wedge_sign,
2364 BLOCK_SIZE bsize, BLOCK_SIZE plane_bsize,
2365 uint8_t *comppred, int compstride,
2366 const uint8_t *interpred, int interstride,
2367 const uint8_t *intrapred, int intrastride) {
Jingning Hanae5cfde2016-11-30 12:01:44 -08002368 const int bw = block_size_wide[plane_bsize];
2369 const int bh = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002370 const int size_scale = ii_size_scales[plane_bsize];
2371 int i, j;
2372
2373 if (use_wedge_interintra) {
2374 if (is_interintra_wedge_used(bsize)) {
2375 const uint8_t *mask =
Yaowu Xuf883b422016-08-30 14:01:10 -07002376 av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002377 const int subw = 2 * num_4x4_blocks_wide_lookup[bsize] == bw;
2378 const int subh = 2 * num_4x4_blocks_high_lookup[bsize] == bh;
Jingning Hanae5cfde2016-11-30 12:01:44 -08002379 aom_blend_a64_mask(comppred, compstride, intrapred, intrastride,
2380 interpred, interstride, mask, block_size_wide[bsize],
2381 bh, bw, subh, subw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002382 }
2383 return;
2384 }
2385
2386 switch (mode) {
2387 case II_V_PRED:
2388 for (i = 0; i < bh; ++i) {
2389 for (j = 0; j < bw; ++j) {
2390 int scale = ii_weights1d[i * size_scale];
2391 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002392 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002393 interpred[i * interstride + j]);
2394 }
2395 }
2396 break;
2397
2398 case II_H_PRED:
2399 for (i = 0; i < bh; ++i) {
2400 for (j = 0; j < bw; ++j) {
2401 int scale = ii_weights1d[j * size_scale];
2402 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002403 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002404 interpred[i * interstride + j]);
2405 }
2406 }
2407 break;
2408
2409 case II_D63_PRED:
2410 case II_D117_PRED:
2411 for (i = 0; i < bh; ++i) {
2412 for (j = 0; j < bw; ++j) {
2413 int scale = (ii_weights1d[i * size_scale] * 3 +
2414 ii_weights1d[j * size_scale]) >>
2415 2;
2416 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002417 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002418 interpred[i * interstride + j]);
2419 }
2420 }
2421 break;
2422
2423 case II_D207_PRED:
2424 case II_D153_PRED:
2425 for (i = 0; i < bh; ++i) {
2426 for (j = 0; j < bw; ++j) {
2427 int scale = (ii_weights1d[j * size_scale] * 3 +
2428 ii_weights1d[i * size_scale]) >>
2429 2;
2430 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002431 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002432 interpred[i * interstride + j]);
2433 }
2434 }
2435 break;
2436
2437 case II_D135_PRED:
2438 for (i = 0; i < bh; ++i) {
2439 for (j = 0; j < bw; ++j) {
2440 int scale = ii_weights1d[(i < j ? i : j) * size_scale];
2441 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002442 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002443 interpred[i * interstride + j]);
2444 }
2445 }
2446 break;
2447
2448 case II_D45_PRED:
2449 for (i = 0; i < bh; ++i) {
2450 for (j = 0; j < bw; ++j) {
2451 int scale =
2452 (ii_weights1d[i * size_scale] + ii_weights1d[j * size_scale]) >>
2453 1;
2454 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002455 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002456 interpred[i * interstride + j]);
2457 }
2458 }
2459 break;
2460
2461 case II_TM_PRED:
2462 case II_DC_PRED:
2463 default:
2464 for (i = 0; i < bh; ++i) {
2465 for (j = 0; j < bw; ++j) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002466 comppred[i * compstride + j] = AOM_BLEND_AVG(
Yaowu Xuc27fc142016-08-22 16:08:15 -07002467 intrapred[i * intrastride + j], interpred[i * interstride + j]);
2468 }
2469 }
2470 break;
2471 }
2472}
2473
Yaowu Xuf883b422016-08-30 14:01:10 -07002474#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002475static void combine_interintra_highbd(
2476 INTERINTRA_MODE mode, int use_wedge_interintra, int wedge_index,
2477 int wedge_sign, BLOCK_SIZE bsize, BLOCK_SIZE plane_bsize,
2478 uint8_t *comppred8, int compstride, const uint8_t *interpred8,
2479 int interstride, const uint8_t *intrapred8, int intrastride, int bd) {
Jingning Hanae5cfde2016-11-30 12:01:44 -08002480 const int bw = block_size_wide[plane_bsize];
2481 const int bh = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002482 const int size_scale = ii_size_scales[plane_bsize];
2483 int i, j;
2484
2485 uint16_t *comppred = CONVERT_TO_SHORTPTR(comppred8);
2486 const uint16_t *interpred = CONVERT_TO_SHORTPTR(interpred8);
2487 const uint16_t *intrapred = CONVERT_TO_SHORTPTR(intrapred8);
2488
2489 if (use_wedge_interintra) {
2490 if (is_interintra_wedge_used(bsize)) {
2491 const uint8_t *mask =
Yaowu Xuf883b422016-08-30 14:01:10 -07002492 av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002493 const int subh = 2 * num_4x4_blocks_high_lookup[bsize] == bh;
2494 const int subw = 2 * num_4x4_blocks_wide_lookup[bsize] == bw;
Yaowu Xuf883b422016-08-30 14:01:10 -07002495 aom_highbd_blend_a64_mask(comppred8, compstride, intrapred8, intrastride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002496 interpred8, interstride, mask, bw, bh, bw, subh,
2497 subw, bd);
2498 }
2499 return;
2500 }
2501
2502 switch (mode) {
2503 case II_V_PRED:
2504 for (i = 0; i < bh; ++i) {
2505 for (j = 0; j < bw; ++j) {
2506 int scale = ii_weights1d[i * size_scale];
2507 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002508 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002509 interpred[i * interstride + j]);
2510 }
2511 }
2512 break;
2513
2514 case II_H_PRED:
2515 for (i = 0; i < bh; ++i) {
2516 for (j = 0; j < bw; ++j) {
2517 int scale = ii_weights1d[j * size_scale];
2518 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002519 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002520 interpred[i * interstride + j]);
2521 }
2522 }
2523 break;
2524
2525 case II_D63_PRED:
2526 case II_D117_PRED:
2527 for (i = 0; i < bh; ++i) {
2528 for (j = 0; j < bw; ++j) {
2529 int scale = (ii_weights1d[i * size_scale] * 3 +
2530 ii_weights1d[j * size_scale]) >>
2531 2;
2532 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002533 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002534 interpred[i * interstride + j]);
2535 }
2536 }
2537 break;
2538
2539 case II_D207_PRED:
2540 case II_D153_PRED:
2541 for (i = 0; i < bh; ++i) {
2542 for (j = 0; j < bw; ++j) {
2543 int scale = (ii_weights1d[j * size_scale] * 3 +
2544 ii_weights1d[i * size_scale]) >>
2545 2;
2546 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002547 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002548 interpred[i * interstride + j]);
2549 }
2550 }
2551 break;
2552
2553 case II_D135_PRED:
2554 for (i = 0; i < bh; ++i) {
2555 for (j = 0; j < bw; ++j) {
2556 int scale = ii_weights1d[(i < j ? i : j) * size_scale];
2557 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002558 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002559 interpred[i * interstride + j]);
2560 }
2561 }
2562 break;
2563
2564 case II_D45_PRED:
2565 for (i = 0; i < bh; ++i) {
2566 for (j = 0; j < bw; ++j) {
2567 int scale =
2568 (ii_weights1d[i * size_scale] + ii_weights1d[j * size_scale]) >>
2569 1;
2570 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002571 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002572 interpred[i * interstride + j]);
2573 }
2574 }
2575 break;
2576
2577 case II_TM_PRED:
2578 case II_DC_PRED:
2579 default:
2580 for (i = 0; i < bh; ++i) {
2581 for (j = 0; j < bw; ++j) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002582 comppred[i * compstride + j] = AOM_BLEND_AVG(
Yaowu Xuc27fc142016-08-22 16:08:15 -07002583 interpred[i * interstride + j], intrapred[i * intrastride + j]);
2584 }
2585 }
2586 break;
2587 }
2588}
Yaowu Xuf883b422016-08-30 14:01:10 -07002589#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002590
Yaowu Xuf883b422016-08-30 14:01:10 -07002591void av1_build_intra_predictors_for_interintra(MACROBLOCKD *xd,
2592 BLOCK_SIZE bsize, int plane,
David Barkerac37fa32016-12-02 12:30:21 +00002593 BUFFER_SET *ctx, uint8_t *dst,
2594 int dst_stride) {
David Barker839467f2017-01-19 11:06:15 +00002595 struct macroblockd_plane *const pd = &xd->plane[plane];
2596 BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, &xd->plane[plane]);
2597 PREDICTION_MODE mode =
2598 interintra_to_intra_mode[xd->mi[0]->mbmi.interintra_mode];
2599
2600 av1_predict_intra_block(xd, pd->width, pd->height, plane_bsize, mode,
2601 ctx->plane[plane], ctx->stride[plane], dst,
2602 dst_stride, 0, 0, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002603}
2604
Yaowu Xuf883b422016-08-30 14:01:10 -07002605void av1_combine_interintra(MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane,
2606 const uint8_t *inter_pred, int inter_stride,
2607 const uint8_t *intra_pred, int intra_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002608 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, &xd->plane[plane]);
Yaowu Xuf883b422016-08-30 14:01:10 -07002609#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002610 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2611 combine_interintra_highbd(
2612 xd->mi[0]->mbmi.interintra_mode, xd->mi[0]->mbmi.use_wedge_interintra,
2613 xd->mi[0]->mbmi.interintra_wedge_index,
2614 xd->mi[0]->mbmi.interintra_wedge_sign, bsize, plane_bsize,
2615 xd->plane[plane].dst.buf, xd->plane[plane].dst.stride, inter_pred,
2616 inter_stride, intra_pred, intra_stride, xd->bd);
2617 return;
2618 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002619#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002620 combine_interintra(xd->mi[0]->mbmi.interintra_mode,
2621 xd->mi[0]->mbmi.use_wedge_interintra,
2622 xd->mi[0]->mbmi.interintra_wedge_index,
2623 xd->mi[0]->mbmi.interintra_wedge_sign, bsize, plane_bsize,
2624 xd->plane[plane].dst.buf, xd->plane[plane].dst.stride,
2625 inter_pred, inter_stride, intra_pred, intra_stride);
2626}
2627
Yaowu Xuf883b422016-08-30 14:01:10 -07002628void av1_build_interintra_predictors_sby(MACROBLOCKD *xd, uint8_t *ypred,
David Barkerac37fa32016-12-02 12:30:21 +00002629 int ystride, BUFFER_SET *ctx,
2630 BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002631#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002632 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2633 DECLARE_ALIGNED(16, uint16_t, intrapredictor[MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07002634 av1_build_intra_predictors_for_interintra(
David Barkerac37fa32016-12-02 12:30:21 +00002635 xd, bsize, 0, ctx, CONVERT_TO_BYTEPTR(intrapredictor), MAX_SB_SIZE);
Yaowu Xuf883b422016-08-30 14:01:10 -07002636 av1_combine_interintra(xd, bsize, 0, ypred, ystride,
2637 CONVERT_TO_BYTEPTR(intrapredictor), MAX_SB_SIZE);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002638 return;
2639 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002640#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002641 {
2642 DECLARE_ALIGNED(16, uint8_t, intrapredictor[MAX_SB_SQUARE]);
David Barkerac37fa32016-12-02 12:30:21 +00002643 av1_build_intra_predictors_for_interintra(xd, bsize, 0, ctx, intrapredictor,
Yaowu Xuf883b422016-08-30 14:01:10 -07002644 MAX_SB_SIZE);
2645 av1_combine_interintra(xd, bsize, 0, ypred, ystride, intrapredictor,
2646 MAX_SB_SIZE);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002647 }
2648}
2649
Yaowu Xuf883b422016-08-30 14:01:10 -07002650void av1_build_interintra_predictors_sbc(MACROBLOCKD *xd, uint8_t *upred,
David Barkerac37fa32016-12-02 12:30:21 +00002651 int ustride, BUFFER_SET *ctx,
2652 int plane, BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002653#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002654 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2655 DECLARE_ALIGNED(16, uint16_t, uintrapredictor[MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07002656 av1_build_intra_predictors_for_interintra(
David Barkerac37fa32016-12-02 12:30:21 +00002657 xd, bsize, plane, ctx, CONVERT_TO_BYTEPTR(uintrapredictor),
2658 MAX_SB_SIZE);
Yaowu Xuf883b422016-08-30 14:01:10 -07002659 av1_combine_interintra(xd, bsize, plane, upred, ustride,
2660 CONVERT_TO_BYTEPTR(uintrapredictor), MAX_SB_SIZE);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002661 return;
2662 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002663#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002664 {
2665 DECLARE_ALIGNED(16, uint8_t, uintrapredictor[MAX_SB_SQUARE]);
David Barkerac37fa32016-12-02 12:30:21 +00002666 av1_build_intra_predictors_for_interintra(xd, bsize, plane, ctx,
2667 uintrapredictor, MAX_SB_SIZE);
Yaowu Xuf883b422016-08-30 14:01:10 -07002668 av1_combine_interintra(xd, bsize, plane, upred, ustride, uintrapredictor,
2669 MAX_SB_SIZE);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002670 }
2671}
2672
Yaowu Xuf883b422016-08-30 14:01:10 -07002673void av1_build_interintra_predictors_sbuv(MACROBLOCKD *xd, uint8_t *upred,
2674 uint8_t *vpred, int ustride,
David Barkerac37fa32016-12-02 12:30:21 +00002675 int vstride, BUFFER_SET *ctx,
2676 BLOCK_SIZE bsize) {
2677 av1_build_interintra_predictors_sbc(xd, upred, ustride, ctx, 1, bsize);
2678 av1_build_interintra_predictors_sbc(xd, vpred, vstride, ctx, 2, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002679}
2680
Yaowu Xuf883b422016-08-30 14:01:10 -07002681void av1_build_interintra_predictors(MACROBLOCKD *xd, uint8_t *ypred,
2682 uint8_t *upred, uint8_t *vpred,
2683 int ystride, int ustride, int vstride,
David Barkerac37fa32016-12-02 12:30:21 +00002684 BUFFER_SET *ctx, BLOCK_SIZE bsize) {
2685 av1_build_interintra_predictors_sby(xd, ypred, ystride, ctx, bsize);
2686 av1_build_interintra_predictors_sbuv(xd, upred, vpred, ustride, vstride, ctx,
Yaowu Xuf883b422016-08-30 14:01:10 -07002687 bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002688}
2689
2690// Builds the inter-predictor for the single ref case
2691// for use in the encoder to search the wedges efficiently.
2692static void build_inter_predictors_single_buf(MACROBLOCKD *xd, int plane,
2693 int block, int bw, int bh, int x,
2694 int y, int w, int h, int mi_x,
2695 int mi_y, int ref,
2696 uint8_t *const ext_dst,
2697 int ext_dst_stride) {
2698 struct macroblockd_plane *const pd = &xd->plane[plane];
2699 const MODE_INFO *mi = xd->mi[0];
2700
2701 const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
2702 struct buf_2d *const pre_buf = &pd->pre[ref];
Yaowu Xuf883b422016-08-30 14:01:10 -07002703#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002704 uint8_t *const dst =
2705 (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH ? CONVERT_TO_BYTEPTR(ext_dst)
2706 : ext_dst) +
2707 ext_dst_stride * y + x;
2708#else
2709 uint8_t *const dst = ext_dst + ext_dst_stride * y + x;
2710#endif
2711 const MV mv = mi->mbmi.sb_type < BLOCK_8X8
2712 ? average_split_mvs(pd, mi, ref, block)
2713 : mi->mbmi.mv[ref].as_mv;
2714
2715 // TODO(jkoleszar): This clamping is done in the incorrect place for the
2716 // scaling case. It needs to be done on the scaled MV, not the pre-scaling
2717 // MV. Note however that it performs the subsampling aware scaling so
2718 // that the result is always q4.
2719 // mv_precision precision is MV_PRECISION_Q4.
2720 const MV mv_q4 = clamp_mv_to_umv_border_sb(xd, &mv, bw, bh, pd->subsampling_x,
2721 pd->subsampling_y);
2722
2723 uint8_t *pre;
2724 MV32 scaled_mv;
2725 int xs, ys, subpel_x, subpel_y;
Yaowu Xuf883b422016-08-30 14:01:10 -07002726 const int is_scaled = av1_is_scaled(sf);
Angie Chiang9f45bc42017-01-13 16:27:54 -08002727 ConvolveParams conv_params = get_conv_params(0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002728
2729 if (is_scaled) {
2730 pre = pre_buf->buf + scaled_buffer_offset(x, y, pre_buf->stride, sf);
Yaowu Xuf883b422016-08-30 14:01:10 -07002731 scaled_mv = av1_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002732 xs = sf->x_step_q4;
2733 ys = sf->y_step_q4;
2734 } else {
2735 pre = pre_buf->buf + (y * pre_buf->stride + x);
2736 scaled_mv.row = mv_q4.row;
2737 scaled_mv.col = mv_q4.col;
2738 xs = ys = 16;
2739 }
2740
2741 subpel_x = scaled_mv.col & SUBPEL_MASK;
2742 subpel_y = scaled_mv.row & SUBPEL_MASK;
2743 pre += (scaled_mv.row >> SUBPEL_BITS) * pre_buf->stride +
2744 (scaled_mv.col >> SUBPEL_BITS);
2745
Yaowu Xuf883b422016-08-30 14:01:10 -07002746 av1_make_inter_predictor(pre, pre_buf->stride, dst, ext_dst_stride, subpel_x,
Angie Chiang9f45bc42017-01-13 16:27:54 -08002747 subpel_y, sf, w, h, &conv_params,
2748 mi->mbmi.interp_filter, xs, ys, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002749}
2750
Yaowu Xuf883b422016-08-30 14:01:10 -07002751void av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07002752 MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane_from, int plane_to, int mi_row,
2753 int mi_col, int ref, uint8_t *ext_dst[3], int ext_dst_stride[3]) {
2754 int plane;
2755 const int mi_x = mi_col * MI_SIZE;
2756 const int mi_y = mi_row * MI_SIZE;
2757 for (plane = plane_from; plane <= plane_to; ++plane) {
2758 const BLOCK_SIZE plane_bsize =
2759 get_plane_block_size(bsize, &xd->plane[plane]);
2760 const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize];
2761 const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han691a6902016-11-30 14:53:44 -08002762 const int bw = block_size_wide[plane_bsize];
2763 const int bh = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002764
Jingning Han61418bb2017-01-23 17:12:48 -08002765 if (xd->mi[0]->mbmi.sb_type < BLOCK_8X8 && !CONFIG_CB4X4) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002766 int x, y;
2767 assert(bsize == BLOCK_8X8);
2768 for (y = 0; y < num_4x4_h; ++y)
2769 for (x = 0; x < num_4x4_w; ++x)
2770 build_inter_predictors_single_buf(
2771 xd, plane, y * 2 + x, bw, bh, 4 * x, 4 * y, 4, 4, mi_x, mi_y, ref,
2772 ext_dst[plane], ext_dst_stride[plane]);
2773 } else {
2774 build_inter_predictors_single_buf(xd, plane, 0, bw, bh, 0, 0, bw, bh,
2775 mi_x, mi_y, ref, ext_dst[plane],
2776 ext_dst_stride[plane]);
2777 }
2778 }
2779}
2780
2781static void build_wedge_inter_predictor_from_buf(
2782 MACROBLOCKD *xd, int plane, int x, int y, int w, int h, uint8_t *ext_dst0,
2783 int ext_dst_stride0, uint8_t *ext_dst1, int ext_dst_stride1) {
Sarah Parker569edda2016-12-14 14:57:38 -08002784 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002785 const int is_compound = has_second_ref(mbmi);
2786 MACROBLOCKD_PLANE *const pd = &xd->plane[plane];
2787 struct buf_2d *const dst_buf = &pd->dst;
2788 uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x;
Sarah Parker569edda2016-12-14 14:57:38 -08002789 INTERINTER_COMPOUND_DATA *comp_data = &mbmi->interinter_compound_data;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002790
Sarah Parker6fdc8532016-11-16 17:47:13 -08002791 if (is_compound &&
2792 is_masked_compound_type(mbmi->interinter_compound_data.type)) {
Sarah Parker569edda2016-12-14 14:57:38 -08002793#if CONFIG_COMPOUND_SEGMENT
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08002794#if CONFIG_AOM_HIGHBITDEPTH
2795 if (!plane && comp_data->type == COMPOUND_SEG) {
2796 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
2797 build_compound_seg_mask_highbd(
2798 comp_data->seg_mask, comp_data->mask_type,
2799 CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0,
2800 CONVERT_TO_BYTEPTR(ext_dst1), ext_dst_stride1, mbmi->sb_type, h, w,
2801 xd->bd);
2802 else
2803 build_compound_seg_mask(comp_data->seg_mask, comp_data->mask_type,
2804 ext_dst0, ext_dst_stride0, ext_dst1,
2805 ext_dst_stride1, mbmi->sb_type, h, w);
2806 }
2807#else
Sarah Parker569edda2016-12-14 14:57:38 -08002808 if (!plane && comp_data->type == COMPOUND_SEG)
Sarah Parkerb9f757c2017-01-06 17:12:24 -08002809 build_compound_seg_mask(comp_data->seg_mask, comp_data->mask_type,
2810 ext_dst0, ext_dst_stride0, ext_dst1,
Sarah Parker569edda2016-12-14 14:57:38 -08002811 ext_dst_stride1, mbmi->sb_type, h, w);
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08002812#endif // CONFIG_AOM_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08002813#endif // CONFIG_COMPOUND_SEGMENT
Yaowu Xuf883b422016-08-30 14:01:10 -07002814#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002815 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08002816 build_masked_compound_highbd(
Yaowu Xuc27fc142016-08-22 16:08:15 -07002817 dst, dst_buf->stride, CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08002818 CONVERT_TO_BYTEPTR(ext_dst1), ext_dst_stride1, comp_data,
2819 mbmi->sb_type, h, w, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002820 else
Yaowu Xuf883b422016-08-30 14:01:10 -07002821#endif // CONFIG_AOM_HIGHBITDEPTH
Sarah Parker6fdc8532016-11-16 17:47:13 -08002822 build_masked_compound(dst, dst_buf->stride, ext_dst0, ext_dst_stride0,
2823 ext_dst1, ext_dst_stride1, comp_data, mbmi->sb_type,
2824 h, w);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002825 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07002826#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002827 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
Yaowu Xuf883b422016-08-30 14:01:10 -07002828 aom_highbd_convolve_copy(CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002829 dst, dst_buf->stride, NULL, 0, NULL, 0, w, h,
2830 xd->bd);
2831 else
Yaowu Xuf883b422016-08-30 14:01:10 -07002832#endif // CONFIG_AOM_HIGHBITDEPTH
2833 aom_convolve_copy(ext_dst0, ext_dst_stride0, dst, dst_buf->stride, NULL,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002834 0, NULL, 0, w, h);
2835 }
2836}
2837
Yaowu Xuf883b422016-08-30 14:01:10 -07002838void av1_build_wedge_inter_predictor_from_buf(MACROBLOCKD *xd, BLOCK_SIZE bsize,
2839 int plane_from, int plane_to,
2840 uint8_t *ext_dst0[3],
2841 int ext_dst_stride0[3],
2842 uint8_t *ext_dst1[3],
2843 int ext_dst_stride1[3]) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002844 int plane;
2845 for (plane = plane_from; plane <= plane_to; ++plane) {
2846 const BLOCK_SIZE plane_bsize =
2847 get_plane_block_size(bsize, &xd->plane[plane]);
2848 const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize];
2849 const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize];
2850
Jingning Han61418bb2017-01-23 17:12:48 -08002851 if (xd->mi[0]->mbmi.sb_type < BLOCK_8X8 && !CONFIG_CB4X4) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002852 int x, y;
2853 assert(bsize == BLOCK_8X8);
2854 for (y = 0; y < num_4x4_h; ++y)
2855 for (x = 0; x < num_4x4_w; ++x)
2856 build_wedge_inter_predictor_from_buf(
2857 xd, plane, 4 * x, 4 * y, 4, 4, ext_dst0[plane],
2858 ext_dst_stride0[plane], ext_dst1[plane], ext_dst_stride1[plane]);
2859 } else {
Jingning Han61418bb2017-01-23 17:12:48 -08002860 const int bw = block_size_wide[plane_bsize];
2861 const int bh = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002862 build_wedge_inter_predictor_from_buf(
2863 xd, plane, 0, 0, bw, bh, ext_dst0[plane], ext_dst_stride0[plane],
2864 ext_dst1[plane], ext_dst_stride1[plane]);
2865 }
2866 }
2867}
2868#endif // CONFIG_EXT_INTER