blob: af6cb1cf1145f316b3b023cfdcf20a8b64cd1974 [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
Yaowu Xuc27fc142016-08-22 16:08:15 -070027
28#if CONFIG_EXT_INTER
29
30#define NSMOOTHERS 1
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -080031#define USE_SOFT_WEIGHTS_IN_WEDGE 1
Yaowu Xuc27fc142016-08-22 16:08:15 -070032static int get_masked_weight(int m, int smoothness) {
33#define SMOOTHER_LEN 32
34 static const uint8_t smoothfn[NSMOOTHERS][2 * SMOOTHER_LEN + 1] = { {
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -080035#if USE_SOFT_WEIGHTS_IN_WEDGE
clang-format67948d32016-09-07 22:40:40 -070036 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
37 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 7, 13, 21, 32, 43,
38 51, 57, 60, 62, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
39 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -080040#else
41 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 64, 32, 64,
43 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
44 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
45#endif // USE_SOFT_WEIGHTS_IN_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -070046 } };
47 if (m < -SMOOTHER_LEN)
48 return 0;
49 else if (m > SMOOTHER_LEN)
50 return (1 << WEDGE_WEIGHT_BITS);
51 else
52 return smoothfn[smoothness][m + SMOOTHER_LEN];
53}
54
55// [smoother][negative][direction]
clang-format67948d32016-09-07 22:40:40 -070056DECLARE_ALIGNED(16, static uint8_t,
57 wedge_mask_obl[NSMOOTHERS][2][WEDGE_DIRECTIONS]
58 [MASK_MASTER_SIZE * MASK_MASTER_SIZE]);
Yaowu Xuc27fc142016-08-22 16:08:15 -070059
60DECLARE_ALIGNED(16, static uint8_t,
61 wedge_signflip_lookup[BLOCK_SIZES][MAX_WEDGE_TYPES]);
62
63// 3 * MAX_WEDGE_SQUARE is an easy to compute and fairly tight upper bound
64// on the sum of all mask sizes up to an including MAX_WEDGE_SQUARE.
65DECLARE_ALIGNED(16, static uint8_t,
66 wedge_mask_buf[2 * MAX_WEDGE_TYPES * 3 * MAX_WEDGE_SQUARE]);
67
68static wedge_masks_type wedge_masks[BLOCK_SIZES][2];
69
70// Some unused wedge codebooks left temporarily to facilitate experiments.
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -080071// To be removed when settled.
72/*
Yaowu Xuc27fc142016-08-22 16:08:15 -070073static wedge_code_type wedge_codebook_8_hgtw[8] = {
74 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
75 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
76 { WEDGE_OBLIQUE27, 4, 2 }, { WEDGE_OBLIQUE27, 4, 6 },
77 { WEDGE_OBLIQUE153, 4, 2 }, { WEDGE_OBLIQUE153, 4, 6 },
78};
79
80static wedge_code_type wedge_codebook_8_hltw[8] = {
81 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
82 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
83 { WEDGE_OBLIQUE63, 2, 4 }, { WEDGE_OBLIQUE63, 6, 4 },
84 { WEDGE_OBLIQUE117, 2, 4 }, { WEDGE_OBLIQUE117, 6, 4 },
85};
86
87static wedge_code_type wedge_codebook_8_heqw[8] = {
88 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
89 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
90 { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 6 },
91 { WEDGE_VERTICAL, 2, 4 }, { WEDGE_VERTICAL, 6, 4 },
92};
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -080093*/
Yaowu Xuc27fc142016-08-22 16:08:15 -070094
95#if !USE_LARGE_WEDGE_CODEBOOK
96static const wedge_code_type wedge_codebook_16_hgtw[16] = {
97 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
98 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
99 { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 4 },
100 { WEDGE_HORIZONTAL, 4, 6 }, { WEDGE_VERTICAL, 4, 4 },
101 { WEDGE_OBLIQUE27, 4, 2 }, { WEDGE_OBLIQUE27, 4, 6 },
102 { WEDGE_OBLIQUE153, 4, 2 }, { WEDGE_OBLIQUE153, 4, 6 },
103 { WEDGE_OBLIQUE63, 2, 4 }, { WEDGE_OBLIQUE63, 6, 4 },
104 { WEDGE_OBLIQUE117, 2, 4 }, { WEDGE_OBLIQUE117, 6, 4 },
105};
106
107static const wedge_code_type wedge_codebook_16_hltw[16] = {
108 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
109 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
110 { WEDGE_VERTICAL, 2, 4 }, { WEDGE_VERTICAL, 4, 4 },
111 { WEDGE_VERTICAL, 6, 4 }, { WEDGE_HORIZONTAL, 4, 4 },
112 { WEDGE_OBLIQUE27, 4, 2 }, { WEDGE_OBLIQUE27, 4, 6 },
113 { WEDGE_OBLIQUE153, 4, 2 }, { WEDGE_OBLIQUE153, 4, 6 },
114 { WEDGE_OBLIQUE63, 2, 4 }, { WEDGE_OBLIQUE63, 6, 4 },
115 { WEDGE_OBLIQUE117, 2, 4 }, { WEDGE_OBLIQUE117, 6, 4 },
116};
117
118static const wedge_code_type wedge_codebook_16_heqw[16] = {
119 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
120 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
121 { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 6 },
122 { WEDGE_VERTICAL, 2, 4 }, { WEDGE_VERTICAL, 6, 4 },
123 { WEDGE_OBLIQUE27, 4, 2 }, { WEDGE_OBLIQUE27, 4, 6 },
124 { WEDGE_OBLIQUE153, 4, 2 }, { WEDGE_OBLIQUE153, 4, 6 },
125 { WEDGE_OBLIQUE63, 2, 4 }, { WEDGE_OBLIQUE63, 6, 4 },
126 { WEDGE_OBLIQUE117, 2, 4 }, { WEDGE_OBLIQUE117, 6, 4 },
127};
128
129const wedge_params_type wedge_params_lookup[BLOCK_SIZES] = {
Jingning Han61418bb2017-01-23 17:12:48 -0800130#if CONFIG_CB4X4
131 { 0, NULL, NULL, 0, NULL },
132 { 0, NULL, NULL, 0, NULL },
133 { 0, NULL, NULL, 0, NULL },
Debargha Mukherjee0be0aa12017-02-12 01:42:56 -0800134#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -0700135 { 0, NULL, NULL, 0, NULL },
136 { 0, NULL, NULL, 0, NULL },
137 { 0, NULL, NULL, 0, NULL },
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -0800138#if CONFIG_WEDGE
Debargha Mukherjee0be0aa12017-02-12 01:42:56 -0800139 { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_8X8], 0,
140 wedge_masks[BLOCK_8X8] },
141 { 4, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_8X16], 0,
142 wedge_masks[BLOCK_8X16] },
143 { 4, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_16X8], 0,
144 wedge_masks[BLOCK_16X8] },
145 { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_16X16], 0,
146 wedge_masks[BLOCK_16X16] },
147 { 4, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_16X32], 0,
148 wedge_masks[BLOCK_16X32] },
149 { 4, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_32X16], 0,
150 wedge_masks[BLOCK_32X16] },
151 { 4, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_32X32], 0,
152 wedge_masks[BLOCK_32X32] },
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -0800153 { 0, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_32X64], 0,
Debargha Mukherjee0be0aa12017-02-12 01:42:56 -0800154 wedge_masks[BLOCK_32X64] },
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -0800155 { 0, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_64X32], 0,
Debargha Mukherjee0be0aa12017-02-12 01:42:56 -0800156 wedge_masks[BLOCK_64X32] },
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -0800157 { 0, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_64X64], 0,
Debargha Mukherjee0be0aa12017-02-12 01:42:56 -0800158 wedge_masks[BLOCK_64X64] },
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -0800159#else
160 { 0, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_8X8], 0,
161 wedge_masks[BLOCK_8X8] },
162 { 0, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_8X16], 0,
163 wedge_masks[BLOCK_8X16] },
164 { 0, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_16X8], 0,
165 wedge_masks[BLOCK_16X8] },
166 { 0, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_16X16], 0,
167 wedge_masks[BLOCK_16X16] },
168 { 0, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_16X32], 0,
169 wedge_masks[BLOCK_16X32] },
170 { 0, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_32X16], 0,
171 wedge_masks[BLOCK_32X16] },
172 { 0, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_32X32], 0,
173 wedge_masks[BLOCK_32X32] },
174 { 0, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_32X64], 0,
175 wedge_masks[BLOCK_32X64] },
176 { 0, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_64X32], 0,
177 wedge_masks[BLOCK_64X32] },
178 { 0, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_64X64], 0,
179 wedge_masks[BLOCK_64X64] },
180#endif // CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700181#if CONFIG_EXT_PARTITION
182 { 0, NULL, NULL, 0, NULL },
183 { 0, NULL, NULL, 0, NULL },
184 { 0, NULL, NULL, 0, NULL },
185#endif // CONFIG_EXT_PARTITION
186};
187
188#else
189
190static const wedge_code_type wedge_codebook_32_hgtw[32] = {
191 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
192 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
193 { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 4 },
194 { WEDGE_HORIZONTAL, 4, 6 }, { WEDGE_VERTICAL, 4, 4 },
195 { WEDGE_OBLIQUE27, 4, 1 }, { WEDGE_OBLIQUE27, 4, 2 },
196 { WEDGE_OBLIQUE27, 4, 3 }, { WEDGE_OBLIQUE27, 4, 5 },
197 { WEDGE_OBLIQUE27, 4, 6 }, { WEDGE_OBLIQUE27, 4, 7 },
198 { WEDGE_OBLIQUE153, 4, 1 }, { WEDGE_OBLIQUE153, 4, 2 },
199 { WEDGE_OBLIQUE153, 4, 3 }, { WEDGE_OBLIQUE153, 4, 5 },
200 { WEDGE_OBLIQUE153, 4, 6 }, { WEDGE_OBLIQUE153, 4, 7 },
201 { WEDGE_OBLIQUE63, 1, 4 }, { WEDGE_OBLIQUE63, 2, 4 },
202 { WEDGE_OBLIQUE63, 3, 4 }, { WEDGE_OBLIQUE63, 5, 4 },
203 { WEDGE_OBLIQUE63, 6, 4 }, { WEDGE_OBLIQUE63, 7, 4 },
204 { WEDGE_OBLIQUE117, 1, 4 }, { WEDGE_OBLIQUE117, 2, 4 },
205 { WEDGE_OBLIQUE117, 3, 4 }, { WEDGE_OBLIQUE117, 5, 4 },
206 { WEDGE_OBLIQUE117, 6, 4 }, { WEDGE_OBLIQUE117, 7, 4 },
207};
208
209static const wedge_code_type wedge_codebook_32_hltw[32] = {
210 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
211 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
212 { WEDGE_VERTICAL, 2, 4 }, { WEDGE_VERTICAL, 4, 4 },
213 { WEDGE_VERTICAL, 6, 4 }, { WEDGE_HORIZONTAL, 4, 4 },
214 { WEDGE_OBLIQUE27, 4, 1 }, { WEDGE_OBLIQUE27, 4, 2 },
215 { WEDGE_OBLIQUE27, 4, 3 }, { WEDGE_OBLIQUE27, 4, 5 },
216 { WEDGE_OBLIQUE27, 4, 6 }, { WEDGE_OBLIQUE27, 4, 7 },
217 { WEDGE_OBLIQUE153, 4, 1 }, { WEDGE_OBLIQUE153, 4, 2 },
218 { WEDGE_OBLIQUE153, 4, 3 }, { WEDGE_OBLIQUE153, 4, 5 },
219 { WEDGE_OBLIQUE153, 4, 6 }, { WEDGE_OBLIQUE153, 4, 7 },
220 { WEDGE_OBLIQUE63, 1, 4 }, { WEDGE_OBLIQUE63, 2, 4 },
221 { WEDGE_OBLIQUE63, 3, 4 }, { WEDGE_OBLIQUE63, 5, 4 },
222 { WEDGE_OBLIQUE63, 6, 4 }, { WEDGE_OBLIQUE63, 7, 4 },
223 { WEDGE_OBLIQUE117, 1, 4 }, { WEDGE_OBLIQUE117, 2, 4 },
224 { WEDGE_OBLIQUE117, 3, 4 }, { WEDGE_OBLIQUE117, 5, 4 },
225 { WEDGE_OBLIQUE117, 6, 4 }, { WEDGE_OBLIQUE117, 7, 4 },
226};
227
228static const wedge_code_type wedge_codebook_32_heqw[32] = {
229 { WEDGE_OBLIQUE27, 4, 4 }, { WEDGE_OBLIQUE63, 4, 4 },
230 { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
231 { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 6 },
232 { WEDGE_VERTICAL, 2, 4 }, { WEDGE_VERTICAL, 6, 4 },
233 { WEDGE_OBLIQUE27, 4, 1 }, { WEDGE_OBLIQUE27, 4, 2 },
234 { WEDGE_OBLIQUE27, 4, 3 }, { WEDGE_OBLIQUE27, 4, 5 },
235 { WEDGE_OBLIQUE27, 4, 6 }, { WEDGE_OBLIQUE27, 4, 7 },
236 { WEDGE_OBLIQUE153, 4, 1 }, { WEDGE_OBLIQUE153, 4, 2 },
237 { WEDGE_OBLIQUE153, 4, 3 }, { WEDGE_OBLIQUE153, 4, 5 },
238 { WEDGE_OBLIQUE153, 4, 6 }, { WEDGE_OBLIQUE153, 4, 7 },
239 { WEDGE_OBLIQUE63, 1, 4 }, { WEDGE_OBLIQUE63, 2, 4 },
240 { WEDGE_OBLIQUE63, 3, 4 }, { WEDGE_OBLIQUE63, 5, 4 },
241 { WEDGE_OBLIQUE63, 6, 4 }, { WEDGE_OBLIQUE63, 7, 4 },
242 { WEDGE_OBLIQUE117, 1, 4 }, { WEDGE_OBLIQUE117, 2, 4 },
243 { WEDGE_OBLIQUE117, 3, 4 }, { WEDGE_OBLIQUE117, 5, 4 },
244 { WEDGE_OBLIQUE117, 6, 4 }, { WEDGE_OBLIQUE117, 7, 4 },
245};
246
247const wedge_params_type wedge_params_lookup[BLOCK_SIZES] = {
Jingning Han61418bb2017-01-23 17:12:48 -0800248#if CONFIG_CB4X4
249 { 0, NULL, NULL, 0, NULL },
250 { 0, NULL, NULL, 0, NULL },
251 { 0, NULL, NULL, 0, NULL },
252#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700253 { 0, NULL, NULL, 0, NULL },
254 { 0, NULL, NULL, 0, NULL },
255 { 0, NULL, NULL, 0, NULL },
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -0800256#if CONFIG_WEDGE
Debargha Mukherjee0be0aa12017-02-12 01:42:56 -0800257 { 5, wedge_codebook_32_heqw, wedge_signflip_lookup[BLOCK_8X8], 0,
258 wedge_masks[BLOCK_8X8] },
259 { 5, wedge_codebook_32_hgtw, wedge_signflip_lookup[BLOCK_8X16], 0,
260 wedge_masks[BLOCK_8X16] },
261 { 5, wedge_codebook_32_hltw, wedge_signflip_lookup[BLOCK_16X8], 0,
262 wedge_masks[BLOCK_16X8] },
263 { 5, wedge_codebook_32_heqw, wedge_signflip_lookup[BLOCK_16X16], 0,
264 wedge_masks[BLOCK_16X16] },
265 { 5, wedge_codebook_32_hgtw, wedge_signflip_lookup[BLOCK_16X32], 0,
266 wedge_masks[BLOCK_16X32] },
267 { 5, wedge_codebook_32_hltw, wedge_signflip_lookup[BLOCK_32X16], 0,
268 wedge_masks[BLOCK_32X16] },
269 { 5, wedge_codebook_32_heqw, wedge_signflip_lookup[BLOCK_32X32], 0,
270 wedge_masks[BLOCK_32X32] },
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -0800271 { 0, wedge_codebook_32_hgtw, wedge_signflip_lookup[BLOCK_32X64], 0,
Debargha Mukherjee0be0aa12017-02-12 01:42:56 -0800272 wedge_masks[BLOCK_32X64] },
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -0800273 { 0, wedge_codebook_32_hltw, wedge_signflip_lookup[BLOCK_64X32], 0,
Debargha Mukherjee0be0aa12017-02-12 01:42:56 -0800274 wedge_masks[BLOCK_64X32] },
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -0800275 { 0, wedge_codebook_32_heqw, wedge_signflip_lookup[BLOCK_64X64], 0,
Debargha Mukherjee0be0aa12017-02-12 01:42:56 -0800276 wedge_masks[BLOCK_64X64] },
Debargha Mukherjee37f6fe62017-02-10 21:44:13 -0800277#else
278 { 0, wedge_codebook_32_heqw, wedge_signflip_lookup[BLOCK_8X8], 0,
279 wedge_masks[BLOCK_8X8] },
280 { 0, wedge_codebook_32_hgtw, wedge_signflip_lookup[BLOCK_8X16], 0,
281 wedge_masks[BLOCK_8X16] },
282 { 0, wedge_codebook_32_hltw, wedge_signflip_lookup[BLOCK_16X8], 0,
283 wedge_masks[BLOCK_16X8] },
284 { 0, wedge_codebook_32_heqw, wedge_signflip_lookup[BLOCK_16X16], 0,
285 wedge_masks[BLOCK_16X16] },
286 { 0, wedge_codebook_32_hgtw, wedge_signflip_lookup[BLOCK_16X32], 0,
287 wedge_masks[BLOCK_16X32] },
288 { 0, wedge_codebook_32_hltw, wedge_signflip_lookup[BLOCK_32X16], 0,
289 wedge_masks[BLOCK_32X16] },
290 { 0, wedge_codebook_32_heqw, wedge_signflip_lookup[BLOCK_32X32], 0,
291 wedge_masks[BLOCK_32X32] },
292 { 0, wedge_codebook_32_hgtw, wedge_signflip_lookup[BLOCK_32X64], 0,
293 wedge_masks[BLOCK_32X64] },
294 { 0, wedge_codebook_32_hltw, wedge_signflip_lookup[BLOCK_64X32], 0,
295 wedge_masks[BLOCK_64X32] },
296 { 0, wedge_codebook_32_heqw, wedge_signflip_lookup[BLOCK_64X64], 0,
297 wedge_masks[BLOCK_64X64] },
298#endif // CONFIG_WEDGE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700299#if CONFIG_EXT_PARTITION
300 { 0, NULL, NULL, 0, NULL },
301 { 0, NULL, NULL, 0, NULL },
302 { 0, NULL, NULL, 0, NULL },
303#endif // CONFIG_EXT_PARTITION
304};
305#endif // USE_LARGE_WEDGE_CODEBOOK
306
307static const uint8_t *get_wedge_mask_inplace(int wedge_index, int neg,
308 BLOCK_SIZE sb_type) {
309 const uint8_t *master;
Jingning Han61418bb2017-01-23 17:12:48 -0800310 const int bh = block_size_high[sb_type];
311 const int bw = block_size_wide[sb_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700312 const wedge_code_type *a =
313 wedge_params_lookup[sb_type].codebook + wedge_index;
314 const int smoother = wedge_params_lookup[sb_type].smoother;
315 int woff, hoff;
316 const uint8_t wsignflip = wedge_params_lookup[sb_type].signflip[wedge_index];
317
318 assert(wedge_index >= 0 &&
319 wedge_index < (1 << get_wedge_bits_lookup(sb_type)));
320 woff = (a->x_offset * bw) >> 3;
321 hoff = (a->y_offset * bh) >> 3;
322 master = wedge_mask_obl[smoother][neg ^ wsignflip][a->direction] +
323 MASK_MASTER_STRIDE * (MASK_MASTER_SIZE / 2 - hoff) +
324 MASK_MASTER_SIZE / 2 - woff;
325 return master;
326}
327
Yaowu Xuf883b422016-08-30 14:01:10 -0700328const uint8_t *av1_get_soft_mask(int wedge_index, int wedge_sign,
329 BLOCK_SIZE sb_type, int offset_x,
330 int offset_y) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700331 const uint8_t *mask =
332 get_wedge_mask_inplace(wedge_index, wedge_sign, sb_type);
333 if (mask) mask -= (offset_x + offset_y * MASK_MASTER_STRIDE);
334 return mask;
335}
336
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800337#if CONFIG_COMPOUND_SEGMENT
338static uint8_t *invert_mask(uint8_t *mask_inv_buffer, const uint8_t *const mask,
339 int h, int w, int stride) {
340 int i, j;
341
342 for (i = 0; i < h; ++i)
343 for (j = 0; j < w; ++j) {
344 mask_inv_buffer[i * stride + j] =
345 AOM_BLEND_A64_MAX_ALPHA - mask[i * stride + j];
346 }
347 return mask_inv_buffer;
348}
349#endif // CONFIG_COMPOUND_SEGMENT
350
351const uint8_t *av1_get_compound_type_mask_inverse(
352 const INTERINTER_COMPOUND_DATA *const comp_data,
353#if CONFIG_COMPOUND_SEGMENT
354 uint8_t *mask_buffer, int h, int w, int stride,
355#endif
356 BLOCK_SIZE sb_type) {
Sarah Parker6fdc8532016-11-16 17:47:13 -0800357 assert(is_masked_compound_type(comp_data->type));
358 switch (comp_data->type) {
359 case COMPOUND_WEDGE:
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800360 return av1_get_contiguous_soft_mask(comp_data->wedge_index,
361 !comp_data->wedge_sign, sb_type);
Sarah Parker569edda2016-12-14 14:57:38 -0800362#if CONFIG_COMPOUND_SEGMENT
363 case COMPOUND_SEG:
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800364 return invert_mask(mask_buffer, comp_data->seg_mask, h, w, stride);
365#endif // CONFIG_COMPOUND_SEGMENT
366 default: assert(0); return NULL;
367 }
368}
369
370const uint8_t *av1_get_compound_type_mask(
371 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type) {
372 assert(is_masked_compound_type(comp_data->type));
373 switch (comp_data->type) {
374 case COMPOUND_WEDGE:
375 return av1_get_contiguous_soft_mask(comp_data->wedge_index,
376 comp_data->wedge_sign, sb_type);
377#if CONFIG_COMPOUND_SEGMENT
378 case COMPOUND_SEG: return comp_data->seg_mask;
Sarah Parker569edda2016-12-14 14:57:38 -0800379#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -0800380 default: assert(0); return NULL;
381 }
382}
Sarah Parker569edda2016-12-14 14:57:38 -0800383
384#if CONFIG_COMPOUND_SEGMENT
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800385#if COMPOUND_SEGMENT_TYPE == 0
386static void uniform_mask(uint8_t *mask, int which_inverse, BLOCK_SIZE sb_type,
387 int h, int w, int mask_val) {
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800388 int i, j;
389 int block_stride = block_size_wide[sb_type];
390 for (i = 0; i < h; ++i)
391 for (j = 0; j < w; ++j) {
392 mask[i * block_stride + j] =
393 which_inverse ? AOM_BLEND_A64_MAX_ALPHA - mask_val : mask_val;
394 }
395}
396
397void build_compound_seg_mask(uint8_t *mask, SEG_MASK_TYPE mask_type,
Sarah Parker569edda2016-12-14 14:57:38 -0800398 const uint8_t *src0, int src0_stride,
399 const uint8_t *src1, int src1_stride,
400 BLOCK_SIZE sb_type, int h, int w) {
Sarah Parker569edda2016-12-14 14:57:38 -0800401 (void)src0;
402 (void)src1;
403 (void)src0_stride;
404 (void)src1_stride;
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800405 switch (mask_type) {
406 case UNIFORM_45: uniform_mask(mask, 0, sb_type, h, w, 45); break;
407 case UNIFORM_45_INV: uniform_mask(mask, 1, sb_type, h, w, 45); break;
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800408 default: assert(0);
409 }
Sarah Parker569edda2016-12-14 14:57:38 -0800410}
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800411
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200412#if CONFIG_HIGHBITDEPTH
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800413void build_compound_seg_mask_highbd(uint8_t *mask, SEG_MASK_TYPE mask_type,
414 const uint8_t *src0, int src0_stride,
415 const uint8_t *src1, int src1_stride,
416 BLOCK_SIZE sb_type, int h, int w, int bd) {
417 (void)src0;
418 (void)src1;
419 (void)src0_stride;
420 (void)src1_stride;
421 (void)bd;
422 switch (mask_type) {
423 case UNIFORM_45: uniform_mask(mask, 0, sb_type, h, w, 45); break;
424 case UNIFORM_45_INV: uniform_mask(mask, 1, sb_type, h, w, 45); break;
425 default: assert(0);
426 }
427}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200428#endif // CONFIG_HIGHBITDEPTH
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800429
430#elif COMPOUND_SEGMENT_TYPE == 1
431#define DIFF_FACTOR 16
432static void diffwtd_mask(uint8_t *mask, int which_inverse, int mask_base,
433 const uint8_t *src0, int src0_stride,
434 const uint8_t *src1, int src1_stride,
435 BLOCK_SIZE sb_type, int h, int w) {
436 int i, j, m, diff;
437 int block_stride = block_size_wide[sb_type];
438 for (i = 0; i < h; ++i) {
439 for (j = 0; j < w; ++j) {
440 diff =
441 abs((int)src0[i * src0_stride + j] - (int)src1[i * src1_stride + j]);
442 m = clamp(mask_base + (diff / DIFF_FACTOR), 0, AOM_BLEND_A64_MAX_ALPHA);
443 mask[i * block_stride + j] =
444 which_inverse ? AOM_BLEND_A64_MAX_ALPHA - m : m;
445 }
446 }
447}
448
449void build_compound_seg_mask(uint8_t *mask, SEG_MASK_TYPE mask_type,
450 const uint8_t *src0, int src0_stride,
451 const uint8_t *src1, int src1_stride,
452 BLOCK_SIZE sb_type, int h, int w) {
453 switch (mask_type) {
Yaowu Xua93e65e2017-01-24 10:58:48 -0800454 case DIFFWTD_42:
455 diffwtd_mask(mask, 0, 42, src0, src0_stride, src1, src1_stride, sb_type,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800456 h, w);
457 break;
Yaowu Xua93e65e2017-01-24 10:58:48 -0800458 case DIFFWTD_42_INV:
459 diffwtd_mask(mask, 1, 42, src0, src0_stride, src1, src1_stride, sb_type,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800460 h, w);
461 break;
462 default: assert(0);
463 }
464}
465
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200466#if CONFIG_HIGHBITDEPTH
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800467static void diffwtd_mask_highbd(uint8_t *mask, int which_inverse, int mask_base,
468 const uint16_t *src0, int src0_stride,
469 const uint16_t *src1, int src1_stride,
470 BLOCK_SIZE sb_type, int h, int w, int bd) {
471 int i, j, m, diff;
472 int block_stride = block_size_wide[sb_type];
473 for (i = 0; i < h; ++i) {
474 for (j = 0; j < w; ++j) {
475 diff = abs((int)src0[i * src0_stride + j] -
476 (int)src1[i * src1_stride + j]) >>
477 (bd - 8);
478 m = clamp(mask_base + (diff / DIFF_FACTOR), 0, AOM_BLEND_A64_MAX_ALPHA);
479 mask[i * block_stride + j] =
480 which_inverse ? AOM_BLEND_A64_MAX_ALPHA - m : m;
481 }
482 }
483}
484
485void build_compound_seg_mask_highbd(uint8_t *mask, SEG_MASK_TYPE mask_type,
486 const uint8_t *src0, int src0_stride,
487 const uint8_t *src1, int src1_stride,
488 BLOCK_SIZE sb_type, int h, int w, int bd) {
489 switch (mask_type) {
490 case DIFFWTD_42:
491 diffwtd_mask_highbd(mask, 0, 42, CONVERT_TO_SHORTPTR(src0), src0_stride,
492 CONVERT_TO_SHORTPTR(src1), src1_stride, sb_type, h, w,
493 bd);
494 break;
495 case DIFFWTD_42_INV:
496 diffwtd_mask_highbd(mask, 1, 42, CONVERT_TO_SHORTPTR(src0), src0_stride,
497 CONVERT_TO_SHORTPTR(src1), src1_stride, sb_type, h, w,
498 bd);
499 break;
500 default: assert(0);
501 }
502}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200503#endif // CONFIG_HIGHBITDEPTH
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800504#endif // COMPOUND_SEGMENT_TYPE
Sarah Parker569edda2016-12-14 14:57:38 -0800505#endif // CONFIG_COMPOUND_SEGMENT
Sarah Parker6fdc8532016-11-16 17:47:13 -0800506
Yaowu Xuc27fc142016-08-22 16:08:15 -0700507static void init_wedge_master_masks() {
508 int i, j, s;
509 const int w = MASK_MASTER_SIZE;
510 const int h = MASK_MASTER_SIZE;
511 const int stride = MASK_MASTER_STRIDE;
512 const int a[2] = { 2, 1 };
513 const double asqrt = sqrt(a[0] * a[0] + a[1] * a[1]);
514 for (s = 0; s < NSMOOTHERS; s++) {
515 for (i = 0; i < h; ++i)
516 for (j = 0; j < w; ++j) {
517 int x = (2 * j + 1 - w);
518 int y = (2 * i + 1 - h);
519 int m = (int)rint((a[0] * x + a[1] * y) / asqrt);
520 wedge_mask_obl[s][1][WEDGE_OBLIQUE63][i * stride + j] =
521 wedge_mask_obl[s][1][WEDGE_OBLIQUE27][j * stride + i] =
522 get_masked_weight(m, s);
523 wedge_mask_obl[s][1][WEDGE_OBLIQUE117][i * stride + w - 1 - j] =
524 wedge_mask_obl[s][1][WEDGE_OBLIQUE153][(w - 1 - j) * stride + i] =
525 (1 << WEDGE_WEIGHT_BITS) - get_masked_weight(m, s);
526 wedge_mask_obl[s][0][WEDGE_OBLIQUE63][i * stride + j] =
527 wedge_mask_obl[s][0][WEDGE_OBLIQUE27][j * stride + i] =
528 (1 << WEDGE_WEIGHT_BITS) - get_masked_weight(m, s);
529 wedge_mask_obl[s][0][WEDGE_OBLIQUE117][i * stride + w - 1 - j] =
530 wedge_mask_obl[s][0][WEDGE_OBLIQUE153][(w - 1 - j) * stride + i] =
531 get_masked_weight(m, s);
532 wedge_mask_obl[s][1][WEDGE_VERTICAL][i * stride + j] =
533 wedge_mask_obl[s][1][WEDGE_HORIZONTAL][j * stride + i] =
534 get_masked_weight(x, s);
535 wedge_mask_obl[s][0][WEDGE_VERTICAL][i * stride + j] =
536 wedge_mask_obl[s][0][WEDGE_HORIZONTAL][j * stride + i] =
537 (1 << WEDGE_WEIGHT_BITS) - get_masked_weight(x, s);
538 }
539 }
540}
541
542// If the signs for the wedges for various blocksizes are
543// inconsistent flip the sign flag. Do it only once for every
544// wedge codebook.
545static void init_wedge_signs() {
546 BLOCK_SIZE sb_type;
547 memset(wedge_signflip_lookup, 0, sizeof(wedge_signflip_lookup));
548 for (sb_type = BLOCK_4X4; sb_type < BLOCK_SIZES; ++sb_type) {
Jingning Hanae5cfde2016-11-30 12:01:44 -0800549 const int bw = block_size_wide[sb_type];
550 const int bh = block_size_high[sb_type];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700551 const wedge_params_type wedge_params = wedge_params_lookup[sb_type];
552 const int wbits = wedge_params.bits;
553 const int wtypes = 1 << wbits;
554 int i, w;
555 if (wbits == 0) continue;
556 for (w = 0; w < wtypes; ++w) {
557 const uint8_t *mask = get_wedge_mask_inplace(w, 0, sb_type);
558 int sum = 0;
559 for (i = 0; i < bw; ++i) sum += mask[i];
560 for (i = 0; i < bh; ++i) sum += mask[i * MASK_MASTER_STRIDE];
561 sum = (sum + (bw + bh) / 2) / (bw + bh);
562 wedge_params.signflip[w] = (sum < 32);
563 }
564 }
565}
566
567static void init_wedge_masks() {
568 uint8_t *dst = wedge_mask_buf;
569 BLOCK_SIZE bsize;
570 memset(wedge_masks, 0, sizeof(wedge_masks));
571 for (bsize = BLOCK_4X4; bsize < BLOCK_SIZES; ++bsize) {
572 const uint8_t *mask;
Jingning Hanae5cfde2016-11-30 12:01:44 -0800573 const int bw = block_size_wide[bsize];
574 const int bh = block_size_high[bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700575 const wedge_params_type *wedge_params = &wedge_params_lookup[bsize];
576 const int wbits = wedge_params->bits;
577 const int wtypes = 1 << wbits;
578 int w;
579 if (wbits == 0) continue;
580 for (w = 0; w < wtypes; ++w) {
581 mask = get_wedge_mask_inplace(w, 0, bsize);
Yaowu Xuf883b422016-08-30 14:01:10 -0700582 aom_convolve_copy(mask, MASK_MASTER_STRIDE, dst, bw, NULL, 0, NULL, 0, bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700583 bh);
584 wedge_params->masks[0][w] = dst;
585 dst += bw * bh;
586
587 mask = get_wedge_mask_inplace(w, 1, bsize);
Yaowu Xuf883b422016-08-30 14:01:10 -0700588 aom_convolve_copy(mask, MASK_MASTER_STRIDE, dst, bw, NULL, 0, NULL, 0, bw,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700589 bh);
590 wedge_params->masks[1][w] = dst;
591 dst += bw * bh;
592 }
593 assert(sizeof(wedge_mask_buf) >= (size_t)(dst - wedge_mask_buf));
594 }
595}
596
597// 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 -0700598void av1_init_wedge_masks() {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700599 init_wedge_master_masks();
600 init_wedge_signs();
601 init_wedge_masks();
602}
603
604#if CONFIG_SUPERTX
605static void build_masked_compound_wedge_extend(
606 uint8_t *dst, int dst_stride, const uint8_t *src0, int src0_stride,
David Barker426a9972017-01-27 11:03:11 +0000607 const uint8_t *src1, int src1_stride,
608 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type,
609 int wedge_offset_x, int wedge_offset_y, int h, int w) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700610 const int subh = (2 << b_height_log2_lookup[sb_type]) == h;
611 const int subw = (2 << b_width_log2_lookup[sb_type]) == w;
David Barker426a9972017-01-27 11:03:11 +0000612 const uint8_t *mask;
613 size_t mask_stride;
614 switch (comp_data->type) {
615 case COMPOUND_WEDGE:
616 mask = av1_get_soft_mask(comp_data->wedge_index, comp_data->wedge_sign,
617 sb_type, wedge_offset_x, wedge_offset_y);
618 mask_stride = MASK_MASTER_STRIDE;
619 break;
620#if CONFIG_COMPOUND_SEGMENT
621 case COMPOUND_SEG:
622 mask = comp_data->seg_mask;
623 mask_stride = block_size_wide[sb_type];
624 break;
625#endif
626 default: assert(0); return;
627 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700628 aom_blend_a64_mask(dst, dst_stride, src0, src0_stride, src1, src1_stride,
David Barker426a9972017-01-27 11:03:11 +0000629 mask, mask_stride, h, w, subh, subw);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700630}
631
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200632#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700633static void build_masked_compound_wedge_extend_highbd(
634 uint8_t *dst_8, int dst_stride, const uint8_t *src0_8, int src0_stride,
David Barker426a9972017-01-27 11:03:11 +0000635 const uint8_t *src1_8, int src1_stride,
636 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type,
637 int wedge_offset_x, int wedge_offset_y, int h, int w, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700638 const int subh = (2 << b_height_log2_lookup[sb_type]) == h;
639 const int subw = (2 << b_width_log2_lookup[sb_type]) == w;
David Barker426a9972017-01-27 11:03:11 +0000640 const uint8_t *mask;
641 size_t mask_stride;
642 switch (comp_data->type) {
643 case COMPOUND_WEDGE:
644 mask = av1_get_soft_mask(comp_data->wedge_index, comp_data->wedge_sign,
645 sb_type, wedge_offset_x, wedge_offset_y);
646 mask_stride = MASK_MASTER_STRIDE;
647 break;
648#if CONFIG_COMPOUND_SEGMENT
649 case COMPOUND_SEG:
650 mask = comp_data->seg_mask;
651 mask_stride = block_size_wide[sb_type];
652 break;
653#endif
654 default: assert(0); return;
655 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700656 aom_highbd_blend_a64_mask(dst_8, dst_stride, src0_8, src0_stride, src1_8,
David Barker426a9972017-01-27 11:03:11 +0000657 src1_stride, mask, mask_stride, h, w, subh, subw,
658 bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700659}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200660#endif // CONFIG_HIGHBITDEPTH
David Barker426a9972017-01-27 11:03:11 +0000661#else
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800662static void build_masked_compound(
663 uint8_t *dst, int dst_stride, const uint8_t *src0, int src0_stride,
664 const uint8_t *src1, int src1_stride,
665 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type, int h,
666 int w) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700667 // Derive subsampling from h and w passed in. May be refactored to
668 // pass in subsampling factors directly.
669 const int subh = (2 << b_height_log2_lookup[sb_type]) == h;
670 const int subw = (2 << b_width_log2_lookup[sb_type]) == w;
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800671 const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type);
Yaowu Xuf883b422016-08-30 14:01:10 -0700672 aom_blend_a64_mask(dst, dst_stride, src0, src0_stride, src1, src1_stride,
Jingning Hanae5cfde2016-11-30 12:01:44 -0800673 mask, block_size_wide[sb_type], h, w, subh, subw);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700674}
675
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200676#if CONFIG_HIGHBITDEPTH
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800677static void build_masked_compound_highbd(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700678 uint8_t *dst_8, int dst_stride, const uint8_t *src0_8, int src0_stride,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800679 const uint8_t *src1_8, int src1_stride,
680 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type, int h,
681 int w, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700682 // Derive subsampling from h and w passed in. May be refactored to
683 // pass in subsampling factors directly.
684 const int subh = (2 << b_height_log2_lookup[sb_type]) == h;
685 const int subw = (2 << b_width_log2_lookup[sb_type]) == w;
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800686 const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type);
687 // const uint8_t *mask =
688 // av1_get_contiguous_soft_mask(wedge_index, wedge_sign, sb_type);
Jingning Hanae5cfde2016-11-30 12:01:44 -0800689 aom_highbd_blend_a64_mask(dst_8, dst_stride, src0_8, src0_stride, src1_8,
690 src1_stride, mask, block_size_wide[sb_type], h, w,
691 subh, subw, bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700692}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200693#endif // CONFIG_HIGHBITDEPTH
David Barker426a9972017-01-27 11:03:11 +0000694#endif // CONFIG_SUPERTX
Yaowu Xuc27fc142016-08-22 16:08:15 -0700695
Yaowu Xuf883b422016-08-30 14:01:10 -0700696void av1_make_masked_inter_predictor(const uint8_t *pre, int pre_stride,
697 uint8_t *dst, int dst_stride,
698 const int subpel_x, const int subpel_y,
699 const struct scale_factors *sf, int w,
700 int h,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700701#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -0700702 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700703#else
James Zern7b9407a2016-05-18 23:48:05 -0700704 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700705#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700706 int xs, int ys,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700707#if CONFIG_SUPERTX
Yaowu Xuf883b422016-08-30 14:01:10 -0700708 int wedge_offset_x, int wedge_offset_y,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700709#endif // CONFIG_SUPERTX
Sarah Parker569edda2016-12-14 14:57:38 -0800710 int plane,
Sarah Parker4c10a3c2017-04-10 19:37:59 -0700711#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
712 const WarpTypesAllowed *warp_types,
713 int p_col, int p_row, int ref,
714#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parker569edda2016-12-14 14:57:38 -0800715 MACROBLOCKD *xd) {
716 MODE_INFO *mi = xd->mi[0];
717 INTERINTER_COMPOUND_DATA *comp_data = &mi->mbmi.interinter_compound_data;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700718// The prediction filter types used here should be those for
719// the second reference block.
720#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -0700721 InterpFilter tmp_ipf[4] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700722 interp_filter[2], interp_filter[3], interp_filter[2], interp_filter[3],
723 };
724#else
James Zern7b9407a2016-05-18 23:48:05 -0700725 InterpFilter tmp_ipf = interp_filter;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700726#endif // CONFIG_DUAL_FILTER
Angie Chiange3a4c1c2017-02-10 16:26:49 -0800727 ConvolveParams conv_params = get_conv_params(0, plane);
David Barker426a9972017-01-27 11:03:11 +0000728
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200729#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700730 DECLARE_ALIGNED(16, uint8_t, tmp_dst_[2 * MAX_SB_SQUARE]);
731 uint8_t *tmp_dst = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
732 ? CONVERT_TO_BYTEPTR(tmp_dst_)
733 : tmp_dst_;
Yaowu Xuf883b422016-08-30 14:01:10 -0700734 av1_make_inter_predictor(pre, pre_stride, tmp_dst, MAX_SB_SIZE, subpel_x,
Sarah Parkerc2d38712017-01-24 15:15:41 -0800735 subpel_y, sf, w, h, &conv_params, tmp_ipf,
Sarah Parker4c10a3c2017-04-10 19:37:59 -0700736#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
737 warp_types, p_col, p_row, plane, ref,
738#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yue Chen74a77542017-03-14 17:30:42 -0700739#if CONFIG_MOTION_VAR
740 0, 0,
741#endif
Sarah Parkerc2d38712017-01-24 15:15:41 -0800742 xs, ys, xd);
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800743#if CONFIG_COMPOUND_SEGMENT
744 if (!plane && comp_data->type == COMPOUND_SEG) {
745 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
746 build_compound_seg_mask_highbd(comp_data->seg_mask, comp_data->mask_type,
747 dst, dst_stride, tmp_dst, MAX_SB_SIZE,
748 mi->mbmi.sb_type, h, w, xd->bd);
749 else
750 build_compound_seg_mask(comp_data->seg_mask, comp_data->mask_type, dst,
751 dst_stride, tmp_dst, MAX_SB_SIZE,
752 mi->mbmi.sb_type, h, w);
753 }
754#endif // CONFIG_COMPOUND_SEGMENT
David Barker426a9972017-01-27 11:03:11 +0000755
756#if CONFIG_SUPERTX
757 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
758 build_masked_compound_wedge_extend_highbd(
759 dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE, comp_data,
760 mi->mbmi.sb_type, wedge_offset_x, wedge_offset_y, h, w, xd->bd);
761 else
762 build_masked_compound_wedge_extend(
763 dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE, comp_data,
764 mi->mbmi.sb_type, wedge_offset_x, wedge_offset_y, h, w);
765#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700766 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -0800767 build_masked_compound_highbd(dst, dst_stride, dst, dst_stride, tmp_dst,
768 MAX_SB_SIZE, comp_data, mi->mbmi.sb_type, h, w,
769 xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700770 else
Sarah Parker6fdc8532016-11-16 17:47:13 -0800771 build_masked_compound(dst, dst_stride, dst, dst_stride, tmp_dst,
772 MAX_SB_SIZE, comp_data, mi->mbmi.sb_type, h, w);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700773#endif // CONFIG_SUPERTX
David Barker426a9972017-01-27 11:03:11 +0000774
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200775#else // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700776 DECLARE_ALIGNED(16, uint8_t, tmp_dst[MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -0700777 av1_make_inter_predictor(pre, pre_stride, tmp_dst, MAX_SB_SIZE, subpel_x,
Sarah Parkerc2d38712017-01-24 15:15:41 -0800778 subpel_y, sf, w, h, &conv_params, tmp_ipf,
Sarah Parker4c10a3c2017-04-10 19:37:59 -0700779#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
780 warp_types, p_col, p_row, plane, ref,
781#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yue Chen74a77542017-03-14 17:30:42 -0700782#if CONFIG_MOTION_VAR
783 0, 0,
784#endif
Sarah Parkerc2d38712017-01-24 15:15:41 -0800785 xs, ys, xd);
Sarah Parker569edda2016-12-14 14:57:38 -0800786#if CONFIG_COMPOUND_SEGMENT
787 if (!plane && comp_data->type == COMPOUND_SEG)
Sarah Parkerb9f757c2017-01-06 17:12:24 -0800788 build_compound_seg_mask(comp_data->seg_mask, comp_data->mask_type, dst,
789 dst_stride, tmp_dst, MAX_SB_SIZE, mi->mbmi.sb_type,
790 h, w);
Sarah Parker569edda2016-12-14 14:57:38 -0800791#endif // CONFIG_COMPOUND_SEGMENT
David Barker426a9972017-01-27 11:03:11 +0000792#if CONFIG_SUPERTX
793 build_masked_compound_wedge_extend(dst, dst_stride, dst, dst_stride, tmp_dst,
794 MAX_SB_SIZE, comp_data, mi->mbmi.sb_type,
795 wedge_offset_x, wedge_offset_y, h, w);
796#else
Sarah Parker6fdc8532016-11-16 17:47:13 -0800797 build_masked_compound(dst, dst_stride, dst, dst_stride, tmp_dst, MAX_SB_SIZE,
798 comp_data, mi->mbmi.sb_type, h, w);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700799#endif // CONFIG_SUPERTX
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200800#endif // CONFIG_HIGHBITDEPTH
Debargha Mukherjee63131ea2017-01-24 15:52:46 -0800801#if CONFIG_COMPOUND_SEGMENT
802 (void)plane;
803#endif // CONFIG_COMPOUND_SEGMENT
Yaowu Xuc27fc142016-08-22 16:08:15 -0700804}
805#endif // CONFIG_EXT_INTER
806
Sarah Parkerb3ebed12017-03-09 10:52:03 -0800807// TODO(sarahparker) av1_highbd_build_inter_predictor and
808// av1_build_inter_predictor should be combined with
809// av1_make_inter_predictor
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200810#if CONFIG_HIGHBITDEPTH
Sarah Parker4c10a3c2017-04-10 19:37:59 -0700811void av1_highbd_build_inter_predictor(
812 const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride,
813 const MV *src_mv, const struct scale_factors *sf, int w, int h, int ref,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700814#if CONFIG_DUAL_FILTER
Sarah Parker4c10a3c2017-04-10 19:37:59 -0700815 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700816#else
Sarah Parker4c10a3c2017-04-10 19:37:59 -0700817 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700818#endif
Sarah Parker4c10a3c2017-04-10 19:37:59 -0700819#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
820 const WarpTypesAllowed *warp_types, int p_col, int p_row,
821#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
822 int plane, enum mv_precision precision, int x, int y,
823 const MACROBLOCKD *xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700824 const int is_q4 = precision == MV_PRECISION_Q4;
825 const MV mv_q4 = { is_q4 ? src_mv->row : src_mv->row * 2,
826 is_q4 ? src_mv->col : src_mv->col * 2 };
Yaowu Xuf883b422016-08-30 14:01:10 -0700827 MV32 mv = av1_scale_mv(&mv_q4, x, y, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700828 const int subpel_x = mv.col & SUBPEL_MASK;
829 const int subpel_y = mv.row & SUBPEL_MASK;
Sarah Parkerb3ebed12017-03-09 10:52:03 -0800830 ConvolveParams conv_params = get_conv_params(ref, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700831
832 src += (mv.row >> SUBPEL_BITS) * src_stride + (mv.col >> SUBPEL_BITS);
833
Sarah Parkerb3ebed12017-03-09 10:52:03 -0800834 av1_make_inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y,
835 sf, w, h, &conv_params, interp_filter,
Sarah Parker4c10a3c2017-04-10 19:37:59 -0700836#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
837 warp_types, p_col, p_row, plane, ref,
838#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yue Chen74a77542017-03-14 17:30:42 -0700839#if CONFIG_MOTION_VAR
840 0, 0,
841#endif
Sarah Parkerb3ebed12017-03-09 10:52:03 -0800842 sf->x_step_q4, sf->y_step_q4, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700843}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200844#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700845
Yaowu Xuf883b422016-08-30 14:01:10 -0700846void av1_build_inter_predictor(const uint8_t *src, int src_stride, uint8_t *dst,
847 int dst_stride, const MV *src_mv,
848 const struct scale_factors *sf, int w, int h,
Angie Chiang9f45bc42017-01-13 16:27:54 -0800849 ConvolveParams *conv_params,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700850#if CONFIG_DUAL_FILTER
James Zern7b9407a2016-05-18 23:48:05 -0700851 const InterpFilter *interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700852#else
James Zern7b9407a2016-05-18 23:48:05 -0700853 const InterpFilter interp_filter,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700854#endif
Sarah Parker4c10a3c2017-04-10 19:37:59 -0700855#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
856 const WarpTypesAllowed *warp_types, int p_col,
857 int p_row, int plane, int ref,
858#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -0800859 enum mv_precision precision, int x, int y,
860 const MACROBLOCKD *xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700861 const int is_q4 = precision == MV_PRECISION_Q4;
862 const MV mv_q4 = { is_q4 ? src_mv->row : src_mv->row * 2,
863 is_q4 ? src_mv->col : src_mv->col * 2 };
Yaowu Xuf883b422016-08-30 14:01:10 -0700864 MV32 mv = av1_scale_mv(&mv_q4, x, y, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700865 const int subpel_x = mv.col & SUBPEL_MASK;
866 const int subpel_y = mv.row & SUBPEL_MASK;
867
868 src += (mv.row >> SUBPEL_BITS) * src_stride + (mv.col >> SUBPEL_BITS);
869
Sarah Parkerb3ebed12017-03-09 10:52:03 -0800870 av1_make_inter_predictor(src, src_stride, dst, dst_stride, subpel_x, subpel_y,
871 sf, w, h, conv_params, interp_filter,
Sarah Parker4c10a3c2017-04-10 19:37:59 -0700872#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
873 warp_types, p_col, p_row, plane, ref,
874#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yue Chen74a77542017-03-14 17:30:42 -0700875#if CONFIG_MOTION_VAR
876 0, 0,
877#endif
Sarah Parkerb3ebed12017-03-09 10:52:03 -0800878 sf->x_step_q4, sf->y_step_q4, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700879}
880
Angie Chiang907230e2017-01-17 17:39:14 -0800881typedef struct SubpelParams {
882 int xs;
883 int ys;
884 int subpel_x;
885 int subpel_y;
886} SubpelParams;
887
Yaowu Xuc27fc142016-08-22 16:08:15 -0700888void build_inter_predictors(MACROBLOCKD *xd, int plane,
Yue Chencb60b182016-10-13 15:18:22 -0700889#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700890 int mi_col_offset, int mi_row_offset,
Yue Chencb60b182016-10-13 15:18:22 -0700891#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700892 int block, int bw, int bh, int x, int y, int w,
893 int h,
894#if CONFIG_SUPERTX && CONFIG_EXT_INTER
895 int wedge_offset_x, int wedge_offset_y,
896#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
897 int mi_x, int mi_y) {
898 struct macroblockd_plane *const pd = &xd->plane[plane];
Yue Chencb60b182016-10-13 15:18:22 -0700899#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700900 const MODE_INFO *mi = xd->mi[mi_col_offset + xd->mi_stride * mi_row_offset];
Jingning Han679a6be2017-04-06 09:05:54 -0700901#if !CONFIG_CB4X4 || CONFIG_SUB8X8_MC
Yue Chen894fcce2016-10-21 16:50:52 -0700902 const int build_for_obmc = !(mi_col_offset == 0 && mi_row_offset == 0);
Jingning Han679a6be2017-04-06 09:05:54 -0700903#endif // !CONFIG_CB4X4 || CONFIG_SUB8X8_MC
Yaowu Xuc27fc142016-08-22 16:08:15 -0700904#else
905 const MODE_INFO *mi = xd->mi[0];
Yue Chencb60b182016-10-13 15:18:22 -0700906#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700907 const int is_compound = has_second_ref(&mi->mbmi);
908 int ref;
Alex Converse28744302017-04-13 14:46:22 -0700909#if CONFIG_INTRABC
910 const int is_intrabc = is_intrabc_block(&mi->mbmi);
911 struct scale_factors sf_identity;
912#if CONFIG_HIGHBITDEPTH
913 av1_setup_scale_factors_for_frame(
914 &sf_identity, 64, 64, 64, 64,
915 xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH);
916#else
917 av1_setup_scale_factors_for_frame(&sf_identity, 64, 64, 64, 64);
918#endif // CONFIG_HIGHBITDEPTH
919 assert(IMPLIES(is_intrabc, !is_compound));
920#endif // CONFIG_INTRABC
Yaowu Xuc27fc142016-08-22 16:08:15 -0700921#if CONFIG_GLOBAL_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -0700922 int is_global[2];
923 for (ref = 0; ref < 1 + is_compound; ++ref) {
Sarah Parkerc2d38712017-01-24 15:15:41 -0800924 WarpedMotionParams *const wm = &xd->global_motion[mi->mbmi.ref_frame[ref]];
Sarah Parkerae7c4582017-02-28 16:30:30 -0800925 is_global[ref] = is_global_mv_block(mi, block, wm->wmtype);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700926 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700927#endif // CONFIG_GLOBAL_MOTION
928
Jingning Hanb46540c2016-12-14 10:59:20 -0800929#if CONFIG_CB4X4
930 (void)block;
931#endif
932
Jingning Han46003142016-11-02 14:57:11 -0700933#if CONFIG_SUB8X8_MC
Yue Chen894fcce2016-10-21 16:50:52 -0700934#if CONFIG_MOTION_VAR
935 if (mi->mbmi.sb_type < BLOCK_8X8 && plane > 0 && !build_for_obmc) {
936#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700937 if (mi->mbmi.sb_type < BLOCK_8X8 && plane > 0) {
Yue Chen894fcce2016-10-21 16:50:52 -0700938#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -0700939 // block size in log2
940 const int b4_wl = b_width_log2_lookup[mi->mbmi.sb_type];
941 const int b4_hl = b_height_log2_lookup[mi->mbmi.sb_type];
942 const int b8_sl = b_width_log2_lookup[BLOCK_8X8];
943
944 // block size
945 const int b4_w = 1 << b4_wl;
946 const int b4_h = 1 << b4_hl;
947 const int b8_s = 1 << b8_sl;
948 int idx, idy;
949
950 const int x_base = x;
951 const int y_base = y;
952
953 // processing unit size
954 const int x_step = w >> (b8_sl - b4_wl);
955 const int y_step = h >> (b8_sl - b4_hl);
956
957 for (idy = 0; idy < b8_s; idy += b4_h) {
958 for (idx = 0; idx < b8_s; idx += b4_w) {
959 const int chr_idx = (idy * 2) + idx;
960 for (ref = 0; ref < 1 + is_compound; ++ref) {
Alex Converse28744302017-04-13 14:46:22 -0700961 struct buf_2d *const dst_buf = &pd->dst;
962#if CONFIG_INTRABC
963 const struct scale_factors *const sf =
964 is_intrabc ? &sf_identity : &xd->block_refs[ref]->sf;
965 struct buf_2d *const pre_buf = is_intrabc ? dst_buf : &pd->pre[ref];
966#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700967 const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
968 struct buf_2d *const pre_buf = &pd->pre[ref];
Alex Converse28744302017-04-13 14:46:22 -0700969#endif // CONFIG_INTRABC
Yaowu Xuc27fc142016-08-22 16:08:15 -0700970 uint8_t *dst = dst_buf->buf;
971 const MV mv = mi->bmi[chr_idx].as_mv[ref].as_mv;
972 const MV mv_q4 = clamp_mv_to_umv_border_sb(
973 xd, &mv, bw, bh, pd->subsampling_x, pd->subsampling_y);
974 uint8_t *pre;
975 MV32 scaled_mv;
976 int xs, ys, subpel_x, subpel_y;
Yaowu Xuf883b422016-08-30 14:01:10 -0700977 const int is_scaled = av1_is_scaled(sf);
Angie Chiange3a4c1c2017-02-10 16:26:49 -0800978 ConvolveParams conv_params = get_conv_params(ref, plane);
Sarah Parker4c10a3c2017-04-10 19:37:59 -0700979#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
980 WarpTypesAllowed warp_types;
981#if CONFIG_GLOBAL_MOTION
982 warp_types.global_warp_allowed = is_global[ref];
983#endif // CONFIG_GLOBAL_MOTION
984#if CONFIG_WARPED_MOTION
985 warp_types.local_warp_allowed = mi->mbmi.motion_mode == WARPED_CAUSAL;
986#endif // CONFIG_WARPED_MOTION
987#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -0700988
989 x = x_base + idx * x_step;
990 y = y_base + idy * y_step;
991
992 dst += dst_buf->stride * y + x;
993
994 if (is_scaled) {
995 pre =
996 pre_buf->buf + scaled_buffer_offset(x, y, pre_buf->stride, sf);
Yaowu Xuf883b422016-08-30 14:01:10 -0700997 scaled_mv = av1_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700998 xs = sf->x_step_q4;
999 ys = sf->y_step_q4;
1000 } else {
1001 pre = pre_buf->buf + y * pre_buf->stride + x;
1002 scaled_mv.row = mv_q4.row;
1003 scaled_mv.col = mv_q4.col;
1004 xs = ys = 16;
1005 }
1006
1007 subpel_x = scaled_mv.col & SUBPEL_MASK;
1008 subpel_y = scaled_mv.row & SUBPEL_MASK;
1009 pre += (scaled_mv.row >> SUBPEL_BITS) * pre_buf->stride +
1010 (scaled_mv.col >> SUBPEL_BITS);
1011
1012#if CONFIG_EXT_INTER
Sarah Parker6fdc8532016-11-16 17:47:13 -08001013 if (ref &&
1014 is_masked_compound_type(mi->mbmi.interinter_compound_data.type))
Yaowu Xuf883b422016-08-30 14:01:10 -07001015 av1_make_masked_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001016 pre, pre_buf->stride, dst, dst_buf->stride, subpel_x, subpel_y,
1017 sf, w, h, mi->mbmi.interp_filter, xs, ys,
1018#if CONFIG_SUPERTX
1019 wedge_offset_x, wedge_offset_y,
1020#endif // CONFIG_SUPERTX
Sarah Parker569edda2016-12-14 14:57:38 -08001021 plane,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07001022#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
1023 &warp_types, (mi_x >> pd->subsampling_x) + x,
Sarah Parkeradb28aa2017-04-03 11:04:57 -07001024 (mi_y >> pd->subsampling_y) + y, ref,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07001025#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkeradb28aa2017-04-03 11:04:57 -07001026 xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001027 else
1028#endif // CONFIG_EXT_INTER
Sarah Parkerc2d38712017-01-24 15:15:41 -08001029 av1_make_inter_predictor(
1030 pre, pre_buf->stride, dst, dst_buf->stride, subpel_x, subpel_y,
1031 sf, x_step, y_step, &conv_params, mi->mbmi.interp_filter,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07001032#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
1033 &warp_types, (mi_x >> pd->subsampling_x) + x,
Sarah Parkerc2d38712017-01-24 15:15:41 -08001034 (mi_y >> pd->subsampling_y) + y, plane, ref,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07001035#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yue Chen74a77542017-03-14 17:30:42 -07001036#if CONFIG_MOTION_VAR
1037 mi_col_offset, mi_row_offset,
1038#endif
Sarah Parkerc2d38712017-01-24 15:15:41 -08001039 xs, ys, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001040 }
1041 }
1042 }
1043 return;
1044 }
1045#endif
1046
Angie Chiang907230e2017-01-17 17:39:14 -08001047 {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001048 struct buf_2d *const dst_buf = &pd->dst;
1049 uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x;
Angie Chiang907230e2017-01-17 17:39:14 -08001050 uint8_t *pre[2];
1051 MV32 scaled_mv[2];
1052 SubpelParams subpel_params[2];
Angie Chiangdbfec2a2017-02-01 15:04:59 -08001053#if CONFIG_CONVOLVE_ROUND
Angie Chiang7927a972017-02-02 18:13:04 -08001054 DECLARE_ALIGNED(16, int32_t, tmp_dst[MAX_SB_SIZE * MAX_SB_SIZE]);
1055 av1_zero(tmp_dst);
Angie Chiangdbfec2a2017-02-01 15:04:59 -08001056#endif // CONFIG_CONVOLVE_ROUND
Angie Chiang907230e2017-01-17 17:39:14 -08001057
1058 for (ref = 0; ref < 1 + is_compound; ++ref) {
Alex Converse28744302017-04-13 14:46:22 -07001059#if CONFIG_INTRABC
1060 const struct scale_factors *const sf =
1061 is_intrabc ? &sf_identity : &xd->block_refs[ref]->sf;
1062 struct buf_2d *const pre_buf = is_intrabc ? dst_buf : &pd->pre[ref];
1063#else
Angie Chiang907230e2017-01-17 17:39:14 -08001064 const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
1065 struct buf_2d *const pre_buf = &pd->pre[ref];
Alex Converse28744302017-04-13 14:46:22 -07001066#endif // CONFIG_INTRABC
Jingning Hanb46540c2016-12-14 10:59:20 -08001067#if CONFIG_CB4X4
Angie Chiang907230e2017-01-17 17:39:14 -08001068 const MV mv = mi->mbmi.mv[ref].as_mv;
Jingning Hanb46540c2016-12-14 10:59:20 -08001069#else
Angie Chiang907230e2017-01-17 17:39:14 -08001070 const MV mv =
Yue Chen894fcce2016-10-21 16:50:52 -07001071#if CONFIG_MOTION_VAR
Yue Chen13e412e2017-03-30 17:32:21 -07001072 (mi->mbmi.sb_type < BLOCK_8X8 && !build_for_obmc)
1073 ?
Yue Chen894fcce2016-10-21 16:50:52 -07001074#else
Yue Chen13e412e2017-03-30 17:32:21 -07001075 mi->mbmi.sb_type < BLOCK_8X8 ?
1076#endif
1077 average_split_mvs(pd, mi, ref, block)
Angie Chiang907230e2017-01-17 17:39:14 -08001078 : mi->mbmi.mv[ref].as_mv;
Jingning Hanb46540c2016-12-14 10:59:20 -08001079#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001080
Angie Chiang907230e2017-01-17 17:39:14 -08001081 // TODO(jkoleszar): This clamping is done in the incorrect place for the
1082 // scaling case. It needs to be done on the scaled MV, not the pre-scaling
1083 // MV. Note however that it performs the subsampling aware scaling so
1084 // that the result is always q4.
1085 // mv_precision precision is MV_PRECISION_Q4.
1086 const MV mv_q4 = clamp_mv_to_umv_border_sb(
1087 xd, &mv, bw, bh, pd->subsampling_x, pd->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001088
Angie Chiang907230e2017-01-17 17:39:14 -08001089 const int is_scaled = av1_is_scaled(sf);
Angie Chiang907230e2017-01-17 17:39:14 -08001090 if (is_scaled) {
1091 pre[ref] =
1092 pre_buf->buf + scaled_buffer_offset(x, y, pre_buf->stride, sf);
1093 scaled_mv[ref] = av1_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf);
1094 subpel_params[ref].xs = sf->x_step_q4;
1095 subpel_params[ref].ys = sf->y_step_q4;
1096 } else {
1097 pre[ref] = pre_buf->buf + (y * pre_buf->stride + x);
1098 scaled_mv[ref].row = mv_q4.row;
1099 scaled_mv[ref].col = mv_q4.col;
1100 subpel_params[ref].xs = 16;
1101 subpel_params[ref].ys = 16;
1102 }
1103
1104 subpel_params[ref].subpel_x = scaled_mv[ref].col & SUBPEL_MASK;
1105 subpel_params[ref].subpel_y = scaled_mv[ref].row & SUBPEL_MASK;
1106 pre[ref] += (scaled_mv[ref].row >> SUBPEL_BITS) * pre_buf->stride +
1107 (scaled_mv[ref].col >> SUBPEL_BITS);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001108 }
1109
Angie Chiang7927a972017-02-02 18:13:04 -08001110#if CONFIG_CONVOLVE_ROUND
1111 ConvolveParams conv_params =
Angie Chiange3a4c1c2017-02-10 16:26:49 -08001112 get_conv_params_no_round(ref, plane, tmp_dst, MAX_SB_SIZE);
Angie Chiang7927a972017-02-02 18:13:04 -08001113#else
Angie Chiange3a4c1c2017-02-10 16:26:49 -08001114 ConvolveParams conv_params = get_conv_params(ref, plane);
Angie Chiang7927a972017-02-02 18:13:04 -08001115#endif // CONFIG_CONVOLVE_ROUND
Angie Chiang907230e2017-01-17 17:39:14 -08001116 for (ref = 0; ref < 1 + is_compound; ++ref) {
Alex Converse28744302017-04-13 14:46:22 -07001117#if CONFIG_INTRABC
1118 const struct scale_factors *const sf =
1119 is_intrabc ? &sf_identity : &xd->block_refs[ref]->sf;
1120 struct buf_2d *const pre_buf = is_intrabc ? dst_buf : &pd->pre[ref];
1121#else
Angie Chiang907230e2017-01-17 17:39:14 -08001122 const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
Angie Chiang907230e2017-01-17 17:39:14 -08001123 struct buf_2d *const pre_buf = &pd->pre[ref];
Alex Converse28744302017-04-13 14:46:22 -07001124#endif // CONFIG_INTRABC
Sarah Parker4c10a3c2017-04-10 19:37:59 -07001125#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
1126 WarpTypesAllowed warp_types;
1127#if CONFIG_GLOBAL_MOTION
1128 warp_types.global_warp_allowed = is_global[ref];
1129#endif // CONFIG_GLOBAL_MOTION
1130#if CONFIG_WARPED_MOTION
1131 warp_types.local_warp_allowed = mi->mbmi.motion_mode == WARPED_CAUSAL;
1132#endif // CONFIG_WARPED_MOTION
1133#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Angie Chiang7927a972017-02-02 18:13:04 -08001134 conv_params.ref = ref;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001135#if CONFIG_EXT_INTER
Angie Chiang907230e2017-01-17 17:39:14 -08001136 if (ref &&
1137 is_masked_compound_type(mi->mbmi.interinter_compound_data.type))
1138 av1_make_masked_inter_predictor(
1139 pre[ref], pre_buf->stride, dst, dst_buf->stride,
1140 subpel_params[ref].subpel_x, subpel_params[ref].subpel_y, sf, w, h,
1141 mi->mbmi.interp_filter, subpel_params[ref].xs,
1142 subpel_params[ref].ys,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001143#if CONFIG_SUPERTX
Angie Chiang907230e2017-01-17 17:39:14 -08001144 wedge_offset_x, wedge_offset_y,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001145#endif // CONFIG_SUPERTX
Angie Chiang907230e2017-01-17 17:39:14 -08001146 plane,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07001147#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
1148 &warp_types, (mi_x >> pd->subsampling_x) + x,
Sarah Parkerc2d38712017-01-24 15:15:41 -08001149 (mi_y >> pd->subsampling_y) + y, ref,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07001150#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Angie Chiang907230e2017-01-17 17:39:14 -08001151 xd);
1152 else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001153#endif // CONFIG_EXT_INTER
Angie Chiang907230e2017-01-17 17:39:14 -08001154 av1_make_inter_predictor(
1155 pre[ref], pre_buf->stride, dst, dst_buf->stride,
1156 subpel_params[ref].subpel_x, subpel_params[ref].subpel_y, sf, w, h,
Sarah Parkerc2d38712017-01-24 15:15:41 -08001157 &conv_params, mi->mbmi.interp_filter,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07001158#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
1159 &warp_types, (mi_x >> pd->subsampling_x) + x,
Sarah Parkerc2d38712017-01-24 15:15:41 -08001160 (mi_y >> pd->subsampling_y) + y, plane, ref,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07001161#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yue Chen74a77542017-03-14 17:30:42 -07001162#if CONFIG_MOTION_VAR
1163 mi_col_offset, mi_row_offset,
1164#endif
Sarah Parkerc2d38712017-01-24 15:15:41 -08001165 subpel_params[ref].xs, subpel_params[ref].ys, xd);
Angie Chiang907230e2017-01-17 17:39:14 -08001166 }
Angie Chiang117aa0d2017-01-18 15:27:03 -08001167
Angie Chiangdbfec2a2017-02-01 15:04:59 -08001168#if CONFIG_CONVOLVE_ROUND
Angie Chiang54294192017-01-20 17:27:13 -08001169// TODO(angiebird): This part needs optimization
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001170#if CONFIG_HIGHBITDEPTH
Angie Chiang54294192017-01-20 17:27:13 -08001171 if (!(xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH))
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001172#endif // CONFIG_HIGHBITDEPTH
Angie Chiang7927a972017-02-02 18:13:04 -08001173 av1_convolve_rounding(tmp_dst, MAX_SB_SIZE, dst, dst_buf->stride, w, h,
1174 FILTER_BITS * 2 + is_compound -
1175 conv_params.round_0 - conv_params.round_1);
Angie Chiangdbfec2a2017-02-01 15:04:59 -08001176#endif // CONFIG_CONVOLVE_ROUND
Yaowu Xuc27fc142016-08-22 16:08:15 -07001177 }
1178}
1179
Yaowu Xuf883b422016-08-30 14:01:10 -07001180void av1_build_inter_predictor_sub8x8(MACROBLOCKD *xd, int plane, int i, int ir,
1181 int ic, int mi_row, int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001182 struct macroblockd_plane *const pd = &xd->plane[plane];
1183 MODE_INFO *const mi = xd->mi[0];
1184 const BLOCK_SIZE plane_bsize = get_plane_block_size(mi->mbmi.sb_type, pd);
Jingning Hanae5cfde2016-11-30 12:01:44 -08001185 const int width = block_size_wide[plane_bsize];
1186 const int height = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001187 uint8_t *const dst = &pd->dst.buf[(ir * pd->dst.stride + ic) << 2];
1188 int ref;
1189 const int is_compound = has_second_ref(&mi->mbmi);
Sarah Parker4c10a3c2017-04-10 19:37:59 -07001190#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
1191 WarpTypesAllowed warp_types;
Sarah Parkerb3ebed12017-03-09 10:52:03 -08001192 const int p_col = ((mi_col * MI_SIZE) >> pd->subsampling_x) + 4 * ic;
1193 const int p_row = ((mi_row * MI_SIZE) >> pd->subsampling_y) + 4 * ir;
Sarah Parker4c10a3c2017-04-10 19:37:59 -07001194#if CONFIG_GLOBAL_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08001195 int is_global[2];
1196 for (ref = 0; ref < 1 + is_compound; ++ref) {
1197 WarpedMotionParams *const wm = &xd->global_motion[mi->mbmi.ref_frame[ref]];
1198 is_global[ref] = is_global_mv_block(mi, i, wm->wmtype);
1199 }
1200#endif // CONFIG_GLOBAL_MOTION
Sarah Parker4c10a3c2017-04-10 19:37:59 -07001201#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07001202
1203 for (ref = 0; ref < 1 + is_compound; ++ref) {
Angie Chiange3a4c1c2017-02-10 16:26:49 -08001204 ConvolveParams conv_params = get_conv_params(ref, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001205 const uint8_t *pre =
1206 &pd->pre[ref].buf[(ir * pd->pre[ref].stride + ic) << 2];
Sarah Parker4c10a3c2017-04-10 19:37:59 -07001207#if CONFIG_GLOBAL_MOTION
1208 warp_types.global_warp_allowed = is_global[ref];
1209#endif // CONFIG_GLOBAL_MOTION
1210#if CONFIG_WARPED_MOTION
1211 warp_types.local_warp_allowed = mi->mbmi.motion_mode == WARPED_CAUSAL;
1212#endif // CONFIG_WARPED_MOTION
1213
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001214#if CONFIG_HIGHBITDEPTH
Zoe Liu2768ebc2017-02-01 16:13:25 -08001215 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
Yaowu Xuf883b422016-08-30 14:01:10 -07001216 av1_highbd_build_inter_predictor(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001217 pre, pd->pre[ref].stride, dst, pd->dst.stride,
1218 &mi->bmi[i].as_mv[ref].as_mv, &xd->block_refs[ref]->sf, width, height,
Sarah Parkerb3ebed12017-03-09 10:52:03 -08001219 ref, mi->mbmi.interp_filter,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07001220#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
1221 &warp_types, p_col, p_row,
1222#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08001223 plane, MV_PRECISION_Q3, mi_col * MI_SIZE + 4 * ic,
1224 mi_row * MI_SIZE + 4 * ir, xd);
Zoe Liu2768ebc2017-02-01 16:13:25 -08001225 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001226#endif // CONFIG_HIGHBITDEPTH
Sarah Parkerb3ebed12017-03-09 10:52:03 -08001227 av1_build_inter_predictor(pre, pd->pre[ref].stride, dst, pd->dst.stride,
1228 &mi->bmi[i].as_mv[ref].as_mv,
1229 &xd->block_refs[ref]->sf, width, height,
1230 &conv_params, mi->mbmi.interp_filter,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07001231#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
1232 &warp_types, p_col, p_row, plane, ref,
1233#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Sarah Parkerb3ebed12017-03-09 10:52:03 -08001234 MV_PRECISION_Q3, mi_col * MI_SIZE + 4 * ic,
1235 mi_row * MI_SIZE + 4 * ir, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001236 }
1237}
1238
1239static void build_inter_predictors_for_planes(MACROBLOCKD *xd, BLOCK_SIZE bsize,
1240 int mi_row, int mi_col,
1241 int plane_from, int plane_to) {
1242 int plane;
1243 const int mi_x = mi_col * MI_SIZE;
1244 const int mi_y = mi_row * MI_SIZE;
Jingning Hanb46540c2016-12-14 10:59:20 -08001245#if CONFIG_CB4X4
1246 const int unify_bsize = 1;
1247#else
1248 const int unify_bsize = 0;
1249#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001250 for (plane = plane_from; plane <= plane_to; ++plane) {
1251 const struct macroblockd_plane *pd = &xd->plane[plane];
Jingning Hanf828d402017-02-17 15:54:49 -08001252 const int bw = pd->width;
1253 const int bh = pd->height;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001254
Jingning Hanc20dc8e2017-02-17 15:37:28 -08001255#if CONFIG_CB4X4
Jingning Hand3a64432017-04-06 17:04:17 -07001256 if (!is_chroma_reference(mi_row, mi_col, bsize, pd->subsampling_x,
1257 pd->subsampling_y))
Jingning Hanc20dc8e2017-02-17 15:37:28 -08001258 continue;
1259#endif
1260
Jingning Hanb46540c2016-12-14 10:59:20 -08001261 if (xd->mi[0]->mbmi.sb_type < BLOCK_8X8 && !unify_bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001262 const PARTITION_TYPE bp = bsize - xd->mi[0]->mbmi.sb_type;
1263 const int have_vsplit = bp != PARTITION_HORZ;
1264 const int have_hsplit = bp != PARTITION_VERT;
1265 const int num_4x4_w = 2 >> ((!have_vsplit) | pd->subsampling_x);
1266 const int num_4x4_h = 2 >> ((!have_hsplit) | pd->subsampling_y);
1267 const int pw = 8 >> (have_vsplit | pd->subsampling_x);
1268 const int ph = 8 >> (have_hsplit | pd->subsampling_y);
1269 int x, y;
1270 assert(bp != PARTITION_NONE && bp < PARTITION_TYPES);
1271 assert(bsize == BLOCK_8X8);
1272 assert(pw * num_4x4_w == bw && ph * num_4x4_h == bh);
1273 for (y = 0; y < num_4x4_h; ++y)
1274 for (x = 0; x < num_4x4_w; ++x)
1275 build_inter_predictors(xd, plane,
Yue Chencb60b182016-10-13 15:18:22 -07001276#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001277 0, 0,
Yue Chencb60b182016-10-13 15:18:22 -07001278#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001279 y * 2 + x, bw, bh, 4 * x, 4 * y, pw, ph,
1280#if CONFIG_SUPERTX && CONFIG_EXT_INTER
1281 0, 0,
1282#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
1283 mi_x, mi_y);
1284 } else {
1285 build_inter_predictors(xd, plane,
Yue Chencb60b182016-10-13 15:18:22 -07001286#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001287 0, 0,
Yue Chencb60b182016-10-13 15:18:22 -07001288#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001289 0, bw, bh, 0, 0, bw, bh,
1290#if CONFIG_SUPERTX && CONFIG_EXT_INTER
1291 0, 0,
1292#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
1293 mi_x, mi_y);
1294 }
1295 }
1296}
1297
Yaowu Xuf883b422016-08-30 14:01:10 -07001298void av1_build_inter_predictors_sby(MACROBLOCKD *xd, int mi_row, int mi_col,
David Barkerac37fa32016-12-02 12:30:21 +00001299 BUFFER_SET *ctx, BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001300 build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 0, 0);
1301#if CONFIG_EXT_INTER
David Barkerac37fa32016-12-02 12:30:21 +00001302 if (is_interintra_pred(&xd->mi[0]->mbmi)) {
1303 BUFFER_SET default_ctx = { { xd->plane[0].dst.buf, NULL, NULL },
1304 { xd->plane[0].dst.stride, 0, 0 } };
1305 if (!ctx) ctx = &default_ctx;
Yaowu Xuf883b422016-08-30 14:01:10 -07001306 av1_build_interintra_predictors_sby(xd, xd->plane[0].dst.buf,
David Barkerac37fa32016-12-02 12:30:21 +00001307 xd->plane[0].dst.stride, ctx, bsize);
1308 }
1309#else
1310 (void)ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001311#endif // CONFIG_EXT_INTER
1312}
1313
Yaowu Xuf883b422016-08-30 14:01:10 -07001314void av1_build_inter_predictors_sbuv(MACROBLOCKD *xd, int mi_row, int mi_col,
David Barkerac37fa32016-12-02 12:30:21 +00001315 BUFFER_SET *ctx, BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001316 build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 1,
1317 MAX_MB_PLANE - 1);
1318#if CONFIG_EXT_INTER
David Barkerac37fa32016-12-02 12:30:21 +00001319 if (is_interintra_pred(&xd->mi[0]->mbmi)) {
1320 BUFFER_SET default_ctx = {
1321 { NULL, xd->plane[1].dst.buf, xd->plane[2].dst.buf },
1322 { 0, xd->plane[1].dst.stride, xd->plane[2].dst.stride }
1323 };
1324 if (!ctx) ctx = &default_ctx;
Yaowu Xuf883b422016-08-30 14:01:10 -07001325 av1_build_interintra_predictors_sbuv(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001326 xd, xd->plane[1].dst.buf, xd->plane[2].dst.buf, xd->plane[1].dst.stride,
David Barkerac37fa32016-12-02 12:30:21 +00001327 xd->plane[2].dst.stride, ctx, bsize);
1328 }
1329#else
1330 (void)ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001331#endif // CONFIG_EXT_INTER
1332}
1333
Fergus Simpsonde18e2b2017-03-01 20:12:34 -08001334// TODO(afergs): Check if ctx can be made constant
Yaowu Xuf883b422016-08-30 14:01:10 -07001335void av1_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col,
David Barkerac37fa32016-12-02 12:30:21 +00001336 BUFFER_SET *ctx, BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001337 build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 0,
1338 MAX_MB_PLANE - 1);
1339#if CONFIG_EXT_INTER
David Barkerac37fa32016-12-02 12:30:21 +00001340 if (is_interintra_pred(&xd->mi[0]->mbmi)) {
1341 BUFFER_SET default_ctx = {
1342 { xd->plane[0].dst.buf, xd->plane[1].dst.buf, xd->plane[2].dst.buf },
1343 { xd->plane[0].dst.stride, xd->plane[1].dst.stride,
1344 xd->plane[2].dst.stride }
1345 };
1346 if (!ctx) ctx = &default_ctx;
Yaowu Xuf883b422016-08-30 14:01:10 -07001347 av1_build_interintra_predictors(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001348 xd, xd->plane[0].dst.buf, xd->plane[1].dst.buf, xd->plane[2].dst.buf,
1349 xd->plane[0].dst.stride, xd->plane[1].dst.stride,
David Barkerac37fa32016-12-02 12:30:21 +00001350 xd->plane[2].dst.stride, ctx, bsize);
1351 }
1352#else
1353 (void)ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001354#endif // CONFIG_EXT_INTER
1355}
1356
Yaowu Xuf883b422016-08-30 14:01:10 -07001357void av1_setup_dst_planes(struct macroblockd_plane planes[MAX_MB_PLANE],
1358 const YV12_BUFFER_CONFIG *src, int mi_row,
1359 int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001360 uint8_t *const buffers[MAX_MB_PLANE] = { src->y_buffer, src->u_buffer,
1361 src->v_buffer };
1362 const int widths[MAX_MB_PLANE] = { src->y_crop_width, src->uv_crop_width,
1363 src->uv_crop_width };
1364 const int heights[MAX_MB_PLANE] = { src->y_crop_height, src->uv_crop_height,
1365 src->uv_crop_height };
1366 const int strides[MAX_MB_PLANE] = { src->y_stride, src->uv_stride,
1367 src->uv_stride };
1368 int i;
1369
1370 for (i = 0; i < MAX_MB_PLANE; ++i) {
1371 struct macroblockd_plane *const pd = &planes[i];
1372 setup_pred_plane(&pd->dst, buffers[i], widths[i], heights[i], strides[i],
1373 mi_row, mi_col, NULL, pd->subsampling_x,
1374 pd->subsampling_y);
1375 }
1376}
1377
Yaowu Xuf883b422016-08-30 14:01:10 -07001378void av1_setup_pre_planes(MACROBLOCKD *xd, int idx,
1379 const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col,
1380 const struct scale_factors *sf) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001381 if (src != NULL) {
1382 int i;
1383 uint8_t *const buffers[MAX_MB_PLANE] = { src->y_buffer, src->u_buffer,
1384 src->v_buffer };
1385 const int widths[MAX_MB_PLANE] = { src->y_crop_width, src->uv_crop_width,
1386 src->uv_crop_width };
1387 const int heights[MAX_MB_PLANE] = { src->y_crop_height, src->uv_crop_height,
1388 src->uv_crop_height };
1389 const int strides[MAX_MB_PLANE] = { src->y_stride, src->uv_stride,
1390 src->uv_stride };
1391 for (i = 0; i < MAX_MB_PLANE; ++i) {
1392 struct macroblockd_plane *const pd = &xd->plane[i];
1393 setup_pred_plane(&pd->pre[idx], buffers[i], widths[i], heights[i],
1394 strides[i], mi_row, mi_col, sf, pd->subsampling_x,
1395 pd->subsampling_y);
1396 }
1397 }
1398}
1399
1400#if CONFIG_SUPERTX
Jingning Hanfeb517c2016-12-21 16:02:07 -08001401#if CONFIG_CB4X4
Jingning Han9e0976a2016-12-27 17:52:42 -08001402static const uint8_t mask_4[4] = { 64, 52, 12, 0 };
1403static const uint8_t mask_4_uv[4] = { 64, 52, 12, 0 };
Jingning Hanfeb517c2016-12-21 16:02:07 -08001404#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07001405static const uint8_t mask_8[8] = { 64, 64, 62, 52, 12, 2, 0, 0 };
1406
1407static const uint8_t mask_16[16] = { 63, 62, 60, 58, 55, 50, 43, 36,
1408 28, 21, 14, 9, 6, 4, 2, 1 };
1409
1410static const uint8_t mask_32[32] = { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 63,
1411 61, 57, 52, 45, 36, 28, 19, 12, 7, 3, 1,
1412 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1413
1414static const uint8_t mask_8_uv[8] = { 64, 64, 62, 52, 12, 2, 0, 0 };
1415
1416static const uint8_t mask_16_uv[16] = { 64, 64, 64, 64, 61, 53, 45, 36,
1417 28, 19, 11, 3, 0, 0, 0, 0 };
1418
1419static const uint8_t mask_32_uv[32] = { 64, 64, 64, 64, 64, 64, 64, 64,
1420 64, 64, 64, 64, 60, 54, 46, 36,
1421 28, 18, 10, 4, 0, 0, 0, 0,
1422 0, 0, 0, 0, 0, 0, 0, 0 };
1423
1424static const uint8_t *get_supertx_mask(int length, int plane) {
1425 switch (length) {
Jingning Hanfeb517c2016-12-21 16:02:07 -08001426#if CONFIG_CB4X4
1427 case 4: return plane ? mask_4_uv : mask_4;
1428#endif // CONFIG_CB4X4
Yaowu Xuc27fc142016-08-22 16:08:15 -07001429 case 8: return plane ? mask_8_uv : mask_8;
1430 case 16: return plane ? mask_16_uv : mask_16;
1431 case 32: return plane ? mask_32_uv : mask_32;
1432 default: assert(0);
1433 }
1434 return NULL;
1435}
1436
Yaowu Xuf883b422016-08-30 14:01:10 -07001437void av1_build_masked_inter_predictor_complex(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001438 MACROBLOCKD *xd, uint8_t *dst, int dst_stride, const uint8_t *pre,
1439 int pre_stride, int mi_row, int mi_col, int mi_row_ori, int mi_col_ori,
1440 BLOCK_SIZE bsize, BLOCK_SIZE top_bsize, PARTITION_TYPE partition,
1441 int plane) {
1442 const struct macroblockd_plane *pd = &xd->plane[plane];
1443 const int ssx = pd->subsampling_x;
1444 const int ssy = pd->subsampling_y;
Jingning Han93531242016-12-20 11:54:36 -08001445 const int top_w = block_size_wide[top_bsize] >> ssx;
1446 const int top_h = block_size_high[top_bsize] >> ssy;
1447 const int w = block_size_wide[bsize] >> ssx;
1448 const int h = block_size_high[bsize] >> ssy;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001449 const int w_offset = ((mi_col - mi_col_ori) * MI_SIZE) >> ssx;
1450 const int h_offset = ((mi_row - mi_row_ori) * MI_SIZE) >> ssy;
1451
1452 int w_remain, h_remain;
1453
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001454#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001455 const int is_hdb = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001456#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001457
1458 assert(bsize <= BLOCK_32X32);
1459 assert(IMPLIES(plane == 0, ssx == 0));
1460 assert(IMPLIES(plane == 0, ssy == 0));
1461
1462 switch (partition) {
1463 case PARTITION_HORZ: {
1464 const uint8_t *const mask = get_supertx_mask(h, ssy);
1465
1466 w_remain = top_w;
1467 h_remain = top_h - h_offset - h;
1468 dst += h_offset * dst_stride;
1469 pre += h_offset * pre_stride;
1470
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001471#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001472 if (is_hdb)
Yaowu Xuf883b422016-08-30 14:01:10 -07001473 aom_highbd_blend_a64_vmask(dst, dst_stride, dst, dst_stride, pre,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001474 pre_stride, mask, h, top_w, xd->bd);
1475 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001476#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07001477 aom_blend_a64_vmask(dst, dst_stride, dst, dst_stride, pre, pre_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001478 mask, h, top_w);
1479
1480 dst += h * dst_stride;
1481 pre += h * pre_stride;
1482 break;
1483 }
1484 case PARTITION_VERT: {
1485 const uint8_t *const mask = get_supertx_mask(w, ssx);
1486
1487 w_remain = top_w - w_offset - w;
1488 h_remain = top_h;
1489 dst += w_offset;
1490 pre += w_offset;
1491
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001492#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001493 if (is_hdb)
Yaowu Xuf883b422016-08-30 14:01:10 -07001494 aom_highbd_blend_a64_hmask(dst, dst_stride, dst, dst_stride, pre,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001495 pre_stride, mask, top_h, w, xd->bd);
1496 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001497#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07001498 aom_blend_a64_hmask(dst, dst_stride, dst, dst_stride, pre, pre_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001499 mask, top_h, w);
1500
1501 dst += w;
1502 pre += w;
1503 break;
1504 }
1505 default: {
1506 assert(0);
1507 return;
1508 }
1509 }
1510
1511 if (w_remain == 0 || h_remain == 0) {
1512 return;
1513 }
1514
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001515#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001516 if (is_hdb) {
1517 dst = (uint8_t *)CONVERT_TO_SHORTPTR(dst);
1518 pre = (const uint8_t *)CONVERT_TO_SHORTPTR(pre);
1519 dst_stride *= 2;
1520 pre_stride *= 2;
1521 w_remain *= 2;
1522 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001523#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001524
1525 do {
1526 memcpy(dst, pre, w_remain * sizeof(uint8_t));
1527 dst += dst_stride;
1528 pre += pre_stride;
1529 } while (--h_remain);
1530}
1531
Yaowu Xuf883b422016-08-30 14:01:10 -07001532void av1_build_inter_predictors_sb_sub8x8_extend(MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001533#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07001534 int mi_row_ori, int mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001535#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07001536 int mi_row, int mi_col,
1537 BLOCK_SIZE bsize, int block) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001538 // Prediction function used in supertx:
1539 // Use the mv at current block (which is less than 8x8)
1540 // to get prediction of a block located at (mi_row, mi_col) at size of bsize
1541 // bsize can be larger than 8x8.
1542 // block (0-3): the sub8x8 location of current block
1543 int plane;
1544 const int mi_x = mi_col * MI_SIZE;
1545 const int mi_y = mi_row * MI_SIZE;
1546#if CONFIG_EXT_INTER
1547 const int wedge_offset_x = (mi_col_ori - mi_col) * MI_SIZE;
1548 const int wedge_offset_y = (mi_row_ori - mi_row) * MI_SIZE;
1549#endif // CONFIG_EXT_INTER
1550
1551 // For sub8x8 uv:
1552 // Skip uv prediction in supertx except the first block (block = 0)
1553 int max_plane = block ? 1 : MAX_MB_PLANE;
1554
1555 for (plane = 0; plane < max_plane; plane++) {
1556 const BLOCK_SIZE plane_bsize =
1557 get_plane_block_size(bsize, &xd->plane[plane]);
1558 const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize];
1559 const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize];
1560 const int bw = 4 * num_4x4_w;
1561 const int bh = 4 * num_4x4_h;
1562
1563 build_inter_predictors(xd, plane,
Yue Chencb60b182016-10-13 15:18:22 -07001564#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001565 0, 0,
Yue Chencb60b182016-10-13 15:18:22 -07001566#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001567 block, bw, bh, 0, 0, bw, bh,
1568#if CONFIG_EXT_INTER
1569 wedge_offset_x, wedge_offset_y,
1570#endif // CONFIG_EXT_INTER
1571 mi_x, mi_y);
1572 }
1573#if CONFIG_EXT_INTER
Yaowu Xuf4c904c2016-12-07 11:18:27 -08001574 if (is_interintra_pred(&xd->mi[0]->mbmi)) {
1575 BUFFER_SET ctx = { { xd->plane[0].dst.buf, xd->plane[1].dst.buf,
1576 xd->plane[2].dst.buf },
1577 { xd->plane[0].dst.stride, xd->plane[1].dst.stride,
1578 xd->plane[2].dst.stride } };
Yaowu Xuf883b422016-08-30 14:01:10 -07001579 av1_build_interintra_predictors(
Yaowu Xuc27fc142016-08-22 16:08:15 -07001580 xd, xd->plane[0].dst.buf, xd->plane[1].dst.buf, xd->plane[2].dst.buf,
1581 xd->plane[0].dst.stride, xd->plane[1].dst.stride,
David Barkerac37fa32016-12-02 12:30:21 +00001582 xd->plane[2].dst.stride, &ctx, bsize);
Yaowu Xuf4c904c2016-12-07 11:18:27 -08001583 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001584#endif // CONFIG_EXT_INTER
1585}
1586
Yaowu Xuf883b422016-08-30 14:01:10 -07001587void av1_build_inter_predictors_sb_extend(MACROBLOCKD *xd,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001588#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07001589 int mi_row_ori, int mi_col_ori,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001590#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07001591 int mi_row, int mi_col,
1592 BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001593 int plane;
1594 const int mi_x = mi_col * MI_SIZE;
1595 const int mi_y = mi_row * MI_SIZE;
1596#if CONFIG_EXT_INTER
1597 const int wedge_offset_x = (mi_col_ori - mi_col) * MI_SIZE;
1598 const int wedge_offset_y = (mi_row_ori - mi_row) * MI_SIZE;
1599#endif // CONFIG_EXT_INTER
1600 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
1601 const BLOCK_SIZE plane_bsize =
1602 get_plane_block_size(bsize, &xd->plane[plane]);
Jingning Hanae5cfde2016-11-30 12:01:44 -08001603 const int bw = block_size_wide[plane_bsize];
1604 const int bh = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001605
Jingning Han002c8142016-12-20 15:07:58 -08001606 build_inter_predictors(xd, plane,
Yue Chencb60b182016-10-13 15:18:22 -07001607#if CONFIG_MOTION_VAR
Jingning Han002c8142016-12-20 15:07:58 -08001608 0, 0,
Yue Chencb60b182016-10-13 15:18:22 -07001609#endif // CONFIG_MOTION_VAR
Jingning Han002c8142016-12-20 15:07:58 -08001610 0, bw, bh, 0, 0, bw, bh,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001611#if CONFIG_EXT_INTER
Jingning Han002c8142016-12-20 15:07:58 -08001612 wedge_offset_x, wedge_offset_y,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001613#endif // CONFIG_EXT_INTER
Jingning Han002c8142016-12-20 15:07:58 -08001614 mi_x, mi_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001615 }
1616}
1617#endif // CONFIG_SUPERTX
1618
Yue Chencb60b182016-10-13 15:18:22 -07001619#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001620// obmc_mask_N[overlap_position]
Yue Chen0f1d27c2017-03-07 01:26:50 +08001621static const uint8_t obmc_mask_1[1] = { 64 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07001622
Yue Chen0f1d27c2017-03-07 01:26:50 +08001623static const uint8_t obmc_mask_2[2] = { 45, 64 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07001624
1625static const uint8_t obmc_mask_4[4] = { 39, 50, 59, 64 };
1626
Yue Chen0f1d27c2017-03-07 01:26:50 +08001627static const uint8_t obmc_mask_8[8] = { 36, 42, 48, 53, 57, 61, 64, 64 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07001628
1629static const uint8_t obmc_mask_16[16] = { 34, 37, 40, 43, 46, 49, 52, 54,
Yue Chen0f1d27c2017-03-07 01:26:50 +08001630 56, 58, 60, 61, 64, 64, 64, 64 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07001631
1632static const uint8_t obmc_mask_32[32] = { 33, 35, 36, 38, 40, 41, 43, 44,
1633 45, 47, 48, 50, 51, 52, 53, 55,
1634 56, 57, 58, 59, 60, 60, 61, 62,
Yue Chen0f1d27c2017-03-07 01:26:50 +08001635 64, 64, 64, 64, 64, 64, 64, 64 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07001636
1637#if CONFIG_EXT_PARTITION
1638static const uint8_t obmc_mask_64[64] = {
1639 33, 34, 35, 35, 36, 37, 38, 39, 40, 40, 41, 42, 43, 44, 44, 44,
1640 45, 46, 47, 47, 48, 49, 50, 51, 51, 51, 52, 52, 53, 54, 55, 56,
1641 56, 56, 57, 57, 58, 58, 59, 60, 60, 60, 60, 60, 61, 62, 62, 62,
1642 62, 62, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
1643};
1644#endif // CONFIG_EXT_PARTITION
1645
Yaowu Xuf883b422016-08-30 14:01:10 -07001646const uint8_t *av1_get_obmc_mask(int length) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001647 switch (length) {
1648 case 1: return obmc_mask_1;
1649 case 2: return obmc_mask_2;
1650 case 4: return obmc_mask_4;
1651 case 8: return obmc_mask_8;
1652 case 16: return obmc_mask_16;
1653 case 32: return obmc_mask_32;
1654#if CONFIG_EXT_PARTITION
1655 case 64: return obmc_mask_64;
1656#endif // CONFIG_EXT_PARTITION
1657 default: assert(0); return NULL;
1658 }
1659}
1660
Yue Chen86ae7b12017-01-11 17:04:29 -08001661#if CONFIG_NCOBMC
1662// obmc_mask_flipN[overlap_position]
1663static const uint8_t obmc_mask_flip1[1] = { 55 };
1664
1665static const uint8_t obmc_mask_flip2[2] = { 62, 45 };
1666
1667static const uint8_t obmc_mask_flip4[4] = { 64, 59, 50, 39 };
1668
1669static const uint8_t obmc_mask_flip8[8] = { 64, 63, 61, 57, 53, 48, 42, 36 };
1670
1671static const uint8_t obmc_mask_flip16[16] = { 64, 64, 64, 63, 61, 60, 58, 56,
1672 54, 52, 49, 46, 43, 40, 37, 34 };
1673
1674static const uint8_t obmc_mask_flip32[32] = { 64, 64, 64, 64, 64, 63, 63, 62,
1675 62, 61, 60, 60, 59, 58, 57, 56,
1676 55, 53, 52, 51, 50, 48, 47, 45,
1677 44, 43, 41, 40, 38, 36, 35, 33 };
1678
1679#if CONFIG_EXT_PARTITION
1680static const uint8_t obmc_mask_flip64[64] = {
1681 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 63, 63, 63, 63, 62, 62,
1682 62, 62, 62, 61, 60, 60, 60, 60, 60, 59, 58, 58, 57, 57, 56, 56,
1683 56, 55, 54, 53, 52, 52, 51, 51, 51, 50, 49, 48, 47, 47, 46, 45,
1684 44, 44, 44, 43, 42, 41, 40, 40, 39, 38, 37, 36, 35, 35, 34, 33,
1685};
1686#endif // CONFIG_EXT_PARTITION
1687
1688const uint8_t *av1_get_obmc_mask_flipped(int length) {
1689 switch (length) {
1690 case 1: return obmc_mask_flip1;
1691 case 2: return obmc_mask_flip2;
1692 case 4: return obmc_mask_flip4;
1693 case 8: return obmc_mask_flip8;
1694 case 16: return obmc_mask_flip16;
1695 case 32: return obmc_mask_flip32;
1696#if CONFIG_EXT_PARTITION
1697 case 64: return obmc_mask_flip64;
1698#endif // CONFIG_EXT_PARTITION
1699 default: assert(0); return NULL;
1700 }
1701}
1702#endif // CONFIG_NCOBMC
1703
Yue Chen5329a2b2017-02-28 17:33:00 +08001704void av1_count_overlappable_neighbors(const AV1_COMMON *cm, MACROBLOCKD *xd,
1705 int mi_row, int mi_col) {
1706 int i, mi_step;
1707
1708 xd->mi[0]->mbmi.overlappable_neighbors[0] = 0;
1709 xd->mi[0]->mbmi.overlappable_neighbors[1] = 0;
1710
1711 if (xd->up_available) {
Yue Chen2338fa12017-03-07 01:40:42 +08001712 const int ilimit = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
1713 for (i = 0; i < ilimit; i += mi_step) {
Yue Chen5329a2b2017-02-28 17:33:00 +08001714 int mi_row_offset = -1;
1715 int mi_col_offset = i;
1716 MODE_INFO *above_mi =
1717 xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
1718 MB_MODE_INFO *above_mbmi = &above_mi->mbmi;
1719
1720 mi_step = AOMMIN(xd->n8_w, mi_size_wide[above_mbmi->sb_type]);
1721
Yue Chen13e412e2017-03-30 17:32:21 -07001722 if (is_neighbor_overlappable(above_mbmi))
Yue Chen5329a2b2017-02-28 17:33:00 +08001723 xd->mi[0]->mbmi.overlappable_neighbors[0]++;
Yue Chen5329a2b2017-02-28 17:33:00 +08001724 }
1725 }
1726
1727 if (xd->left_available) {
Yue Chen2338fa12017-03-07 01:40:42 +08001728 const int ilimit = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
1729 for (i = 0; i < ilimit; i += mi_step) {
Yue Chen5329a2b2017-02-28 17:33:00 +08001730 int mi_row_offset = i;
1731 int mi_col_offset = -1;
1732 MODE_INFO *left_mi =
1733 xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
1734 MB_MODE_INFO *left_mbmi = &left_mi->mbmi;
1735
1736 mi_step = AOMMIN(xd->n8_h, mi_size_high[left_mbmi->sb_type]);
1737
Yue Chen13e412e2017-03-30 17:32:21 -07001738 if (is_neighbor_overlappable(left_mbmi))
Yue Chen5329a2b2017-02-28 17:33:00 +08001739 xd->mi[0]->mbmi.overlappable_neighbors[1]++;
Yue Chen5329a2b2017-02-28 17:33:00 +08001740 }
1741 }
1742}
1743
Yue Chen85c7e902017-04-12 00:06:00 -07001744// HW does not support < 4x4 prediction. To limit the bandwidth requirement, for
1745// small blocks, only blend with neighbors from one side. If block-size of
1746// current plane is 4x4 or 8x4, the above neighbor (dir = 0) will be skipped. If
1747// it is 4x8, the left neighbor (dir = 1) will be skipped.
Yue Chenf0dfc032017-04-17 10:20:56 -07001748#define DISABLE_CHROMA_U8X8_OBMC 0 // 0: one-sided obmc; 1: disable
1749
Yue Chen85c7e902017-04-12 00:06:00 -07001750int skip_u4x4_pred_in_obmc(BLOCK_SIZE bsize, const struct macroblockd_plane *pd,
1751 int dir) {
1752 assert(is_motion_variation_allowed_bsize(bsize));
1753
1754 BLOCK_SIZE bsize_plane =
1755 ss_size_lookup[bsize][pd->subsampling_x][pd->subsampling_y];
1756#if CONFIG_CB4X4
1757 if (bsize_plane < BLOCK_4X4) return 1;
1758#endif
1759 switch (bsize_plane) {
Yue Chenf0dfc032017-04-17 10:20:56 -07001760#if DISABLE_CHROMA_U8X8_OBMC
Yue Chen85c7e902017-04-12 00:06:00 -07001761 case BLOCK_4X4:
Yue Chenf0dfc032017-04-17 10:20:56 -07001762 case BLOCK_8X4:
1763 case BLOCK_4X8: return 1; break;
1764#else
Yue Chenf7ba6472017-04-19 11:08:58 -07001765 case BLOCK_4X4:
1766 case BLOCK_8X4:
Yue Chen85c7e902017-04-12 00:06:00 -07001767 case BLOCK_4X8: return dir == 1; break;
Yue Chenf0dfc032017-04-17 10:20:56 -07001768#endif
Yue Chen85c7e902017-04-12 00:06:00 -07001769 default: return 0;
1770 }
1771}
1772
Yaowu Xuc27fc142016-08-22 16:08:15 -07001773// This function combines motion compensated predictions that is generated by
1774// top/left neighboring blocks' inter predictors with the regular inter
1775// prediction. We assume the original prediction (bmc) is stored in
1776// xd->plane[].dst.buf
Urvang Joshi52648442016-10-13 17:27:51 -07001777void av1_build_obmc_inter_prediction(const AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xuf883b422016-08-30 14:01:10 -07001778 int mi_row, int mi_col,
1779 uint8_t *above[MAX_MB_PLANE],
1780 int above_stride[MAX_MB_PLANE],
1781 uint8_t *left[MAX_MB_PLANE],
1782 int left_stride[MAX_MB_PLANE]) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001783 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
1784 int plane, i;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001785#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001786 const int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001787#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001788
1789 // handle above row
1790 if (xd->up_available) {
1791 const int overlap = num_4x4_blocks_high_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -07001792 const int miw = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001793 const int mi_row_offset = -1;
Yue Chen1bd42be2017-03-15 18:07:04 -07001794 const int neighbor_limit = max_neighbor_obmc[b_width_log2_lookup[bsize]];
1795 int neighbor_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001796
1797 assert(miw > 0);
1798
1799 i = 0;
1800 do { // for each mi in the above row
1801 const int mi_col_offset = i;
1802 const MB_MODE_INFO *const above_mbmi =
1803 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
Yue Chen1bd42be2017-03-15 18:07:04 -07001804 const BLOCK_SIZE a_bsize = above_mbmi->sb_type;
1805 const int mi_step = AOMMIN(xd->n8_w, mi_size_wide[a_bsize]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001806
1807 if (is_neighbor_overlappable(above_mbmi)) {
Yue Chen13e412e2017-03-30 17:32:21 -07001808 neighbor_count++;
Yue Chen1bd42be2017-03-15 18:07:04 -07001809 if (neighbor_count > neighbor_limit) break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001810 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
1811 const struct macroblockd_plane *pd = &xd->plane[plane];
1812 const int bw = (mi_step * MI_SIZE) >> pd->subsampling_x;
1813 const int bh = overlap >> pd->subsampling_y;
Yue Chen85c7e902017-04-12 00:06:00 -07001814
1815 if (skip_u4x4_pred_in_obmc(bsize, pd, 0)) continue;
1816
Yaowu Xuc27fc142016-08-22 16:08:15 -07001817 const int dst_stride = pd->dst.stride;
1818 uint8_t *const dst = &pd->dst.buf[(i * MI_SIZE) >> pd->subsampling_x];
1819 const int tmp_stride = above_stride[plane];
1820 const uint8_t *const tmp =
1821 &above[plane][(i * MI_SIZE) >> pd->subsampling_x];
Yaowu Xuf883b422016-08-30 14:01:10 -07001822 const uint8_t *const mask = av1_get_obmc_mask(bh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001823
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001824#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001825 if (is_hbd)
Yaowu Xuf883b422016-08-30 14:01:10 -07001826 aom_highbd_blend_a64_vmask(dst, dst_stride, dst, dst_stride, tmp,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001827 tmp_stride, mask, bh, bw, xd->bd);
1828 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001829#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07001830 aom_blend_a64_vmask(dst, dst_stride, dst, dst_stride, tmp,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001831 tmp_stride, mask, bh, bw);
1832 }
1833 }
1834 i += mi_step;
1835 } while (i < miw);
1836 }
1837
1838 // handle left column
1839 if (xd->left_available) {
1840 const int overlap = num_4x4_blocks_wide_lookup[bsize] * 2;
Yaowu Xuf883b422016-08-30 14:01:10 -07001841 const int mih = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001842 const int mi_col_offset = -1;
Yue Chen1bd42be2017-03-15 18:07:04 -07001843 const int neighbor_limit = max_neighbor_obmc[b_height_log2_lookup[bsize]];
1844 int neighbor_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001845
1846 assert(mih > 0);
1847
1848 i = 0;
1849 do { // for each mi in the left column
1850 const int mi_row_offset = i;
1851 const MB_MODE_INFO *const left_mbmi =
1852 &xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride]->mbmi;
Yue Chen1bd42be2017-03-15 18:07:04 -07001853 const BLOCK_SIZE l_bsize = left_mbmi->sb_type;
1854 const int mi_step = AOMMIN(xd->n8_h, mi_size_high[l_bsize]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001855
1856 if (is_neighbor_overlappable(left_mbmi)) {
Yue Chen13e412e2017-03-30 17:32:21 -07001857 neighbor_count++;
Yue Chen1bd42be2017-03-15 18:07:04 -07001858 if (neighbor_count > neighbor_limit) break;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001859 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
1860 const struct macroblockd_plane *pd = &xd->plane[plane];
1861 const int bw = overlap >> pd->subsampling_x;
1862 const int bh = (mi_step * MI_SIZE) >> pd->subsampling_y;
Yue Chen85c7e902017-04-12 00:06:00 -07001863
1864 if (skip_u4x4_pred_in_obmc(bsize, pd, 1)) continue;
1865
Yaowu Xuc27fc142016-08-22 16:08:15 -07001866 const int dst_stride = pd->dst.stride;
1867 uint8_t *const dst =
1868 &pd->dst.buf[(i * MI_SIZE * dst_stride) >> pd->subsampling_y];
1869 const int tmp_stride = left_stride[plane];
1870 const uint8_t *const tmp =
1871 &left[plane][(i * MI_SIZE * tmp_stride) >> pd->subsampling_y];
Yaowu Xuf883b422016-08-30 14:01:10 -07001872 const uint8_t *const mask = av1_get_obmc_mask(bw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001873
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001874#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001875 if (is_hbd)
Yaowu Xuf883b422016-08-30 14:01:10 -07001876 aom_highbd_blend_a64_hmask(dst, dst_stride, dst, dst_stride, tmp,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001877 tmp_stride, mask, bh, bw, xd->bd);
1878 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001879#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07001880 aom_blend_a64_hmask(dst, dst_stride, dst, dst_stride, tmp,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001881 tmp_stride, mask, bh, bw);
1882 }
1883 }
1884 i += mi_step;
1885 } while (i < mih);
1886 }
1887}
1888
Yaowu Xuc27fc142016-08-22 16:08:15 -07001889void modify_neighbor_predictor_for_obmc(MB_MODE_INFO *mbmi) {
Yue Chen54723f92017-03-03 11:49:17 +08001890#if CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07001891 if (is_interintra_pred(mbmi)) {
Emil Keyder01770b32017-01-20 18:03:11 -05001892 mbmi->ref_frame[1] = NONE_FRAME;
Sarah Parker6fdc8532016-11-16 17:47:13 -08001893 } else if (has_second_ref(mbmi) &&
1894 is_masked_compound_type(mbmi->interinter_compound_data.type)) {
1895 mbmi->interinter_compound_data.type = COMPOUND_AVERAGE;
Emil Keyder01770b32017-01-20 18:03:11 -05001896 mbmi->ref_frame[1] = NONE_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001897 }
Yue Chen54723f92017-03-03 11:49:17 +08001898#endif // CONFIG_EXT_INTER
1899 if (has_second_ref(mbmi)) mbmi->ref_frame[1] = NONE_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001900 return;
1901}
Yaowu Xuc27fc142016-08-22 16:08:15 -07001902
Urvang Joshi52648442016-10-13 17:27:51 -07001903void av1_build_prediction_by_above_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xuf883b422016-08-30 14:01:10 -07001904 int mi_row, int mi_col,
1905 uint8_t *tmp_buf[MAX_MB_PLANE],
1906 int tmp_width[MAX_MB_PLANE],
1907 int tmp_height[MAX_MB_PLANE],
1908 int tmp_stride[MAX_MB_PLANE]) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001909 const TileInfo *const tile = &xd->tile;
1910 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
1911 int i, j, mi_step, ref;
Yue Chen2338fa12017-03-07 01:40:42 +08001912 const int ilimit = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
Yue Chen894fcce2016-10-21 16:50:52 -07001913 int mb_to_right_edge_base = xd->mb_to_right_edge;
Yue Chen1bd42be2017-03-15 18:07:04 -07001914 const int neighbor_limit = max_neighbor_obmc[b_width_log2_lookup[bsize]];
1915 int neighbor_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001916
1917 if (mi_row <= tile->mi_row_start) return;
1918
Yue Chen894fcce2016-10-21 16:50:52 -07001919 xd->mb_to_bottom_edge += xd->n8_h * 32;
Yue Chen2338fa12017-03-07 01:40:42 +08001920 for (i = 0; i < ilimit; i += mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001921 int mi_row_offset = -1;
1922 int mi_col_offset = i;
1923 int mi_x, mi_y, bw, bh;
1924 MODE_INFO *above_mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
1925 MB_MODE_INFO *above_mbmi = &above_mi->mbmi;
Yue Chen1bd42be2017-03-15 18:07:04 -07001926 const BLOCK_SIZE a_bsize = above_mbmi->sb_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001927 MB_MODE_INFO backup_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001928
Yue Chen1bd42be2017-03-15 18:07:04 -07001929 mi_step = AOMMIN(xd->n8_w, mi_size_wide[a_bsize]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001930
1931 if (!is_neighbor_overlappable(above_mbmi)) continue;
1932
Yue Chen13e412e2017-03-30 17:32:21 -07001933 neighbor_count++;
Yue Chen1bd42be2017-03-15 18:07:04 -07001934 if (neighbor_count > neighbor_limit) break;
1935
Yaowu Xuc27fc142016-08-22 16:08:15 -07001936 backup_mbmi = *above_mbmi;
1937 modify_neighbor_predictor_for_obmc(above_mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001938
1939 for (j = 0; j < MAX_MB_PLANE; ++j) {
1940 struct macroblockd_plane *const pd = &xd->plane[j];
1941 setup_pred_plane(&pd->dst, tmp_buf[j], tmp_width[j], tmp_height[j],
1942 tmp_stride[j], 0, i, NULL, pd->subsampling_x,
1943 pd->subsampling_y);
1944 }
1945 for (ref = 0; ref < 1 + has_second_ref(above_mbmi); ++ref) {
Urvang Joshi52648442016-10-13 17:27:51 -07001946 const MV_REFERENCE_FRAME frame = above_mbmi->ref_frame[ref];
1947 const RefBuffer *const ref_buf = &cm->frame_refs[frame - LAST_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001948
1949 xd->block_refs[ref] = ref_buf;
Yaowu Xuf883b422016-08-30 14:01:10 -07001950 if ((!av1_is_valid_scale(&ref_buf->sf)))
1951 aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001952 "Reference frame has invalid dimensions");
Yaowu Xuf883b422016-08-30 14:01:10 -07001953 av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col + i,
1954 &ref_buf->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001955 }
1956
1957 xd->mb_to_left_edge = -(((mi_col + i) * MI_SIZE) * 8);
Yue Chen894fcce2016-10-21 16:50:52 -07001958 xd->mb_to_right_edge =
1959 mb_to_right_edge_base + (xd->n8_w - i - mi_step) * 64;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001960 mi_x = (mi_col + i) << MI_SIZE_LOG2;
1961 mi_y = mi_row << MI_SIZE_LOG2;
1962
1963 for (j = 0; j < MAX_MB_PLANE; ++j) {
1964 const struct macroblockd_plane *pd = &xd->plane[j];
Jingning Han51ec5052017-01-18 16:27:57 -08001965 bw = (mi_step * MI_SIZE) >> pd->subsampling_x;
Yaowu Xuf883b422016-08-30 14:01:10 -07001966 bh = AOMMAX((num_4x4_blocks_high_lookup[bsize] * 2) >> pd->subsampling_y,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001967 4);
1968
Yue Chen85c7e902017-04-12 00:06:00 -07001969 if (skip_u4x4_pred_in_obmc(bsize, pd, 0)) continue;
Sarah Parker4c10a3c2017-04-10 19:37:59 -07001970 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0, bw, bh, 0,
1971 0, bw, bh,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001972#if CONFIG_SUPERTX && CONFIG_EXT_INTER
Sarah Parker4c10a3c2017-04-10 19:37:59 -07001973 0, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001974#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
Sarah Parker4c10a3c2017-04-10 19:37:59 -07001975 mi_x, mi_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001976 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001977 *above_mbmi = backup_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001978 }
1979 xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8);
Yue Chen894fcce2016-10-21 16:50:52 -07001980 xd->mb_to_right_edge = mb_to_right_edge_base;
1981 xd->mb_to_bottom_edge -= xd->n8_h * 32;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001982}
1983
Urvang Joshi52648442016-10-13 17:27:51 -07001984void av1_build_prediction_by_left_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
Yaowu Xuf883b422016-08-30 14:01:10 -07001985 int mi_row, int mi_col,
1986 uint8_t *tmp_buf[MAX_MB_PLANE],
1987 int tmp_width[MAX_MB_PLANE],
1988 int tmp_height[MAX_MB_PLANE],
1989 int tmp_stride[MAX_MB_PLANE]) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001990 const TileInfo *const tile = &xd->tile;
1991 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
1992 int i, j, mi_step, ref;
Yue Chen2338fa12017-03-07 01:40:42 +08001993 const int ilimit = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
Yue Chen894fcce2016-10-21 16:50:52 -07001994 int mb_to_bottom_edge_base = xd->mb_to_bottom_edge;
Yue Chen1bd42be2017-03-15 18:07:04 -07001995 const int neighbor_limit = max_neighbor_obmc[b_height_log2_lookup[bsize]];
1996 int neighbor_count = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001997
1998 if (mi_col == 0 || (mi_col - 1 < tile->mi_col_start)) return;
1999
Yue Chen894fcce2016-10-21 16:50:52 -07002000 xd->mb_to_right_edge += xd->n8_w * 32;
Yue Chen2338fa12017-03-07 01:40:42 +08002001 for (i = 0; i < ilimit; i += mi_step) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002002 int mi_row_offset = i;
2003 int mi_col_offset = -1;
2004 int mi_x, mi_y, bw, bh;
2005 MODE_INFO *left_mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
2006 MB_MODE_INFO *left_mbmi = &left_mi->mbmi;
Yue Chen1bd42be2017-03-15 18:07:04 -07002007 const BLOCK_SIZE l_bsize = left_mbmi->sb_type;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002008 MB_MODE_INFO backup_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002009
Yue Chen1bd42be2017-03-15 18:07:04 -07002010 mi_step = AOMMIN(xd->n8_h, mi_size_high[l_bsize]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002011
2012 if (!is_neighbor_overlappable(left_mbmi)) continue;
2013
Yue Chen13e412e2017-03-30 17:32:21 -07002014 neighbor_count++;
Yue Chen1bd42be2017-03-15 18:07:04 -07002015 if (neighbor_count > neighbor_limit) break;
2016
Yaowu Xuc27fc142016-08-22 16:08:15 -07002017 backup_mbmi = *left_mbmi;
2018 modify_neighbor_predictor_for_obmc(left_mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002019
2020 for (j = 0; j < MAX_MB_PLANE; ++j) {
2021 struct macroblockd_plane *const pd = &xd->plane[j];
2022 setup_pred_plane(&pd->dst, tmp_buf[j], tmp_width[j], tmp_height[j],
2023 tmp_stride[j], i, 0, NULL, pd->subsampling_x,
2024 pd->subsampling_y);
2025 }
2026 for (ref = 0; ref < 1 + has_second_ref(left_mbmi); ++ref) {
Urvang Joshi52648442016-10-13 17:27:51 -07002027 const MV_REFERENCE_FRAME frame = left_mbmi->ref_frame[ref];
2028 const RefBuffer *const ref_buf = &cm->frame_refs[frame - LAST_FRAME];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002029
2030 xd->block_refs[ref] = ref_buf;
Yaowu Xuf883b422016-08-30 14:01:10 -07002031 if ((!av1_is_valid_scale(&ref_buf->sf)))
2032 aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002033 "Reference frame has invalid dimensions");
Yaowu Xuf883b422016-08-30 14:01:10 -07002034 av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row + i, mi_col,
2035 &ref_buf->sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002036 }
2037
2038 xd->mb_to_top_edge = -(((mi_row + i) * MI_SIZE) * 8);
Yue Chen894fcce2016-10-21 16:50:52 -07002039 xd->mb_to_bottom_edge =
2040 mb_to_bottom_edge_base + (xd->n8_h - i - mi_step) * 64;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002041 mi_x = mi_col << MI_SIZE_LOG2;
2042 mi_y = (mi_row + i) << MI_SIZE_LOG2;
2043
2044 for (j = 0; j < MAX_MB_PLANE; ++j) {
2045 const struct macroblockd_plane *pd = &xd->plane[j];
Yaowu Xuf883b422016-08-30 14:01:10 -07002046 bw = AOMMAX((num_4x4_blocks_wide_lookup[bsize] * 2) >> pd->subsampling_x,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002047 4);
2048 bh = (mi_step << MI_SIZE_LOG2) >> pd->subsampling_y;
2049
Yue Chen85c7e902017-04-12 00:06:00 -07002050 if (skip_u4x4_pred_in_obmc(bsize, pd, 1)) continue;
Sarah Parker4c10a3c2017-04-10 19:37:59 -07002051 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0, bw, bh, 0,
2052 0, bw, bh,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002053#if CONFIG_SUPERTX && CONFIG_EXT_INTER
Sarah Parker4c10a3c2017-04-10 19:37:59 -07002054 0, 0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002055#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
Sarah Parker4c10a3c2017-04-10 19:37:59 -07002056 mi_x, mi_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002057 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002058 *left_mbmi = backup_mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002059 }
2060 xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8);
Yue Chen894fcce2016-10-21 16:50:52 -07002061 xd->mb_to_bottom_edge = mb_to_bottom_edge_base;
2062 xd->mb_to_right_edge -= xd->n8_w * 32;
2063}
2064
2065void av1_build_obmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
2066 int mi_row, int mi_col) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002067#if CONFIG_HIGHBITDEPTH
Yue Chen894fcce2016-10-21 16:50:52 -07002068 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
2069 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
2070#else
2071 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
2072 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002073#endif // CONFIG_HIGHBITDEPTH
Yue Chen894fcce2016-10-21 16:50:52 -07002074 uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
2075 int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2076 int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2077 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2078 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2079 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2080 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2081
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002082#if CONFIG_HIGHBITDEPTH
Yue Chen894fcce2016-10-21 16:50:52 -07002083 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2084 int len = sizeof(uint16_t);
2085 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
2086 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
2087 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * 2 * len);
2088 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
2089 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
2090 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * 2 * len);
2091 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002092#endif // CONFIG_HIGHBITDEPTH
Yue Chen894fcce2016-10-21 16:50:52 -07002093 dst_buf1[0] = tmp_buf1;
2094 dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE;
2095 dst_buf1[2] = tmp_buf1 + MAX_SB_SQUARE * 2;
2096 dst_buf2[0] = tmp_buf2;
2097 dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE;
2098 dst_buf2[2] = tmp_buf2 + MAX_SB_SQUARE * 2;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002099#if CONFIG_HIGHBITDEPTH
Yue Chen894fcce2016-10-21 16:50:52 -07002100 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002101#endif // CONFIG_HIGHBITDEPTH
Yue Chen894fcce2016-10-21 16:50:52 -07002102 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col, dst_buf1,
2103 dst_width1, dst_height1, dst_stride1);
2104 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col, dst_buf2,
2105 dst_width2, dst_height2, dst_stride2);
2106 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
2107 av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, dst_buf1, dst_stride1,
2108 dst_buf2, dst_stride2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002109}
Yue Chen86ae7b12017-01-11 17:04:29 -08002110
2111#if CONFIG_NCOBMC
2112void av1_build_prediction_by_bottom_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
2113 int mi_row, int mi_col,
2114 uint8_t *tmp_buf[MAX_MB_PLANE],
2115 int tmp_width[MAX_MB_PLANE],
2116 int tmp_height[MAX_MB_PLANE],
2117 int tmp_stride[MAX_MB_PLANE]) {
2118 const TileInfo *const tile = &xd->tile;
2119 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
2120 int i, j, mi_step, ref;
Yue Chen2338fa12017-03-07 01:40:42 +08002121 const int ilimit = AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
Yue Chen86ae7b12017-01-11 17:04:29 -08002122 int mb_to_right_edge_base = xd->mb_to_right_edge;
2123
Jingning Han91f01fd2017-01-18 17:16:40 -08002124 if (mi_row + xd->n8_h >= tile->mi_row_end ||
2125 (mi_row + xd->n8_h) % MI_SIZE == 0 || (mi_row + xd->n8_h) >= cm->mi_rows)
Yue Chen86ae7b12017-01-11 17:04:29 -08002126 return;
2127 assert(bsize >= BLOCK_8X8);
2128
2129 xd->mb_to_top_edge -= xd->n8_h * 32;
Yue Chen2338fa12017-03-07 01:40:42 +08002130 for (i = 0; i < ilimit; i += mi_step) {
Yue Chen86ae7b12017-01-11 17:04:29 -08002131 int mi_row_offset = xd->n8_h;
2132 int mi_col_offset = i;
2133 int mi_x, mi_y, bw, bh;
2134 MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
2135 MB_MODE_INFO *mbmi = &mi->mbmi;
2136#if CONFIG_EXT_INTER
2137 MB_MODE_INFO backup_mbmi;
2138#endif // CONFIG_EXT_INTER
2139
Jingning Han91f01fd2017-01-18 17:16:40 -08002140 mi_step = AOMMIN(xd->n8_w, mi_size_wide[mbmi->sb_type]);
Yue Chen86ae7b12017-01-11 17:04:29 -08002141
2142 if (!is_neighbor_overlappable(mbmi)) continue;
2143
2144#if CONFIG_EXT_INTER
2145 backup_mbmi = *mbmi;
2146 modify_neighbor_predictor_for_obmc(mbmi);
2147#endif // CONFIG_EXT_INTER
2148
2149 for (j = 0; j < MAX_MB_PLANE; ++j) {
2150 struct macroblockd_plane *const pd = &xd->plane[j];
2151 setup_pred_plane(&pd->dst, tmp_buf[j], tmp_width[j], tmp_height[j],
2152 tmp_stride[j], (xd->n8_h >> 1), i, NULL,
2153 pd->subsampling_x, pd->subsampling_y);
2154 }
2155 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
2156 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
2157 const RefBuffer *const ref_buf = &cm->frame_refs[frame - LAST_FRAME];
2158
2159 xd->block_refs[ref] = ref_buf;
2160 if ((!av1_is_valid_scale(&ref_buf->sf)))
2161 aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
2162 "Reference frame has invalid dimensions");
2163 av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row + (xd->n8_h >> 1),
2164 mi_col + i, &ref_buf->sf);
2165 }
2166
2167 xd->mb_to_left_edge = -(((mi_col + i) * MI_SIZE) * 8);
2168 xd->mb_to_right_edge =
2169 mb_to_right_edge_base + (xd->n8_w - i - mi_step) * 64;
2170 mi_x = (mi_col + i) << MI_SIZE_LOG2;
2171 mi_y = (mi_row << MI_SIZE_LOG2) + xd->n8_h * 4;
2172
2173 for (j = 0; j < MAX_MB_PLANE; ++j) {
2174 const struct macroblockd_plane *pd = &xd->plane[j];
2175 bw = (mi_step << MI_SIZE_LOG2) >> pd->subsampling_x;
2176 bh = (num_4x4_blocks_high_lookup[bsize] << 1) >> pd->subsampling_y;
2177
Jingning Han91f01fd2017-01-18 17:16:40 -08002178 if (mbmi->sb_type < BLOCK_8X8 && !CONFIG_CB4X4) {
Yue Chen86ae7b12017-01-11 17:04:29 -08002179 const PARTITION_TYPE bp = BLOCK_8X8 - mbmi->sb_type;
2180 const int have_vsplit = bp != PARTITION_HORZ;
2181 const int have_hsplit = bp != PARTITION_VERT;
2182 const int num_4x4_w = 2 >> (!have_vsplit);
2183 const int num_4x4_h = 2 >> (!have_hsplit);
2184 const int pw = 8 >> (have_vsplit + pd->subsampling_x);
2185 int x, y;
2186
2187 for (y = 0; y < num_4x4_h; ++y)
2188 for (x = 0; x < num_4x4_w; ++x) {
2189 if ((bp == PARTITION_HORZ || bp == PARTITION_SPLIT) && y != 0)
2190 continue;
2191
2192 build_inter_predictors(
2193 xd, j, mi_col_offset, mi_row_offset, y * 2 + x, bw, bh,
2194 (4 * x) >> pd->subsampling_x,
2195 xd->n8_h == 1 ? (4 >> pd->subsampling_y) : 0, pw, bh,
2196#if CONFIG_SUPERTX && CONFIG_EXT_INTER
2197 0, 0,
2198#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
2199 mi_x, mi_y);
2200 }
2201 } else {
Sarah Parker4c10a3c2017-04-10 19:37:59 -07002202 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0, bw, bh,
2203 0, xd->n8_h == 1 ? (4 >> pd->subsampling_y) : 0,
2204 bw, bh,
Yue Chen86ae7b12017-01-11 17:04:29 -08002205#if CONFIG_SUPERTX && CONFIG_EXT_INTER
Sarah Parker4c10a3c2017-04-10 19:37:59 -07002206 0, 0,
Yue Chen86ae7b12017-01-11 17:04:29 -08002207#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
Sarah Parker4c10a3c2017-04-10 19:37:59 -07002208 mi_x, mi_y);
Yue Chen86ae7b12017-01-11 17:04:29 -08002209 }
2210 }
2211#if CONFIG_EXT_INTER
2212 *mbmi = backup_mbmi;
2213#endif // CONFIG_EXT_INTER
2214 }
2215 xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8);
2216 xd->mb_to_right_edge = mb_to_right_edge_base;
2217 xd->mb_to_top_edge += xd->n8_h * 32;
2218}
2219
2220void av1_build_prediction_by_right_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
2221 int mi_row, int mi_col,
2222 uint8_t *tmp_buf[MAX_MB_PLANE],
2223 int tmp_width[MAX_MB_PLANE],
2224 int tmp_height[MAX_MB_PLANE],
2225 const int tmp_stride[MAX_MB_PLANE]) {
2226 const TileInfo *const tile = &xd->tile;
2227 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
2228 int i, j, mi_step, ref;
Yue Chen2338fa12017-03-07 01:40:42 +08002229 const int ilimit = AOMMIN(xd->n8_h, cm->mi_rows - mi_row);
Yue Chen86ae7b12017-01-11 17:04:29 -08002230 int mb_to_bottom_edge_base = xd->mb_to_bottom_edge;
2231
Jingning Han91f01fd2017-01-18 17:16:40 -08002232 if (mi_col + xd->n8_w >= tile->mi_col_end ||
2233 (mi_col + xd->n8_w) % MI_SIZE == 0 || (mi_col + xd->n8_w) >= cm->mi_cols)
Yue Chen86ae7b12017-01-11 17:04:29 -08002234 return;
2235
2236 xd->mb_to_left_edge -= xd->n8_w * 32;
Yue Chen2338fa12017-03-07 01:40:42 +08002237 for (i = 0; i < ilimit; i += mi_step) {
Yue Chen86ae7b12017-01-11 17:04:29 -08002238 int mi_row_offset = i;
2239 int mi_col_offset = xd->n8_w;
2240 int mi_x, mi_y, bw, bh;
2241 MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
2242 MB_MODE_INFO *mbmi = &mi->mbmi;
2243#if CONFIG_EXT_INTER
2244 MB_MODE_INFO backup_mbmi;
2245#endif // CONFIG_EXT_INTER
2246
Jingning Han91f01fd2017-01-18 17:16:40 -08002247 mi_step = AOMMIN(xd->n8_h, mi_size_high[mbmi->sb_type]);
Yue Chen86ae7b12017-01-11 17:04:29 -08002248
2249 if (!is_neighbor_overlappable(mbmi)) continue;
2250
2251#if CONFIG_EXT_INTER
2252 backup_mbmi = *mbmi;
2253 modify_neighbor_predictor_for_obmc(mbmi);
2254#endif // CONFIG_EXT_INTER
2255
2256 for (j = 0; j < MAX_MB_PLANE; ++j) {
2257 struct macroblockd_plane *const pd = &xd->plane[j];
2258 setup_pred_plane(&pd->dst, tmp_buf[j], tmp_width[j], tmp_height[j],
2259 tmp_stride[j], i, xd->n8_w >> 1, NULL, pd->subsampling_x,
2260 pd->subsampling_y);
2261 }
2262 for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
2263 const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
2264 const RefBuffer *const ref_buf = &cm->frame_refs[frame - LAST_FRAME];
2265
2266 xd->block_refs[ref] = ref_buf;
2267 if ((!av1_is_valid_scale(&ref_buf->sf)))
2268 aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
2269 "Reference frame has invalid dimensions");
2270 av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row + i,
2271 mi_col + (xd->n8_w >> 1), &ref_buf->sf);
2272 }
2273
2274 xd->mb_to_top_edge = -(((mi_row + i) * MI_SIZE) * 8);
2275 xd->mb_to_bottom_edge =
2276 mb_to_bottom_edge_base + (xd->n8_h - i - mi_step) * 64;
2277 mi_x = (mi_col << MI_SIZE_LOG2) + xd->n8_w * 4;
2278 mi_y = (mi_row + i) << MI_SIZE_LOG2;
2279
2280 for (j = 0; j < MAX_MB_PLANE; ++j) {
2281 const struct macroblockd_plane *pd = &xd->plane[j];
2282 bw = (num_4x4_blocks_wide_lookup[bsize] << 1) >> pd->subsampling_x;
2283 bh = (mi_step << MI_SIZE_LOG2) >> pd->subsampling_y;
2284
Jingning Han91f01fd2017-01-18 17:16:40 -08002285 if (mbmi->sb_type < BLOCK_8X8 && !CONFIG_CB4X4) {
Yue Chen86ae7b12017-01-11 17:04:29 -08002286 const PARTITION_TYPE bp = BLOCK_8X8 - mbmi->sb_type;
2287 const int have_vsplit = bp != PARTITION_HORZ;
2288 const int have_hsplit = bp != PARTITION_VERT;
2289 const int num_4x4_w = 2 >> (!have_vsplit);
2290 const int num_4x4_h = 2 >> (!have_hsplit);
2291 const int ph = 8 >> (have_hsplit + pd->subsampling_y);
2292 int x, y;
2293
2294 for (y = 0; y < num_4x4_h; ++y)
2295 for (x = 0; x < num_4x4_w; ++x) {
2296 if ((bp == PARTITION_VERT || bp == PARTITION_SPLIT) && x != 0)
2297 continue;
2298
2299 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset,
2300 y * 2 + x, bw, bh,
2301 xd->n8_w == 1 ? 4 >> pd->subsampling_x : 0,
2302 (4 * y) >> pd->subsampling_y, bw, ph,
2303#if CONFIG_SUPERTX && CONFIG_EXT_INTER
2304 0, 0,
2305#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
2306 mi_x, mi_y);
2307 }
2308 } else {
Sarah Parker4c10a3c2017-04-10 19:37:59 -07002309 build_inter_predictors(xd, j, mi_col_offset, mi_row_offset, 0, bw, bh,
2310 xd->n8_w == 1 ? 4 >> pd->subsampling_x : 0, 0,
2311 bw, bh,
Yue Chen86ae7b12017-01-11 17:04:29 -08002312#if CONFIG_SUPERTX && CONFIG_EXT_INTER
Sarah Parker4c10a3c2017-04-10 19:37:59 -07002313 0, 0,
Yue Chen86ae7b12017-01-11 17:04:29 -08002314#endif // CONFIG_SUPERTX && CONFIG_EXT_INTER
Sarah Parker4c10a3c2017-04-10 19:37:59 -07002315 mi_x, mi_y);
Yue Chen86ae7b12017-01-11 17:04:29 -08002316 }
2317 }
2318#if CONFIG_EXT_INTER
2319 *mbmi = backup_mbmi;
2320#endif // CONFIG_EXT_INTER
2321 }
2322 xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8);
2323 xd->mb_to_bottom_edge = mb_to_bottom_edge_base;
2324 xd->mb_to_left_edge += xd->n8_w * 32;
2325}
2326
2327// This function combines motion compensated predictions that is generated by
2328// bottom/right neighboring blocks' inter predictors with prediction in dst
2329// buffer.
2330void av1_merge_dst_bottom_right_preds(const AV1_COMMON *cm, MACROBLOCKD *xd,
2331 int mi_row, int mi_col,
2332 uint8_t *bottom[MAX_MB_PLANE],
2333 const int bottom_stride[MAX_MB_PLANE],
2334 uint8_t *right[MAX_MB_PLANE],
2335 const int right_stride[MAX_MB_PLANE]) {
2336 const TileInfo *const tile = &xd->tile;
2337 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
2338 int plane, i, mi_step;
2339 const int bottom_available = mi_row + xd->n8_h < tile->mi_row_end &&
Jingning Han91f01fd2017-01-18 17:16:40 -08002340 (mi_row + xd->n8_h) % MI_SIZE != 0 &&
Yue Chen86ae7b12017-01-11 17:04:29 -08002341 (mi_row + xd->n8_h) < cm->mi_rows;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002342#if CONFIG_HIGHBITDEPTH
Yue Chen86ae7b12017-01-11 17:04:29 -08002343 int is_hbd = (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002344#endif // CONFIG_HIGHBITDEPTH
Yue Chen86ae7b12017-01-11 17:04:29 -08002345
2346 // handle bottom row
2347 for (i = 0; bottom_available && i < AOMMIN(xd->n8_w, cm->mi_cols - mi_col);
2348 i += mi_step) {
2349 int mi_row_offset = xd->n8_h;
2350 int mi_col_offset = i;
2351 MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
2352 MB_MODE_INFO *mbmi = &mi->mbmi;
2353 int overlap;
2354
Jingning Han91f01fd2017-01-18 17:16:40 -08002355 mi_step = AOMMIN(xd->n8_w, mi_size_wide[mbmi->sb_type]);
Yue Chen86ae7b12017-01-11 17:04:29 -08002356
2357 if (!is_neighbor_overlappable(mbmi)) continue;
2358
2359 overlap = num_4x4_blocks_high_lookup[bsize] << 1;
2360
2361 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
2362 const struct macroblockd_plane *pd = &xd->plane[plane];
2363 const int bw = (mi_step * MI_SIZE) >> pd->subsampling_x;
2364 const int bh = overlap >> pd->subsampling_y;
2365 const int dst_stride = pd->dst.stride;
Jingning Han91f01fd2017-01-18 17:16:40 -08002366 uint8_t *dst =
2367 &pd->dst.buf[((i * MI_SIZE) >> pd->subsampling_x) +
2368 (((xd->n8_h * MI_SIZE - overlap) * dst_stride) >>
2369 pd->subsampling_y)];
Yue Chen86ae7b12017-01-11 17:04:29 -08002370 const int tmp_stride = bottom_stride[plane];
2371 const uint8_t *const tmp =
2372 &bottom[plane][((i * MI_SIZE) >> pd->subsampling_x) +
Jingning Han91f01fd2017-01-18 17:16:40 -08002373 (((xd->n8_h * MI_SIZE - overlap) * tmp_stride) >>
Yue Chen86ae7b12017-01-11 17:04:29 -08002374 pd->subsampling_y)];
2375 const uint8_t *const mask = av1_get_obmc_mask_flipped(bh);
2376
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002377#if CONFIG_HIGHBITDEPTH
Yue Chen86ae7b12017-01-11 17:04:29 -08002378 if (is_hbd)
2379 aom_highbd_blend_a64_vmask(dst, dst_stride, dst, dst_stride, tmp,
2380 tmp_stride, mask, bh, bw, xd->bd);
2381 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002382#endif // CONFIG_HIGHBITDEPTH
Yue Chen86ae7b12017-01-11 17:04:29 -08002383 aom_blend_a64_vmask(dst, dst_stride, dst, dst_stride, tmp, tmp_stride,
2384 mask, bh, bw);
2385 }
2386 } // each mi in the bottom row
2387
2388 // handle right column
Jingning Han91f01fd2017-01-18 17:16:40 -08002389 if (mi_col + xd->n8_w >= tile->mi_col_end ||
2390 (mi_col + xd->n8_w) % MI_SIZE == 0 || (mi_col + xd->n8_w) >= cm->mi_cols)
Yue Chen86ae7b12017-01-11 17:04:29 -08002391 return;
2392
2393 for (i = 0; i < AOMMIN(xd->n8_h, cm->mi_rows - mi_row); i += mi_step) {
2394 int mi_row_offset = i;
2395 int mi_col_offset = xd->n8_w;
2396 int overlap;
2397 MODE_INFO *mi = xd->mi[mi_col_offset + mi_row_offset * xd->mi_stride];
2398 MB_MODE_INFO *mbmi = &mi->mbmi;
2399
Jingning Han91f01fd2017-01-18 17:16:40 -08002400 mi_step = AOMMIN(xd->n8_h, mi_size_high[mbmi->sb_type]);
Yue Chen86ae7b12017-01-11 17:04:29 -08002401
2402 if (!is_neighbor_overlappable(mbmi)) continue;
2403
2404 overlap = num_4x4_blocks_wide_lookup[bsize] << 1;
2405
2406 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
2407 const struct macroblockd_plane *pd = &xd->plane[plane];
2408 const int bw = overlap >> pd->subsampling_x;
2409 const int bh = (mi_step * MI_SIZE) >> pd->subsampling_y;
2410 const int dst_stride = pd->dst.stride;
2411 uint8_t *dst =
2412 &pd->dst.buf[((i * MI_SIZE * dst_stride) >> pd->subsampling_y) +
Jingning Han91f01fd2017-01-18 17:16:40 -08002413 ((xd->n8_w * MI_SIZE - overlap) >> pd->subsampling_x)];
Yue Chen86ae7b12017-01-11 17:04:29 -08002414 const int tmp_stride = right_stride[plane];
2415 const uint8_t *const tmp =
2416 &right[plane][((i * MI_SIZE * tmp_stride) >> pd->subsampling_y) +
Jingning Han91f01fd2017-01-18 17:16:40 -08002417 ((xd->n8_w * MI_SIZE - overlap) >> pd->subsampling_x)];
Yue Chen86ae7b12017-01-11 17:04:29 -08002418 const uint8_t *const mask = av1_get_obmc_mask_flipped(bw);
2419
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002420#if CONFIG_HIGHBITDEPTH
Yue Chen86ae7b12017-01-11 17:04:29 -08002421 if (is_hbd)
2422 aom_highbd_blend_a64_hmask(dst, dst_stride, dst, dst_stride, tmp,
2423 tmp_stride, mask, bh, bw, xd->bd);
2424 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002425#endif // CONFIG_HIGHBITDEPTH
Yue Chen86ae7b12017-01-11 17:04:29 -08002426 aom_blend_a64_hmask(dst, dst_stride, dst, dst_stride, tmp, tmp_stride,
2427 mask, bh, bw);
2428 }
2429 } // each mi in the right column
2430}
2431
2432// This function generates 4 sided obmc. (1) Prediction blocks generated by
2433// bottom and right motion vectors are calculated. (2) Combine them with the
2434// original prediction block (which should be pre-stored in xd->plane[].dst.buf
2435// before calling this function). The results is updated in xd->plane[].dst.buf
2436// (3) Call causal obmc prediction function, which will generate left and above
2437// preds, and then merge them and xd->plane[].dst.buf.
2438void av1_build_ncobmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd,
2439 int mi_row, int mi_col) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002440#if CONFIG_HIGHBITDEPTH
Yue Chen86ae7b12017-01-11 17:04:29 -08002441 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
2442 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[2 * MAX_MB_PLANE * MAX_SB_SQUARE]);
2443#else
2444 DECLARE_ALIGNED(16, uint8_t, tmp_buf1[MAX_MB_PLANE * MAX_SB_SQUARE]);
2445 DECLARE_ALIGNED(16, uint8_t, tmp_buf2[MAX_MB_PLANE * MAX_SB_SQUARE]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002446#endif // CONFIG_HIGHBITDEPTH
Yue Chen86ae7b12017-01-11 17:04:29 -08002447 uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE];
2448 int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2449 int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2450 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2451 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2452 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2453 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
2454
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002455#if CONFIG_HIGHBITDEPTH
Yue Chen86ae7b12017-01-11 17:04:29 -08002456 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2457 int len = sizeof(uint16_t);
2458 dst_buf1[0] = CONVERT_TO_BYTEPTR(tmp_buf1);
2459 dst_buf1[1] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * len);
2460 dst_buf1[2] = CONVERT_TO_BYTEPTR(tmp_buf1 + MAX_SB_SQUARE * 2 * len);
2461 dst_buf2[0] = CONVERT_TO_BYTEPTR(tmp_buf2);
2462 dst_buf2[1] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * len);
2463 dst_buf2[2] = CONVERT_TO_BYTEPTR(tmp_buf2 + MAX_SB_SQUARE * 2 * len);
2464 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002465#endif // CONFIG_HIGHBITDEPTH
Yue Chen86ae7b12017-01-11 17:04:29 -08002466 dst_buf1[0] = tmp_buf1;
2467 dst_buf1[1] = tmp_buf1 + MAX_SB_SQUARE;
2468 dst_buf1[2] = tmp_buf1 + MAX_SB_SQUARE * 2;
2469 dst_buf2[0] = tmp_buf2;
2470 dst_buf2[1] = tmp_buf2 + MAX_SB_SQUARE;
2471 dst_buf2[2] = tmp_buf2 + MAX_SB_SQUARE * 2;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002472#if CONFIG_HIGHBITDEPTH
Yue Chen86ae7b12017-01-11 17:04:29 -08002473 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002474#endif // CONFIG_HIGHBITDEPTH
Yue Chen86ae7b12017-01-11 17:04:29 -08002475
Yue Chen86ae7b12017-01-11 17:04:29 -08002476 av1_build_prediction_by_bottom_preds(cm, xd, mi_row, mi_col, dst_buf1,
2477 dst_width1, dst_height1, dst_stride1);
2478 av1_build_prediction_by_right_preds(cm, xd, mi_row, mi_col, dst_buf2,
2479 dst_width2, dst_height2, dst_stride2);
2480 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
2481 av1_merge_dst_bottom_right_preds(cm, xd, mi_row, mi_col, dst_buf1,
2482 dst_stride1, dst_buf2, dst_stride2);
2483 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
2484 av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
2485 av1_setup_dst_planes(xd->plane, get_frame_new_buffer(cm), mi_row, mi_col);
2486}
2487#endif // CONFIG_NCOBMC
Yue Chencb60b182016-10-13 15:18:22 -07002488#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07002489
2490#if CONFIG_EXT_INTER
Jingning Han61418bb2017-01-23 17:12:48 -08002491/* clang-format off */
Yaowu Xuc27fc142016-08-22 16:08:15 -07002492#if CONFIG_EXT_PARTITION
2493static const int ii_weights1d[MAX_SB_SIZE] = {
2494 102, 100, 97, 95, 92, 90, 88, 86, 84, 82, 80, 78, 76, 74, 73, 71, 69, 68, 67,
2495 65, 64, 62, 61, 60, 59, 58, 57, 55, 54, 53, 52, 52, 51, 50, 49, 48, 47, 47,
2496 46, 45, 45, 44, 43, 43, 42, 41, 41, 40, 40, 39, 39, 38, 38, 38, 37, 37, 36,
2497 36, 36, 35, 35, 35, 34, 34, 34, 33, 33, 33, 33, 32, 32, 32, 32, 32, 31, 31,
2498 31, 31, 31, 30, 30, 30, 30, 30, 30, 30, 29, 29, 29, 29, 29, 29, 29, 29, 28,
2499 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 27, 27, 27, 27, 27, 27, 27, 27,
2500 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
2501};
Jingning Han61418bb2017-01-23 17:12:48 -08002502static int ii_size_scales[BLOCK_SIZES] = {
2503#if CONFIG_CB4X4
2504 32, 32, 32,
2505#endif
2506 32, 16, 16, 16, 8, 8, 8, 4,
2507 4, 4, 2, 2, 2, 1, 1, 1,
2508};
Yaowu Xuc27fc142016-08-22 16:08:15 -07002509#else
2510static const int ii_weights1d[MAX_SB_SIZE] = {
2511 102, 100, 97, 95, 92, 90, 88, 86, 84, 82, 80, 78, 76, 74, 73, 71,
2512 69, 68, 67, 65, 64, 62, 61, 60, 59, 58, 57, 55, 54, 53, 52, 52,
2513 51, 50, 49, 48, 47, 47, 46, 45, 45, 44, 43, 43, 42, 41, 41, 40,
2514 40, 39, 39, 38, 38, 38, 37, 37, 36, 36, 36, 35, 35, 35, 34, 34,
2515};
Jingning Han61418bb2017-01-23 17:12:48 -08002516static int ii_size_scales[BLOCK_SIZES] = {
2517#if CONFIG_CB4X4
2518 16, 16, 16,
2519#endif
2520 16, 8, 8, 8, 4, 4, 4,
2521 2, 2, 2, 1, 1, 1,
2522};
2523/* clang-format on */
Yaowu Xuc27fc142016-08-22 16:08:15 -07002524#endif // CONFIG_EXT_PARTITION
2525
2526static void combine_interintra(INTERINTRA_MODE mode, int use_wedge_interintra,
2527 int wedge_index, int wedge_sign,
2528 BLOCK_SIZE bsize, BLOCK_SIZE plane_bsize,
2529 uint8_t *comppred, int compstride,
2530 const uint8_t *interpred, int interstride,
2531 const uint8_t *intrapred, int intrastride) {
Jingning Hanae5cfde2016-11-30 12:01:44 -08002532 const int bw = block_size_wide[plane_bsize];
2533 const int bh = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002534 const int size_scale = ii_size_scales[plane_bsize];
2535 int i, j;
2536
2537 if (use_wedge_interintra) {
2538 if (is_interintra_wedge_used(bsize)) {
2539 const uint8_t *mask =
Yaowu Xuf883b422016-08-30 14:01:10 -07002540 av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002541 const int subw = 2 * num_4x4_blocks_wide_lookup[bsize] == bw;
2542 const int subh = 2 * num_4x4_blocks_high_lookup[bsize] == bh;
Jingning Hanae5cfde2016-11-30 12:01:44 -08002543 aom_blend_a64_mask(comppred, compstride, intrapred, intrastride,
2544 interpred, interstride, mask, block_size_wide[bsize],
2545 bh, bw, subh, subw);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002546 }
2547 return;
2548 }
2549
2550 switch (mode) {
2551 case II_V_PRED:
2552 for (i = 0; i < bh; ++i) {
2553 for (j = 0; j < bw; ++j) {
2554 int scale = ii_weights1d[i * size_scale];
2555 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002556 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002557 interpred[i * interstride + j]);
2558 }
2559 }
2560 break;
2561
2562 case II_H_PRED:
2563 for (i = 0; i < bh; ++i) {
2564 for (j = 0; j < bw; ++j) {
2565 int scale = ii_weights1d[j * size_scale];
2566 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002567 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002568 interpred[i * interstride + j]);
2569 }
2570 }
2571 break;
2572
2573 case II_D63_PRED:
2574 case II_D117_PRED:
2575 for (i = 0; i < bh; ++i) {
2576 for (j = 0; j < bw; ++j) {
2577 int scale = (ii_weights1d[i * size_scale] * 3 +
2578 ii_weights1d[j * size_scale]) >>
2579 2;
2580 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002581 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002582 interpred[i * interstride + j]);
2583 }
2584 }
2585 break;
2586
2587 case II_D207_PRED:
2588 case II_D153_PRED:
2589 for (i = 0; i < bh; ++i) {
2590 for (j = 0; j < bw; ++j) {
2591 int scale = (ii_weights1d[j * size_scale] * 3 +
2592 ii_weights1d[i * size_scale]) >>
2593 2;
2594 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002595 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002596 interpred[i * interstride + j]);
2597 }
2598 }
2599 break;
2600
2601 case II_D135_PRED:
2602 for (i = 0; i < bh; ++i) {
2603 for (j = 0; j < bw; ++j) {
2604 int scale = ii_weights1d[(i < j ? i : j) * size_scale];
2605 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002606 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002607 interpred[i * interstride + j]);
2608 }
2609 }
2610 break;
2611
2612 case II_D45_PRED:
2613 for (i = 0; i < bh; ++i) {
2614 for (j = 0; j < bw; ++j) {
2615 int scale =
2616 (ii_weights1d[i * size_scale] + ii_weights1d[j * size_scale]) >>
2617 1;
2618 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002619 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002620 interpred[i * interstride + j]);
2621 }
2622 }
2623 break;
2624
2625 case II_TM_PRED:
2626 case II_DC_PRED:
2627 default:
2628 for (i = 0; i < bh; ++i) {
2629 for (j = 0; j < bw; ++j) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002630 comppred[i * compstride + j] = AOM_BLEND_AVG(
Yaowu Xuc27fc142016-08-22 16:08:15 -07002631 intrapred[i * intrastride + j], interpred[i * interstride + j]);
2632 }
2633 }
2634 break;
2635 }
2636}
2637
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002638#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002639static void combine_interintra_highbd(
2640 INTERINTRA_MODE mode, int use_wedge_interintra, int wedge_index,
2641 int wedge_sign, BLOCK_SIZE bsize, BLOCK_SIZE plane_bsize,
2642 uint8_t *comppred8, int compstride, const uint8_t *interpred8,
2643 int interstride, const uint8_t *intrapred8, int intrastride, int bd) {
Jingning Hanae5cfde2016-11-30 12:01:44 -08002644 const int bw = block_size_wide[plane_bsize];
2645 const int bh = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002646 const int size_scale = ii_size_scales[plane_bsize];
2647 int i, j;
2648
2649 uint16_t *comppred = CONVERT_TO_SHORTPTR(comppred8);
2650 const uint16_t *interpred = CONVERT_TO_SHORTPTR(interpred8);
2651 const uint16_t *intrapred = CONVERT_TO_SHORTPTR(intrapred8);
2652
2653 if (use_wedge_interintra) {
2654 if (is_interintra_wedge_used(bsize)) {
2655 const uint8_t *mask =
Yaowu Xuf883b422016-08-30 14:01:10 -07002656 av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002657 const int subh = 2 * num_4x4_blocks_high_lookup[bsize] == bh;
2658 const int subw = 2 * num_4x4_blocks_wide_lookup[bsize] == bw;
Yaowu Xuf883b422016-08-30 14:01:10 -07002659 aom_highbd_blend_a64_mask(comppred8, compstride, intrapred8, intrastride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002660 interpred8, interstride, mask, bw, bh, bw, subh,
2661 subw, bd);
2662 }
2663 return;
2664 }
2665
2666 switch (mode) {
2667 case II_V_PRED:
2668 for (i = 0; i < bh; ++i) {
2669 for (j = 0; j < bw; ++j) {
2670 int scale = ii_weights1d[i * size_scale];
2671 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002672 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002673 interpred[i * interstride + j]);
2674 }
2675 }
2676 break;
2677
2678 case II_H_PRED:
2679 for (i = 0; i < bh; ++i) {
2680 for (j = 0; j < bw; ++j) {
2681 int scale = ii_weights1d[j * size_scale];
2682 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002683 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002684 interpred[i * interstride + j]);
2685 }
2686 }
2687 break;
2688
2689 case II_D63_PRED:
2690 case II_D117_PRED:
2691 for (i = 0; i < bh; ++i) {
2692 for (j = 0; j < bw; ++j) {
2693 int scale = (ii_weights1d[i * size_scale] * 3 +
2694 ii_weights1d[j * size_scale]) >>
2695 2;
2696 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002697 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002698 interpred[i * interstride + j]);
2699 }
2700 }
2701 break;
2702
2703 case II_D207_PRED:
2704 case II_D153_PRED:
2705 for (i = 0; i < bh; ++i) {
2706 for (j = 0; j < bw; ++j) {
2707 int scale = (ii_weights1d[j * size_scale] * 3 +
2708 ii_weights1d[i * size_scale]) >>
2709 2;
2710 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002711 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002712 interpred[i * interstride + j]);
2713 }
2714 }
2715 break;
2716
2717 case II_D135_PRED:
2718 for (i = 0; i < bh; ++i) {
2719 for (j = 0; j < bw; ++j) {
2720 int scale = ii_weights1d[(i < j ? i : j) * size_scale];
2721 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002722 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002723 interpred[i * interstride + j]);
2724 }
2725 }
2726 break;
2727
2728 case II_D45_PRED:
2729 for (i = 0; i < bh; ++i) {
2730 for (j = 0; j < bw; ++j) {
2731 int scale =
2732 (ii_weights1d[i * size_scale] + ii_weights1d[j * size_scale]) >>
2733 1;
2734 comppred[i * compstride + j] =
Yaowu Xuf883b422016-08-30 14:01:10 -07002735 AOM_BLEND_A256(scale, intrapred[i * intrastride + j],
Yaowu Xuc27fc142016-08-22 16:08:15 -07002736 interpred[i * interstride + j]);
2737 }
2738 }
2739 break;
2740
2741 case II_TM_PRED:
2742 case II_DC_PRED:
2743 default:
2744 for (i = 0; i < bh; ++i) {
2745 for (j = 0; j < bw; ++j) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002746 comppred[i * compstride + j] = AOM_BLEND_AVG(
Yaowu Xuc27fc142016-08-22 16:08:15 -07002747 interpred[i * interstride + j], intrapred[i * intrastride + j]);
2748 }
2749 }
2750 break;
2751 }
2752}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002753#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002754
Yaowu Xuf883b422016-08-30 14:01:10 -07002755void av1_build_intra_predictors_for_interintra(MACROBLOCKD *xd,
2756 BLOCK_SIZE bsize, int plane,
David Barkerac37fa32016-12-02 12:30:21 +00002757 BUFFER_SET *ctx, uint8_t *dst,
2758 int dst_stride) {
David Barker839467f2017-01-19 11:06:15 +00002759 struct macroblockd_plane *const pd = &xd->plane[plane];
2760 BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, &xd->plane[plane]);
2761 PREDICTION_MODE mode =
2762 interintra_to_intra_mode[xd->mi[0]->mbmi.interintra_mode];
2763
2764 av1_predict_intra_block(xd, pd->width, pd->height, plane_bsize, mode,
2765 ctx->plane[plane], ctx->stride[plane], dst,
2766 dst_stride, 0, 0, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002767}
2768
Yaowu Xuf883b422016-08-30 14:01:10 -07002769void av1_combine_interintra(MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane,
2770 const uint8_t *inter_pred, int inter_stride,
2771 const uint8_t *intra_pred, int intra_stride) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002772 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, &xd->plane[plane]);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002773#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002774 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2775 combine_interintra_highbd(
2776 xd->mi[0]->mbmi.interintra_mode, xd->mi[0]->mbmi.use_wedge_interintra,
2777 xd->mi[0]->mbmi.interintra_wedge_index,
2778 xd->mi[0]->mbmi.interintra_wedge_sign, bsize, plane_bsize,
2779 xd->plane[plane].dst.buf, xd->plane[plane].dst.stride, inter_pred,
2780 inter_stride, intra_pred, intra_stride, xd->bd);
2781 return;
2782 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002783#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002784 combine_interintra(xd->mi[0]->mbmi.interintra_mode,
2785 xd->mi[0]->mbmi.use_wedge_interintra,
2786 xd->mi[0]->mbmi.interintra_wedge_index,
2787 xd->mi[0]->mbmi.interintra_wedge_sign, bsize, plane_bsize,
2788 xd->plane[plane].dst.buf, xd->plane[plane].dst.stride,
2789 inter_pred, inter_stride, intra_pred, intra_stride);
2790}
2791
Yaowu Xuf883b422016-08-30 14:01:10 -07002792void av1_build_interintra_predictors_sby(MACROBLOCKD *xd, uint8_t *ypred,
David Barkerac37fa32016-12-02 12:30:21 +00002793 int ystride, BUFFER_SET *ctx,
2794 BLOCK_SIZE bsize) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002795#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002796 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2797 DECLARE_ALIGNED(16, uint16_t, intrapredictor[MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07002798 av1_build_intra_predictors_for_interintra(
David Barkerac37fa32016-12-02 12:30:21 +00002799 xd, bsize, 0, ctx, CONVERT_TO_BYTEPTR(intrapredictor), MAX_SB_SIZE);
Yaowu Xuf883b422016-08-30 14:01:10 -07002800 av1_combine_interintra(xd, bsize, 0, ypred, ystride,
2801 CONVERT_TO_BYTEPTR(intrapredictor), MAX_SB_SIZE);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002802 return;
2803 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002804#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002805 {
2806 DECLARE_ALIGNED(16, uint8_t, intrapredictor[MAX_SB_SQUARE]);
David Barkerac37fa32016-12-02 12:30:21 +00002807 av1_build_intra_predictors_for_interintra(xd, bsize, 0, ctx, intrapredictor,
Yaowu Xuf883b422016-08-30 14:01:10 -07002808 MAX_SB_SIZE);
2809 av1_combine_interintra(xd, bsize, 0, ypred, ystride, intrapredictor,
2810 MAX_SB_SIZE);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002811 }
2812}
2813
Yaowu Xuf883b422016-08-30 14:01:10 -07002814void av1_build_interintra_predictors_sbc(MACROBLOCKD *xd, uint8_t *upred,
David Barkerac37fa32016-12-02 12:30:21 +00002815 int ustride, BUFFER_SET *ctx,
2816 int plane, BLOCK_SIZE bsize) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002817#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002818 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2819 DECLARE_ALIGNED(16, uint16_t, uintrapredictor[MAX_SB_SQUARE]);
Yaowu Xuf883b422016-08-30 14:01:10 -07002820 av1_build_intra_predictors_for_interintra(
David Barkerac37fa32016-12-02 12:30:21 +00002821 xd, bsize, plane, ctx, CONVERT_TO_BYTEPTR(uintrapredictor),
2822 MAX_SB_SIZE);
Yaowu Xuf883b422016-08-30 14:01:10 -07002823 av1_combine_interintra(xd, bsize, plane, upred, ustride,
2824 CONVERT_TO_BYTEPTR(uintrapredictor), MAX_SB_SIZE);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002825 return;
2826 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002827#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002828 {
2829 DECLARE_ALIGNED(16, uint8_t, uintrapredictor[MAX_SB_SQUARE]);
David Barkerac37fa32016-12-02 12:30:21 +00002830 av1_build_intra_predictors_for_interintra(xd, bsize, plane, ctx,
2831 uintrapredictor, MAX_SB_SIZE);
Yaowu Xuf883b422016-08-30 14:01:10 -07002832 av1_combine_interintra(xd, bsize, plane, upred, ustride, uintrapredictor,
2833 MAX_SB_SIZE);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002834 }
2835}
2836
Yaowu Xuf883b422016-08-30 14:01:10 -07002837void av1_build_interintra_predictors_sbuv(MACROBLOCKD *xd, uint8_t *upred,
2838 uint8_t *vpred, int ustride,
David Barkerac37fa32016-12-02 12:30:21 +00002839 int vstride, BUFFER_SET *ctx,
2840 BLOCK_SIZE bsize) {
2841 av1_build_interintra_predictors_sbc(xd, upred, ustride, ctx, 1, bsize);
2842 av1_build_interintra_predictors_sbc(xd, vpred, vstride, ctx, 2, bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002843}
2844
Yaowu Xuf883b422016-08-30 14:01:10 -07002845void av1_build_interintra_predictors(MACROBLOCKD *xd, uint8_t *ypred,
2846 uint8_t *upred, uint8_t *vpred,
2847 int ystride, int ustride, int vstride,
David Barkerac37fa32016-12-02 12:30:21 +00002848 BUFFER_SET *ctx, BLOCK_SIZE bsize) {
2849 av1_build_interintra_predictors_sby(xd, ypred, ystride, ctx, bsize);
2850 av1_build_interintra_predictors_sbuv(xd, upred, vpred, ustride, vstride, ctx,
Yaowu Xuf883b422016-08-30 14:01:10 -07002851 bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002852}
2853
2854// Builds the inter-predictor for the single ref case
2855// for use in the encoder to search the wedges efficiently.
2856static void build_inter_predictors_single_buf(MACROBLOCKD *xd, int plane,
2857 int block, int bw, int bh, int x,
2858 int y, int w, int h, int mi_x,
2859 int mi_y, int ref,
2860 uint8_t *const ext_dst,
2861 int ext_dst_stride) {
2862 struct macroblockd_plane *const pd = &xd->plane[plane];
2863 const MODE_INFO *mi = xd->mi[0];
2864
2865 const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
2866 struct buf_2d *const pre_buf = &pd->pre[ref];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002867#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002868 uint8_t *const dst =
2869 (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH ? CONVERT_TO_BYTEPTR(ext_dst)
2870 : ext_dst) +
2871 ext_dst_stride * y + x;
2872#else
2873 uint8_t *const dst = ext_dst + ext_dst_stride * y + x;
2874#endif
2875 const MV mv = mi->mbmi.sb_type < BLOCK_8X8
2876 ? average_split_mvs(pd, mi, ref, block)
2877 : mi->mbmi.mv[ref].as_mv;
2878
2879 // TODO(jkoleszar): This clamping is done in the incorrect place for the
2880 // scaling case. It needs to be done on the scaled MV, not the pre-scaling
2881 // MV. Note however that it performs the subsampling aware scaling so
2882 // that the result is always q4.
2883 // mv_precision precision is MV_PRECISION_Q4.
2884 const MV mv_q4 = clamp_mv_to_umv_border_sb(xd, &mv, bw, bh, pd->subsampling_x,
2885 pd->subsampling_y);
2886
2887 uint8_t *pre;
2888 MV32 scaled_mv;
2889 int xs, ys, subpel_x, subpel_y;
Yaowu Xuf883b422016-08-30 14:01:10 -07002890 const int is_scaled = av1_is_scaled(sf);
Angie Chiange3a4c1c2017-02-10 16:26:49 -08002891 ConvolveParams conv_params = get_conv_params(0, plane);
Sarah Parker4c10a3c2017-04-10 19:37:59 -07002892#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
2893 WarpTypesAllowed warp_types;
Sarah Parkerc2d38712017-01-24 15:15:41 -08002894#if CONFIG_GLOBAL_MOTION
2895 WarpedMotionParams *const wm = &xd->global_motion[mi->mbmi.ref_frame[ref]];
Sarah Parker4c10a3c2017-04-10 19:37:59 -07002896 warp_types.global_warp_allowed = is_global_mv_block(mi, block, wm->wmtype);
Sarah Parkerc2d38712017-01-24 15:15:41 -08002897#endif // CONFIG_GLOBAL_MOTION
Sarah Parker4c10a3c2017-04-10 19:37:59 -07002898#if CONFIG_WARPED_MOTION
2899 warp_types.local_warp_allowed = mi->mbmi.motion_mode == WARPED_CAUSAL;
2900#endif // CONFIG_WARPED_MOTION
2901#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yaowu Xuc27fc142016-08-22 16:08:15 -07002902
2903 if (is_scaled) {
2904 pre = pre_buf->buf + scaled_buffer_offset(x, y, pre_buf->stride, sf);
Yaowu Xuf883b422016-08-30 14:01:10 -07002905 scaled_mv = av1_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002906 xs = sf->x_step_q4;
2907 ys = sf->y_step_q4;
2908 } else {
2909 pre = pre_buf->buf + (y * pre_buf->stride + x);
2910 scaled_mv.row = mv_q4.row;
2911 scaled_mv.col = mv_q4.col;
2912 xs = ys = 16;
2913 }
2914
2915 subpel_x = scaled_mv.col & SUBPEL_MASK;
2916 subpel_y = scaled_mv.row & SUBPEL_MASK;
2917 pre += (scaled_mv.row >> SUBPEL_BITS) * pre_buf->stride +
2918 (scaled_mv.col >> SUBPEL_BITS);
2919
Yaowu Xuf883b422016-08-30 14:01:10 -07002920 av1_make_inter_predictor(pre, pre_buf->stride, dst, ext_dst_stride, subpel_x,
Angie Chiang9f45bc42017-01-13 16:27:54 -08002921 subpel_y, sf, w, h, &conv_params,
Sarah Parkerc2d38712017-01-24 15:15:41 -08002922 mi->mbmi.interp_filter,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07002923#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
2924 &warp_types, (mi_x >> pd->subsampling_x) + x,
Sarah Parkerc2d38712017-01-24 15:15:41 -08002925 (mi_y >> pd->subsampling_y) + y, plane, ref,
Sarah Parker4c10a3c2017-04-10 19:37:59 -07002926#endif // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
Yue Chen74a77542017-03-14 17:30:42 -07002927#if CONFIG_MOTION_VAR
2928 0, 0,
2929#endif
Sarah Parkerc2d38712017-01-24 15:15:41 -08002930 xs, ys, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002931}
2932
Yaowu Xuf883b422016-08-30 14:01:10 -07002933void av1_build_inter_predictors_for_planes_single_buf(
Yaowu Xuc27fc142016-08-22 16:08:15 -07002934 MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane_from, int plane_to, int mi_row,
2935 int mi_col, int ref, uint8_t *ext_dst[3], int ext_dst_stride[3]) {
2936 int plane;
2937 const int mi_x = mi_col * MI_SIZE;
2938 const int mi_y = mi_row * MI_SIZE;
2939 for (plane = plane_from; plane <= plane_to; ++plane) {
2940 const BLOCK_SIZE plane_bsize =
2941 get_plane_block_size(bsize, &xd->plane[plane]);
2942 const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize];
2943 const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize];
Jingning Han691a6902016-11-30 14:53:44 -08002944 const int bw = block_size_wide[plane_bsize];
2945 const int bh = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002946
Jingning Han61418bb2017-01-23 17:12:48 -08002947 if (xd->mi[0]->mbmi.sb_type < BLOCK_8X8 && !CONFIG_CB4X4) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002948 int x, y;
2949 assert(bsize == BLOCK_8X8);
2950 for (y = 0; y < num_4x4_h; ++y)
2951 for (x = 0; x < num_4x4_w; ++x)
2952 build_inter_predictors_single_buf(
2953 xd, plane, y * 2 + x, bw, bh, 4 * x, 4 * y, 4, 4, mi_x, mi_y, ref,
2954 ext_dst[plane], ext_dst_stride[plane]);
2955 } else {
2956 build_inter_predictors_single_buf(xd, plane, 0, bw, bh, 0, 0, bw, bh,
2957 mi_x, mi_y, ref, ext_dst[plane],
2958 ext_dst_stride[plane]);
2959 }
2960 }
2961}
2962
2963static void build_wedge_inter_predictor_from_buf(
David Barker426a9972017-01-27 11:03:11 +00002964 MACROBLOCKD *xd, int plane, int x, int y, int w, int h,
2965#if CONFIG_SUPERTX
2966 int wedge_offset_x, int wedge_offset_y,
2967#endif // CONFIG_SUPERTX
2968 uint8_t *ext_dst0, int ext_dst_stride0, uint8_t *ext_dst1,
2969 int ext_dst_stride1) {
Sarah Parker569edda2016-12-14 14:57:38 -08002970 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002971 const int is_compound = has_second_ref(mbmi);
2972 MACROBLOCKD_PLANE *const pd = &xd->plane[plane];
2973 struct buf_2d *const dst_buf = &pd->dst;
2974 uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x;
Sarah Parker569edda2016-12-14 14:57:38 -08002975 INTERINTER_COMPOUND_DATA *comp_data = &mbmi->interinter_compound_data;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002976
Sarah Parker6fdc8532016-11-16 17:47:13 -08002977 if (is_compound &&
2978 is_masked_compound_type(mbmi->interinter_compound_data.type)) {
Sarah Parker569edda2016-12-14 14:57:38 -08002979#if CONFIG_COMPOUND_SEGMENT
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002980#if CONFIG_HIGHBITDEPTH
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08002981 if (!plane && comp_data->type == COMPOUND_SEG) {
2982 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
2983 build_compound_seg_mask_highbd(
2984 comp_data->seg_mask, comp_data->mask_type,
2985 CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0,
2986 CONVERT_TO_BYTEPTR(ext_dst1), ext_dst_stride1, mbmi->sb_type, h, w,
2987 xd->bd);
2988 else
2989 build_compound_seg_mask(comp_data->seg_mask, comp_data->mask_type,
2990 ext_dst0, ext_dst_stride0, ext_dst1,
2991 ext_dst_stride1, mbmi->sb_type, h, w);
2992 }
2993#else
Sarah Parker569edda2016-12-14 14:57:38 -08002994 if (!plane && comp_data->type == COMPOUND_SEG)
Sarah Parkerb9f757c2017-01-06 17:12:24 -08002995 build_compound_seg_mask(comp_data->seg_mask, comp_data->mask_type,
2996 ext_dst0, ext_dst_stride0, ext_dst1,
Sarah Parker569edda2016-12-14 14:57:38 -08002997 ext_dst_stride1, mbmi->sb_type, h, w);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002998#endif // CONFIG_HIGHBITDEPTH
Sarah Parker569edda2016-12-14 14:57:38 -08002999#endif // CONFIG_COMPOUND_SEGMENT
David Barker426a9972017-01-27 11:03:11 +00003000
3001#if CONFIG_SUPERTX
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003002#if CONFIG_HIGHBITDEPTH
David Barker426a9972017-01-27 11:03:11 +00003003 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
3004 build_masked_compound_wedge_extend_highbd(
3005 dst, dst_buf->stride, CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0,
3006 CONVERT_TO_BYTEPTR(ext_dst1), ext_dst_stride1, comp_data,
3007 mbmi->sb_type, wedge_offset_x, wedge_offset_y, h, w, xd->bd);
3008 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003009#endif // CONFIG_HIGHBITDEPTH
David Barker426a9972017-01-27 11:03:11 +00003010 build_masked_compound_wedge_extend(
3011 dst, dst_buf->stride, ext_dst0, ext_dst_stride0, ext_dst1,
3012 ext_dst_stride1, comp_data, mbmi->sb_type, wedge_offset_x,
3013 wedge_offset_y, h, w);
3014#else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003015#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003016 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08003017 build_masked_compound_highbd(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003018 dst, dst_buf->stride, CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0,
Debargha Mukherjee1edf9a32017-01-07 18:54:20 -08003019 CONVERT_TO_BYTEPTR(ext_dst1), ext_dst_stride1, comp_data,
3020 mbmi->sb_type, h, w, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003021 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003022#endif // CONFIG_HIGHBITDEPTH
Sarah Parker6fdc8532016-11-16 17:47:13 -08003023 build_masked_compound(dst, dst_buf->stride, ext_dst0, ext_dst_stride0,
3024 ext_dst1, ext_dst_stride1, comp_data, mbmi->sb_type,
3025 h, w);
David Barker426a9972017-01-27 11:03:11 +00003026#endif // CONFIG_SUPERTX
Yaowu Xuc27fc142016-08-22 16:08:15 -07003027 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003028#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003029 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
Yaowu Xuf883b422016-08-30 14:01:10 -07003030 aom_highbd_convolve_copy(CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003031 dst, dst_buf->stride, NULL, 0, NULL, 0, w, h,
3032 xd->bd);
3033 else
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003034#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07003035 aom_convolve_copy(ext_dst0, ext_dst_stride0, dst, dst_buf->stride, NULL,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003036 0, NULL, 0, w, h);
3037 }
3038}
3039
David Barker426a9972017-01-27 11:03:11 +00003040void av1_build_wedge_inter_predictor_from_buf(
3041 MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane_from, int plane_to,
3042#if CONFIG_SUPERTX
3043 int wedge_offset_x, int wedge_offset_y,
3044#endif // CONFIG_SUPERTX
3045 uint8_t *ext_dst0[3], int ext_dst_stride0[3], uint8_t *ext_dst1[3],
3046 int ext_dst_stride1[3]) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003047 int plane;
3048 for (plane = plane_from; plane <= plane_to; ++plane) {
3049 const BLOCK_SIZE plane_bsize =
3050 get_plane_block_size(bsize, &xd->plane[plane]);
3051 const int num_4x4_w = num_4x4_blocks_wide_lookup[plane_bsize];
3052 const int num_4x4_h = num_4x4_blocks_high_lookup[plane_bsize];
3053
Jingning Han61418bb2017-01-23 17:12:48 -08003054 if (xd->mi[0]->mbmi.sb_type < BLOCK_8X8 && !CONFIG_CB4X4) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003055 int x, y;
3056 assert(bsize == BLOCK_8X8);
3057 for (y = 0; y < num_4x4_h; ++y)
3058 for (x = 0; x < num_4x4_w; ++x)
3059 build_wedge_inter_predictor_from_buf(
David Barker426a9972017-01-27 11:03:11 +00003060 xd, plane, 4 * x, 4 * y, 4, 4,
3061#if CONFIG_SUPERTX
3062 wedge_offset_x, wedge_offset_y,
3063#endif // CONFIG_SUPERTX
3064 ext_dst0[plane], ext_dst_stride0[plane], ext_dst1[plane],
3065 ext_dst_stride1[plane]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003066 } else {
Jingning Han61418bb2017-01-23 17:12:48 -08003067 const int bw = block_size_wide[plane_bsize];
3068 const int bh = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07003069 build_wedge_inter_predictor_from_buf(
David Barker426a9972017-01-27 11:03:11 +00003070 xd, plane, 0, 0, bw, bh,
3071#if CONFIG_SUPERTX
3072 wedge_offset_x, wedge_offset_y,
3073#endif // CONFIG_SUPERTX
3074 ext_dst0[plane], ext_dst_stride0[plane], ext_dst1[plane],
3075 ext_dst_stride1[plane]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003076 }
3077 }
3078}
3079#endif // CONFIG_EXT_INTER