blob: ba2ed889009ca763f899c96509c11839f342114d [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] = {
123 { 0, NULL, NULL, 0, NULL },
124 { 0, NULL, NULL, 0, NULL },
125 { 0, NULL, NULL, 0, NULL },
126 { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[3], 0, wedge_masks[3] },
127 { 4, wedge_codebook_16_hgtw, wedge_signflip_lookup[4], 0, wedge_masks[4] },
128 { 4, wedge_codebook_16_hltw, wedge_signflip_lookup[5], 0, wedge_masks[5] },
129 { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[6], 0, wedge_masks[6] },
130 { 4, wedge_codebook_16_hgtw, wedge_signflip_lookup[7], 0, wedge_masks[7] },
131 { 4, wedge_codebook_16_hltw, wedge_signflip_lookup[8], 0, wedge_masks[8] },
132 { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[9], 0, wedge_masks[9] },
133 { 0, wedge_codebook_8_hgtw, wedge_signflip_lookup[10], 0, wedge_masks[10] },
134 { 0, wedge_codebook_8_hltw, wedge_signflip_lookup[11], 0, wedge_masks[11] },
135 { 0, wedge_codebook_8_heqw, wedge_signflip_lookup[12], 0, wedge_masks[12] },
136#if CONFIG_EXT_PARTITION
137 { 0, NULL, NULL, 0, NULL },
138 { 0, NULL, NULL, 0, NULL },
139 { 0, NULL, NULL, 0, NULL },
140#endif // CONFIG_EXT_PARTITION
141};
142
143#else
144
145static const wedge_code_type wedge_codebook_32_hgtw[32] = {
146 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
147 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
148 { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 4 },
149 { WEDGE_HORIZONTAL, 4, 6 }, { WEDGE_VERTICAL, 4, 4 },
150 { WEDGE_OBLIQUE27, 4, 1 }, { WEDGE_OBLIQUE27, 4, 2 },
151 { WEDGE_OBLIQUE27, 4, 3 }, { WEDGE_OBLIQUE27, 4, 5 },
152 { WEDGE_OBLIQUE27, 4, 6 }, { WEDGE_OBLIQUE27, 4, 7 },
153 { WEDGE_OBLIQUE153, 4, 1 }, { WEDGE_OBLIQUE153, 4, 2 },
154 { WEDGE_OBLIQUE153, 4, 3 }, { WEDGE_OBLIQUE153, 4, 5 },
155 { WEDGE_OBLIQUE153, 4, 6 }, { WEDGE_OBLIQUE153, 4, 7 },
156 { WEDGE_OBLIQUE63, 1, 4 }, { WEDGE_OBLIQUE63, 2, 4 },
157 { WEDGE_OBLIQUE63, 3, 4 }, { WEDGE_OBLIQUE63, 5, 4 },
158 { WEDGE_OBLIQUE63, 6, 4 }, { WEDGE_OBLIQUE63, 7, 4 },
159 { WEDGE_OBLIQUE117, 1, 4 }, { WEDGE_OBLIQUE117, 2, 4 },
160 { WEDGE_OBLIQUE117, 3, 4 }, { WEDGE_OBLIQUE117, 5, 4 },
161 { WEDGE_OBLIQUE117, 6, 4 }, { WEDGE_OBLIQUE117, 7, 4 },
162};
163
164static const wedge_code_type wedge_codebook_32_hltw[32] = {
165 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
166 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
167 { WEDGE_VERTICAL, 2, 4 }, { WEDGE_VERTICAL, 4, 4 },
168 { WEDGE_VERTICAL, 6, 4 }, { WEDGE_HORIZONTAL, 4, 4 },
169 { WEDGE_OBLIQUE27, 4, 1 }, { WEDGE_OBLIQUE27, 4, 2 },
170 { WEDGE_OBLIQUE27, 4, 3 }, { WEDGE_OBLIQUE27, 4, 5 },
171 { WEDGE_OBLIQUE27, 4, 6 }, { WEDGE_OBLIQUE27, 4, 7 },
172 { WEDGE_OBLIQUE153, 4, 1 }, { WEDGE_OBLIQUE153, 4, 2 },
173 { WEDGE_OBLIQUE153, 4, 3 }, { WEDGE_OBLIQUE153, 4, 5 },
174 { WEDGE_OBLIQUE153, 4, 6 }, { WEDGE_OBLIQUE153, 4, 7 },
175 { WEDGE_OBLIQUE63, 1, 4 }, { WEDGE_OBLIQUE63, 2, 4 },
176 { WEDGE_OBLIQUE63, 3, 4 }, { WEDGE_OBLIQUE63, 5, 4 },
177 { WEDGE_OBLIQUE63, 6, 4 }, { WEDGE_OBLIQUE63, 7, 4 },
178 { WEDGE_OBLIQUE117, 1, 4 }, { WEDGE_OBLIQUE117, 2, 4 },
179 { WEDGE_OBLIQUE117, 3, 4 }, { WEDGE_OBLIQUE117, 5, 4 },
180 { WEDGE_OBLIQUE117, 6, 4 }, { WEDGE_OBLIQUE117, 7, 4 },
181};
182
183static const wedge_code_type wedge_codebook_32_heqw[32] = {
184 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
185 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
186 { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 6 },
187 { WEDGE_VERTICAL, 2, 4 }, { WEDGE_VERTICAL, 6, 4 },
188 { WEDGE_OBLIQUE27, 4, 1 }, { WEDGE_OBLIQUE27, 4, 2 },
189 { WEDGE_OBLIQUE27, 4, 3 }, { WEDGE_OBLIQUE27, 4, 5 },
190 { WEDGE_OBLIQUE27, 4, 6 }, { WEDGE_OBLIQUE27, 4, 7 },
191 { WEDGE_OBLIQUE153, 4, 1 }, { WEDGE_OBLIQUE153, 4, 2 },
192 { WEDGE_OBLIQUE153, 4, 3 }, { WEDGE_OBLIQUE153, 4, 5 },
193 { WEDGE_OBLIQUE153, 4, 6 }, { WEDGE_OBLIQUE153, 4, 7 },
194 { WEDGE_OBLIQUE63, 1, 4 }, { WEDGE_OBLIQUE63, 2, 4 },
195 { WEDGE_OBLIQUE63, 3, 4 }, { WEDGE_OBLIQUE63, 5, 4 },
196 { WEDGE_OBLIQUE63, 6, 4 }, { WEDGE_OBLIQUE63, 7, 4 },
197 { WEDGE_OBLIQUE117, 1, 4 }, { WEDGE_OBLIQUE117, 2, 4 },
198 { WEDGE_OBLIQUE117, 3, 4 }, { WEDGE_OBLIQUE117, 5, 4 },
199 { WEDGE_OBLIQUE117, 6, 4 }, { WEDGE_OBLIQUE117, 7, 4 },
200};
201
202const wedge_params_type wedge_params_lookup[BLOCK_SIZES] = {
203 { 0, NULL, NULL, 0, NULL },
204 { 0, NULL, NULL, 0, NULL },
205 { 0, NULL, NULL, 0, NULL },
206 { 5, wedge_codebook_32_heqw, wedge_signflip_lookup[3], 0, wedge_masks[3] },
207 { 5, wedge_codebook_32_hgtw, wedge_signflip_lookup[4], 0, wedge_masks[4] },
208 { 5, wedge_codebook_32_hltw, wedge_signflip_lookup[5], 0, wedge_masks[5] },
209 { 5, wedge_codebook_32_heqw, wedge_signflip_lookup[6], 0, wedge_masks[6] },
210 { 5, wedge_codebook_32_hgtw, wedge_signflip_lookup[7], 0, wedge_masks[7] },
211 { 5, wedge_codebook_32_hltw, wedge_signflip_lookup[8], 0, wedge_masks[8] },
212 { 5, wedge_codebook_32_heqw, wedge_signflip_lookup[9], 0, wedge_masks[9] },
213 { 0, wedge_codebook_8_hgtw, wedge_signflip_lookup[10], 0, wedge_masks[10] },
214 { 0, wedge_codebook_8_hltw, wedge_signflip_lookup[11], 0, wedge_masks[11] },
215 { 0, wedge_codebook_8_heqw, wedge_signflip_lookup[12], 0, wedge_masks[12] },
216#if CONFIG_EXT_PARTITION
217 { 0, NULL, NULL, 0, NULL },
218 { 0, NULL, NULL, 0, NULL },
219 { 0, NULL, NULL, 0, NULL },
220#endif // CONFIG_EXT_PARTITION
221};
222#endif // USE_LARGE_WEDGE_CODEBOOK
223
224static const uint8_t *get_wedge_mask_inplace(int wedge_index, int neg,
225 BLOCK_SIZE sb_type) {
226 const uint8_t *master;
227 const int bh = 4 << b_height_log2_lookup[sb_type];
228 const int bw = 4 << b_width_log2_lookup[sb_type];
229 const wedge_code_type *a =
230 wedge_params_lookup[sb_type].codebook + wedge_index;
231 const int smoother = wedge_params_lookup[sb_type].smoother;
232 int woff, hoff;
233 const uint8_t wsignflip = wedge_params_lookup[sb_type].signflip[wedge_index];
234
235 assert(wedge_index >= 0 &&
236 wedge_index < (1 << get_wedge_bits_lookup(sb_type)));
237 woff = (a->x_offset * bw) >> 3;
238 hoff = (a->y_offset * bh) >> 3;
239 master = wedge_mask_obl[smoother][neg ^ wsignflip][a->direction] +
240 MASK_MASTER_STRIDE * (MASK_MASTER_SIZE / 2 - hoff) +
241 MASK_MASTER_SIZE / 2 - woff;
242 return master;
243}
244
Yaowu Xuf883b422016-08-30 14:01:10 -0700245const uint8_t *av1_get_soft_mask(int wedge_index, int wedge_sign,
246 BLOCK_SIZE sb_type, int offset_x,
247 int offset_y) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700248 const uint8_t *mask =
249 get_wedge_mask_inplace(wedge_index, wedge_sign, sb_type);
250 if (mask) mask -= (offset_x + offset_y * MASK_MASTER_STRIDE);
251 return mask;
252}
253
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800254#if CONFIG_COMPOUND_SEGMENT
255static uint8_t *invert_mask(uint8_t *mask_inv_buffer, const uint8_t *const mask,
256 int h, int w, int stride) {
257 int i, j;
258
259 for (i = 0; i < h; ++i)
260 for (j = 0; j < w; ++j) {
261 mask_inv_buffer[i * stride + j] =
262 AOM_BLEND_A64_MAX_ALPHA - mask[i * stride + j];
263 }
264 return mask_inv_buffer;
265}
266#endif // CONFIG_COMPOUND_SEGMENT
267
268const uint8_t *av1_get_compound_type_mask_inverse(
269 const INTERINTER_COMPOUND_DATA *const comp_data,
270#if CONFIG_COMPOUND_SEGMENT
271 uint8_t *mask_buffer, int h, int w, int stride,
272#endif
273 BLOCK_SIZE sb_type) {
Sarah Parker6fdc8532016-11-16 17:47:13 -0800274 assert(is_masked_compound_type(comp_data->type));
275 switch (comp_data->type) {
276 case COMPOUND_WEDGE:
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800277 return av1_get_contiguous_soft_mask(comp_data->wedge_index,
278 !comp_data->wedge_sign, sb_type);
Sarah Parker569edda2016-12-14 14:57:38 -0800279#if CONFIG_COMPOUND_SEGMENT
280 case COMPOUND_SEG:
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800281 return invert_mask(mask_buffer, comp_data->seg_mask, h, w, stride);
282#endif // CONFIG_COMPOUND_SEGMENT
283 default: assert(0); return NULL;
284 }
285}
286
287const uint8_t *av1_get_compound_type_mask(
288 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type) {
289 assert(is_masked_compound_type(comp_data->type));
290 switch (comp_data->type) {
291 case COMPOUND_WEDGE:
292 return av1_get_contiguous_soft_mask(comp_data->wedge_index,
293 comp_data->wedge_sign, sb_type);
294#if CONFIG_COMPOUND_SEGMENT
295 case COMPOUND_SEG: return comp_data->seg_mask;
Sarah Parker569edda2016-12-14 14:57:38 -0800296#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -0800297 default: assert(0); return NULL;
298 }
299}
Sarah Parker569edda2016-12-14 14:57:38 -0800300
301#if CONFIG_COMPOUND_SEGMENT
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800302#if COMPOUND_SEGMENT_TYPE == 0
303static void uniform_mask(uint8_t *mask, int which_inverse, BLOCK_SIZE sb_type,
304 int h, int w, int mask_val) {
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800305 int i, j;
306 int block_stride = block_size_wide[sb_type];
307 for (i = 0; i < h; ++i)
308 for (j = 0; j < w; ++j) {
309 mask[i * block_stride + j] =
310 which_inverse ? AOM_BLEND_A64_MAX_ALPHA - mask_val : mask_val;
311 }
312}
313
314void build_compound_seg_mask(uint8_t *mask, SEG_MASK_TYPE mask_type,
Sarah Parker569edda2016-12-14 14:57:38 -0800315 const uint8_t *src0, int src0_stride,
316 const uint8_t *src1, int src1_stride,
317 BLOCK_SIZE sb_type, int h, int w) {
Sarah Parker569edda2016-12-14 14:57:38 -0800318 (void)src0;
319 (void)src1;
320 (void)src0_stride;
321 (void)src1_stride;
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800322 switch (mask_type) {
323 case UNIFORM_45: uniform_mask(mask, 0, sb_type, h, w, 45); break;
324 case UNIFORM_45_INV: uniform_mask(mask, 1, sb_type, h, w, 45); break;
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800325 default: assert(0);
326 }
Sarah Parker569edda2016-12-14 14:57:38 -0800327}
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800328
329#if CONFIG_AOM_HIGHBITDEPTH
330void build_compound_seg_mask_highbd(uint8_t *mask, SEG_MASK_TYPE mask_type,
331 const uint8_t *src0, int src0_stride,
332 const uint8_t *src1, int src1_stride,
333 BLOCK_SIZE sb_type, int h, int w, int bd) {
334 (void)src0;
335 (void)src1;
336 (void)src0_stride;
337 (void)src1_stride;
338 (void)bd;
339 switch (mask_type) {
340 case UNIFORM_45: uniform_mask(mask, 0, sb_type, h, w, 45); break;
341 case UNIFORM_45_INV: uniform_mask(mask, 1, sb_type, h, w, 45); break;
342 default: assert(0);
343 }
344}
345#endif // CONFIG_AOM_HIGHBITDEPTH
346
347#elif COMPOUND_SEGMENT_TYPE == 1
348#define DIFF_FACTOR 16
349static void diffwtd_mask(uint8_t *mask, int which_inverse, int mask_base,
350 const uint8_t *src0, int src0_stride,
351 const uint8_t *src1, int src1_stride,
352 BLOCK_SIZE sb_type, int h, int w) {
353 int i, j, m, diff;
354 int block_stride = block_size_wide[sb_type];
355 for (i = 0; i < h; ++i) {
356 for (j = 0; j < w; ++j) {
357 diff =
358 abs((int)src0[i * src0_stride + j] - (int)src1[i * src1_stride + j]);
359 m = clamp(mask_base + (diff / DIFF_FACTOR), 0, AOM_BLEND_A64_MAX_ALPHA);
360 mask[i * block_stride + j] =
361 which_inverse ? AOM_BLEND_A64_MAX_ALPHA - m : m;
362 }
363 }
364}
365
366void build_compound_seg_mask(uint8_t *mask, SEG_MASK_TYPE mask_type,
367 const uint8_t *src0, int src0_stride,
368 const uint8_t *src1, int src1_stride,
369 BLOCK_SIZE sb_type, int h, int w) {
370 switch (mask_type) {
371 case DIFFWTD_45:
372 diffwtd_mask(mask, 0, 47, src0, src0_stride, src1, src1_stride, sb_type,
373 h, w);
374 break;
375 case DIFFWTD_45_INV:
376 diffwtd_mask(mask, 1, 47, src0, src0_stride, src1, src1_stride, sb_type,
377 h, w);
378 break;
379 default: assert(0);
380 }
381}
382
383#if CONFIG_AOM_HIGHBITDEPTH
384static void diffwtd_mask_highbd(uint8_t *mask, int which_inverse, int mask_base,
385 const uint16_t *src0, int src0_stride,
386 const uint16_t *src1, int src1_stride,
387 BLOCK_SIZE sb_type, int h, int w, int bd) {
388 int i, j, m, diff;
389 int block_stride = block_size_wide[sb_type];
390 for (i = 0; i < h; ++i) {
391 for (j = 0; j < w; ++j) {
392 diff = abs((int)src0[i * src0_stride + j] -
393 (int)src1[i * src1_stride + j]) >>
394 (bd - 8);
395 m = clamp(mask_base + (diff / DIFF_FACTOR), 0, AOM_BLEND_A64_MAX_ALPHA);
396 mask[i * block_stride + j] =
397 which_inverse ? AOM_BLEND_A64_MAX_ALPHA - m : m;
398 }
399 }
400}
401
402void build_compound_seg_mask_highbd(uint8_t *mask, SEG_MASK_TYPE mask_type,
403 const uint8_t *src0, int src0_stride,
404 const uint8_t *src1, int src1_stride,
405 BLOCK_SIZE sb_type, int h, int w, int bd) {
406 switch (mask_type) {
407 case DIFFWTD_42:
408 diffwtd_mask_highbd(mask, 0, 42, CONVERT_TO_SHORTPTR(src0), src0_stride,
409 CONVERT_TO_SHORTPTR(src1), src1_stride, sb_type, h, w,
410 bd);
411 break;
412 case DIFFWTD_42_INV:
413 diffwtd_mask_highbd(mask, 1, 42, CONVERT_TO_SHORTPTR(src0), src0_stride,
414 CONVERT_TO_SHORTPTR(src1), src1_stride, sb_type, h, w,
415 bd);
416 break;
417 default: assert(0);
418 }
419}
420#endif // CONFIG_AOM_HIGHBITDEPTH
421#endif // COMPOUND_SEGMENT_TYPE
Sarah Parker569edda2016-12-14 14:57:38 -0800422#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -0800423
Yaowu Xuc27fc142016-08-22 16:08:15 -0700424static void init_wedge_master_masks() {
425 int i, j, s;
426 const int w = MASK_MASTER_SIZE;
427 const int h = MASK_MASTER_SIZE;
428 const int stride = MASK_MASTER_STRIDE;
429 const int a[2] = { 2, 1 };
430 const double asqrt = sqrt(a[0] * a[0] + a[1] * a[1]);
431 for (s = 0; s < NSMOOTHERS; s++) {
432 for (i = 0; i < h; ++i)
433 for (j = 0; j < w; ++j) {
434 int x = (2 * j + 1 - w);
435 int y = (2 * i + 1 - h);
436 int m = (int)rint((a[0] * x + a[1] * y) / asqrt);
437 wedge_mask_obl[s][1][WEDGE_OBLIQUE63][i * stride + j] =
438 wedge_mask_obl[s][1][WEDGE_OBLIQUE27][j * stride + i] =
439 get_masked_weight(m, s);
440 wedge_mask_obl[s][1][WEDGE_OBLIQUE117][i * stride + w - 1 - j] =
441 wedge_mask_obl[s][1][WEDGE_OBLIQUE153][(w - 1 - j) * stride + i] =
442 (1 << WEDGE_WEIGHT_BITS) - get_masked_weight(m, s);
443 wedge_mask_obl[s][0][WEDGE_OBLIQUE63][i * stride + j] =
444 wedge_mask_obl[s][0][WEDGE_OBLIQUE27][j * stride + i] =
445 (1 << WEDGE_WEIGHT_BITS) - get_masked_weight(m, s);
446 wedge_mask_obl[s][0][WEDGE_OBLIQUE117][i * stride + w - 1 - j] =
447 wedge_mask_obl[s][0][WEDGE_OBLIQUE153][(w - 1 - j) * stride + i] =
448 get_masked_weight(m, s);
449 wedge_mask_obl[s][1][WEDGE_VERTICAL][i * stride + j] =
450 wedge_mask_obl[s][1][WEDGE_HORIZONTAL][j * stride + i] =
451 get_masked_weight(x, s);
452 wedge_mask_obl[s][0][WEDGE_VERTICAL][i * stride + j] =
453 wedge_mask_obl[s][0][WEDGE_HORIZONTAL][j * stride + i] =
454 (1 << WEDGE_WEIGHT_BITS) - get_masked_weight(x, s);
455 }
456 }
457}
458
459// If the signs for the wedges for various blocksizes are
460// inconsistent flip the sign flag. Do it only once for every
461// wedge codebook.
462static void init_wedge_signs() {
463 BLOCK_SIZE sb_type;
464 memset(wedge_signflip_lookup, 0, sizeof(wedge_signflip_lookup));
465 for (sb_type = BLOCK_4X4; sb_type < BLOCK_SIZES; ++sb_type) {
Jingning Hanae5cfde2016-11-30 12:01:44 -0800466 const int bw = block_size_wide[sb_type];
467 const int bh = block_size_high[sb_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700468 const wedge_params_type wedge_params = wedge_params_lookup[sb_type];
469 const int wbits = wedge_params.bits;
470 const int wtypes = 1 << wbits;
471 int i, w;
472 if (wbits == 0) continue;
473 for (w = 0; w < wtypes; ++w) {
474 const uint8_t *mask = get_wedge_mask_inplace(w, 0, sb_type);
475 int sum = 0;
476 for (i = 0; i < bw; ++i) sum += mask[i];
477 for (i = 0; i < bh; ++i) sum += mask[i * MASK_MASTER_STRIDE];
478 sum = (sum + (bw + bh) / 2) / (bw + bh);
479 wedge_params.signflip[w] = (sum < 32);
480 }
481 }
482}
483
484static void init_wedge_masks() {
485 uint8_t *dst = wedge_mask_buf;
486 BLOCK_SIZE bsize;
487 memset(wedge_masks, 0, sizeof(wedge_masks));
488 for (bsize = BLOCK_4X4; bsize < BLOCK_SIZES; ++bsize) {
489 const uint8_t *mask;
Jingning Hanae5cfde2016-11-30 12:01:44 -0800490 const int bw = block_size_wide[bsize];
491 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700492 const wedge_params_type *wedge_params = &wedge_params_lookup[bsize];
493 const int wbits = wedge_params->bits;
494 const int wtypes = 1 << wbits;
495 int w;
496 if (wbits == 0) continue;
497 for (w = 0; w < wtypes; ++w) {
498 mask = get_wedge_mask_inplace(w, 0, bsize);
Yaowu Xuf883b422016-08-30 14:01:10 -0700499 aom_convolve_copy(mask, MASK_MASTER_STRIDE, dst, bw, NULL, 0, NULL, 0, bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700500 bh);
501 wedge_params->masks[0][w] = dst;
502 dst += bw * bh;
503
504 mask = get_wedge_mask_inplace(w, 1, bsize);
Yaowu Xuf883b422016-08-30 14:01:10 -0700505 aom_convolve_copy(mask, MASK_MASTER_STRIDE, dst, bw, NULL, 0, NULL, 0, bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700506 bh);
507 wedge_params->masks[1][w] = dst;
508 dst += bw * bh;
509 }
510 assert(sizeof(wedge_mask_buf) >= (size_t)(dst - wedge_mask_buf));
511 }
512}
513
514// 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 -0700515void av1_init_wedge_masks() {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700516 init_wedge_master_masks();
517 init_wedge_signs();
518 init_wedge_masks();
519}
520
521#if CONFIG_SUPERTX
522static void build_masked_compound_wedge_extend(
523 uint8_t *dst, int dst_stride, const uint8_t *src0, int src0_stride,
524 const uint8_t *src1, int src1_stride, int wedge_index, int wedge_sign,
525 BLOCK_SIZE sb_type, int wedge_offset_x, int wedge_offset_y, int h, int w) {
526 const int subh = (2 << b_height_log2_lookup[sb_type]) == h;
527 const int subw = (2 << b_width_log2_lookup[sb_type]) == w;
Yaowu Xuf883b422016-08-30 14:01:10 -0700528 const uint8_t *mask = av1_get_soft_mask(wedge_index, wedge_sign, sb_type,
529 wedge_offset_x, wedge_offset_y);
530 aom_blend_a64_mask(dst, dst_stride, src0, src0_stride, src1, src1_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700531 mask, MASK_MASTER_STRIDE, h, w, subh, subw);
532}
533
Yaowu Xuf883b422016-08-30 14:01:10 -0700534#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700535static void build_masked_compound_wedge_extend_highbd(
536 uint8_t *dst_8, int dst_stride, const uint8_t *src0_8, int src0_stride,
537 const uint8_t *src1_8, int src1_stride, int wedge_index, int wedge_sign,
538 BLOCK_SIZE sb_type, int wedge_offset_x, int wedge_offset_y, int h, int w,
539 int bd) {
540 const int subh = (2 << b_height_log2_lookup[sb_type]) == h;
541 const int subw = (2 << b_width_log2_lookup[sb_type]) == w;
Yaowu Xuf883b422016-08-30 14:01:10 -0700542 const uint8_t *mask = av1_get_soft_mask(wedge_index, wedge_sign, sb_type,
543 wedge_offset_x, wedge_offset_y);
544 aom_highbd_blend_a64_mask(dst_8, dst_stride, src0_8, src0_stride, src1_8,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700545 src1_stride, mask, MASK_MASTER_STRIDE, h, w, subh,
546 subw, bd);
547}
Yaowu Xuf883b422016-08-30 14:01:10 -0700548#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700549#endif // CONFIG_SUPERTX
550
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800551static void build_masked_compound(
552 uint8_t *dst, int dst_stride, const uint8_t *src0, int src0_stride,
553 const uint8_t *src1, int src1_stride,
554 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type, int h,
555 int w) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700556 // Derive subsampling from h and w passed in. May be refactored to
557 // pass in subsampling factors directly.
558 const int subh = (2 << b_height_log2_lookup[sb_type]) == h;
559 const int subw = (2 << b_width_log2_lookup[sb_type]) == w;
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800560 const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type);
Yaowu Xuf883b422016-08-30 14:01:10 -0700561 aom_blend_a64_mask(dst, dst_stride, src0, src0_stride, src1, src1_stride,
Jingning Hanae5cfde2016-11-30 12:01:44 -0800562 mask, block_size_wide[sb_type], h, w, subh, subw);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700563}
564
Yaowu Xuf883b422016-08-30 14:01:10 -0700565#if CONFIG_AOM_HIGHBITDEPTH
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800566static void build_masked_compound_highbd(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700567 uint8_t *dst_8, int dst_stride, const uint8_t *src0_8, int src0_stride,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800568 const uint8_t *src1_8, int src1_stride,
569 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type, int h,
570 int w, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700571 // Derive subsampling from h and w passed in. May be refactored to
572 // pass in subsampling factors directly.
573 const int subh = (2 << b_height_log2_lookup[sb_type]) == h;
574 const int subw = (2 << b_width_log2_lookup[sb_type]) == w;
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800575 const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type);
576 // const uint8_t *mask =
577 // av1_get_contiguous_soft_mask(wedge_index, wedge_sign, sb_type);
Jingning Hanae5cfde2016-11-30 12:01:44 -0800578 aom_highbd_blend_a64_mask(dst_8, dst_stride, src0_8, src0_stride, src1_8,
579 src1_stride, mask, block_size_wide[sb_type], h, w,
580 subh, subw, bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700581}
Yaowu Xuf883b422016-08-30 14:01:10 -0700582#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700583
Yaowu Xuf883b422016-08-30 14:01:10 -0700584void av1_make_masked_inter_predictor(const uint8_t *pre, int pre_stride,
585 uint8_t *dst, int dst_stride,
586 const int subpel_x, const int subpel_y,
587 const struct scale_factors *sf, int w,
588 int h,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700589#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -0700590 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700591#else
James Zern7b9407a2016-05-18 23:48:05 -0700592 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700593#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700594 int xs, int ys,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700595#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -0700596 int wedge_offset_x, int wedge_offset_y,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700597#endif // CONFIG_SUPERTX
Sarah Parker569edda2016-12-14 14:57:38 -0800598#if CONFIG_COMPOUND_SEGMENT
599 int plane,
600#endif // CONFIG_COMPOUND_SEGMENT
601 MACROBLOCKD *xd) {
602 MODE_INFO *mi = xd->mi[0];
603 INTERINTER_COMPOUND_DATA *comp_data = &mi->mbmi.interinter_compound_data;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700604// The prediction filter types used here should be those for
605// the second reference block.
606#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -0700607 InterpFilter tmp_ipf[4] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700608 interp_filter[2], interp_filter[3], interp_filter[2], interp_filter[3],
609 };
610#else
James Zern7b9407a2016-05-18 23:48:05 -0700611 InterpFilter tmp_ipf = interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700612#endif // CONFIG_DUAL_FILTER
Angie Chiang9f45bc42017-01-13 16:27:54 -0800613 ConvolveParams conv_params = get_conv_params(0);
Yaowu Xuf883b422016-08-30 14:01:10 -0700614#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700615 DECLARE_ALIGNED(16, uint8_t, tmp_dst_[2 * MAX_SB_SQUARE]);
616 uint8_t *tmp_dst = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
617 ? CONVERT_TO_BYTEPTR(tmp_dst_)
618 : tmp_dst_;
Yaowu Xuf883b422016-08-30 14:01:10 -0700619 av1_make_inter_predictor(pre, pre_stride, tmp_dst, MAX_SB_SIZE, subpel_x,
Angie Chiang9f45bc42017-01-13 16:27:54 -0800620 subpel_y, sf, w, h, &conv_params, tmp_ipf, xs, ys,
621 xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700622#if CONFIG_SUPERTX
623 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
624 build_masked_compound_wedge_extend_highbd(
625 dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE,
Sarah Parker6fdc8532016-11-16 17:47:13 -0800626 comp_data->wedge_index, comp_data->wedge_sign, mi->mbmi.sb_type,
627 wedge_offset_x, wedge_offset_y, h, w, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700628 else
629 build_masked_compound_wedge_extend(
630 dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE,
Sarah Parker6fdc8532016-11-16 17:47:13 -0800631 comp_data->wedge_index, comp_data->wedge_sign, mi->mbmi.sb_type,
632 wedge_offset_x, wedge_offset_y, h, w);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700633#else
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800634#if CONFIG_COMPOUND_SEGMENT
635 if (!plane && comp_data->type == COMPOUND_SEG) {
636 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
637 build_compound_seg_mask_highbd(comp_data->seg_mask, comp_data->mask_type,
638 dst, dst_stride, tmp_dst, MAX_SB_SIZE,
639 mi->mbmi.sb_type, h, w, xd->bd);
640 else
641 build_compound_seg_mask(comp_data->seg_mask, comp_data->mask_type, dst,
642 dst_stride, tmp_dst, MAX_SB_SIZE,
643 mi->mbmi.sb_type, h, w);
644 }
645#endif // CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -0700646 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800647 build_masked_compound_highbd(dst, dst_stride, dst, dst_stride, tmp_dst,
648 MAX_SB_SIZE, comp_data, mi->mbmi.sb_type, h, w,
649 xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700650 else
Sarah Parker6fdc8532016-11-16 17:47:13 -0800651 build_masked_compound(dst, dst_stride, dst, dst_stride, tmp_dst,
652 MAX_SB_SIZE, comp_data, mi->mbmi.sb_type, h, w);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700653#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -0700654#else // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700655 DECLARE_ALIGNED(16, uint8_t, tmp_dst[MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -0700656 av1_make_inter_predictor(pre, pre_stride, tmp_dst, MAX_SB_SIZE, subpel_x,
Angie Chiang9f45bc42017-01-13 16:27:54 -0800657 subpel_y, sf, w, h, &conv_params, tmp_ipf, xs, ys,
658 xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700659#if CONFIG_SUPERTX
Sarah Parker6fdc8532016-11-16 17:47:13 -0800660 build_masked_compound_wedge_extend(dst, dst_stride, dst, dst_stride, tmp_dst,
661 MAX_SB_SIZE, comp_data->wedge_index,
662 comp_data->wedge_sign, mi->mbmi.sb_type,
663 wedge_offset_x, wedge_offset_y, h, w);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700664#else
Sarah Parker569edda2016-12-14 14:57:38 -0800665#if CONFIG_COMPOUND_SEGMENT
666 if (!plane && comp_data->type == COMPOUND_SEG)
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800667 build_compound_seg_mask(comp_data->seg_mask, comp_data->mask_type, dst,
668 dst_stride, tmp_dst, MAX_SB_SIZE, mi->mbmi.sb_type,
669 h, w);
Sarah Parker569edda2016-12-14 14:57:38 -0800670#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -0800671 build_masked_compound(dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE,
672 comp_data, mi->mbmi.sb_type, h, w);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700673#endif // CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -0700674#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700675}
676#endif // CONFIG_EXT_INTER
677
Yaowu Xuf883b422016-08-30 14:01:10 -0700678#if CONFIG_AOM_HIGHBITDEPTH
679void av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700680 const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride,
681 const MV *src_mv, const struct scale_factors *sf, int w, int h, int ref,
682#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -0700683 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700684#else
James Zern7b9407a2016-05-18 23:48:05 -0700685 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700686#endif
687 enum mv_precision precision, int x, int y, int bd) {
688 const int is_q4 = precision == MV_PRECISION_Q4;
689 const MV mv_q4 = { is_q4 ? src_mv->row : src_mv->row * 2,
690 is_q4 ? src_mv->col : src_mv->col * 2 };
Yaowu Xuf883b422016-08-30 14:01:10 -0700691 MV32 mv = av1_scale_mv(&mv_q4, x, y, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700692 const int subpel_x = mv.col & SUBPEL_MASK;
693 const int subpel_y = mv.row & SUBPEL_MASK;
694
695 src += (mv.row >> SUBPEL_BITS) * src_stride + (mv.col >> SUBPEL_BITS);
696
697 highbd_inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y,
698 sf, w, h, ref, interp_filter, sf->x_step_q4,
699 sf->y_step_q4, bd);
700}
Yaowu Xuf883b422016-08-30 14:01:10 -0700701#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700702
Yaowu Xuf883b422016-08-30 14:01:10 -0700703void av1_build_inter_predictor(const uint8_t *src, int src_stride, uint8_t *dst,
704 int dst_stride, const MV *src_mv,
705 const struct scale_factors *sf, int w, int h,
Angie Chiang9f45bc42017-01-13 16:27:54 -0800706 ConvolveParams *conv_params,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700707#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -0700708 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700709#else
James Zern7b9407a2016-05-18 23:48:05 -0700710 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700711#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700712 enum mv_precision precision, int x, int y) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700713 const int is_q4 = precision == MV_PRECISION_Q4;
714 const MV mv_q4 = { is_q4 ? src_mv->row : src_mv->row * 2,
715 is_q4 ? src_mv->col : src_mv->col * 2 };
Yaowu Xuf883b422016-08-30 14:01:10 -0700716 MV32 mv = av1_scale_mv(&mv_q4, x, y, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700717 const int subpel_x = mv.col & SUBPEL_MASK;
718 const int subpel_y = mv.row & SUBPEL_MASK;
719
720 src += (mv.row >> SUBPEL_BITS) * src_stride + (mv.col >> SUBPEL_BITS);
721
722 inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y, sf, w,
Angie Chiang9f45bc42017-01-13 16:27:54 -0800723 h, conv_params, interp_filter, sf->x_step_q4, sf->y_step_q4);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700724}
725
726void build_inter_predictors(MACROBLOCKD *xd, int plane,
Yue Chencb60b182016-10-13 15:18:22 -0700727#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700728 int mi_col_offset, int mi_row_offset,
Yue Chencb60b182016-10-13 15:18:22 -0700729#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700730 int block, int bw, int bh, int x, int y, int w,
731 int h,
732#if CONFIG_SUPERTX && CONFIG_EXT_INTER
733 int wedge_offset_x, int wedge_offset_y,
734#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
735 int mi_x, int mi_y) {
736 struct macroblockd_plane *const pd = &xd->plane[plane];
Yue Chencb60b182016-10-13 15:18:22 -0700737#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700738 const MODE_INFO *mi = xd->mi[mi_col_offset + xd->mi_stride * mi_row_offset];
Yue Chen894fcce2016-10-21 16:50:52 -0700739 const int build_for_obmc = !(mi_col_offset == 0 && mi_row_offset == 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700740#else
741 const MODE_INFO *mi = xd->mi[0];
Yue Chencb60b182016-10-13 15:18:22 -0700742#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700743 const int is_compound = has_second_ref(&mi->mbmi);
744 int ref;
745#if CONFIG_GLOBAL_MOTION
David Barkercf3d0b02016-11-10 10:14:49 +0000746 WarpedMotionParams *gm[2];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700747 int is_global[2];
748 for (ref = 0; ref < 1 + is_compound; ++ref) {
749 gm[ref] = &xd->global_motion[mi->mbmi.ref_frame[ref]];
750 is_global[ref] =
Debargha Mukherjeee3e00792016-11-13 11:35:44 -0800751 (get_y_mode(mi, block) == ZEROMV && gm[ref]->wmtype > TRANSLATION);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700752 }
753 // TODO(sarahparker) remove these once gm works with all experiments
754 (void)gm;
755 (void)is_global;
756#endif // CONFIG_GLOBAL_MOTION
757
Jingning Hanb46540c2016-12-14 10:59:20 -0800758#if CONFIG_CB4X4
759 (void)block;
760#endif
761
Yaowu Xuc27fc142016-08-22 16:08:15 -0700762// TODO(sarahparker) enable the use of DUAL_FILTER in warped motion functions
763// in order to allow GLOBAL_MOTION and DUAL_FILTER to work together
Jingning Han46003142016-11-02 14:57:11 -0700764#if CONFIG_SUB8X8_MC
Yue Chen894fcce2016-10-21 16:50:52 -0700765#if CONFIG_MOTION_VAR
766 if (mi->mbmi.sb_type < BLOCK_8X8 && plane > 0 && !build_for_obmc) {
767#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700768 if (mi->mbmi.sb_type < BLOCK_8X8 && plane > 0) {
Yue Chen894fcce2016-10-21 16:50:52 -0700769#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700770 // block size in log2
771 const int b4_wl = b_width_log2_lookup[mi->mbmi.sb_type];
772 const int b4_hl = b_height_log2_lookup[mi->mbmi.sb_type];
773 const int b8_sl = b_width_log2_lookup[BLOCK_8X8];
774
775 // block size
776 const int b4_w = 1 << b4_wl;
777 const int b4_h = 1 << b4_hl;
778 const int b8_s = 1 << b8_sl;
779 int idx, idy;
780
781 const int x_base = x;
782 const int y_base = y;
783
784 // processing unit size
785 const int x_step = w >> (b8_sl - b4_wl);
786 const int y_step = h >> (b8_sl - b4_hl);
787
788 for (idy = 0; idy < b8_s; idy += b4_h) {
789 for (idx = 0; idx < b8_s; idx += b4_w) {
790 const int chr_idx = (idy * 2) + idx;
791 for (ref = 0; ref < 1 + is_compound; ++ref) {
792 const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
793 struct buf_2d *const pre_buf = &pd->pre[ref];
794 struct buf_2d *const dst_buf = &pd->dst;
795 uint8_t *dst = dst_buf->buf;
796 const MV mv = mi->bmi[chr_idx].as_mv[ref].as_mv;
797 const MV mv_q4 = clamp_mv_to_umv_border_sb(
798 xd, &mv, bw, bh, pd->subsampling_x, pd->subsampling_y);
799 uint8_t *pre;
800 MV32 scaled_mv;
801 int xs, ys, subpel_x, subpel_y;
Yaowu Xuf883b422016-08-30 14:01:10 -0700802 const int is_scaled = av1_is_scaled(sf);
Angie Chiang9f45bc42017-01-13 16:27:54 -0800803 ConvolveParams conv_params = get_conv_params(ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700804
805 x = x_base + idx * x_step;
806 y = y_base + idy * y_step;
807
808 dst += dst_buf->stride * y + x;
809
810 if (is_scaled) {
811 pre =
812 pre_buf->buf + scaled_buffer_offset(x, y, pre_buf->stride, sf);
Yaowu Xuf883b422016-08-30 14:01:10 -0700813 scaled_mv = av1_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700814 xs = sf->x_step_q4;
815 ys = sf->y_step_q4;
816 } else {
817 pre = pre_buf->buf + y * pre_buf->stride + x;
818 scaled_mv.row = mv_q4.row;
819 scaled_mv.col = mv_q4.col;
820 xs = ys = 16;
821 }
822
823 subpel_x = scaled_mv.col & SUBPEL_MASK;
824 subpel_y = scaled_mv.row & SUBPEL_MASK;
825 pre += (scaled_mv.row >> SUBPEL_BITS) * pre_buf->stride +
826 (scaled_mv.col >> SUBPEL_BITS);
827
828#if CONFIG_EXT_INTER
Sarah Parker6fdc8532016-11-16 17:47:13 -0800829 if (ref &&
830 is_masked_compound_type(mi->mbmi.interinter_compound_data.type))
Yaowu Xuf883b422016-08-30 14:01:10 -0700831 av1_make_masked_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700832 pre, pre_buf->stride, dst, dst_buf->stride, subpel_x, subpel_y,
833 sf, w, h, mi->mbmi.interp_filter, xs, ys,
834#if CONFIG_SUPERTX
835 wedge_offset_x, wedge_offset_y,
836#endif // CONFIG_SUPERTX
Sarah Parker569edda2016-12-14 14:57:38 -0800837#if CONFIG_COMPOUND_SEGMENT
838 plane,
839#endif // CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -0700840 xd);
841 else
842#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -0700843 av1_make_inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride,
844 subpel_x, subpel_y, sf, x_step, y_step,
Angie Chiang9f45bc42017-01-13 16:27:54 -0800845 &conv_params, mi->mbmi.interp_filter, xs,
846 ys, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700847 }
848 }
849 }
850 return;
851 }
852#endif
853
854 for (ref = 0; ref < 1 + is_compound; ++ref) {
855 const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
856 struct buf_2d *const pre_buf = &pd->pre[ref];
857 struct buf_2d *const dst_buf = &pd->dst;
858 uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x;
Jingning Hanb46540c2016-12-14 10:59:20 -0800859#if CONFIG_CB4X4
860 const MV mv = mi->mbmi.mv[ref].as_mv;
861#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700862 const MV mv = mi->mbmi.sb_type < BLOCK_8X8
Yue Chen894fcce2016-10-21 16:50:52 -0700863#if CONFIG_MOTION_VAR
864 ? (build_for_obmc ? mi->bmi[block].as_mv[ref].as_mv
865 : average_split_mvs(pd, mi, ref, block))
866#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700867 ? average_split_mvs(pd, mi, ref, block)
Yue Chen894fcce2016-10-21 16:50:52 -0700868#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700869 : mi->mbmi.mv[ref].as_mv;
Jingning Hanb46540c2016-12-14 10:59:20 -0800870#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700871
872 // TODO(jkoleszar): This clamping is done in the incorrect place for the
873 // scaling case. It needs to be done on the scaled MV, not the pre-scaling
874 // MV. Note however that it performs the subsampling aware scaling so
875 // that the result is always q4.
876 // mv_precision precision is MV_PRECISION_Q4.
877 const MV mv_q4 = clamp_mv_to_umv_border_sb(
878 xd, &mv, bw, bh, pd->subsampling_x, pd->subsampling_y);
879
880 uint8_t *pre;
881 MV32 scaled_mv;
882 int xs, ys, subpel_x, subpel_y;
Yaowu Xuf883b422016-08-30 14:01:10 -0700883 const int is_scaled = av1_is_scaled(sf);
Angie Chiang9f45bc42017-01-13 16:27:54 -0800884 ConvolveParams conv_params = get_conv_params(ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700885
886 if (is_scaled) {
887 pre = pre_buf->buf + scaled_buffer_offset(x, y, pre_buf->stride, sf);
Yaowu Xuf883b422016-08-30 14:01:10 -0700888 scaled_mv = av1_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700889 xs = sf->x_step_q4;
890 ys = sf->y_step_q4;
891 } else {
892 pre = pre_buf->buf + (y * pre_buf->stride + x);
893 scaled_mv.row = mv_q4.row;
894 scaled_mv.col = mv_q4.col;
895 xs = ys = 16;
896 }
897
898 subpel_x = scaled_mv.col & SUBPEL_MASK;
899 subpel_y = scaled_mv.row & SUBPEL_MASK;
900 pre += (scaled_mv.row >> SUBPEL_BITS) * pre_buf->stride +
901 (scaled_mv.col >> SUBPEL_BITS);
902
903#if CONFIG_EXT_INTER
Sarah Parker6fdc8532016-11-16 17:47:13 -0800904 if (ref && is_masked_compound_type(mi->mbmi.interinter_compound_data.type))
Yaowu Xuf883b422016-08-30 14:01:10 -0700905 av1_make_masked_inter_predictor(pre, pre_buf->stride, dst,
906 dst_buf->stride, subpel_x, subpel_y, sf,
907 w, h, mi->mbmi.interp_filter, xs, ys,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700908#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -0700909 wedge_offset_x, wedge_offset_y,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700910#endif // CONFIG_SUPERTX
Sarah Parker569edda2016-12-14 14:57:38 -0800911#if CONFIG_COMPOUND_SEGMENT
912 plane,
913#endif // CONFIG_COMPOUND_SEGMENT
Yaowu Xuf883b422016-08-30 14:01:10 -0700914 xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700915 else
916#else // CONFIG_EXT_INTER
917#if CONFIG_GLOBAL_MOTION
918 if (is_global[ref])
David Barkercf3d0b02016-11-10 10:14:49 +0000919 av1_warp_plane(gm[ref],
Yaowu Xuf883b422016-08-30 14:01:10 -0700920#if CONFIG_AOM_HIGHBITDEPTH
921 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
922#endif // CONFIG_AOM_HIGHBITDEPTH
923 pre_buf->buf0, pre_buf->width, pre_buf->height,
924 pre_buf->stride, dst, (mi_x >> pd->subsampling_x) + x,
925 (mi_y >> pd->subsampling_y) + y, w, h, dst_buf->stride,
Sarah Parker43d56f32016-10-21 17:06:37 -0700926 pd->subsampling_x, pd->subsampling_y, xs, ys, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700927 else
928#endif // CONFIG_GLOBAL_MOTION
929#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -0700930 av1_make_inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride,
Angie Chiang9f45bc42017-01-13 16:27:54 -0800931 subpel_x, subpel_y, sf, w, h, &conv_params,
Yaowu Xuf883b422016-08-30 14:01:10 -0700932 mi->mbmi.interp_filter, xs, ys, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700933 }
934}
935
Yaowu Xuf883b422016-08-30 14:01:10 -0700936void av1_build_inter_predictor_sub8x8(MACROBLOCKD *xd, int plane, int i, int ir,
937 int ic, int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700938 struct macroblockd_plane *const pd = &xd->plane[plane];
939 MODE_INFO *const mi = xd->mi[0];
940 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
Jingning Hanae5cfde2016-11-30 12:01:44 -0800941 const int width = block_size_wide[plane_bsize];
942 const int height = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700943 uint8_t *const dst = &pd->dst.buf[(ir * pd->dst.stride + ic) << 2];
944 int ref;
945 const int is_compound = has_second_ref(&mi->mbmi);
946
947 for (ref = 0; ref < 1 + is_compound; ++ref) {
Angie Chiang9f45bc42017-01-13 16:27:54 -0800948 ConvolveParams conv_params = get_conv_params(ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700949 const uint8_t *pre =
950 &pd->pre[ref].buf[(ir * pd->pre[ref].stride + ic) << 2];
Yaowu Xuf883b422016-08-30 14:01:10 -0700951#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700952 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700953 av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700954 pre, pd->pre[ref].stride, dst, pd->dst.stride,
955 &mi->bmi[i].as_mv[ref].as_mv, &xd->block_refs[ref]->sf, width, height,
956 ref, mi->mbmi.interp_filter, MV_PRECISION_Q3,
957 mi_col * MI_SIZE + 4 * ic, mi_row * MI_SIZE + 4 * ir, xd->bd);
958 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700959 av1_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700960 pre, pd->pre[ref].stride, dst, pd->dst.stride,
961 &mi->bmi[i].as_mv[ref].as_mv, &xd->block_refs[ref]->sf, width, height,
Angie Chiang9f45bc42017-01-13 16:27:54 -0800962 &conv_params, mi->mbmi.interp_filter, MV_PRECISION_Q3,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700963 mi_col * MI_SIZE + 4 * ic, mi_row * MI_SIZE + 4 * ir);
964 }
965#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700966 av1_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700967 pre, pd->pre[ref].stride, dst, pd->dst.stride,
968 &mi->bmi[i].as_mv[ref].as_mv, &xd->block_refs[ref]->sf, width, height,
Angie Chiang9f45bc42017-01-13 16:27:54 -0800969 &conv_params, mi->mbmi.interp_filter, MV_PRECISION_Q3,
970 mi_col * MI_SIZE + 4 * ic, mi_row * MI_SIZE + 4 * ir);
Yaowu Xuf883b422016-08-30 14:01:10 -0700971#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700972 }
973}
974
975static void build_inter_predictors_for_planes(MACROBLOCKD *xd, BLOCK_SIZE bsize,
976 int mi_row, int mi_col,
977 int plane_from, int plane_to) {
978 int plane;
979 const int mi_x = mi_col * MI_SIZE;
980 const int mi_y = mi_row * MI_SIZE;
Jingning Hanb46540c2016-12-14 10:59:20 -0800981#if CONFIG_CB4X4
982 const int unify_bsize = 1;
983#else
984 const int unify_bsize = 0;
985#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700986 for (plane = plane_from; plane <= plane_to; ++plane) {
987 const struct macroblockd_plane *pd = &xd->plane[plane];
Jingning Hanae5cfde2016-11-30 12:01:44 -0800988 const int bw = block_size_wide[bsize] >> pd->subsampling_x;
989 const int bh = block_size_high[bsize] >> pd->subsampling_y;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700990
Jingning Hanb46540c2016-12-14 10:59:20 -0800991 if (xd->mi[0]->mbmi.sb_type < BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700992 const PARTITION_TYPE bp = bsize - xd->mi[0]->mbmi.sb_type;
993 const int have_vsplit = bp != PARTITION_HORZ;
994 const int have_hsplit = bp != PARTITION_VERT;
995 const int num_4x4_w = 2 >> ((!have_vsplit) | pd->subsampling_x);
996 const int num_4x4_h = 2 >> ((!have_hsplit) | pd->subsampling_y);
997 const int pw = 8 >> (have_vsplit | pd->subsampling_x);
998 const int ph = 8 >> (have_hsplit | pd->subsampling_y);
999 int x, y;
1000 assert(bp != PARTITION_NONE && bp < PARTITION_TYPES);
1001 assert(bsize == BLOCK_8X8);
1002 assert(pw * num_4x4_w == bw && ph * num_4x4_h == bh);
1003 for (y = 0; y < num_4x4_h; ++y)
1004 for (x = 0; x < num_4x4_w; ++x)
1005 build_inter_predictors(xd, plane,
Yue Chencb60b182016-10-13 15:18:22 -07001006#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001007 0, 0,
Yue Chencb60b182016-10-13 15:18:22 -07001008#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001009 y * 2 + x, bw, bh, 4 * x, 4 * y, pw, ph,
1010#if CONFIG_SUPERTX && CONFIG_EXT_INTER
1011 0, 0,
1012#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
1013 mi_x, mi_y);
1014 } else {
1015 build_inter_predictors(xd, plane,
Yue Chencb60b182016-10-13 15:18:22 -07001016#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001017 0, 0,
Yue Chencb60b182016-10-13 15:18:22 -07001018#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001019 0, bw, bh, 0, 0, bw, bh,
1020#if CONFIG_SUPERTX && CONFIG_EXT_INTER
1021 0, 0,
1022#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
1023 mi_x, mi_y);
1024 }
1025 }
1026}
1027
Yaowu Xuf883b422016-08-30 14:01:10 -07001028void av1_build_inter_predictors_sby(MACROBLOCKD *xd, int mi_row, int mi_col,
David Barkerac37fa32016-12-02 12:30:21 +00001029 BUFFER_SET *ctx, BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001030 build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 0, 0);
1031#if CONFIG_EXT_INTER
David Barkerac37fa32016-12-02 12:30:21 +00001032 if (is_interintra_pred(&xd->mi[0]->mbmi)) {
1033 BUFFER_SET default_ctx = { { xd->plane[0].dst.buf, NULL, NULL },
1034 { xd->plane[0].dst.stride, 0, 0 } };
1035 if (!ctx) ctx = &default_ctx;
Yaowu Xuf883b422016-08-30 14:01:10 -07001036 av1_build_interintra_predictors_sby(xd, xd->plane[0].dst.buf,
David Barkerac37fa32016-12-02 12:30:21 +00001037 xd->plane[0].dst.stride, ctx, bsize);
1038 }
1039#else
1040 (void)ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001041#endif // CONFIG_EXT_INTER
1042}
1043
Yaowu Xuf883b422016-08-30 14:01:10 -07001044void av1_build_inter_predictors_sbp(MACROBLOCKD *xd, int mi_row, int mi_col,
David Barkerac37fa32016-12-02 12:30:21 +00001045 BUFFER_SET *ctx, BLOCK_SIZE bsize,
1046 int plane) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001047 build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, plane, plane);
1048#if CONFIG_EXT_INTER
1049 if (is_interintra_pred(&xd->mi[0]->mbmi)) {
David Barkerac37fa32016-12-02 12:30:21 +00001050 BUFFER_SET default_ctx = {
1051 { xd->plane[0].dst.buf, xd->plane[1].dst.buf, xd->plane[2].dst.buf },
1052 { xd->plane[0].dst.stride, xd->plane[1].dst.stride,
1053 xd->plane[2].dst.stride }
1054 };
1055 if (!ctx) ctx = &default_ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001056 if (plane == 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001057 av1_build_interintra_predictors_sby(xd, xd->plane[0].dst.buf,
David Barkerac37fa32016-12-02 12:30:21 +00001058 xd->plane[0].dst.stride, ctx, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001059 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001060 av1_build_interintra_predictors_sbc(xd, xd->plane[plane].dst.buf,
David Barkerac37fa32016-12-02 12:30:21 +00001061 xd->plane[plane].dst.stride, ctx,
1062 plane, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001063 }
1064 }
David Barkerac37fa32016-12-02 12:30:21 +00001065#else
1066 (void)ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001067#endif // CONFIG_EXT_INTER
1068}
1069
Yaowu Xuf883b422016-08-30 14:01:10 -07001070void av1_build_inter_predictors_sbuv(MACROBLOCKD *xd, int mi_row, int mi_col,
David Barkerac37fa32016-12-02 12:30:21 +00001071 BUFFER_SET *ctx, BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001072 build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 1,
1073 MAX_MB_PLANE - 1);
1074#if CONFIG_EXT_INTER
David Barkerac37fa32016-12-02 12:30:21 +00001075 if (is_interintra_pred(&xd->mi[0]->mbmi)) {
1076 BUFFER_SET default_ctx = {
1077 { NULL, xd->plane[1].dst.buf, xd->plane[2].dst.buf },
1078 { 0, xd->plane[1].dst.stride, xd->plane[2].dst.stride }
1079 };
1080 if (!ctx) ctx = &default_ctx;
Yaowu Xuf883b422016-08-30 14:01:10 -07001081 av1_build_interintra_predictors_sbuv(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001082 xd, xd->plane[1].dst.buf, xd->plane[2].dst.buf, xd->plane[1].dst.stride,
David Barkerac37fa32016-12-02 12:30:21 +00001083 xd->plane[2].dst.stride, ctx, bsize);
1084 }
1085#else
1086 (void)ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001087#endif // CONFIG_EXT_INTER
1088}
1089
Yaowu Xuf883b422016-08-30 14:01:10 -07001090void av1_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col,
David Barkerac37fa32016-12-02 12:30:21 +00001091 BUFFER_SET *ctx, BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001092 build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 0,
1093 MAX_MB_PLANE - 1);
1094#if CONFIG_EXT_INTER
David Barkerac37fa32016-12-02 12:30:21 +00001095 if (is_interintra_pred(&xd->mi[0]->mbmi)) {
1096 BUFFER_SET default_ctx = {
1097 { xd->plane[0].dst.buf, xd->plane[1].dst.buf, xd->plane[2].dst.buf },
1098 { xd->plane[0].dst.stride, xd->plane[1].dst.stride,
1099 xd->plane[2].dst.stride }
1100 };
1101 if (!ctx) ctx = &default_ctx;
Yaowu Xuf883b422016-08-30 14:01:10 -07001102 av1_build_interintra_predictors(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001103 xd, xd->plane[0].dst.buf, xd->plane[1].dst.buf, xd->plane[2].dst.buf,
1104 xd->plane[0].dst.stride, xd->plane[1].dst.stride,
David Barkerac37fa32016-12-02 12:30:21 +00001105 xd->plane[2].dst.stride, ctx, bsize);
1106 }
1107#else
1108 (void)ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001109#endif // CONFIG_EXT_INTER
1110}
1111
Yaowu Xuf883b422016-08-30 14:01:10 -07001112void av1_setup_dst_planes(struct macroblockd_plane planes[MAX_MB_PLANE],
1113 const YV12_BUFFER_CONFIG *src, int mi_row,
1114 int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001115 uint8_t *const buffers[MAX_MB_PLANE] = { src->y_buffer, src->u_buffer,
1116 src->v_buffer };
1117 const int widths[MAX_MB_PLANE] = { src->y_crop_width, src->uv_crop_width,
1118 src->uv_crop_width };
1119 const int heights[MAX_MB_PLANE] = { src->y_crop_height, src->uv_crop_height,
1120 src->uv_crop_height };
1121 const int strides[MAX_MB_PLANE] = { src->y_stride, src->uv_stride,
1122 src->uv_stride };
1123 int i;
1124
1125 for (i = 0; i < MAX_MB_PLANE; ++i) {
1126 struct macroblockd_plane *const pd = &planes[i];
1127 setup_pred_plane(&pd->dst, buffers[i], widths[i], heights[i], strides[i],
1128 mi_row, mi_col, NULL, pd->subsampling_x,
1129 pd->subsampling_y);
1130 }
1131}
1132
Yaowu Xuf883b422016-08-30 14:01:10 -07001133void av1_setup_pre_planes(MACROBLOCKD *xd, int idx,
1134 const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col,
1135 const struct scale_factors *sf) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001136 if (src != NULL) {
1137 int i;
1138 uint8_t *const buffers[MAX_MB_PLANE] = { src->y_buffer, src->u_buffer,
1139 src->v_buffer };
1140 const int widths[MAX_MB_PLANE] = { src->y_crop_width, src->uv_crop_width,
1141 src->uv_crop_width };
1142 const int heights[MAX_MB_PLANE] = { src->y_crop_height, src->uv_crop_height,
1143 src->uv_crop_height };
1144 const int strides[MAX_MB_PLANE] = { src->y_stride, src->uv_stride,
1145 src->uv_stride };
1146 for (i = 0; i < MAX_MB_PLANE; ++i) {
1147 struct macroblockd_plane *const pd = &xd->plane[i];
1148 setup_pred_plane(&pd->pre[idx], buffers[i], widths[i], heights[i],
1149 strides[i], mi_row, mi_col, sf, pd->subsampling_x,
1150 pd->subsampling_y);
1151 }
1152 }
1153}
1154
1155#if CONFIG_SUPERTX
Jingning Hanfeb517c2016-12-21 16:02:07 -08001156#if CONFIG_CB4X4
Jingning Han9e0976a2016-12-27 17:52:42 -08001157static const uint8_t mask_4[4] = { 64, 52, 12, 0 };
1158static const uint8_t mask_4_uv[4] = { 64, 52, 12, 0 };
Jingning Hanfeb517c2016-12-21 16:02:07 -08001159#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07001160static const uint8_t mask_8[8] = { 64, 64, 62, 52, 12, 2, 0, 0 };
1161
1162static const uint8_t mask_16[16] = { 63, 62, 60, 58, 55, 50, 43, 36,
1163 28, 21, 14, 9, 6, 4, 2, 1 };
1164
1165static const uint8_t mask_32[32] = { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 63,
1166 61, 57, 52, 45, 36, 28, 19, 12, 7, 3, 1,
1167 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1168
1169static const uint8_t mask_8_uv[8] = { 64, 64, 62, 52, 12, 2, 0, 0 };
1170
1171static const uint8_t mask_16_uv[16] = { 64, 64, 64, 64, 61, 53, 45, 36,
1172 28, 19, 11, 3, 0, 0, 0, 0 };
1173
1174static const uint8_t mask_32_uv[32] = { 64, 64, 64, 64, 64, 64, 64, 64,
1175 64, 64, 64, 64, 60, 54, 46, 36,
1176 28, 18, 10, 4, 0, 0, 0, 0,
1177 0, 0, 0, 0, 0, 0, 0, 0 };
1178
1179static const uint8_t *get_supertx_mask(int length, int plane) {
1180 switch (length) {
Jingning Hanfeb517c2016-12-21 16:02:07 -08001181#if CONFIG_CB4X4
1182 case 4: return plane ? mask_4_uv : mask_4;
1183#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07001184 case 8: return plane ? mask_8_uv : mask_8;
1185 case 16: return plane ? mask_16_uv : mask_16;
1186 case 32: return plane ? mask_32_uv : mask_32;
1187 default: assert(0);
1188 }
1189 return NULL;
1190}
1191
Yaowu Xuf883b422016-08-30 14:01:10 -07001192void av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001193 MACROBLOCKD *xd, uint8_t *dst, int dst_stride, const uint8_t *pre,
1194 int pre_stride, int mi_row, int mi_col, int mi_row_ori, int mi_col_ori,
1195 BLOCK_SIZE bsize, BLOCK_SIZE top_bsize, PARTITION_TYPE partition,
1196 int plane) {
1197 const struct macroblockd_plane *pd = &xd->plane[plane];
1198 const int ssx = pd->subsampling_x;
1199 const int ssy = pd->subsampling_y;
Jingning Han93531242016-12-20 11:54:36 -08001200 const int top_w = block_size_wide[top_bsize] >> ssx;
1201 const int top_h = block_size_high[top_bsize] >> ssy;
1202 const int w = block_size_wide[bsize] >> ssx;
1203 const int h = block_size_high[bsize] >> ssy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001204 const int w_offset = ((mi_col - mi_col_ori) * MI_SIZE) >> ssx;
1205 const int h_offset = ((mi_row - mi_row_ori) * MI_SIZE) >> ssy;
1206
1207 int w_remain, h_remain;
1208
Yaowu Xuf883b422016-08-30 14:01:10 -07001209#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001210 const int is_hdb = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07001211#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001212
1213 assert(bsize <= BLOCK_32X32);
1214 assert(IMPLIES(plane == 0, ssx == 0));
1215 assert(IMPLIES(plane == 0, ssy == 0));
1216
1217 switch (partition) {
1218 case PARTITION_HORZ: {
1219 const uint8_t *const mask = get_supertx_mask(h, ssy);
1220
1221 w_remain = top_w;
1222 h_remain = top_h - h_offset - h;
1223 dst += h_offset * dst_stride;
1224 pre += h_offset * pre_stride;
1225
Yaowu Xuf883b422016-08-30 14:01:10 -07001226#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001227 if (is_hdb)
Yaowu Xuf883b422016-08-30 14:01:10 -07001228 aom_highbd_blend_a64_vmask(dst, dst_stride, dst, dst_stride, pre,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001229 pre_stride, mask, h, top_w, xd->bd);
1230 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001231#endif // CONFIG_AOM_HIGHBITDEPTH
1232 aom_blend_a64_vmask(dst, dst_stride, dst, dst_stride, pre, pre_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001233 mask, h, top_w);
1234
1235 dst += h * dst_stride;
1236 pre += h * pre_stride;
1237 break;
1238 }
1239 case PARTITION_VERT: {
1240 const uint8_t *const mask = get_supertx_mask(w, ssx);
1241
1242 w_remain = top_w - w_offset - w;
1243 h_remain = top_h;
1244 dst += w_offset;
1245 pre += w_offset;
1246
Yaowu Xuf883b422016-08-30 14:01:10 -07001247#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001248 if (is_hdb)
Yaowu Xuf883b422016-08-30 14:01:10 -07001249 aom_highbd_blend_a64_hmask(dst, dst_stride, dst, dst_stride, pre,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001250 pre_stride, mask, top_h, w, xd->bd);
1251 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001252#endif // CONFIG_AOM_HIGHBITDEPTH
1253 aom_blend_a64_hmask(dst, dst_stride, dst, dst_stride, pre, pre_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001254 mask, top_h, w);
1255
1256 dst += w;
1257 pre += w;
1258 break;
1259 }
1260 default: {
1261 assert(0);
1262 return;
1263 }
1264 }
1265
1266 if (w_remain == 0 || h_remain == 0) {
1267 return;
1268 }
1269
Yaowu Xuf883b422016-08-30 14:01:10 -07001270#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001271 if (is_hdb) {
1272 dst = (uint8_t *)CONVERT_TO_SHORTPTR(dst);
1273 pre = (const uint8_t *)CONVERT_TO_SHORTPTR(pre);
1274 dst_stride *= 2;
1275 pre_stride *= 2;
1276 w_remain *= 2;
1277 }
Yaowu Xuf883b422016-08-30 14:01:10 -07001278#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001279
1280 do {
1281 memcpy(dst, pre, w_remain * sizeof(uint8_t));
1282 dst += dst_stride;
1283 pre += pre_stride;
1284 } while (--h_remain);
1285}
1286
Yaowu Xuf883b422016-08-30 14:01:10 -07001287void av1_build_inter_predictors_sb_sub8x8_extend(MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001288#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07001289 int mi_row_ori, int mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001290#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07001291 int mi_row, int mi_col,
1292 BLOCK_SIZE bsize, int block) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001293 // Prediction function used in supertx:
1294 // Use the mv at current block (which is less than 8x8)
1295 // to get prediction of a block located at (mi_row, mi_col) at size of bsize
1296 // bsize can be larger than 8x8.
1297 // block (0-3): the sub8x8 location of current block
1298 int plane;
1299 const int mi_x = mi_col * MI_SIZE;
1300 const int mi_y = mi_row * MI_SIZE;
1301#if CONFIG_EXT_INTER
1302 const int wedge_offset_x = (mi_col_ori - mi_col) * MI_SIZE;
1303 const int wedge_offset_y = (mi_row_ori - mi_row) * MI_SIZE;
1304#endif // CONFIG_EXT_INTER
1305
1306 // For sub8x8 uv:
1307 // Skip uv prediction in supertx except the first block (block = 0)
1308 int max_plane = block ? 1 : MAX_MB_PLANE;
1309
1310 for (plane = 0; plane < max_plane; plane++) {
1311 const BLOCK_SIZE plane_bsize =
1312 get_plane_block_size(bsize, &xd->plane[plane]);
1313 const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize];
1314 const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize];
1315 const int bw = 4 * num_4x4_w;
1316 const int bh = 4 * num_4x4_h;
1317
1318 build_inter_predictors(xd, plane,
Yue Chencb60b182016-10-13 15:18:22 -07001319#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001320 0, 0,
Yue Chencb60b182016-10-13 15:18:22 -07001321#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001322 block, bw, bh, 0, 0, bw, bh,
1323#if CONFIG_EXT_INTER
1324 wedge_offset_x, wedge_offset_y,
1325#endif // CONFIG_EXT_INTER
1326 mi_x, mi_y);
1327 }
1328#if CONFIG_EXT_INTER
Yaowu Xuf4c904c2016-12-07 11:18:27 -08001329 if (is_interintra_pred(&xd->mi[0]->mbmi)) {
1330 BUFFER_SET ctx = { { xd->plane[0].dst.buf, xd->plane[1].dst.buf,
1331 xd->plane[2].dst.buf },
1332 { xd->plane[0].dst.stride, xd->plane[1].dst.stride,
1333 xd->plane[2].dst.stride } };
Yaowu Xuf883b422016-08-30 14:01:10 -07001334 av1_build_interintra_predictors(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001335 xd, xd->plane[0].dst.buf, xd->plane[1].dst.buf, xd->plane[2].dst.buf,
1336 xd->plane[0].dst.stride, xd->plane[1].dst.stride,
David Barkerac37fa32016-12-02 12:30:21 +00001337 xd->plane[2].dst.stride, &ctx, bsize);
Yaowu Xuf4c904c2016-12-07 11:18:27 -08001338 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001339#endif // CONFIG_EXT_INTER
1340}
1341
Yaowu Xuf883b422016-08-30 14:01:10 -07001342void av1_build_inter_predictors_sb_extend(MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001343#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07001344 int mi_row_ori, int mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001345#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07001346 int mi_row, int mi_col,
1347 BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001348 int plane;
1349 const int mi_x = mi_col * MI_SIZE;
1350 const int mi_y = mi_row * MI_SIZE;
1351#if CONFIG_EXT_INTER
1352 const int wedge_offset_x = (mi_col_ori - mi_col) * MI_SIZE;
1353 const int wedge_offset_y = (mi_row_ori - mi_row) * MI_SIZE;
1354#endif // CONFIG_EXT_INTER
1355 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
1356 const BLOCK_SIZE plane_bsize =
1357 get_plane_block_size(bsize, &xd->plane[plane]);
Jingning Hanae5cfde2016-11-30 12:01:44 -08001358 const int bw = block_size_wide[plane_bsize];
1359 const int bh = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001360
Jingning Han002c8142016-12-20 15:07:58 -08001361 build_inter_predictors(xd, plane,
Yue Chencb60b182016-10-13 15:18:22 -07001362#if CONFIG_MOTION_VAR
Jingning Han002c8142016-12-20 15:07:58 -08001363 0, 0,
Yue Chencb60b182016-10-13 15:18:22 -07001364#endif // CONFIG_MOTION_VAR
Jingning Han002c8142016-12-20 15:07:58 -08001365 0, bw, bh, 0, 0, bw, bh,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001366#if CONFIG_EXT_INTER
Jingning Han002c8142016-12-20 15:07:58 -08001367 wedge_offset_x, wedge_offset_y,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001368#endif // CONFIG_EXT_INTER
Jingning Han002c8142016-12-20 15:07:58 -08001369 mi_x, mi_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001370 }
1371}
1372#endif // CONFIG_SUPERTX
1373
Yue Chencb60b182016-10-13 15:18:22 -07001374#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001375// obmc_mask_N[overlap_position]
1376static const uint8_t obmc_mask_1[1] = { 55 };
1377
1378static const uint8_t obmc_mask_2[2] = { 45, 62 };
1379
1380static const uint8_t obmc_mask_4[4] = { 39, 50, 59, 64 };
1381
1382static const uint8_t obmc_mask_8[8] = { 36, 42, 48, 53, 57, 61, 63, 64 };
1383
1384static const uint8_t obmc_mask_16[16] = { 34, 37, 40, 43, 46, 49, 52, 54,
1385 56, 58, 60, 61, 63, 64, 64, 64 };
1386
1387static const uint8_t obmc_mask_32[32] = { 33, 35, 36, 38, 40, 41, 43, 44,
1388 45, 47, 48, 50, 51, 52, 53, 55,
1389 56, 57, 58, 59, 60, 60, 61, 62,
1390 62, 63, 63, 64, 64, 64, 64, 64 };
1391
1392#if CONFIG_EXT_PARTITION
1393static const uint8_t obmc_mask_64[64] = {
1394 33, 34, 35, 35, 36, 37, 38, 39, 40, 40, 41, 42, 43, 44, 44, 44,
1395 45, 46, 47, 47, 48, 49, 50, 51, 51, 51, 52, 52, 53, 54, 55, 56,
1396 56, 56, 57, 57, 58, 58, 59, 60, 60, 60, 60, 60, 61, 62, 62, 62,
1397 62, 62, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
1398};
1399#endif // CONFIG_EXT_PARTITION
1400
Yaowu Xuf883b422016-08-30 14:01:10 -07001401const uint8_t *av1_get_obmc_mask(int length) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001402 switch (length) {
1403 case 1: return obmc_mask_1;
1404 case 2: return obmc_mask_2;
1405 case 4: return obmc_mask_4;
1406 case 8: return obmc_mask_8;
1407 case 16: return obmc_mask_16;
1408 case 32: return obmc_mask_32;
1409#if CONFIG_EXT_PARTITION
1410 case 64: return obmc_mask_64;
1411#endif // CONFIG_EXT_PARTITION
1412 default: assert(0); return NULL;
1413 }
1414}
1415
Yue Chen86ae7b12017-01-11 17:04:29 -08001416#if CONFIG_NCOBMC
1417// obmc_mask_flipN[overlap_position]
1418static const uint8_t obmc_mask_flip1[1] = { 55 };
1419
1420static const uint8_t obmc_mask_flip2[2] = { 62, 45 };
1421
1422static const uint8_t obmc_mask_flip4[4] = { 64, 59, 50, 39 };
1423
1424static const uint8_t obmc_mask_flip8[8] = { 64, 63, 61, 57, 53, 48, 42, 36 };
1425
1426static const uint8_t obmc_mask_flip16[16] = { 64, 64, 64, 63, 61, 60, 58, 56,
1427 54, 52, 49, 46, 43, 40, 37, 34 };
1428
1429static const uint8_t obmc_mask_flip32[32] = { 64, 64, 64, 64, 64, 63, 63, 62,
1430 62, 61, 60, 60, 59, 58, 57, 56,
1431 55, 53, 52, 51, 50, 48, 47, 45,
1432 44, 43, 41, 40, 38, 36, 35, 33 };
1433
1434#if CONFIG_EXT_PARTITION
1435static const uint8_t obmc_mask_flip64[64] = {
1436 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 63, 63, 63, 63, 62, 62,
1437 62, 62, 62, 61, 60, 60, 60, 60, 60, 59, 58, 58, 57, 57, 56, 56,
1438 56, 55, 54, 53, 52, 52, 51, 51, 51, 50, 49, 48, 47, 47, 46, 45,
1439 44, 44, 44, 43, 42, 41, 40, 40, 39, 38, 37, 36, 35, 35, 34, 33,
1440};
1441#endif // CONFIG_EXT_PARTITION
1442
1443const uint8_t *av1_get_obmc_mask_flipped(int length) {
1444 switch (length) {
1445 case 1: return obmc_mask_flip1;
1446 case 2: return obmc_mask_flip2;
1447 case 4: return obmc_mask_flip4;
1448 case 8: return obmc_mask_flip8;
1449 case 16: return obmc_mask_flip16;
1450 case 32: return obmc_mask_flip32;
1451#if CONFIG_EXT_PARTITION
1452 case 64: return obmc_mask_flip64;
1453#endif // CONFIG_EXT_PARTITION
1454 default: assert(0); return NULL;
1455 }
1456}
1457#endif // CONFIG_NCOBMC
1458
Yaowu Xuc27fc142016-08-22 16:08:15 -07001459// This function combines motion compensated predictions that is generated by
1460// top/left neighboring blocks' inter predictors with the regular inter
1461// prediction. We assume the original prediction (bmc) is stored in
1462// xd->plane[].dst.buf
Urvang Joshi52648442016-10-13 17:27:51 -07001463void av1_build_obmc_inter_prediction(const AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xuf883b422016-08-30 14:01:10 -07001464 int mi_row, int mi_col,
1465 uint8_t *above[MAX_MB_PLANE],
1466 int above_stride[MAX_MB_PLANE],
1467 uint8_t *left[MAX_MB_PLANE],
1468 int left_stride[MAX_MB_PLANE]) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001469 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
1470 int plane, i;
Yaowu Xuf883b422016-08-30 14:01:10 -07001471#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001472 const int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07001473#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001474
1475 // handle above row
1476 if (xd->up_available) {
1477 const int overlap = num_4x4_blocks_high_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -07001478 const int miw = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001479 const int mi_row_offset = -1;
1480
1481 assert(miw > 0);
1482
1483 i = 0;
1484 do { // for each mi in the above row
1485 const int mi_col_offset = i;
1486 const MB_MODE_INFO *const above_mbmi =
1487 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
1488 const int mi_step =
Yaowu Xuf883b422016-08-30 14:01:10 -07001489 AOMMIN(xd->n8_w, num_8x8_blocks_wide_lookup[above_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001490
1491 if (is_neighbor_overlappable(above_mbmi)) {
1492 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
1493 const struct macroblockd_plane *pd = &xd->plane[plane];
1494 const int bw = (mi_step * MI_SIZE) >> pd->subsampling_x;
1495 const int bh = overlap >> pd->subsampling_y;
1496 const int dst_stride = pd->dst.stride;
1497 uint8_t *const dst = &pd->dst.buf[(i * MI_SIZE) >> pd->subsampling_x];
1498 const int tmp_stride = above_stride[plane];
1499 const uint8_t *const tmp =
1500 &above[plane][(i * MI_SIZE) >> pd->subsampling_x];
Yaowu Xuf883b422016-08-30 14:01:10 -07001501 const uint8_t *const mask = av1_get_obmc_mask(bh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001502
Yaowu Xuf883b422016-08-30 14:01:10 -07001503#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001504 if (is_hbd)
Yaowu Xuf883b422016-08-30 14:01:10 -07001505 aom_highbd_blend_a64_vmask(dst, dst_stride, dst, dst_stride, tmp,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001506 tmp_stride, mask, bh, bw, xd->bd);
1507 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001508#endif // CONFIG_AOM_HIGHBITDEPTH
1509 aom_blend_a64_vmask(dst, dst_stride, dst, dst_stride, tmp,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001510 tmp_stride, mask, bh, bw);
1511 }
1512 }
1513 i += mi_step;
1514 } while (i < miw);
1515 }
1516
1517 // handle left column
1518 if (xd->left_available) {
1519 const int overlap = num_4x4_blocks_wide_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -07001520 const int mih = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001521 const int mi_col_offset = -1;
1522
1523 assert(mih > 0);
1524
1525 i = 0;
1526 do { // for each mi in the left column
1527 const int mi_row_offset = i;
1528 const MB_MODE_INFO *const left_mbmi =
1529 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
1530 const int mi_step =
Yaowu Xuf883b422016-08-30 14:01:10 -07001531 AOMMIN(xd->n8_h, num_8x8_blocks_high_lookup[left_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001532
1533 if (is_neighbor_overlappable(left_mbmi)) {
1534 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
1535 const struct macroblockd_plane *pd = &xd->plane[plane];
1536 const int bw = overlap >> pd->subsampling_x;
1537 const int bh = (mi_step * MI_SIZE) >> pd->subsampling_y;
1538 const int dst_stride = pd->dst.stride;
1539 uint8_t *const dst =
1540 &pd->dst.buf[(i * MI_SIZE * dst_stride) >> pd->subsampling_y];
1541 const int tmp_stride = left_stride[plane];
1542 const uint8_t *const tmp =
1543 &left[plane][(i * MI_SIZE * tmp_stride) >> pd->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07001544 const uint8_t *const mask = av1_get_obmc_mask(bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001545
Yaowu Xuf883b422016-08-30 14:01:10 -07001546#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001547 if (is_hbd)
Yaowu Xuf883b422016-08-30 14:01:10 -07001548 aom_highbd_blend_a64_hmask(dst, dst_stride, dst, dst_stride, tmp,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001549 tmp_stride, mask, bh, bw, xd->bd);
1550 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001551#endif // CONFIG_AOM_HIGHBITDEPTH
1552 aom_blend_a64_hmask(dst, dst_stride, dst, dst_stride, tmp,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001553 tmp_stride, mask, bh, bw);
1554 }
1555 }
1556 i += mi_step;
1557 } while (i < mih);
1558 }
1559}
1560
1561#if CONFIG_EXT_INTER
1562void modify_neighbor_predictor_for_obmc(MB_MODE_INFO *mbmi) {
1563 if (is_interintra_pred(mbmi)) {
1564 mbmi->ref_frame[1] = NONE;
Sarah Parker6fdc8532016-11-16 17:47:13 -08001565 } else if (has_second_ref(mbmi) &&
1566 is_masked_compound_type(mbmi->interinter_compound_data.type)) {
1567 mbmi->interinter_compound_data.type = COMPOUND_AVERAGE;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001568 mbmi->ref_frame[1] = NONE;
1569 }
1570 return;
1571}
1572#endif // CONFIG_EXT_INTER
1573
Urvang Joshi52648442016-10-13 17:27:51 -07001574void av1_build_prediction_by_above_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xuf883b422016-08-30 14:01:10 -07001575 int mi_row, int mi_col,
1576 uint8_t *tmp_buf[MAX_MB_PLANE],
1577 int tmp_width[MAX_MB_PLANE],
1578 int tmp_height[MAX_MB_PLANE],
1579 int tmp_stride[MAX_MB_PLANE]) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001580 const TileInfo *const tile = &xd->tile;
1581 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
1582 int i, j, mi_step, ref;
Yue Chen894fcce2016-10-21 16:50:52 -07001583 int mb_to_right_edge_base = xd->mb_to_right_edge;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001584
1585 if (mi_row <= tile->mi_row_start) return;
1586
Yue Chen894fcce2016-10-21 16:50:52 -07001587 xd->mb_to_bottom_edge += xd->n8_h * 32;
Yaowu Xuf883b422016-08-30 14:01:10 -07001588 for (i = 0; i < AOMMIN(xd->n8_w, cm->mi_cols - mi_col); i += mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001589 int mi_row_offset = -1;
1590 int mi_col_offset = i;
1591 int mi_x, mi_y, bw, bh;
1592 MODE_INFO *above_mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
1593 MB_MODE_INFO *above_mbmi = &above_mi->mbmi;
1594#if CONFIG_EXT_INTER
1595 MB_MODE_INFO backup_mbmi;
1596#endif // CONFIG_EXT_INTER
1597
Yaowu Xuf883b422016-08-30 14:01:10 -07001598 mi_step = AOMMIN(xd->n8_w, num_8x8_blocks_wide_lookup[above_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001599
1600 if (!is_neighbor_overlappable(above_mbmi)) continue;
1601
1602#if CONFIG_EXT_INTER
1603 backup_mbmi = *above_mbmi;
1604 modify_neighbor_predictor_for_obmc(above_mbmi);
1605#endif // CONFIG_EXT_INTER
1606
1607 for (j = 0; j < MAX_MB_PLANE; ++j) {
1608 struct macroblockd_plane *const pd = &xd->plane[j];
1609 setup_pred_plane(&pd->dst, tmp_buf[j], tmp_width[j], tmp_height[j],
1610 tmp_stride[j], 0, i, NULL, pd->subsampling_x,
1611 pd->subsampling_y);
1612 }
1613 for (ref = 0; ref < 1 + has_second_ref(above_mbmi); ++ref) {
Urvang Joshi52648442016-10-13 17:27:51 -07001614 const MV_REFERENCE_FRAME frame = above_mbmi->ref_frame[ref];
1615 const RefBuffer *const ref_buf = &cm->frame_refs[frame - LAST_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001616
1617 xd->block_refs[ref] = ref_buf;
Yaowu Xuf883b422016-08-30 14:01:10 -07001618 if ((!av1_is_valid_scale(&ref_buf->sf)))
1619 aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001620 "Reference frame has invalid dimensions");
Yaowu Xuf883b422016-08-30 14:01:10 -07001621 av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col + i,
1622 &ref_buf->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001623 }
1624
1625 xd->mb_to_left_edge = -(((mi_col + i) * MI_SIZE) * 8);
Yue Chen894fcce2016-10-21 16:50:52 -07001626 xd->mb_to_right_edge =
1627 mb_to_right_edge_base + (xd->n8_w - i - mi_step) * 64;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001628 mi_x = (mi_col + i) << MI_SIZE_LOG2;
1629 mi_y = mi_row << MI_SIZE_LOG2;
1630
1631 for (j = 0; j < MAX_MB_PLANE; ++j) {
1632 const struct macroblockd_plane *pd = &xd->plane[j];
1633 bw = (mi_step * 8) >> pd->subsampling_x;
Yaowu Xuf883b422016-08-30 14:01:10 -07001634 bh = AOMMAX((num_4x4_blocks_high_lookup[bsize] * 2) >> pd->subsampling_y,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001635 4);
1636
1637 if (above_mbmi->sb_type < BLOCK_8X8) {
1638 const PARTITION_TYPE bp = BLOCK_8X8 - above_mbmi->sb_type;
1639 const int have_vsplit = bp != PARTITION_HORZ;
1640 const int have_hsplit = bp != PARTITION_VERT;
Yue Chen894fcce2016-10-21 16:50:52 -07001641 const int num_4x4_w = 2 >> !have_vsplit;
1642 const int num_4x4_h = 2 >> !have_hsplit;
1643 const int pw = 8 >> (have_vsplit + pd->subsampling_x);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001644 int x, y;
1645
1646 for (y = 0; y < num_4x4_h; ++y)
1647 for (x = 0; x < num_4x4_w; ++x) {
Yue Chen894fcce2016-10-21 16:50:52 -07001648 if ((bp == PARTITION_HORZ || bp == PARTITION_SPLIT) && y == 0)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001649 continue;
1650
1651 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset,
Yue Chen894fcce2016-10-21 16:50:52 -07001652 y * 2 + x, bw, bh,
1653 (4 * x) >> pd->subsampling_x, 0, pw, bh,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001654#if CONFIG_SUPERTX && CONFIG_EXT_INTER
1655 0, 0,
1656#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
1657 mi_x, mi_y);
1658 }
1659 } else {
Yue Chen69f18e12016-09-08 14:48:15 -07001660#if CONFIG_WARPED_MOTION
1661 if (above_mbmi->motion_mode == WARPED_CAUSAL) {
1662 av1_warp_plane(&above_mbmi->wm_params[0],
1663#if CONFIG_AOM_HIGHBITDEPTH
1664 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
1665#endif // CONFIG_AOM_HIGHBITDEPTH
1666 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
1667 pd->pre[0].stride, pd->dst.buf,
1668 (((mi_col + i) * MI_SIZE) >> pd->subsampling_x),
1669 ((mi_row * MI_SIZE) >> pd->subsampling_y), bw, bh,
1670 pd->dst.stride, pd->subsampling_x, pd->subsampling_y,
1671 16, 16, 0);
1672
1673 } else {
1674#endif // CONFIG_WARPED_MOTION
1675 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0, bw, bh,
1676 0, 0, bw, bh,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001677#if CONFIG_SUPERTX && CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07001678 0, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001679#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07001680 mi_x, mi_y);
1681#if CONFIG_WARPED_MOTION
1682 }
1683#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07001684 }
1685 }
1686#if CONFIG_EXT_INTER
1687 *above_mbmi = backup_mbmi;
1688#endif // CONFIG_EXT_INTER
1689 }
1690 xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8);
Yue Chen894fcce2016-10-21 16:50:52 -07001691 xd->mb_to_right_edge = mb_to_right_edge_base;
1692 xd->mb_to_bottom_edge -= xd->n8_h * 32;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001693}
1694
Urvang Joshi52648442016-10-13 17:27:51 -07001695void av1_build_prediction_by_left_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xuf883b422016-08-30 14:01:10 -07001696 int mi_row, int mi_col,
1697 uint8_t *tmp_buf[MAX_MB_PLANE],
1698 int tmp_width[MAX_MB_PLANE],
1699 int tmp_height[MAX_MB_PLANE],
1700 int tmp_stride[MAX_MB_PLANE]) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001701 const TileInfo *const tile = &xd->tile;
1702 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
1703 int i, j, mi_step, ref;
Yue Chen894fcce2016-10-21 16:50:52 -07001704 int mb_to_bottom_edge_base = xd->mb_to_bottom_edge;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001705
1706 if (mi_col == 0 || (mi_col - 1 < tile->mi_col_start)) return;
1707
Yue Chen894fcce2016-10-21 16:50:52 -07001708 xd->mb_to_right_edge += xd->n8_w * 32;
Yaowu Xuf883b422016-08-30 14:01:10 -07001709 for (i = 0; i < AOMMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001710 int mi_row_offset = i;
1711 int mi_col_offset = -1;
1712 int mi_x, mi_y, bw, bh;
1713 MODE_INFO *left_mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
1714 MB_MODE_INFO *left_mbmi = &left_mi->mbmi;
1715#if CONFIG_EXT_INTER
1716 MB_MODE_INFO backup_mbmi;
1717#endif // CONFIG_EXT_INTER
1718
Yaowu Xuf883b422016-08-30 14:01:10 -07001719 mi_step = AOMMIN(xd->n8_h, num_8x8_blocks_high_lookup[left_mbmi->sb_type]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001720
1721 if (!is_neighbor_overlappable(left_mbmi)) continue;
1722
1723#if CONFIG_EXT_INTER
1724 backup_mbmi = *left_mbmi;
1725 modify_neighbor_predictor_for_obmc(left_mbmi);
1726#endif // CONFIG_EXT_INTER
1727
1728 for (j = 0; j < MAX_MB_PLANE; ++j) {
1729 struct macroblockd_plane *const pd = &xd->plane[j];
1730 setup_pred_plane(&pd->dst, tmp_buf[j], tmp_width[j], tmp_height[j],
1731 tmp_stride[j], i, 0, NULL, pd->subsampling_x,
1732 pd->subsampling_y);
1733 }
1734 for (ref = 0; ref < 1 + has_second_ref(left_mbmi); ++ref) {
Urvang Joshi52648442016-10-13 17:27:51 -07001735 const MV_REFERENCE_FRAME frame = left_mbmi->ref_frame[ref];
1736 const RefBuffer *const ref_buf = &cm->frame_refs[frame - LAST_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001737
1738 xd->block_refs[ref] = ref_buf;
Yaowu Xuf883b422016-08-30 14:01:10 -07001739 if ((!av1_is_valid_scale(&ref_buf->sf)))
1740 aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001741 "Reference frame has invalid dimensions");
Yaowu Xuf883b422016-08-30 14:01:10 -07001742 av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row + i, mi_col,
1743 &ref_buf->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001744 }
1745
1746 xd->mb_to_top_edge = -(((mi_row + i) * MI_SIZE) * 8);
Yue Chen894fcce2016-10-21 16:50:52 -07001747 xd->mb_to_bottom_edge =
1748 mb_to_bottom_edge_base + (xd->n8_h - i - mi_step) * 64;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001749 mi_x = mi_col << MI_SIZE_LOG2;
1750 mi_y = (mi_row + i) << MI_SIZE_LOG2;
1751
1752 for (j = 0; j < MAX_MB_PLANE; ++j) {
1753 const struct macroblockd_plane *pd = &xd->plane[j];
Yaowu Xuf883b422016-08-30 14:01:10 -07001754 bw = AOMMAX((num_4x4_blocks_wide_lookup[bsize] * 2) >> pd->subsampling_x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001755 4);
1756 bh = (mi_step << MI_SIZE_LOG2) >> pd->subsampling_y;
1757
1758 if (left_mbmi->sb_type < BLOCK_8X8) {
1759 const PARTITION_TYPE bp = BLOCK_8X8 - left_mbmi->sb_type;
1760 const int have_vsplit = bp != PARTITION_HORZ;
1761 const int have_hsplit = bp != PARTITION_VERT;
Yue Chen894fcce2016-10-21 16:50:52 -07001762 const int num_4x4_w = 2 >> !have_vsplit;
1763 const int num_4x4_h = 2 >> !have_hsplit;
1764 const int ph = 8 >> (have_hsplit + pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001765 int x, y;
1766
1767 for (y = 0; y < num_4x4_h; ++y)
1768 for (x = 0; x < num_4x4_w; ++x) {
Yue Chen894fcce2016-10-21 16:50:52 -07001769 if ((bp == PARTITION_VERT || bp == PARTITION_SPLIT) && x == 0)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001770 continue;
1771
1772 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset,
Yue Chen894fcce2016-10-21 16:50:52 -07001773 y * 2 + x, bw, bh, 0,
1774 (4 * y) >> pd->subsampling_y, bw, ph,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001775#if CONFIG_SUPERTX && CONFIG_EXT_INTER
1776 0, 0,
1777#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
1778 mi_x, mi_y);
1779 }
1780 } else {
Yue Chen69f18e12016-09-08 14:48:15 -07001781#if CONFIG_WARPED_MOTION
1782 if (left_mbmi->motion_mode == WARPED_CAUSAL) {
1783 av1_warp_plane(&left_mbmi->wm_params[0],
1784#if CONFIG_AOM_HIGHBITDEPTH
1785 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
1786#endif // CONFIG_AOM_HIGHBITDEPTH
1787 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
1788 pd->pre[0].stride, pd->dst.buf,
1789 ((mi_col * MI_SIZE) >> pd->subsampling_x),
1790 (((mi_row + i) * MI_SIZE) >> pd->subsampling_y), bw,
1791 bh, pd->dst.stride, pd->subsampling_x,
1792 pd->subsampling_y, 16, 16, 0);
1793
1794 } else {
1795#endif // CONFIG_WARPED_MOTION
1796 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0, bw, bh,
1797 0, 0, bw, bh,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001798#if CONFIG_SUPERTX && CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07001799 0, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001800#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
Yue Chen69f18e12016-09-08 14:48:15 -07001801 mi_x, mi_y);
1802#if CONFIG_WARPED_MOTION
1803 }
1804#endif // CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07001805 }
1806 }
1807#if CONFIG_EXT_INTER
1808 *left_mbmi = backup_mbmi;
1809#endif // CONFIG_EXT_INTER
1810 }
1811 xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8);
Yue Chen894fcce2016-10-21 16:50:52 -07001812 xd->mb_to_bottom_edge = mb_to_bottom_edge_base;
1813 xd->mb_to_right_edge -= xd->n8_w * 32;
1814}
1815
1816void av1_build_obmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
1817 int mi_row, int mi_col) {
1818#if CONFIG_AOM_HIGHBITDEPTH
1819 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
1820 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
1821#else
1822 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
1823 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
1824#endif // CONFIG_AOM_HIGHBITDEPTH
1825 uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
1826 int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
1827 int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
1828 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
1829 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
1830 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
1831 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
1832
1833#if CONFIG_AOM_HIGHBITDEPTH
1834 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1835 int len = sizeof(uint16_t);
1836 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
1837 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
1838 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * 2 * len);
1839 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
1840 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
1841 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * 2 * len);
1842 } else {
1843#endif // CONFIG_AOM_HIGHBITDEPTH
1844 dst_buf1[0] = tmp_buf1;
1845 dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE;
1846 dst_buf1[2] = tmp_buf1 + MAX_SB_SQUARE * 2;
1847 dst_buf2[0] = tmp_buf2;
1848 dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE;
1849 dst_buf2[2] = tmp_buf2 + MAX_SB_SQUARE * 2;
1850#if CONFIG_AOM_HIGHBITDEPTH
1851 }
1852#endif // CONFIG_AOM_HIGHBITDEPTH
1853 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col, dst_buf1,
1854 dst_width1, dst_height1, dst_stride1);
1855 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col, dst_buf2,
1856 dst_width2, dst_height2, dst_stride2);
1857 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
1858 av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, dst_buf1, dst_stride1,
1859 dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001860}
Yue Chen86ae7b12017-01-11 17:04:29 -08001861
1862#if CONFIG_NCOBMC
1863void av1_build_prediction_by_bottom_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
1864 int mi_row, int mi_col,
1865 uint8_t *tmp_buf[MAX_MB_PLANE],
1866 int tmp_width[MAX_MB_PLANE],
1867 int tmp_height[MAX_MB_PLANE],
1868 int tmp_stride[MAX_MB_PLANE]) {
1869 const TileInfo *const tile = &xd->tile;
1870 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
1871 int i, j, mi_step, ref;
1872 int mb_to_right_edge_base = xd->mb_to_right_edge;
1873
1874 if (mi_row + xd->n8_h >= tile->mi_row_end || (mi_row + xd->n8_h) % 8 == 0 ||
1875 (mi_row + xd->n8_h) >= cm->mi_rows)
1876 return;
1877 assert(bsize >= BLOCK_8X8);
1878
1879 xd->mb_to_top_edge -= xd->n8_h * 32;
1880 for (i = 0; i < AOMMIN(xd->n8_w, cm->mi_cols - mi_col); i += mi_step) {
1881 int mi_row_offset = xd->n8_h;
1882 int mi_col_offset = i;
1883 int mi_x, mi_y, bw, bh;
1884 MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
1885 MB_MODE_INFO *mbmi = &mi->mbmi;
1886#if CONFIG_EXT_INTER
1887 MB_MODE_INFO backup_mbmi;
1888#endif // CONFIG_EXT_INTER
1889
1890 mi_step = AOMMIN(xd->n8_w, num_8x8_blocks_wide_lookup[mbmi->sb_type]);
1891
1892 if (!is_neighbor_overlappable(mbmi)) continue;
1893
1894#if CONFIG_EXT_INTER
1895 backup_mbmi = *mbmi;
1896 modify_neighbor_predictor_for_obmc(mbmi);
1897#endif // CONFIG_EXT_INTER
1898
1899 for (j = 0; j < MAX_MB_PLANE; ++j) {
1900 struct macroblockd_plane *const pd = &xd->plane[j];
1901 setup_pred_plane(&pd->dst, tmp_buf[j], tmp_width[j], tmp_height[j],
1902 tmp_stride[j], (xd->n8_h >> 1), i, NULL,
1903 pd->subsampling_x, pd->subsampling_y);
1904 }
1905 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
1906 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
1907 const RefBuffer *const ref_buf = &cm->frame_refs[frame - LAST_FRAME];
1908
1909 xd->block_refs[ref] = ref_buf;
1910 if ((!av1_is_valid_scale(&ref_buf->sf)))
1911 aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
1912 "Reference frame has invalid dimensions");
1913 av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row + (xd->n8_h >> 1),
1914 mi_col + i, &ref_buf->sf);
1915 }
1916
1917 xd->mb_to_left_edge = -(((mi_col + i) * MI_SIZE) * 8);
1918 xd->mb_to_right_edge =
1919 mb_to_right_edge_base + (xd->n8_w - i - mi_step) * 64;
1920 mi_x = (mi_col + i) << MI_SIZE_LOG2;
1921 mi_y = (mi_row << MI_SIZE_LOG2) + xd->n8_h * 4;
1922
1923 for (j = 0; j < MAX_MB_PLANE; ++j) {
1924 const struct macroblockd_plane *pd = &xd->plane[j];
1925 bw = (mi_step << MI_SIZE_LOG2) >> pd->subsampling_x;
1926 bh = (num_4x4_blocks_high_lookup[bsize] << 1) >> pd->subsampling_y;
1927
1928 if (mbmi->sb_type < BLOCK_8X8) {
1929 const PARTITION_TYPE bp = BLOCK_8X8 - mbmi->sb_type;
1930 const int have_vsplit = bp != PARTITION_HORZ;
1931 const int have_hsplit = bp != PARTITION_VERT;
1932 const int num_4x4_w = 2 >> (!have_vsplit);
1933 const int num_4x4_h = 2 >> (!have_hsplit);
1934 const int pw = 8 >> (have_vsplit + pd->subsampling_x);
1935 int x, y;
1936
1937 for (y = 0; y < num_4x4_h; ++y)
1938 for (x = 0; x < num_4x4_w; ++x) {
1939 if ((bp == PARTITION_HORZ || bp == PARTITION_SPLIT) && y != 0)
1940 continue;
1941
1942 build_inter_predictors(
1943 xd, j, mi_col_offset, mi_row_offset, y * 2 + x, bw, bh,
1944 (4 * x) >> pd->subsampling_x,
1945 xd->n8_h == 1 ? (4 >> pd->subsampling_y) : 0, pw, bh,
1946#if CONFIG_SUPERTX && CONFIG_EXT_INTER
1947 0, 0,
1948#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
1949 mi_x, mi_y);
1950 }
1951 } else {
1952#if CONFIG_WARPED_MOTION
1953 if (mbmi->motion_mode == WARPED_CAUSAL) {
1954 av1_warp_plane(&mbmi->wm_params[0],
1955#if CONFIG_AOM_HIGHBITDEPTH
1956 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
1957#endif // CONFIG_AOM_HIGHBITDEPTH
1958 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
1959 pd->pre[0].stride, pd->dst.buf,
1960 (((mi_col + i) * MI_SIZE) >> pd->subsampling_x),
1961 ((mi_row * MI_SIZE) >> pd->subsampling_y), bw, bh,
1962 pd->dst.stride, pd->subsampling_x, pd->subsampling_y,
1963 16, 16, 0);
1964
1965 } else {
1966#endif // CONFIG_WARPED_MOTION
1967 build_inter_predictors(
1968 xd, j, mi_col_offset, mi_row_offset, 0, bw, bh, 0,
1969 xd->n8_h == 1 ? (4 >> pd->subsampling_y) : 0, bw, bh,
1970#if CONFIG_SUPERTX && CONFIG_EXT_INTER
1971 0, 0,
1972#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
1973 mi_x, mi_y);
1974#if CONFIG_WARPED_MOTION
1975 }
1976#endif // CONFIG_WARPED_MOTION
1977 }
1978 }
1979#if CONFIG_EXT_INTER
1980 *mbmi = backup_mbmi;
1981#endif // CONFIG_EXT_INTER
1982 }
1983 xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8);
1984 xd->mb_to_right_edge = mb_to_right_edge_base;
1985 xd->mb_to_top_edge += xd->n8_h * 32;
1986}
1987
1988void av1_build_prediction_by_right_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
1989 int mi_row, int mi_col,
1990 uint8_t *tmp_buf[MAX_MB_PLANE],
1991 int tmp_width[MAX_MB_PLANE],
1992 int tmp_height[MAX_MB_PLANE],
1993 const int tmp_stride[MAX_MB_PLANE]) {
1994 const TileInfo *const tile = &xd->tile;
1995 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
1996 int i, j, mi_step, ref;
1997 int mb_to_bottom_edge_base = xd->mb_to_bottom_edge;
1998
1999 if (mi_col + xd->n8_w >= tile->mi_col_end || (mi_col + xd->n8_w) % 8 == 0 ||
2000 (mi_col + xd->n8_w) >= cm->mi_cols)
2001 return;
2002
2003 xd->mb_to_left_edge -= xd->n8_w * 32;
2004 for (i = 0; i < AOMMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) {
2005 int mi_row_offset = i;
2006 int mi_col_offset = xd->n8_w;
2007 int mi_x, mi_y, bw, bh;
2008 MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
2009 MB_MODE_INFO *mbmi = &mi->mbmi;
2010#if CONFIG_EXT_INTER
2011 MB_MODE_INFO backup_mbmi;
2012#endif // CONFIG_EXT_INTER
2013
2014 mi_step = AOMMIN(xd->n8_h, num_8x8_blocks_high_lookup[mbmi->sb_type]);
2015
2016 if (!is_neighbor_overlappable(mbmi)) continue;
2017
2018#if CONFIG_EXT_INTER
2019 backup_mbmi = *mbmi;
2020 modify_neighbor_predictor_for_obmc(mbmi);
2021#endif // CONFIG_EXT_INTER
2022
2023 for (j = 0; j < MAX_MB_PLANE; ++j) {
2024 struct macroblockd_plane *const pd = &xd->plane[j];
2025 setup_pred_plane(&pd->dst, tmp_buf[j], tmp_width[j], tmp_height[j],
2026 tmp_stride[j], i, xd->n8_w >> 1, NULL, pd->subsampling_x,
2027 pd->subsampling_y);
2028 }
2029 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
2030 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
2031 const RefBuffer *const ref_buf = &cm->frame_refs[frame - LAST_FRAME];
2032
2033 xd->block_refs[ref] = ref_buf;
2034 if ((!av1_is_valid_scale(&ref_buf->sf)))
2035 aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
2036 "Reference frame has invalid dimensions");
2037 av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row + i,
2038 mi_col + (xd->n8_w >> 1), &ref_buf->sf);
2039 }
2040
2041 xd->mb_to_top_edge = -(((mi_row + i) * MI_SIZE) * 8);
2042 xd->mb_to_bottom_edge =
2043 mb_to_bottom_edge_base + (xd->n8_h - i - mi_step) * 64;
2044 mi_x = (mi_col << MI_SIZE_LOG2) + xd->n8_w * 4;
2045 mi_y = (mi_row + i) << MI_SIZE_LOG2;
2046
2047 for (j = 0; j < MAX_MB_PLANE; ++j) {
2048 const struct macroblockd_plane *pd = &xd->plane[j];
2049 bw = (num_4x4_blocks_wide_lookup[bsize] << 1) >> pd->subsampling_x;
2050 bh = (mi_step << MI_SIZE_LOG2) >> pd->subsampling_y;
2051
2052 if (mbmi->sb_type < BLOCK_8X8) {
2053 const PARTITION_TYPE bp = BLOCK_8X8 - mbmi->sb_type;
2054 const int have_vsplit = bp != PARTITION_HORZ;
2055 const int have_hsplit = bp != PARTITION_VERT;
2056 const int num_4x4_w = 2 >> (!have_vsplit);
2057 const int num_4x4_h = 2 >> (!have_hsplit);
2058 const int ph = 8 >> (have_hsplit + pd->subsampling_y);
2059 int x, y;
2060
2061 for (y = 0; y < num_4x4_h; ++y)
2062 for (x = 0; x < num_4x4_w; ++x) {
2063 if ((bp == PARTITION_VERT || bp == PARTITION_SPLIT) && x != 0)
2064 continue;
2065
2066 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset,
2067 y * 2 + x, bw, bh,
2068 xd->n8_w == 1 ? 4 >> pd->subsampling_x : 0,
2069 (4 * y) >> pd->subsampling_y, bw, ph,
2070#if CONFIG_SUPERTX && CONFIG_EXT_INTER
2071 0, 0,
2072#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
2073 mi_x, mi_y);
2074 }
2075 } else {
2076#if CONFIG_WARPED_MOTION
2077 if (mbmi->motion_mode == WARPED_CAUSAL) {
2078 av1_warp_plane(&mbmi->wm_params[0],
2079#if CONFIG_AOM_HIGHBITDEPTH
2080 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
2081#endif // CONFIG_AOM_HIGHBITDEPTH
2082 pd->pre[0].buf0, pd->pre[0].width, pd->pre[0].height,
2083 pd->pre[0].stride, pd->dst.buf,
2084 ((mi_col * MI_SIZE) >> pd->subsampling_x),
2085 (((mi_row + i) * MI_SIZE) >> pd->subsampling_y), bw,
2086 bh, pd->dst.stride, pd->subsampling_x,
2087 pd->subsampling_y, 16, 16, 0);
2088
2089 } else {
2090#endif // CONFIG_WARPED_MOTION
2091 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0, bw, bh,
2092 xd->n8_w == 1 ? 4 >> pd->subsampling_x : 0, 0,
2093 bw, bh,
2094#if CONFIG_SUPERTX && CONFIG_EXT_INTER
2095 0, 0,
2096#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
2097 mi_x, mi_y);
2098#if CONFIG_WARPED_MOTION
2099 }
2100#endif // CONFIG_WARPED_MOTION
2101 }
2102 }
2103#if CONFIG_EXT_INTER
2104 *mbmi = backup_mbmi;
2105#endif // CONFIG_EXT_INTER
2106 }
2107 xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8);
2108 xd->mb_to_bottom_edge = mb_to_bottom_edge_base;
2109 xd->mb_to_left_edge += xd->n8_w * 32;
2110}
2111
2112// This function combines motion compensated predictions that is generated by
2113// bottom/right neighboring blocks' inter predictors with prediction in dst
2114// buffer.
2115void av1_merge_dst_bottom_right_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
2116 int mi_row, int mi_col,
2117 uint8_t *bottom[MAX_MB_PLANE],
2118 const int bottom_stride[MAX_MB_PLANE],
2119 uint8_t *right[MAX_MB_PLANE],
2120 const int right_stride[MAX_MB_PLANE]) {
2121 const TileInfo *const tile = &xd->tile;
2122 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
2123 int plane, i, mi_step;
2124 const int bottom_available = mi_row + xd->n8_h < tile->mi_row_end &&
2125 (mi_row + xd->n8_h) % 8 != 0 &&
2126 (mi_row + xd->n8_h) < cm->mi_rows;
2127#if CONFIG_AOM_HIGHBITDEPTH
2128 int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
2129#endif // CONFIG_AOM_HIGHBITDEPTH
2130
2131 // handle bottom row
2132 for (i = 0; bottom_available && i < AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
2133 i += mi_step) {
2134 int mi_row_offset = xd->n8_h;
2135 int mi_col_offset = i;
2136 MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
2137 MB_MODE_INFO *mbmi = &mi->mbmi;
2138 int overlap;
2139
2140 mi_step = AOMMIN(xd->n8_w, num_8x8_blocks_wide_lookup[mbmi->sb_type]);
2141
2142 if (!is_neighbor_overlappable(mbmi)) continue;
2143
2144 overlap = num_4x4_blocks_high_lookup[bsize] << 1;
2145
2146 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
2147 const struct macroblockd_plane *pd = &xd->plane[plane];
2148 const int bw = (mi_step * MI_SIZE) >> pd->subsampling_x;
2149 const int bh = overlap >> pd->subsampling_y;
2150 const int dst_stride = pd->dst.stride;
2151 uint8_t *dst = &pd->dst.buf[((i * MI_SIZE) >> pd->subsampling_x) +
2152 (((xd->n8_h * 8 - overlap) * dst_stride) >>
2153 pd->subsampling_y)];
2154 const int tmp_stride = bottom_stride[plane];
2155 const uint8_t *const tmp =
2156 &bottom[plane][((i * MI_SIZE) >> pd->subsampling_x) +
2157 (((xd->n8_h * 8 - overlap) * tmp_stride) >>
2158 pd->subsampling_y)];
2159 const uint8_t *const mask = av1_get_obmc_mask_flipped(bh);
2160
2161#if CONFIG_AOM_HIGHBITDEPTH
2162 if (is_hbd)
2163 aom_highbd_blend_a64_vmask(dst, dst_stride, dst, dst_stride, tmp,
2164 tmp_stride, mask, bh, bw, xd->bd);
2165 else
2166#endif // CONFIG_AOM_HIGHBITDEPTH
2167 aom_blend_a64_vmask(dst, dst_stride, dst, dst_stride, tmp, tmp_stride,
2168 mask, bh, bw);
2169 }
2170 } // each mi in the bottom row
2171
2172 // handle right column
2173 if (mi_col + xd->n8_w >= tile->mi_col_end || (mi_col + xd->n8_w) % 8 == 0 ||
2174 (mi_col + xd->n8_w) >= cm->mi_cols)
2175 return;
2176
2177 for (i = 0; i < AOMMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) {
2178 int mi_row_offset = i;
2179 int mi_col_offset = xd->n8_w;
2180 int overlap;
2181 MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
2182 MB_MODE_INFO *mbmi = &mi->mbmi;
2183
2184 mi_step = AOMMIN(xd->n8_h, num_8x8_blocks_high_lookup[mbmi->sb_type]);
2185
2186 if (!is_neighbor_overlappable(mbmi)) continue;
2187
2188 overlap = num_4x4_blocks_wide_lookup[bsize] << 1;
2189
2190 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
2191 const struct macroblockd_plane *pd = &xd->plane[plane];
2192 const int bw = overlap >> pd->subsampling_x;
2193 const int bh = (mi_step * MI_SIZE) >> pd->subsampling_y;
2194 const int dst_stride = pd->dst.stride;
2195 uint8_t *dst =
2196 &pd->dst.buf[((i * MI_SIZE * dst_stride) >> pd->subsampling_y) +
2197 ((xd->n8_w * 8 - overlap) >> pd->subsampling_x)];
2198 const int tmp_stride = right_stride[plane];
2199 const uint8_t *const tmp =
2200 &right[plane][((i * MI_SIZE * tmp_stride) >> pd->subsampling_y) +
2201 ((xd->n8_w * 8 - overlap) >> pd->subsampling_x)];
2202 const uint8_t *const mask = av1_get_obmc_mask_flipped(bw);
2203
2204#if CONFIG_AOM_HIGHBITDEPTH
2205 if (is_hbd)
2206 aom_highbd_blend_a64_hmask(dst, dst_stride, dst, dst_stride, tmp,
2207 tmp_stride, mask, bh, bw, xd->bd);
2208 else
2209#endif // CONFIG_AOM_HIGHBITDEPTH
2210 aom_blend_a64_hmask(dst, dst_stride, dst, dst_stride, tmp, tmp_stride,
2211 mask, bh, bw);
2212 }
2213 } // each mi in the right column
2214}
2215
2216// This function generates 4 sided obmc. (1) Prediction blocks generated by
2217// bottom and right motion vectors are calculated. (2) Combine them with the
2218// original prediction block (which should be pre-stored in xd->plane[].dst.buf
2219// before calling this function). The results is updated in xd->plane[].dst.buf
2220// (3) Call causal obmc prediction function, which will generate left and above
2221// preds, and then merge them and xd->plane[].dst.buf.
2222void av1_build_ncobmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
2223 int mi_row, int mi_col) {
2224#if CONFIG_AOM_HIGHBITDEPTH
2225 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
2226 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
2227#else
2228 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
2229 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
2230#endif // CONFIG_AOM_HIGHBITDEPTH
2231 uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
2232 int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2233 int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2234 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2235 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2236 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2237 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2238
2239#if CONFIG_AOM_HIGHBITDEPTH
2240 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2241 int len = sizeof(uint16_t);
2242 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
2243 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
2244 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * 2 * len);
2245 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
2246 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
2247 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * 2 * len);
2248 } else {
2249#endif // CONFIG_AOM_HIGHBITDEPTH
2250 dst_buf1[0] = tmp_buf1;
2251 dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE;
2252 dst_buf1[2] = tmp_buf1 + MAX_SB_SQUARE * 2;
2253 dst_buf2[0] = tmp_buf2;
2254 dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE;
2255 dst_buf2[2] = tmp_buf2 + MAX_SB_SQUARE * 2;
2256#if CONFIG_AOM_HIGHBITDEPTH
2257 }
2258#endif // CONFIG_AOM_HIGHBITDEPTH
2259 // causal obmc pred
2260
2261 // replace by bottom and right preds
2262 av1_build_prediction_by_bottom_preds(cm, xd, mi_row, mi_col, dst_buf1,
2263 dst_width1, dst_height1, dst_stride1);
2264 av1_build_prediction_by_right_preds(cm, xd, mi_row, mi_col, dst_buf2,
2265 dst_width2, dst_height2, dst_stride2);
2266 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
2267 av1_merge_dst_bottom_right_preds(cm, xd, mi_row, mi_col, dst_buf1,
2268 dst_stride1, dst_buf2, dst_stride2);
2269 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
2270 av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
2271 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
2272}
2273#endif // CONFIG_NCOBMC
Yue Chencb60b182016-10-13 15:18:22 -07002274#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07002275
2276#if CONFIG_EXT_INTER
2277#if CONFIG_EXT_PARTITION
2278static const int ii_weights1d[MAX_SB_SIZE] = {
2279 102, 100, 97, 95, 92, 90, 88, 86, 84, 82, 80, 78, 76, 74, 73, 71, 69, 68, 67,
2280 65, 64, 62, 61, 60, 59, 58, 57, 55, 54, 53, 52, 52, 51, 50, 49, 48, 47, 47,
2281 46, 45, 45, 44, 43, 43, 42, 41, 41, 40, 40, 39, 39, 38, 38, 38, 37, 37, 36,
2282 36, 36, 35, 35, 35, 34, 34, 34, 33, 33, 33, 33, 32, 32, 32, 32, 32, 31, 31,
2283 31, 31, 31, 30, 30, 30, 30, 30, 30, 30, 29, 29, 29, 29, 29, 29, 29, 29, 28,
2284 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 27, 27, 27, 27, 27, 27, 27, 27,
2285 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
2286};
2287static int ii_size_scales[BLOCK_SIZES] = { 32, 16, 16, 16, 8, 8, 8, 4,
2288 4, 4, 2, 2, 2, 1, 1, 1 };
2289#else
2290static const int ii_weights1d[MAX_SB_SIZE] = {
2291 102, 100, 97, 95, 92, 90, 88, 86, 84, 82, 80, 78, 76, 74, 73, 71,
2292 69, 68, 67, 65, 64, 62, 61, 60, 59, 58, 57, 55, 54, 53, 52, 52,
2293 51, 50, 49, 48, 47, 47, 46, 45, 45, 44, 43, 43, 42, 41, 41, 40,
2294 40, 39, 39, 38, 38, 38, 37, 37, 36, 36, 36, 35, 35, 35, 34, 34,
2295};
2296static int ii_size_scales[BLOCK_SIZES] = { 16, 8, 8, 8, 4, 4, 4,
2297 2, 2, 2, 1, 1, 1 };
2298#endif // CONFIG_EXT_PARTITION
2299
2300static void combine_interintra(INTERINTRA_MODE mode, int use_wedge_interintra,
2301 int wedge_index, int wedge_sign,
2302 BLOCK_SIZE bsize, BLOCK_SIZE plane_bsize,
2303 uint8_t *comppred, int compstride,
2304 const uint8_t *interpred, int interstride,
2305 const uint8_t *intrapred, int intrastride) {
Jingning Hanae5cfde2016-11-30 12:01:44 -08002306 const int bw = block_size_wide[plane_bsize];
2307 const int bh = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002308 const int size_scale = ii_size_scales[plane_bsize];
2309 int i, j;
2310
2311 if (use_wedge_interintra) {
2312 if (is_interintra_wedge_used(bsize)) {
2313 const uint8_t *mask =
Yaowu Xuf883b422016-08-30 14:01:10 -07002314 av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002315 const int subw = 2 * num_4x4_blocks_wide_lookup[bsize] == bw;
2316 const int subh = 2 * num_4x4_blocks_high_lookup[bsize] == bh;
Jingning Hanae5cfde2016-11-30 12:01:44 -08002317 aom_blend_a64_mask(comppred, compstride, intrapred, intrastride,
2318 interpred, interstride, mask, block_size_wide[bsize],
2319 bh, bw, subh, subw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002320 }
2321 return;
2322 }
2323
2324 switch (mode) {
2325 case II_V_PRED:
2326 for (i = 0; i < bh; ++i) {
2327 for (j = 0; j < bw; ++j) {
2328 int scale = ii_weights1d[i * size_scale];
2329 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002330 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002331 interpred[i * interstride + j]);
2332 }
2333 }
2334 break;
2335
2336 case II_H_PRED:
2337 for (i = 0; i < bh; ++i) {
2338 for (j = 0; j < bw; ++j) {
2339 int scale = ii_weights1d[j * size_scale];
2340 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002341 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002342 interpred[i * interstride + j]);
2343 }
2344 }
2345 break;
2346
2347 case II_D63_PRED:
2348 case II_D117_PRED:
2349 for (i = 0; i < bh; ++i) {
2350 for (j = 0; j < bw; ++j) {
2351 int scale = (ii_weights1d[i * size_scale] * 3 +
2352 ii_weights1d[j * size_scale]) >>
2353 2;
2354 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002355 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002356 interpred[i * interstride + j]);
2357 }
2358 }
2359 break;
2360
2361 case II_D207_PRED:
2362 case II_D153_PRED:
2363 for (i = 0; i < bh; ++i) {
2364 for (j = 0; j < bw; ++j) {
2365 int scale = (ii_weights1d[j * size_scale] * 3 +
2366 ii_weights1d[i * size_scale]) >>
2367 2;
2368 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002369 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002370 interpred[i * interstride + j]);
2371 }
2372 }
2373 break;
2374
2375 case II_D135_PRED:
2376 for (i = 0; i < bh; ++i) {
2377 for (j = 0; j < bw; ++j) {
2378 int scale = ii_weights1d[(i < j ? i : j) * size_scale];
2379 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002380 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002381 interpred[i * interstride + j]);
2382 }
2383 }
2384 break;
2385
2386 case II_D45_PRED:
2387 for (i = 0; i < bh; ++i) {
2388 for (j = 0; j < bw; ++j) {
2389 int scale =
2390 (ii_weights1d[i * size_scale] + ii_weights1d[j * size_scale]) >>
2391 1;
2392 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002393 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002394 interpred[i * interstride + j]);
2395 }
2396 }
2397 break;
2398
2399 case II_TM_PRED:
2400 case II_DC_PRED:
2401 default:
2402 for (i = 0; i < bh; ++i) {
2403 for (j = 0; j < bw; ++j) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002404 comppred[i * compstride + j] = AOM_BLEND_AVG(
Yaowu Xuc27fc142016-08-22 16:08:15 -07002405 intrapred[i * intrastride + j], interpred[i * interstride + j]);
2406 }
2407 }
2408 break;
2409 }
2410}
2411
Yaowu Xuf883b422016-08-30 14:01:10 -07002412#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002413static void combine_interintra_highbd(
2414 INTERINTRA_MODE mode, int use_wedge_interintra, int wedge_index,
2415 int wedge_sign, BLOCK_SIZE bsize, BLOCK_SIZE plane_bsize,
2416 uint8_t *comppred8, int compstride, const uint8_t *interpred8,
2417 int interstride, const uint8_t *intrapred8, int intrastride, int bd) {
Jingning Hanae5cfde2016-11-30 12:01:44 -08002418 const int bw = block_size_wide[plane_bsize];
2419 const int bh = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002420 const int size_scale = ii_size_scales[plane_bsize];
2421 int i, j;
2422
2423 uint16_t *comppred = CONVERT_TO_SHORTPTR(comppred8);
2424 const uint16_t *interpred = CONVERT_TO_SHORTPTR(interpred8);
2425 const uint16_t *intrapred = CONVERT_TO_SHORTPTR(intrapred8);
2426
2427 if (use_wedge_interintra) {
2428 if (is_interintra_wedge_used(bsize)) {
2429 const uint8_t *mask =
Yaowu Xuf883b422016-08-30 14:01:10 -07002430 av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002431 const int subh = 2 * num_4x4_blocks_high_lookup[bsize] == bh;
2432 const int subw = 2 * num_4x4_blocks_wide_lookup[bsize] == bw;
Yaowu Xuf883b422016-08-30 14:01:10 -07002433 aom_highbd_blend_a64_mask(comppred8, compstride, intrapred8, intrastride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002434 interpred8, interstride, mask, bw, bh, bw, subh,
2435 subw, bd);
2436 }
2437 return;
2438 }
2439
2440 switch (mode) {
2441 case II_V_PRED:
2442 for (i = 0; i < bh; ++i) {
2443 for (j = 0; j < bw; ++j) {
2444 int scale = ii_weights1d[i * size_scale];
2445 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002446 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002447 interpred[i * interstride + j]);
2448 }
2449 }
2450 break;
2451
2452 case II_H_PRED:
2453 for (i = 0; i < bh; ++i) {
2454 for (j = 0; j < bw; ++j) {
2455 int scale = ii_weights1d[j * size_scale];
2456 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002457 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002458 interpred[i * interstride + j]);
2459 }
2460 }
2461 break;
2462
2463 case II_D63_PRED:
2464 case II_D117_PRED:
2465 for (i = 0; i < bh; ++i) {
2466 for (j = 0; j < bw; ++j) {
2467 int scale = (ii_weights1d[i * size_scale] * 3 +
2468 ii_weights1d[j * size_scale]) >>
2469 2;
2470 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002471 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002472 interpred[i * interstride + j]);
2473 }
2474 }
2475 break;
2476
2477 case II_D207_PRED:
2478 case II_D153_PRED:
2479 for (i = 0; i < bh; ++i) {
2480 for (j = 0; j < bw; ++j) {
2481 int scale = (ii_weights1d[j * size_scale] * 3 +
2482 ii_weights1d[i * size_scale]) >>
2483 2;
2484 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002485 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002486 interpred[i * interstride + j]);
2487 }
2488 }
2489 break;
2490
2491 case II_D135_PRED:
2492 for (i = 0; i < bh; ++i) {
2493 for (j = 0; j < bw; ++j) {
2494 int scale = ii_weights1d[(i < j ? i : j) * size_scale];
2495 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002496 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002497 interpred[i * interstride + j]);
2498 }
2499 }
2500 break;
2501
2502 case II_D45_PRED:
2503 for (i = 0; i < bh; ++i) {
2504 for (j = 0; j < bw; ++j) {
2505 int scale =
2506 (ii_weights1d[i * size_scale] + ii_weights1d[j * size_scale]) >>
2507 1;
2508 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002509 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002510 interpred[i * interstride + j]);
2511 }
2512 }
2513 break;
2514
2515 case II_TM_PRED:
2516 case II_DC_PRED:
2517 default:
2518 for (i = 0; i < bh; ++i) {
2519 for (j = 0; j < bw; ++j) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002520 comppred[i * compstride + j] = AOM_BLEND_AVG(
Yaowu Xuc27fc142016-08-22 16:08:15 -07002521 interpred[i * interstride + j], intrapred[i * intrastride + j]);
2522 }
2523 }
2524 break;
2525 }
2526}
Yaowu Xuf883b422016-08-30 14:01:10 -07002527#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002528
Yaowu Xuc27fc142016-08-22 16:08:15 -07002529static void build_intra_predictors_for_interintra(MACROBLOCKD *xd, uint8_t *ref,
2530 int ref_stride, uint8_t *dst,
2531 int dst_stride,
2532 PREDICTION_MODE mode,
2533 BLOCK_SIZE bsize, int plane) {
Angie Chiang45c198a2016-10-27 17:12:16 -07002534 struct macroblockd_plane *const pd = &xd->plane[plane];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002535 BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, &xd->plane[plane]);
2536 const int bwl = b_width_log2_lookup[plane_bsize];
2537 const int bhl = b_height_log2_lookup[plane_bsize];
David Barkerac37fa32016-12-02 12:30:21 +00002538 TX_SIZE max_tx_size = max_txsize_lookup[plane_bsize];
2539#if USE_RECT_INTERINTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07002540 const int pxbw = 4 << bwl;
2541 const int pxbh = 4 << bhl;
David Barkerac37fa32016-12-02 12:30:21 +00002542#if CONFIG_AOM_HIGHBITDEPTH
2543 uint16_t tmp16[MAX_SB_SIZE];
2544#endif
2545 uint8_t tmp[MAX_SB_SIZE];
2546#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002547
2548 if (bwl == bhl) {
Angie Chiang45c198a2016-10-27 17:12:16 -07002549 av1_predict_intra_block(xd, pd->width, pd->height, max_tx_size, mode, ref,
2550 ref_stride, dst, dst_stride, 0, 0, plane);
David Barkerac37fa32016-12-02 12:30:21 +00002551#if !USE_RECT_INTERINTRA
2552 } else {
2553 assert(0);
2554 }
2555#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07002556 } else if (bwl < bhl) {
2557 uint8_t *src_2 = ref + pxbw * ref_stride;
2558 uint8_t *dst_2 = dst + pxbw * dst_stride;
Angie Chiang45c198a2016-10-27 17:12:16 -07002559 av1_predict_intra_block(xd, pd->width, pd->height, max_tx_size, mode, ref,
2560 ref_stride, dst, dst_stride, 0, 0, plane);
Yaowu Xuf883b422016-08-30 14:01:10 -07002561#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002562 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2563 uint16_t *src_216 = CONVERT_TO_SHORTPTR(src_2);
2564 uint16_t *dst_216 = CONVERT_TO_SHORTPTR(dst_2);
David Barkerac37fa32016-12-02 12:30:21 +00002565 memcpy(tmp16, src_216 - ref_stride, sizeof(*src_216) * pxbw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002566 memcpy(src_216 - ref_stride, dst_216 - dst_stride,
2567 sizeof(*src_216) * pxbw);
David Barkerac37fa32016-12-02 12:30:21 +00002568 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07002569#endif // CONFIG_AOM_HIGHBITDEPTH
David Barkerac37fa32016-12-02 12:30:21 +00002570 memcpy(tmp, src_2 - ref_stride, sizeof(*src_2) * pxbw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002571 memcpy(src_2 - ref_stride, dst_2 - dst_stride, sizeof(*src_2) * pxbw);
David Barkerac37fa32016-12-02 12:30:21 +00002572#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002573 }
David Barkerac37fa32016-12-02 12:30:21 +00002574#endif
Angie Chiang45c198a2016-10-27 17:12:16 -07002575 av1_predict_intra_block(xd, pd->width, pd->height, max_tx_size, mode, src_2,
2576 ref_stride, dst_2, dst_stride, 0, 1 << bwl, plane);
David Barkerac37fa32016-12-02 12:30:21 +00002577#if CONFIG_AOM_HIGHBITDEPTH
2578 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2579 uint16_t *src_216 = CONVERT_TO_SHORTPTR(src_2);
2580 memcpy(src_216 - ref_stride, tmp16, sizeof(*src_216) * pxbw);
2581 } else {
2582#endif // CONFIG_AOM_HIGHBITDEPTH
2583 memcpy(src_2 - ref_stride, tmp, sizeof(*src_2) * pxbw);
2584#if CONFIG_AOM_HIGHBITDEPTH
2585 }
2586#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002587 } else { // bwl > bhl
2588 int i;
2589 uint8_t *src_2 = ref + pxbh;
2590 uint8_t *dst_2 = dst + pxbh;
Angie Chiang45c198a2016-10-27 17:12:16 -07002591 av1_predict_intra_block(xd, pd->width, pd->height, max_tx_size, mode, ref,
2592 ref_stride, dst, dst_stride, 0, 0, plane);
Yaowu Xuf883b422016-08-30 14:01:10 -07002593#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002594 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2595 uint16_t *src_216 = CONVERT_TO_SHORTPTR(src_2);
2596 uint16_t *dst_216 = CONVERT_TO_SHORTPTR(dst_2);
David Barkerac37fa32016-12-02 12:30:21 +00002597 for (i = 0; i < pxbh; ++i) {
2598 tmp16[i] = src_216[i * ref_stride - 1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002599 src_216[i * ref_stride - 1] = dst_216[i * dst_stride - 1];
David Barkerac37fa32016-12-02 12:30:21 +00002600 }
2601 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07002602#endif // CONFIG_AOM_HIGHBITDEPTH
David Barkerac37fa32016-12-02 12:30:21 +00002603 for (i = 0; i < pxbh; ++i) {
2604 tmp[i] = src_2[i * ref_stride - 1];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002605 src_2[i * ref_stride - 1] = dst_2[i * dst_stride - 1];
David Barkerac37fa32016-12-02 12:30:21 +00002606 }
2607#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002608 }
David Barkerac37fa32016-12-02 12:30:21 +00002609#endif
Angie Chiang45c198a2016-10-27 17:12:16 -07002610 av1_predict_intra_block(xd, pd->width, pd->height, max_tx_size, mode, src_2,
2611 ref_stride, dst_2, dst_stride, 1 << bhl, 0, plane);
David Barkerac37fa32016-12-02 12:30:21 +00002612#if CONFIG_AOM_HIGHBITDEPTH
2613 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2614 uint16_t *src_216 = CONVERT_TO_SHORTPTR(src_2);
2615 for (i = 0; i < pxbh; ++i) src_216[i * ref_stride - 1] = tmp16[i];
2616 } else {
2617#endif // CONFIG_AOM_HIGHBITDEPTH
2618 for (i = 0; i < pxbh; ++i) src_2[i * ref_stride - 1] = tmp[i];
2619#if CONFIG_AOM_HIGHBITDEPTH
2620 }
2621#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002622 }
David Barkerac37fa32016-12-02 12:30:21 +00002623#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002624}
2625
Yaowu Xuf883b422016-08-30 14:01:10 -07002626void av1_build_intra_predictors_for_interintra(MACROBLOCKD *xd,
2627 BLOCK_SIZE bsize, int plane,
David Barkerac37fa32016-12-02 12:30:21 +00002628 BUFFER_SET *ctx, uint8_t *dst,
2629 int dst_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002630 build_intra_predictors_for_interintra(
David Barkerac37fa32016-12-02 12:30:21 +00002631 xd, ctx->plane[plane], ctx->stride[plane], dst, dst_stride,
2632 interintra_to_intra_mode[xd->mi[0]->mbmi.interintra_mode], bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002633}
2634
Yaowu Xuf883b422016-08-30 14:01:10 -07002635void av1_combine_interintra(MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane,
2636 const uint8_t *inter_pred, int inter_stride,
2637 const uint8_t *intra_pred, int intra_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002638 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, &xd->plane[plane]);
Yaowu Xuf883b422016-08-30 14:01:10 -07002639#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002640 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2641 combine_interintra_highbd(
2642 xd->mi[0]->mbmi.interintra_mode, xd->mi[0]->mbmi.use_wedge_interintra,
2643 xd->mi[0]->mbmi.interintra_wedge_index,
2644 xd->mi[0]->mbmi.interintra_wedge_sign, bsize, plane_bsize,
2645 xd->plane[plane].dst.buf, xd->plane[plane].dst.stride, inter_pred,
2646 inter_stride, intra_pred, intra_stride, xd->bd);
2647 return;
2648 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002649#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002650 combine_interintra(xd->mi[0]->mbmi.interintra_mode,
2651 xd->mi[0]->mbmi.use_wedge_interintra,
2652 xd->mi[0]->mbmi.interintra_wedge_index,
2653 xd->mi[0]->mbmi.interintra_wedge_sign, bsize, plane_bsize,
2654 xd->plane[plane].dst.buf, xd->plane[plane].dst.stride,
2655 inter_pred, inter_stride, intra_pred, intra_stride);
2656}
2657
Yaowu Xuf883b422016-08-30 14:01:10 -07002658void av1_build_interintra_predictors_sby(MACROBLOCKD *xd, uint8_t *ypred,
David Barkerac37fa32016-12-02 12:30:21 +00002659 int ystride, BUFFER_SET *ctx,
2660 BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002661#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002662 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2663 DECLARE_ALIGNED(16, uint16_t, intrapredictor[MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07002664 av1_build_intra_predictors_for_interintra(
David Barkerac37fa32016-12-02 12:30:21 +00002665 xd, bsize, 0, ctx, CONVERT_TO_BYTEPTR(intrapredictor), MAX_SB_SIZE);
Yaowu Xuf883b422016-08-30 14:01:10 -07002666 av1_combine_interintra(xd, bsize, 0, ypred, ystride,
2667 CONVERT_TO_BYTEPTR(intrapredictor), MAX_SB_SIZE);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002668 return;
2669 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002670#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002671 {
2672 DECLARE_ALIGNED(16, uint8_t, intrapredictor[MAX_SB_SQUARE]);
David Barkerac37fa32016-12-02 12:30:21 +00002673 av1_build_intra_predictors_for_interintra(xd, bsize, 0, ctx, intrapredictor,
Yaowu Xuf883b422016-08-30 14:01:10 -07002674 MAX_SB_SIZE);
2675 av1_combine_interintra(xd, bsize, 0, ypred, ystride, intrapredictor,
2676 MAX_SB_SIZE);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002677 }
2678}
2679
Yaowu Xuf883b422016-08-30 14:01:10 -07002680void av1_build_interintra_predictors_sbc(MACROBLOCKD *xd, uint8_t *upred,
David Barkerac37fa32016-12-02 12:30:21 +00002681 int ustride, BUFFER_SET *ctx,
2682 int plane, BLOCK_SIZE bsize) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002683#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002684 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2685 DECLARE_ALIGNED(16, uint16_t, uintrapredictor[MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07002686 av1_build_intra_predictors_for_interintra(
David Barkerac37fa32016-12-02 12:30:21 +00002687 xd, bsize, plane, ctx, CONVERT_TO_BYTEPTR(uintrapredictor),
2688 MAX_SB_SIZE);
Yaowu Xuf883b422016-08-30 14:01:10 -07002689 av1_combine_interintra(xd, bsize, plane, upred, ustride,
2690 CONVERT_TO_BYTEPTR(uintrapredictor), MAX_SB_SIZE);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002691 return;
2692 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002693#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002694 {
2695 DECLARE_ALIGNED(16, uint8_t, uintrapredictor[MAX_SB_SQUARE]);
David Barkerac37fa32016-12-02 12:30:21 +00002696 av1_build_intra_predictors_for_interintra(xd, bsize, plane, ctx,
2697 uintrapredictor, MAX_SB_SIZE);
Yaowu Xuf883b422016-08-30 14:01:10 -07002698 av1_combine_interintra(xd, bsize, plane, upred, ustride, uintrapredictor,
2699 MAX_SB_SIZE);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002700 }
2701}
2702
Yaowu Xuf883b422016-08-30 14:01:10 -07002703void av1_build_interintra_predictors_sbuv(MACROBLOCKD *xd, uint8_t *upred,
2704 uint8_t *vpred, int ustride,
David Barkerac37fa32016-12-02 12:30:21 +00002705 int vstride, BUFFER_SET *ctx,
2706 BLOCK_SIZE bsize) {
2707 av1_build_interintra_predictors_sbc(xd, upred, ustride, ctx, 1, bsize);
2708 av1_build_interintra_predictors_sbc(xd, vpred, vstride, ctx, 2, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002709}
2710
Yaowu Xuf883b422016-08-30 14:01:10 -07002711void av1_build_interintra_predictors(MACROBLOCKD *xd, uint8_t *ypred,
2712 uint8_t *upred, uint8_t *vpred,
2713 int ystride, int ustride, int vstride,
David Barkerac37fa32016-12-02 12:30:21 +00002714 BUFFER_SET *ctx, BLOCK_SIZE bsize) {
2715 av1_build_interintra_predictors_sby(xd, ypred, ystride, ctx, bsize);
2716 av1_build_interintra_predictors_sbuv(xd, upred, vpred, ustride, vstride, ctx,
Yaowu Xuf883b422016-08-30 14:01:10 -07002717 bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002718}
2719
2720// Builds the inter-predictor for the single ref case
2721// for use in the encoder to search the wedges efficiently.
2722static void build_inter_predictors_single_buf(MACROBLOCKD *xd, int plane,
2723 int block, int bw, int bh, int x,
2724 int y, int w, int h, int mi_x,
2725 int mi_y, int ref,
2726 uint8_t *const ext_dst,
2727 int ext_dst_stride) {
2728 struct macroblockd_plane *const pd = &xd->plane[plane];
2729 const MODE_INFO *mi = xd->mi[0];
2730
2731 const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
2732 struct buf_2d *const pre_buf = &pd->pre[ref];
Yaowu Xuf883b422016-08-30 14:01:10 -07002733#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002734 uint8_t *const dst =
2735 (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH ? CONVERT_TO_BYTEPTR(ext_dst)
2736 : ext_dst) +
2737 ext_dst_stride * y + x;
2738#else
2739 uint8_t *const dst = ext_dst + ext_dst_stride * y + x;
2740#endif
2741 const MV mv = mi->mbmi.sb_type < BLOCK_8X8
2742 ? average_split_mvs(pd, mi, ref, block)
2743 : mi->mbmi.mv[ref].as_mv;
2744
2745 // TODO(jkoleszar): This clamping is done in the incorrect place for the
2746 // scaling case. It needs to be done on the scaled MV, not the pre-scaling
2747 // MV. Note however that it performs the subsampling aware scaling so
2748 // that the result is always q4.
2749 // mv_precision precision is MV_PRECISION_Q4.
2750 const MV mv_q4 = clamp_mv_to_umv_border_sb(xd, &mv, bw, bh, pd->subsampling_x,
2751 pd->subsampling_y);
2752
2753 uint8_t *pre;
2754 MV32 scaled_mv;
2755 int xs, ys, subpel_x, subpel_y;
Yaowu Xuf883b422016-08-30 14:01:10 -07002756 const int is_scaled = av1_is_scaled(sf);
Angie Chiang9f45bc42017-01-13 16:27:54 -08002757 ConvolveParams conv_params = get_conv_params(0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002758
2759 if (is_scaled) {
2760 pre = pre_buf->buf + scaled_buffer_offset(x, y, pre_buf->stride, sf);
Yaowu Xuf883b422016-08-30 14:01:10 -07002761 scaled_mv = av1_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002762 xs = sf->x_step_q4;
2763 ys = sf->y_step_q4;
2764 } else {
2765 pre = pre_buf->buf + (y * pre_buf->stride + x);
2766 scaled_mv.row = mv_q4.row;
2767 scaled_mv.col = mv_q4.col;
2768 xs = ys = 16;
2769 }
2770
2771 subpel_x = scaled_mv.col & SUBPEL_MASK;
2772 subpel_y = scaled_mv.row & SUBPEL_MASK;
2773 pre += (scaled_mv.row >> SUBPEL_BITS) * pre_buf->stride +
2774 (scaled_mv.col >> SUBPEL_BITS);
2775
Yaowu Xuf883b422016-08-30 14:01:10 -07002776 av1_make_inter_predictor(pre, pre_buf->stride, dst, ext_dst_stride, subpel_x,
Angie Chiang9f45bc42017-01-13 16:27:54 -08002777 subpel_y, sf, w, h, &conv_params,
2778 mi->mbmi.interp_filter, xs, ys, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002779}
2780
Yaowu Xuf883b422016-08-30 14:01:10 -07002781void av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07002782 MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane_from, int plane_to, int mi_row,
2783 int mi_col, int ref, uint8_t *ext_dst[3], int ext_dst_stride[3]) {
2784 int plane;
2785 const int mi_x = mi_col * MI_SIZE;
2786 const int mi_y = mi_row * MI_SIZE;
2787 for (plane = plane_from; plane <= plane_to; ++plane) {
2788 const BLOCK_SIZE plane_bsize =
2789 get_plane_block_size(bsize, &xd->plane[plane]);
2790 const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize];
2791 const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han691a6902016-11-30 14:53:44 -08002792 const int bw = block_size_wide[plane_bsize];
2793 const int bh = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002794
2795 if (xd->mi[0]->mbmi.sb_type < BLOCK_8X8) {
2796 int x, y;
2797 assert(bsize == BLOCK_8X8);
2798 for (y = 0; y < num_4x4_h; ++y)
2799 for (x = 0; x < num_4x4_w; ++x)
2800 build_inter_predictors_single_buf(
2801 xd, plane, y * 2 + x, bw, bh, 4 * x, 4 * y, 4, 4, mi_x, mi_y, ref,
2802 ext_dst[plane], ext_dst_stride[plane]);
2803 } else {
2804 build_inter_predictors_single_buf(xd, plane, 0, bw, bh, 0, 0, bw, bh,
2805 mi_x, mi_y, ref, ext_dst[plane],
2806 ext_dst_stride[plane]);
2807 }
2808 }
2809}
2810
2811static void build_wedge_inter_predictor_from_buf(
2812 MACROBLOCKD *xd, int plane, int x, int y, int w, int h, uint8_t *ext_dst0,
2813 int ext_dst_stride0, uint8_t *ext_dst1, int ext_dst_stride1) {
Sarah Parker569edda2016-12-14 14:57:38 -08002814 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002815 const int is_compound = has_second_ref(mbmi);
2816 MACROBLOCKD_PLANE *const pd = &xd->plane[plane];
2817 struct buf_2d *const dst_buf = &pd->dst;
2818 uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x;
Sarah Parker569edda2016-12-14 14:57:38 -08002819 INTERINTER_COMPOUND_DATA *comp_data = &mbmi->interinter_compound_data;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002820
Sarah Parker6fdc8532016-11-16 17:47:13 -08002821 if (is_compound &&
2822 is_masked_compound_type(mbmi->interinter_compound_data.type)) {
Sarah Parker569edda2016-12-14 14:57:38 -08002823#if CONFIG_COMPOUND_SEGMENT
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08002824#if CONFIG_AOM_HIGHBITDEPTH
2825 if (!plane && comp_data->type == COMPOUND_SEG) {
2826 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
2827 build_compound_seg_mask_highbd(
2828 comp_data->seg_mask, comp_data->mask_type,
2829 CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0,
2830 CONVERT_TO_BYTEPTR(ext_dst1), ext_dst_stride1, mbmi->sb_type, h, w,
2831 xd->bd);
2832 else
2833 build_compound_seg_mask(comp_data->seg_mask, comp_data->mask_type,
2834 ext_dst0, ext_dst_stride0, ext_dst1,
2835 ext_dst_stride1, mbmi->sb_type, h, w);
2836 }
2837#else
Sarah Parker569edda2016-12-14 14:57:38 -08002838 if (!plane && comp_data->type == COMPOUND_SEG)
Sarah Parkerb9f757c2017-01-06 17:12:24 -08002839 build_compound_seg_mask(comp_data->seg_mask, comp_data->mask_type,
2840 ext_dst0, ext_dst_stride0, ext_dst1,
Sarah Parker569edda2016-12-14 14:57:38 -08002841 ext_dst_stride1, mbmi->sb_type, h, w);
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08002842#endif // CONFIG_AOM_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08002843#endif // CONFIG_COMPOUND_SEGMENT
Yaowu Xuf883b422016-08-30 14:01:10 -07002844#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002845 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08002846 build_masked_compound_highbd(
Yaowu Xuc27fc142016-08-22 16:08:15 -07002847 dst, dst_buf->stride, CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08002848 CONVERT_TO_BYTEPTR(ext_dst1), ext_dst_stride1, comp_data,
2849 mbmi->sb_type, h, w, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002850 else
Yaowu Xuf883b422016-08-30 14:01:10 -07002851#endif // CONFIG_AOM_HIGHBITDEPTH
Sarah Parker6fdc8532016-11-16 17:47:13 -08002852 build_masked_compound(dst, dst_buf->stride, ext_dst0, ext_dst_stride0,
2853 ext_dst1, ext_dst_stride1, comp_data, mbmi->sb_type,
2854 h, w);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002855 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07002856#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002857 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
Yaowu Xuf883b422016-08-30 14:01:10 -07002858 aom_highbd_convolve_copy(CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002859 dst, dst_buf->stride, NULL, 0, NULL, 0, w, h,
2860 xd->bd);
2861 else
Yaowu Xuf883b422016-08-30 14:01:10 -07002862#endif // CONFIG_AOM_HIGHBITDEPTH
2863 aom_convolve_copy(ext_dst0, ext_dst_stride0, dst, dst_buf->stride, NULL,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002864 0, NULL, 0, w, h);
2865 }
2866}
2867
Yaowu Xuf883b422016-08-30 14:01:10 -07002868void av1_build_wedge_inter_predictor_from_buf(MACROBLOCKD *xd, BLOCK_SIZE bsize,
2869 int plane_from, int plane_to,
2870 uint8_t *ext_dst0[3],
2871 int ext_dst_stride0[3],
2872 uint8_t *ext_dst1[3],
2873 int ext_dst_stride1[3]) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002874 int plane;
2875 for (plane = plane_from; plane <= plane_to; ++plane) {
2876 const BLOCK_SIZE plane_bsize =
2877 get_plane_block_size(bsize, &xd->plane[plane]);
2878 const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize];
2879 const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize];
2880
2881 if (xd->mi[0]->mbmi.sb_type < BLOCK_8X8) {
2882 int x, y;
2883 assert(bsize == BLOCK_8X8);
2884 for (y = 0; y < num_4x4_h; ++y)
2885 for (x = 0; x < num_4x4_w; ++x)
2886 build_wedge_inter_predictor_from_buf(
2887 xd, plane, 4 * x, 4 * y, 4, 4, ext_dst0[plane],
2888 ext_dst_stride0[plane], ext_dst1[plane], ext_dst_stride1[plane]);
2889 } else {
2890 const int bw = 4 * num_4x4_w;
2891 const int bh = 4 * num_4x4_h;
2892 build_wedge_inter_predictor_from_buf(
2893 xd, plane, 0, 0, bw, bh, ext_dst0[plane], ext_dst_stride0[plane],
2894 ext_dst1[plane], ext_dst_stride1[plane]);
2895 }
2896 }
2897}
2898#endif // CONFIG_EXT_INTER