1 /*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 *
4 * 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.
10 */
11
12 #include <math.h>
13
14 #include "./av1_rtcd.h"
15 #include "./aom_config.h"
16 #include "./aom_dsp_rtcd.h"
17 #include "aom_ports/system_state.h"
18
19 #if CONFIG_HIGHBITDEPTH
20 #include "aom_dsp/aom_dsp_common.h"
21 #endif // CONFIG_HIGHBITDEPTH
22 #include "aom_mem/aom_mem.h"
23 #include "aom_ports/mem.h"
24 #include "aom_ports/aom_once.h"
25 #include "av1/common/reconintra.h"
26 #include "av1/common/onyxc_int.h"
27 #if CONFIG_CFL
28 #include "av1/common/cfl.h"
29 #endif
30
31 enum {
32 NEED_LEFT = 1 << 1,
33 NEED_ABOVE = 1 << 2,
34 NEED_ABOVERIGHT = 1 << 3,
35 NEED_ABOVELEFT = 1 << 4,
36 NEED_BOTTOMLEFT = 1 << 5,
37 };
38
39 #if CONFIG_INTRA_EDGE
40 #define INTRA_EDGE_FILT 3
41 #define INTRA_EDGE_TAPS 5
42 #if CONFIG_INTRA_EDGE_UPSAMPLE
43 #define MAX_UPSAMPLE_SZ 12
44 #endif // CONFIG_INTRA_EDGE_UPSAMPLE
45 #endif // CONFIG_INTRA_EDGE
46
47 #define INTRA_USES_EXT_TRANSFORMS 1
48 #define INTRA_USES_RECT_TRANSFORMS \
49 (CONFIG_RECT_TX && (CONFIG_VAR_TX || CONFIG_EXT_TX))
50
51 static const uint8_t extend_modes[INTRA_MODES] = {
52 NEED_ABOVE | NEED_LEFT, // DC
53 NEED_ABOVE, // V
54 NEED_LEFT, // H
55 NEED_ABOVE | NEED_ABOVERIGHT, // D45
56 NEED_LEFT | NEED_ABOVE | NEED_ABOVELEFT, // D135
57 NEED_LEFT | NEED_ABOVE | NEED_ABOVELEFT, // D117
58 NEED_LEFT | NEED_ABOVE | NEED_ABOVELEFT, // D153
59 NEED_LEFT | NEED_BOTTOMLEFT, // D207
60 NEED_ABOVE | NEED_ABOVERIGHT, // D63
61 NEED_LEFT | NEED_ABOVE, // SMOOTH
62 #if CONFIG_SMOOTH_HV
63 NEED_LEFT | NEED_ABOVE, // SMOOTH_V
64 NEED_LEFT | NEED_ABOVE, // SMOOTH_H
65 #endif // CONFIG_SMOOTH_HV
66 NEED_LEFT | NEED_ABOVE | NEED_ABOVELEFT, // TM
67 };
68
69 static const uint16_t orders_128x128[1] = { 0 };
70 static const uint16_t orders_128x64[2] = { 0, 1 };
71 static const uint16_t orders_64x128[2] = { 0, 1 };
72 static const uint16_t orders_64x64[4] = {
73 0, 1, 2, 3,
74 };
75 static const uint16_t orders_64x32[8] = {
76 0, 2, 1, 3, 4, 6, 5, 7,
77 };
78 static const uint16_t orders_32x64[8] = {
79 0, 1, 2, 3, 4, 5, 6, 7,
80 };
81 static const uint16_t orders_32x32[16] = {
82 0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15,
83 };
84 static const uint16_t orders_32x16[32] = {
85 0, 2, 8, 10, 1, 3, 9, 11, 4, 6, 12, 14, 5, 7, 13, 15,
86 16, 18, 24, 26, 17, 19, 25, 27, 20, 22, 28, 30, 21, 23, 29, 31,
87 };
88 static const uint16_t orders_16x32[32] = {
89 0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15,
90 16, 17, 18, 19, 24, 25, 26, 27, 20, 21, 22, 23, 28, 29, 30, 31,
91 };
92 static const uint16_t orders_16x16[64] = {
93 0, 1, 4, 5, 16, 17, 20, 21, 2, 3, 6, 7, 18, 19, 22, 23,
94 8, 9, 12, 13, 24, 25, 28, 29, 10, 11, 14, 15, 26, 27, 30, 31,
95 32, 33, 36, 37, 48, 49, 52, 53, 34, 35, 38, 39, 50, 51, 54, 55,
96 40, 41, 44, 45, 56, 57, 60, 61, 42, 43, 46, 47, 58, 59, 62, 63,
97 };
98
99 static const uint16_t orders_64x16[16] = {
100 0, 4, 1, 5, 2, 6, 3, 7, 8, 12, 9, 13, 10, 14, 11, 15,
101 };
102 static const uint16_t orders_16x64[16] = {
103 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
104 };
105 static const uint16_t orders_32x8[64] = {
106 0, 4, 16, 20, 1, 5, 17, 21, 2, 6, 18, 22, 3, 7, 19, 23,
107 8, 12, 24, 28, 9, 13, 25, 29, 10, 14, 26, 30, 11, 15, 27, 31,
108 32, 36, 48, 52, 33, 37, 49, 53, 34, 38, 50, 54, 35, 39, 51, 55,
109 40, 44, 56, 60, 41, 45, 57, 61, 42, 46, 58, 62, 43, 47, 59, 63,
110 };
111 static const uint16_t orders_8x32[64] = {
112 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23,
113 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31,
114 32, 33, 34, 35, 36, 37, 38, 39, 48, 49, 50, 51, 52, 53, 54, 55,
115 40, 41, 42, 43, 44, 45, 46, 47, 56, 57, 58, 59, 60, 61, 62, 63,
116 };
117
118 #if CONFIG_EXT_PARTITION
119 static const uint16_t orders_16x4[256] = {
120 0, 4, 16, 20, 64, 68, 80, 84, 1, 5, 17, 21, 65, 69, 81,
121 85, 2, 6, 18, 22, 66, 70, 82, 86, 3, 7, 19, 23, 67, 71,
122 83, 87, 8, 12, 24, 28, 72, 76, 88, 92, 9, 13, 25, 29, 73,
123 77, 89, 93, 10, 14, 26, 30, 74, 78, 90, 94, 11, 15, 27, 31,
124 75, 79, 91, 95, 32, 36, 48, 52, 96, 100, 112, 116, 33, 37, 49,
125 53, 97, 101, 113, 117, 34, 38, 50, 54, 98, 102, 114, 118, 35, 39,
126 51, 55, 99, 103, 115, 119, 40, 44, 56, 60, 104, 108, 120, 124, 41,
127 45, 57, 61, 105, 109, 121, 125, 42, 46, 58, 62, 106, 110, 122, 126,
128 43, 47, 59, 63, 107, 111, 123, 127, 128, 132, 144, 148, 192, 196, 208,
129 212, 129, 133, 145, 149, 193, 197, 209, 213, 130, 134, 146, 150, 194, 198,
130 210, 214, 131, 135, 147, 151, 195, 199, 211, 215, 136, 140, 152, 156, 200,
131 204, 216, 220, 137, 141, 153, 157, 201, 205, 217, 221, 138, 142, 154, 158,
132 202, 206, 218, 222, 139, 143, 155, 159, 203, 207, 219, 223, 160, 164, 176,
133 180, 224, 228, 240, 244, 161, 165, 177, 181, 225, 229, 241, 245, 162, 166,
134 178, 182, 226, 230, 242, 246, 163, 167, 179, 183, 227, 231, 243, 247, 168,
135 172, 184, 188, 232, 236, 248, 252, 169, 173, 185, 189, 233, 237, 249, 253,
136 170, 174, 186, 190, 234, 238, 250, 254, 171, 175, 187, 191, 235, 239, 251,
137 255,
138 };
139 static const uint16_t orders_4x16[256] = {
140 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22,
141 23, 64, 65, 66, 67, 68, 69, 70, 71, 80, 81, 82, 83, 84, 85,
142 86, 87, 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28,
143 29, 30, 31, 72, 73, 74, 75, 76, 77, 78, 79, 88, 89, 90, 91,
144 92, 93, 94, 95, 32, 33, 34, 35, 36, 37, 38, 39, 48, 49, 50,
145 51, 52, 53, 54, 55, 96, 97, 98, 99, 100, 101, 102, 103, 112, 113,
146 114, 115, 116, 117, 118, 119, 40, 41, 42, 43, 44, 45, 46, 47, 56,
147 57, 58, 59, 60, 61, 62, 63, 104, 105, 106, 107, 108, 109, 110, 111,
148 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
149 135, 144, 145, 146, 147, 148, 149, 150, 151, 192, 193, 194, 195, 196, 197,
150 198, 199, 208, 209, 210, 211, 212, 213, 214, 215, 136, 137, 138, 139, 140,
151 141, 142, 143, 152, 153, 154, 155, 156, 157, 158, 159, 200, 201, 202, 203,
152 204, 205, 206, 207, 216, 217, 218, 219, 220, 221, 222, 223, 160, 161, 162,
153 163, 164, 165, 166, 167, 176, 177, 178, 179, 180, 181, 182, 183, 224, 225,
154 226, 227, 228, 229, 230, 231, 240, 241, 242, 243, 244, 245, 246, 247, 168,
155 169, 170, 171, 172, 173, 174, 175, 184, 185, 186, 187, 188, 189, 190, 191,
156 232, 233, 234, 235, 236, 237, 238, 239, 248, 249, 250, 251, 252, 253, 254,
157 255,
158 };
159 #endif
160
161 static const uint16_t orders_32x128[4] = {
162 0, 1, 2, 3,
163 };
164 static const uint16_t orders_128x32[4] = {
165 0, 1, 2, 3,
166 };
167
168 #if CONFIG_CB4X4 || CONFIG_EXT_PARTITION
169 static const uint16_t orders_16x8[128] = {
170 0, 2, 8, 10, 32, 34, 40, 42, 1, 3, 9, 11, 33, 35, 41, 43,
171 4, 6, 12, 14, 36, 38, 44, 46, 5, 7, 13, 15, 37, 39, 45, 47,
172 16, 18, 24, 26, 48, 50, 56, 58, 17, 19, 25, 27, 49, 51, 57, 59,
173 20, 22, 28, 30, 52, 54, 60, 62, 21, 23, 29, 31, 53, 55, 61, 63,
174 64, 66, 72, 74, 96, 98, 104, 106, 65, 67, 73, 75, 97, 99, 105, 107,
175 68, 70, 76, 78, 100, 102, 108, 110, 69, 71, 77, 79, 101, 103, 109, 111,
176 80, 82, 88, 90, 112, 114, 120, 122, 81, 83, 89, 91, 113, 115, 121, 123,
177 84, 86, 92, 94, 116, 118, 124, 126, 85, 87, 93, 95, 117, 119, 125, 127,
178 };
179 static const uint16_t orders_8x16[128] = {
180 0, 1, 2, 3, 8, 9, 10, 11, 32, 33, 34, 35, 40, 41, 42, 43,
181 4, 5, 6, 7, 12, 13, 14, 15, 36, 37, 38, 39, 44, 45, 46, 47,
182 16, 17, 18, 19, 24, 25, 26, 27, 48, 49, 50, 51, 56, 57, 58, 59,
183 20, 21, 22, 23, 28, 29, 30, 31, 52, 53, 54, 55, 60, 61, 62, 63,
184 64, 65, 66, 67, 72, 73, 74, 75, 96, 97, 98, 99, 104, 105, 106, 107,
185 68, 69, 70, 71, 76, 77, 78, 79, 100, 101, 102, 103, 108, 109, 110, 111,
186 80, 81, 82, 83, 88, 89, 90, 91, 112, 113, 114, 115, 120, 121, 122, 123,
187 84, 85, 86, 87, 92, 93, 94, 95, 116, 117, 118, 119, 124, 125, 126, 127,
188 };
189 static const uint16_t orders_8x8[256] = {
190 0, 1, 4, 5, 16, 17, 20, 21, 64, 65, 68, 69, 80, 81, 84,
191 85, 2, 3, 6, 7, 18, 19, 22, 23, 66, 67, 70, 71, 82, 83,
192 86, 87, 8, 9, 12, 13, 24, 25, 28, 29, 72, 73, 76, 77, 88,
193 89, 92, 93, 10, 11, 14, 15, 26, 27, 30, 31, 74, 75, 78, 79,
194 90, 91, 94, 95, 32, 33, 36, 37, 48, 49, 52, 53, 96, 97, 100,
195 101, 112, 113, 116, 117, 34, 35, 38, 39, 50, 51, 54, 55, 98, 99,
196 102, 103, 114, 115, 118, 119, 40, 41, 44, 45, 56, 57, 60, 61, 104,
197 105, 108, 109, 120, 121, 124, 125, 42, 43, 46, 47, 58, 59, 62, 63,
198 106, 107, 110, 111, 122, 123, 126, 127, 128, 129, 132, 133, 144, 145, 148,
199 149, 192, 193, 196, 197, 208, 209, 212, 213, 130, 131, 134, 135, 146, 147,
200 150, 151, 194, 195, 198, 199, 210, 211, 214, 215, 136, 137, 140, 141, 152,
201 153, 156, 157, 200, 201, 204, 205, 216, 217, 220, 221, 138, 139, 142, 143,
202 154, 155, 158, 159, 202, 203, 206, 207, 218, 219, 222, 223, 160, 161, 164,
203 165, 176, 177, 180, 181, 224, 225, 228, 229, 240, 241, 244, 245, 162, 163,
204 166, 167, 178, 179, 182, 183, 226, 227, 230, 231, 242, 243, 246, 247, 168,
205 169, 172, 173, 184, 185, 188, 189, 232, 233, 236, 237, 248, 249, 252, 253,
206 170, 171, 174, 175, 186, 187, 190, 191, 234, 235, 238, 239, 250, 251, 254,
207 255,
208 };
209
210 #if CONFIG_CB4X4 && CONFIG_EXT_PARTITION
211 static const uint16_t orders_4x8[512] = {
212 0, 1, 2, 3, 8, 9, 10, 11, 32, 33, 34, 35, 40, 41, 42,
213 43, 128, 129, 130, 131, 136, 137, 138, 139, 160, 161, 162, 163, 168, 169,
214 170, 171, 4, 5, 6, 7, 12, 13, 14, 15, 36, 37, 38, 39, 44,
215 45, 46, 47, 132, 133, 134, 135, 140, 141, 142, 143, 164, 165, 166, 167,
216 172, 173, 174, 175, 16, 17, 18, 19, 24, 25, 26, 27, 48, 49, 50,
217 51, 56, 57, 58, 59, 144, 145, 146, 147, 152, 153, 154, 155, 176, 177,
218 178, 179, 184, 185, 186, 187, 20, 21, 22, 23, 28, 29, 30, 31, 52,
219 53, 54, 55, 60, 61, 62, 63, 148, 149, 150, 151, 156, 157, 158, 159,
220 180, 181, 182, 183, 188, 189, 190, 191, 64, 65, 66, 67, 72, 73, 74,
221 75, 96, 97, 98, 99, 104, 105, 106, 107, 192, 193, 194, 195, 200, 201,
222 202, 203, 224, 225, 226, 227, 232, 233, 234, 235, 68, 69, 70, 71, 76,
223 77, 78, 79, 100, 101, 102, 103, 108, 109, 110, 111, 196, 197, 198, 199,
224 204, 205, 206, 207, 228, 229, 230, 231, 236, 237, 238, 239, 80, 81, 82,
225 83, 88, 89, 90, 91, 112, 113, 114, 115, 120, 121, 122, 123, 208, 209,
226 210, 211, 216, 217, 218, 219, 240, 241, 242, 243, 248, 249, 250, 251, 84,
227 85, 86, 87, 92, 93, 94, 95, 116, 117, 118, 119, 124, 125, 126, 127,
228 212, 213, 214, 215, 220, 221, 222, 223, 244, 245, 246, 247, 252, 253, 254,
229 255, 256, 257, 258, 259, 264, 265, 266, 267, 288, 289, 290, 291, 296, 297,
230 298, 299, 384, 385, 386, 387, 392, 393, 394, 395, 416, 417, 418, 419, 424,
231 425, 426, 427, 260, 261, 262, 263, 268, 269, 270, 271, 292, 293, 294, 295,
232 300, 301, 302, 303, 388, 389, 390, 391, 396, 397, 398, 399, 420, 421, 422,
233 423, 428, 429, 430, 431, 272, 273, 274, 275, 280, 281, 282, 283, 304, 305,
234 306, 307, 312, 313, 314, 315, 400, 401, 402, 403, 408, 409, 410, 411, 432,
235 433, 434, 435, 440, 441, 442, 443, 276, 277, 278, 279, 284, 285, 286, 287,
236 308, 309, 310, 311, 316, 317, 318, 319, 404, 405, 406, 407, 412, 413, 414,
237 415, 436, 437, 438, 439, 444, 445, 446, 447, 320, 321, 322, 323, 328, 329,
238 330, 331, 352, 353, 354, 355, 360, 361, 362, 363, 448, 449, 450, 451, 456,
239 457, 458, 459, 480, 481, 482, 483, 488, 489, 490, 491, 324, 325, 326, 327,
240 332, 333, 334, 335, 356, 357, 358, 359, 364, 365, 366, 367, 452, 453, 454,
241 455, 460, 461, 462, 463, 484, 485, 486, 487, 492, 493, 494, 495, 336, 337,
242 338, 339, 344, 345, 346, 347, 368, 369, 370, 371, 376, 377, 378, 379, 464,
243 465, 466, 467, 472, 473, 474, 475, 496, 497, 498, 499, 504, 505, 506, 507,
244 340, 341, 342, 343, 348, 349, 350, 351, 372, 373, 374, 375, 380, 381, 382,
245 383, 468, 469, 470, 471, 476, 477, 478, 479, 500, 501, 502, 503, 508, 509,
246 510, 511,
247 };
248
249 static const uint16_t orders_8x4[512] = {
250 0, 2, 8, 10, 32, 34, 40, 42, 128, 130, 136, 138, 160, 162, 168,
251 170, 1, 3, 9, 11, 33, 35, 41, 43, 129, 131, 137, 139, 161, 163,
252 169, 171, 4, 6, 12, 14, 36, 38, 44, 46, 132, 134, 140, 142, 164,
253 166, 172, 174, 5, 7, 13, 15, 37, 39, 45, 47, 133, 135, 141, 143,
254 165, 167, 173, 175, 16, 18, 24, 26, 48, 50, 56, 58, 144, 146, 152,
255 154, 176, 178, 184, 186, 17, 19, 25, 27, 49, 51, 57, 59, 145, 147,
256 153, 155, 177, 179, 185, 187, 20, 22, 28, 30, 52, 54, 60, 62, 148,
257 150, 156, 158, 180, 182, 188, 190, 21, 23, 29, 31, 53, 55, 61, 63,
258 149, 151, 157, 159, 181, 183, 189, 191, 64, 66, 72, 74, 96, 98, 104,
259 106, 192, 194, 200, 202, 224, 226, 232, 234, 65, 67, 73, 75, 97, 99,
260 105, 107, 193, 195, 201, 203, 225, 227, 233, 235, 68, 70, 76, 78, 100,
261 102, 108, 110, 196, 198, 204, 206, 228, 230, 236, 238, 69, 71, 77, 79,
262 101, 103, 109, 111, 197, 199, 205, 207, 229, 231, 237, 239, 80, 82, 88,
263 90, 112, 114, 120, 122, 208, 210, 216, 218, 240, 242, 248, 250, 81, 83,
264 89, 91, 113, 115, 121, 123, 209, 211, 217, 219, 241, 243, 249, 251, 84,
265 86, 92, 94, 116, 118, 124, 126, 212, 214, 220, 222, 244, 246, 252, 254,
266 85, 87, 93, 95, 117, 119, 125, 127, 213, 215, 221, 223, 245, 247, 253,
267 255, 256, 258, 264, 266, 288, 290, 296, 298, 384, 386, 392, 394, 416, 418,
268 424, 426, 257, 259, 265, 267, 289, 291, 297, 299, 385, 387, 393, 395, 417,
269 419, 425, 427, 260, 262, 268, 270, 292, 294, 300, 302, 388, 390, 396, 398,
270 420, 422, 428, 430, 261, 263, 269, 271, 293, 295, 301, 303, 389, 391, 397,
271 399, 421, 423, 429, 431, 272, 274, 280, 282, 304, 306, 312, 314, 400, 402,
272 408, 410, 432, 434, 440, 442, 273, 275, 281, 283, 305, 307, 313, 315, 401,
273 403, 409, 411, 433, 435, 441, 443, 276, 278, 284, 286, 308, 310, 316, 318,
274 404, 406, 412, 414, 436, 438, 444, 446, 277, 279, 285, 287, 309, 311, 317,
275 319, 405, 407, 413, 415, 437, 439, 445, 447, 320, 322, 328, 330, 352, 354,
276 360, 362, 448, 450, 456, 458, 480, 482, 488, 490, 321, 323, 329, 331, 353,
277 355, 361, 363, 449, 451, 457, 459, 481, 483, 489, 491, 324, 326, 332, 334,
278 356, 358, 364, 366, 452, 454, 460, 462, 484, 486, 492, 494, 325, 327, 333,
279 335, 357, 359, 365, 367, 453, 455, 461, 463, 485, 487, 493, 495, 336, 338,
280 344, 346, 368, 370, 376, 378, 464, 466, 472, 474, 496, 498, 504, 506, 337,
281 339, 345, 347, 369, 371, 377, 379, 465, 467, 473, 475, 497, 499, 505, 507,
282 340, 342, 348, 350, 372, 374, 380, 382, 468, 470, 476, 478, 500, 502, 508,
283 510, 341, 343, 349, 351, 373, 375, 381, 383, 469, 471, 477, 479, 501, 503,
284 509, 511,
285 };
286
287 static const uint16_t orders_4x4[1024] = {
288 0, 1, 4, 5, 16, 17, 20, 21, 64, 65, 68, 69, 80,
289 81, 84, 85, 256, 257, 260, 261, 272, 273, 276, 277, 320, 321,
290 324, 325, 336, 337, 340, 341, 2, 3, 6, 7, 18, 19, 22,
291 23, 66, 67, 70, 71, 82, 83, 86, 87, 258, 259, 262, 263,
292 274, 275, 278, 279, 322, 323, 326, 327, 338, 339, 342, 343, 8,
293 9, 12, 13, 24, 25, 28, 29, 72, 73, 76, 77, 88, 89,
294 92, 93, 264, 265, 268, 269, 280, 281, 284, 285, 328, 329, 332,
295 333, 344, 345, 348, 349, 10, 11, 14, 15, 26, 27, 30, 31,
296 74, 75, 78, 79, 90, 91, 94, 95, 266, 267, 270, 271, 282,
297 283, 286, 287, 330, 331, 334, 335, 346, 347, 350, 351, 32, 33,
298 36, 37, 48, 49, 52, 53, 96, 97, 100, 101, 112, 113, 116,
299 117, 288, 289, 292, 293, 304, 305, 308, 309, 352, 353, 356, 357,
300 368, 369, 372, 373, 34, 35, 38, 39, 50, 51, 54, 55, 98,
301 99, 102, 103, 114, 115, 118, 119, 290, 291, 294, 295, 306, 307,
302 310, 311, 354, 355, 358, 359, 370, 371, 374, 375, 40, 41, 44,
303 45, 56, 57, 60, 61, 104, 105, 108, 109, 120, 121, 124, 125,
304 296, 297, 300, 301, 312, 313, 316, 317, 360, 361, 364, 365, 376,
305 377, 380, 381, 42, 43, 46, 47, 58, 59, 62, 63, 106, 107,
306 110, 111, 122, 123, 126, 127, 298, 299, 302, 303, 314, 315, 318,
307 319, 362, 363, 366, 367, 378, 379, 382, 383, 128, 129, 132, 133,
308 144, 145, 148, 149, 192, 193, 196, 197, 208, 209, 212, 213, 384,
309 385, 388, 389, 400, 401, 404, 405, 448, 449, 452, 453, 464, 465,
310 468, 469, 130, 131, 134, 135, 146, 147, 150, 151, 194, 195, 198,
311 199, 210, 211, 214, 215, 386, 387, 390, 391, 402, 403, 406, 407,
312 450, 451, 454, 455, 466, 467, 470, 471, 136, 137, 140, 141, 152,
313 153, 156, 157, 200, 201, 204, 205, 216, 217, 220, 221, 392, 393,
314 396, 397, 408, 409, 412, 413, 456, 457, 460, 461, 472, 473, 476,
315 477, 138, 139, 142, 143, 154, 155, 158, 159, 202, 203, 206, 207,
316 218, 219, 222, 223, 394, 395, 398, 399, 410, 411, 414, 415, 458,
317 459, 462, 463, 474, 475, 478, 479, 160, 161, 164, 165, 176, 177,
318 180, 181, 224, 225, 228, 229, 240, 241, 244, 245, 416, 417, 420,
319 421, 432, 433, 436, 437, 480, 481, 484, 485, 496, 497, 500, 501,
320 162, 163, 166, 167, 178, 179, 182, 183, 226, 227, 230, 231, 242,
321 243, 246, 247, 418, 419, 422, 423, 434, 435, 438, 439, 482, 483,
322 486, 487, 498, 499, 502, 503, 168, 169, 172, 173, 184, 185, 188,
323 189, 232, 233, 236, 237, 248, 249, 252, 253, 424, 425, 428, 429,
324 440, 441, 444, 445, 488, 489, 492, 493, 504, 505, 508, 509, 170,
325 171, 174, 175, 186, 187, 190, 191, 234, 235, 238, 239, 250, 251,
326 254, 255, 426, 427, 430, 431, 442, 443, 446, 447, 490, 491, 494,
327 495, 506, 507, 510, 511, 512, 513, 516, 517, 528, 529, 532, 533,
328 576, 577, 580, 581, 592, 593, 596, 597, 768, 769, 772, 773, 784,
329 785, 788, 789, 832, 833, 836, 837, 848, 849, 852, 853, 514, 515,
330 518, 519, 530, 531, 534, 535, 578, 579, 582, 583, 594, 595, 598,
331 599, 770, 771, 774, 775, 786, 787, 790, 791, 834, 835, 838, 839,
332 850, 851, 854, 855, 520, 521, 524, 525, 536, 537, 540, 541, 584,
333 585, 588, 589, 600, 601, 604, 605, 776, 777, 780, 781, 792, 793,
334 796, 797, 840, 841, 844, 845, 856, 857, 860, 861, 522, 523, 526,
335 527, 538, 539, 542, 543, 586, 587, 590, 591, 602, 603, 606, 607,
336 778, 779, 782, 783, 794, 795, 798, 799, 842, 843, 846, 847, 858,
337 859, 862, 863, 544, 545, 548, 549, 560, 561, 564, 565, 608, 609,
338 612, 613, 624, 625, 628, 629, 800, 801, 804, 805, 816, 817, 820,
339 821, 864, 865, 868, 869, 880, 881, 884, 885, 546, 547, 550, 551,
340 562, 563, 566, 567, 610, 611, 614, 615, 626, 627, 630, 631, 802,
341 803, 806, 807, 818, 819, 822, 823, 866, 867, 870, 871, 882, 883,
342 886, 887, 552, 553, 556, 557, 568, 569, 572, 573, 616, 617, 620,
343 621, 632, 633, 636, 637, 808, 809, 812, 813, 824, 825, 828, 829,
344 872, 873, 876, 877, 888, 889, 892, 893, 554, 555, 558, 559, 570,
345 571, 574, 575, 618, 619, 622, 623, 634, 635, 638, 639, 810, 811,
346 814, 815, 826, 827, 830, 831, 874, 875, 878, 879, 890, 891, 894,
347 895, 640, 641, 644, 645, 656, 657, 660, 661, 704, 705, 708, 709,
348 720, 721, 724, 725, 896, 897, 900, 901, 912, 913, 916, 917, 960,
349 961, 964, 965, 976, 977, 980, 981, 642, 643, 646, 647, 658, 659,
350 662, 663, 706, 707, 710, 711, 722, 723, 726, 727, 898, 899, 902,
351 903, 914, 915, 918, 919, 962, 963, 966, 967, 978, 979, 982, 983,
352 648, 649, 652, 653, 664, 665, 668, 669, 712, 713, 716, 717, 728,
353 729, 732, 733, 904, 905, 908, 909, 920, 921, 924, 925, 968, 969,
354 972, 973, 984, 985, 988, 989, 650, 651, 654, 655, 666, 667, 670,
355 671, 714, 715, 718, 719, 730, 731, 734, 735, 906, 907, 910, 911,
356 922, 923, 926, 927, 970, 971, 974, 975, 986, 987, 990, 991, 672,
357 673, 676, 677, 688, 689, 692, 693, 736, 737, 740, 741, 752, 753,
358 756, 757, 928, 929, 932, 933, 944, 945, 948, 949, 992, 993, 996,
359 997, 1008, 1009, 1012, 1013, 674, 675, 678, 679, 690, 691, 694, 695,
360 738, 739, 742, 743, 754, 755, 758, 759, 930, 931, 934, 935, 946,
361 947, 950, 951, 994, 995, 998, 999, 1010, 1011, 1014, 1015, 680, 681,
362 684, 685, 696, 697, 700, 701, 744, 745, 748, 749, 760, 761, 764,
363 765, 936, 937, 940, 941, 952, 953, 956, 957, 1000, 1001, 1004, 1005,
364 1016, 1017, 1020, 1021, 682, 683, 686, 687, 698, 699, 702, 703, 746,
365 747, 750, 751, 762, 763, 766, 767, 938, 939, 942, 943, 954, 955,
366 958, 959, 1002, 1003, 1006, 1007, 1018, 1019, 1022, 1023,
367 };
368 #endif
369 #endif // CONFIG_CB4X4 || CONFIG_EXT_PARTITION
370
371 #if CONFIG_EXT_PARTITION
372 /* clang-format off */
373 static const uint16_t *const orders[BLOCK_SIZES_ALL] = {
374 #if CONFIG_CB4X4
375 #if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
376 // 2X2, 2X4, 4X2
377 orders_4x4, orders_4x4, orders_4x4,
378 #endif
379 // 4X4
380 orders_4x4,
381 // 4X8, 8X4, 8X8
382 orders_4x8, orders_8x4, orders_8x8,
383 #else // CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
384 // 4X4
385 orders_8x8,
386 // 4X8, 8X4, 8X8
387 orders_8x8, orders_8x8, orders_8x8,
388 #endif
389 // 8X16, 16X8, 16X16
390 orders_8x16, orders_16x8, orders_16x16,
391 // 16X32, 32X16, 32X32
392 orders_16x32, orders_32x16, orders_32x32,
393 // 32X64, 64X32, 64X64
394 orders_32x64, orders_64x32, orders_64x64,
395 // 64x128, 128x64, 128x128
396 orders_64x128, orders_128x64, orders_128x128,
397 // 4x16, 16x4, 8x32
398 orders_4x16, orders_16x4, orders_8x32,
399 // 32x8, 16x64, 64x16
400 orders_32x8, orders_16x64, orders_64x16,
401 // 32x128, 128x32
402 orders_32x128, orders_128x32
403 };
404 /* clang-format on */
405 #else
406 /* clang-format off */
407 static const uint16_t *const orders[BLOCK_SIZES_ALL] = {
408 #if CONFIG_CB4X4
409 #if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
410 // 2X2, 2X4, 4X2
411 orders_8x8, orders_8x8, orders_8x8,
412 #endif
413 // 4X4
414 orders_8x8,
415 // 4X8, 8X4, 8X8
416 orders_8x16, orders_16x8, orders_16x16,
417 #else // CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
418 // 4X4
419 orders_16x16,
420 // 4X8, 8X4, 8X8
421 orders_16x16, orders_16x16, orders_16x16,
422 #endif
423 // 8X16, 16X8, 16X16
424 orders_16x32, orders_32x16, orders_32x32,
425 // 16X32, 32X16, 32X32
426 orders_32x64, orders_64x32, orders_64x64,
427 // 32X64, 64X32, 64X64
428 orders_64x128, orders_128x64, orders_128x128,
429 // 4x16, 16x4, 8x32
430 orders_8x32, orders_32x8, orders_16x64,
431 // 32x8, 16x64, 64x16
432 orders_64x16, orders_32x128, orders_128x32
433 };
434 /* clang-format on */
435 #endif // CONFIG_EXT_PARTITION
436
437 #if CONFIG_EXT_PARTITION_TYPES && !CONFIG_EXT_PARTITION_TYPES_AB
438 static const uint16_t orders_verta_64x64[4] = {
439 0, 2, 1, 2,
440 };
441 static const uint16_t orders_verta_32x32[16] = {
442 0, 2, 4, 6, 1, 2, 5, 6, 8, 10, 12, 14, 9, 10, 13, 14,
443 };
444 static const uint16_t orders_verta_16x16[64] = {
445 0, 2, 4, 6, 16, 18, 20, 22, 1, 2, 5, 6, 17, 18, 21, 22,
446 8, 10, 12, 14, 24, 26, 28, 30, 9, 10, 13, 14, 25, 26, 29, 30,
447 32, 34, 36, 38, 48, 50, 52, 54, 33, 34, 37, 38, 49, 50, 53, 54,
448 40, 42, 44, 46, 56, 58, 60, 62, 41, 42, 45, 46, 57, 58, 61, 62,
449 };
450 #if CONFIG_EXT_PARTITION || CONFIG_CB4X4
451 static const uint16_t orders_verta_8x8[256] = {
452 0, 2, 4, 6, 16, 18, 20, 22, 64, 66, 68, 70, 80, 82, 84,
453 86, 1, 2, 5, 6, 17, 18, 21, 22, 65, 66, 69, 70, 81, 82,
454 85, 86, 8, 10, 12, 14, 24, 26, 28, 30, 72, 74, 76, 78, 88,
455 90, 92, 94, 9, 10, 13, 14, 25, 26, 29, 30, 73, 74, 77, 78,
456 89, 90, 93, 94, 32, 34, 36, 38, 48, 50, 52, 54, 96, 98, 100,
457 102, 112, 114, 116, 118, 33, 34, 37, 38, 49, 50, 53, 54, 97, 98,
458 101, 102, 113, 114, 117, 118, 40, 42, 44, 46, 56, 58, 60, 62, 104,
459 106, 108, 110, 120, 122, 124, 126, 41, 42, 45, 46, 57, 58, 61, 62,
460 105, 106, 109, 110, 121, 122, 125, 126, 128, 130, 132, 134, 144, 146, 148,
461 150, 192, 194, 196, 198, 208, 210, 212, 214, 129, 130, 133, 134, 145, 146,
462 149, 150, 193, 194, 197, 198, 209, 210, 213, 214, 136, 138, 140, 142, 152,
463 154, 156, 158, 200, 202, 204, 206, 216, 218, 220, 222, 137, 138, 141, 142,
464 153, 154, 157, 158, 201, 202, 205, 206, 217, 218, 221, 222, 160, 162, 164,
465 166, 176, 178, 180, 182, 224, 226, 228, 230, 240, 242, 244, 246, 161, 162,
466 165, 166, 177, 178, 181, 182, 225, 226, 229, 230, 241, 242, 245, 246, 168,
467 170, 172, 174, 184, 186, 188, 190, 232, 234, 236, 238, 248, 250, 252, 254,
468 169, 170, 173, 174, 185, 186, 189, 190, 233, 234, 237, 238, 249, 250, 253,
469 254,
470 };
471 #endif // CONFIG_EXT_PARTITION || CONFIG_CB4X4
472
473 #if CONFIG_EXT_PARTITION
474 /* clang-format off */
475 static const uint16_t *const orders_verta[BLOCK_SIZES] = {
476 #if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
477 // 2X2, 2X4, 4X2
478 orders_4x4, orders_4x4, orders_4x4,
479 #endif
480 // 4X4
481 orders_verta_8x8,
482 // 4X8, 8X4, 8X8
483 orders_verta_8x8, orders_verta_8x8, orders_verta_8x8,
484 // 8X16, 16X8, 16X16
485 orders_8x16, orders_16x8, orders_verta_16x16,
486 // 16X32, 32X16, 32X32
487 orders_16x32, orders_32x16, orders_verta_32x32,
488 // 32X64, 64X32, 64X64
489 orders_32x64, orders_64x32, orders_verta_64x64,
490 // 64x128, 128x64, 128x128
491 orders_64x128, orders_128x64, orders_128x128,
492 // Note: We can't get 4:1 shaped blocks from a VERT_A type partition
493 };
494 /* clang-format on */
495 #else
496 /* clang-format off */
497 static const uint16_t *const orders_verta[BLOCK_SIZES] = {
498 #if CONFIG_CB4X4
499 #if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
500 // 2X2, 2X4, 4X2
501 orders_verta_8x8, orders_verta_8x8, orders_verta_8x8,
502 #endif
503 // 4X4
504 orders_verta_8x8,
505 // 4X8, 8X4, 8X8
506 orders_verta_8x8, orders_verta_8x8, orders_verta_16x16,
507 #else // CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
508 // 4X4
509 orders_verta_16x16,
510 // 4X8, 8X4, 8X8
511 orders_verta_16x16, orders_verta_16x16, orders_verta_16x16,
512 #endif
513 // 8X16, 16X8, 16X16
514 orders_16x32, orders_32x16, orders_verta_32x32,
515 // 16X32, 32X16, 32X32
516 orders_32x64, orders_64x32, orders_verta_64x64,
517 // 32X64, 64X32, 64X64
518 orders_64x128, orders_128x64, orders_128x128,
519 // Note: We can't get 4:1 shaped blocks from a VERT_A type partition
520 };
521 /* clang-format on */
522 #endif // CONFIG_EXT_PARTITION
523 #endif // CONFIG_EXT_PARTITION_TYPES
524
has_top_right(const AV1_COMMON * cm,BLOCK_SIZE bsize,int mi_row,int mi_col,int top_available,int right_available,PARTITION_TYPE partition,TX_SIZE txsz,int row_off,int col_off,int ss_x)525 static int has_top_right(const AV1_COMMON *cm, BLOCK_SIZE bsize, int mi_row,
526 int mi_col, int top_available, int right_available,
527 #if CONFIG_EXT_PARTITION_TYPES && !CONFIG_EXT_PARTITION_TYPES_AB
528 PARTITION_TYPE partition,
529 #endif // CONFIG_EXT_PARTITION_TYPES && !CONFIG_EXT_PARTITION_TYPES_AB
530 TX_SIZE txsz, int row_off, int col_off, int ss_x) {
531 if (!top_available || !right_available) return 0;
532
533 #if !CONFIG_CB4X4
534 // TODO(bshacklett, huisu): Currently the RD loop traverses 4X8 blocks in
535 // inverted N order while in the bitstream the subblocks are stored in Z
536 // order. This discrepancy makes this function incorrect when considering 4X8
537 // blocks in the RD loop, so we disable the extended right edge for these
538 // blocks. The correct solution is to change the bitstream to store these
539 // blocks in inverted N order, and then update this function appropriately.
540 if (bsize == BLOCK_4X8 && row_off == 1) return 0;
541 #endif
542
543 const int bw_unit = block_size_wide[bsize] >> tx_size_wide_log2[0];
544 const int plane_bw_unit = AOMMAX(bw_unit >> ss_x, 1);
545 const int top_right_count_unit = tx_size_wide_unit[txsz];
546
547 #if !CONFIG_CB4X4
548 // Special handling for block sizes 4x8 and 4x4.
549 if (ss_x == 0 && bw_unit < 2 && col_off == 0) return 1;
550 #endif
551
552 if (row_off > 0) { // Just need to check if enough pixels on the right.
553 #if CONFIG_EXT_PARTITION
554 if (col_off + top_right_count_unit >=
555 (block_size_wide[BLOCK_64X64] >> (tx_size_wide_log2[0] + ss_x)))
556 return 0;
557 #endif
558 return col_off + top_right_count_unit < plane_bw_unit;
559 } else {
560 // All top-right pixels are in the block above, which is already available.
561 if (col_off + top_right_count_unit < plane_bw_unit) return 1;
562
563 const int bw_in_mi_log2 = mi_width_log2_lookup[bsize];
564 const int bh_in_mi_log2 = mi_height_log2_lookup[bsize];
565 const int sb_mi_size = mi_size_high[cm->sb_size];
566 const int blk_row_in_sb = (mi_row & (sb_mi_size - 1)) >> bh_in_mi_log2;
567 const int blk_col_in_sb = (mi_col & (sb_mi_size - 1)) >> bw_in_mi_log2;
568
569 // Top row of superblock: so top-right pixels are in the top and/or
570 // top-right superblocks, both of which are already available.
571 if (blk_row_in_sb == 0) return 1;
572
573 // Rightmost column of superblock (and not the top row): so top-right pixels
574 // fall in the right superblock, which is not available yet.
575 if (((blk_col_in_sb + 1) << bw_in_mi_log2) >= sb_mi_size) return 0;
576
577 // General case (neither top row nor rightmost column): check if the
578 // top-right block is coded before the current block.
579 const uint16_t *const order =
580 #if CONFIG_EXT_PARTITION_TYPES && !CONFIG_EXT_PARTITION_TYPES_AB
581 (partition == PARTITION_VERT_A) ? orders_verta[bsize] :
582 #endif // CONFIG_EXT_PARTITION_TYPES
583 orders[bsize];
584 const int this_blk_index =
585 ((blk_row_in_sb + 0) << (MAX_MIB_SIZE_LOG2 - bw_in_mi_log2)) +
586 blk_col_in_sb + 0;
587 const uint16_t this_blk_order = order[this_blk_index];
588 const int tr_blk_index =
589 ((blk_row_in_sb - 1) << (MAX_MIB_SIZE_LOG2 - bw_in_mi_log2)) +
590 blk_col_in_sb + 1;
591 const uint16_t tr_blk_order = order[tr_blk_index];
592 return tr_blk_order < this_blk_order;
593 }
594 }
595
has_bottom_left(const AV1_COMMON * cm,BLOCK_SIZE bsize,int mi_row,int mi_col,int bottom_available,int left_available,TX_SIZE txsz,int row_off,int col_off,int ss_y)596 static int has_bottom_left(const AV1_COMMON *cm, BLOCK_SIZE bsize, int mi_row,
597 int mi_col, int bottom_available, int left_available,
598 TX_SIZE txsz, int row_off, int col_off, int ss_y) {
599 if (!bottom_available || !left_available) return 0;
600
601 if (col_off > 0) {
602 // Bottom-left pixels are in the bottom-left block, which is not available.
603 return 0;
604 } else {
605 const int bh_unit = block_size_high[bsize] >> tx_size_high_log2[0];
606 const int plane_bh_unit = AOMMAX(bh_unit >> ss_y, 1);
607 const int bottom_left_count_unit = tx_size_high_unit[txsz];
608
609 #if !CONFIG_CB4X4
610 // Special handling for block sizes 8x4 and 4x4.
611 if (ss_y == 0 && bh_unit < 2 && row_off == 0) return 1;
612 #endif
613
614 // All bottom-left pixels are in the left block, which is already available.
615 if (row_off + bottom_left_count_unit < plane_bh_unit) return 1;
616
617 const int bw_in_mi_log2 = mi_width_log2_lookup[bsize];
618 const int bh_in_mi_log2 = mi_height_log2_lookup[bsize];
619 const int sb_mi_size = mi_size_high[cm->sb_size];
620 const int blk_row_in_sb = (mi_row & (sb_mi_size - 1)) >> bh_in_mi_log2;
621 const int blk_col_in_sb = (mi_col & (sb_mi_size - 1)) >> bw_in_mi_log2;
622
623 // Leftmost column of superblock: so bottom-left pixels maybe in the left
624 // and/or bottom-left superblocks. But only the left superblock is
625 // available, so check if all required pixels fall in that superblock.
626 if (blk_col_in_sb == 0) {
627 const int blk_start_row_off = blk_row_in_sb
628 << (bh_in_mi_log2 + MI_SIZE_LOG2 -
629 tx_size_wide_log2[0]) >>
630 ss_y;
631 const int row_off_in_sb = blk_start_row_off + row_off;
632 const int sb_height_unit =
633 sb_mi_size << (MI_SIZE_LOG2 - tx_size_wide_log2[0]) >> ss_y;
634 return row_off_in_sb + bottom_left_count_unit < sb_height_unit;
635 }
636
637 // Bottom row of superblock (and not the leftmost column): so bottom-left
638 // pixels fall in the bottom superblock, which is not available yet.
639 if (((blk_row_in_sb + 1) << bh_in_mi_log2) >= sb_mi_size) return 0;
640
641 // General case (neither leftmost column nor bottom row): check if the
642 // bottom-left block is coded before the current block.
643 const uint16_t *const order = orders[bsize];
644 const int this_blk_index =
645 ((blk_row_in_sb + 0) << (MAX_MIB_SIZE_LOG2 - bw_in_mi_log2)) +
646 blk_col_in_sb + 0;
647 const uint16_t this_blk_order = order[this_blk_index];
648 const int bl_blk_index =
649 ((blk_row_in_sb + 1) << (MAX_MIB_SIZE_LOG2 - bw_in_mi_log2)) +
650 blk_col_in_sb - 1;
651 const uint16_t bl_blk_order = order[bl_blk_index];
652 return bl_blk_order < this_blk_order;
653 }
654 }
655
656 typedef void (*intra_pred_fn)(uint8_t *dst, ptrdiff_t stride,
657 const uint8_t *above, const uint8_t *left);
658
659 static intra_pred_fn pred[INTRA_MODES][TX_SIZES_ALL];
660 static intra_pred_fn dc_pred[2][2][TX_SIZES_ALL];
661
662 #if CONFIG_HIGHBITDEPTH
663 typedef void (*intra_high_pred_fn)(uint16_t *dst, ptrdiff_t stride,
664 const uint16_t *above, const uint16_t *left,
665 int bd);
666 static intra_high_pred_fn pred_high[INTRA_MODES][TX_SIZES_ALL];
667 static intra_high_pred_fn dc_pred_high[2][2][TX_SIZES_ALL];
668 #endif // CONFIG_HIGHBITDEPTH
669
av1_init_intra_predictors_internal(void)670 static void av1_init_intra_predictors_internal(void) {
671 #if CONFIG_EXT_INTRA
672 assert(NELEMENTS(mode_to_angle_map) == INTRA_MODES);
673 #endif // CONFIG_EXT_INTRA
674
675 #if CONFIG_TX64X64
676 #define INIT_RECTANGULAR(p, type) \
677 p[TX_4X8] = aom_##type##_predictor_4x8; \
678 p[TX_8X4] = aom_##type##_predictor_8x4; \
679 p[TX_8X16] = aom_##type##_predictor_8x16; \
680 p[TX_16X8] = aom_##type##_predictor_16x8; \
681 p[TX_16X32] = aom_##type##_predictor_16x32; \
682 p[TX_32X16] = aom_##type##_predictor_32x16; \
683 p[TX_32X64] = aom_##type##_predictor_32x64; \
684 p[TX_64X32] = aom_##type##_predictor_64x32;
685 #else
686 #define INIT_RECTANGULAR(p, type) \
687 p[TX_4X8] = aom_##type##_predictor_4x8; \
688 p[TX_8X4] = aom_##type##_predictor_8x4; \
689 p[TX_8X16] = aom_##type##_predictor_8x16; \
690 p[TX_16X8] = aom_##type##_predictor_16x8; \
691 p[TX_16X32] = aom_##type##_predictor_16x32; \
692 p[TX_32X16] = aom_##type##_predictor_32x16;
693 #endif // CONFIG_TX64X64
694
695 #if CONFIG_TX64X64
696 #define INIT_NO_4X4(p, type) \
697 p[TX_8X8] = aom_##type##_predictor_8x8; \
698 p[TX_16X16] = aom_##type##_predictor_16x16; \
699 p[TX_32X32] = aom_##type##_predictor_32x32; \
700 p[TX_64X64] = aom_##type##_predictor_64x64; \
701 INIT_RECTANGULAR(p, type)
702 #else
703 #define INIT_NO_4X4(p, type) \
704 p[TX_8X8] = aom_##type##_predictor_8x8; \
705 p[TX_16X16] = aom_##type##_predictor_16x16; \
706 p[TX_32X32] = aom_##type##_predictor_32x32; \
707 INIT_RECTANGULAR(p, type)
708 #endif // CONFIG_TX64X64
709
710 #if CONFIG_CHROMA_2X2
711 #define INIT_ALL_SIZES(p, type) \
712 p[TX_2X2] = aom_##type##_predictor_2x2; \
713 p[TX_4X4] = aom_##type##_predictor_4x4; \
714 INIT_NO_4X4(p, type)
715 #else
716 #define INIT_ALL_SIZES(p, type) \
717 p[TX_4X4] = aom_##type##_predictor_4x4; \
718 INIT_NO_4X4(p, type)
719 #endif
720
721 INIT_ALL_SIZES(pred[V_PRED], v);
722 INIT_ALL_SIZES(pred[H_PRED], h);
723 INIT_ALL_SIZES(pred[D207_PRED], d207e);
724 INIT_ALL_SIZES(pred[D45_PRED], d45e);
725 INIT_ALL_SIZES(pred[D63_PRED], d63e);
726 INIT_ALL_SIZES(pred[D117_PRED], d117);
727 INIT_ALL_SIZES(pred[D135_PRED], d135);
728 INIT_ALL_SIZES(pred[D153_PRED], d153);
729
730 INIT_ALL_SIZES(pred[TM_PRED], paeth);
731 INIT_ALL_SIZES(pred[SMOOTH_PRED], smooth);
732 #if CONFIG_SMOOTH_HV
733 INIT_ALL_SIZES(pred[SMOOTH_V_PRED], smooth_v);
734 INIT_ALL_SIZES(pred[SMOOTH_H_PRED], smooth_h);
735 #endif // CONFIG_SMOOTH_HV
736
737 INIT_ALL_SIZES(dc_pred[0][0], dc_128);
738 INIT_ALL_SIZES(dc_pred[0][1], dc_top);
739 INIT_ALL_SIZES(dc_pred[1][0], dc_left);
740 INIT_ALL_SIZES(dc_pred[1][1], dc);
741
742 #if CONFIG_HIGHBITDEPTH
743 INIT_ALL_SIZES(pred_high[V_PRED], highbd_v);
744 INIT_ALL_SIZES(pred_high[H_PRED], highbd_h);
745 INIT_ALL_SIZES(pred_high[D207_PRED], highbd_d207e);
746 INIT_ALL_SIZES(pred_high[D45_PRED], highbd_d45e);
747 INIT_ALL_SIZES(pred_high[D63_PRED], highbd_d63e);
748 INIT_ALL_SIZES(pred_high[D117_PRED], highbd_d117);
749 INIT_ALL_SIZES(pred_high[D135_PRED], highbd_d135);
750 INIT_ALL_SIZES(pred_high[D153_PRED], highbd_d153);
751
752 INIT_ALL_SIZES(pred_high[TM_PRED], highbd_paeth);
753 INIT_ALL_SIZES(pred_high[SMOOTH_PRED], highbd_smooth);
754 #if CONFIG_SMOOTH_HV
755 INIT_ALL_SIZES(pred_high[SMOOTH_V_PRED], highbd_smooth_v);
756 INIT_ALL_SIZES(pred_high[SMOOTH_H_PRED], highbd_smooth_h);
757 #endif // CONFIG_SMOOTH_HV
758
759 INIT_ALL_SIZES(dc_pred_high[0][0], highbd_dc_128);
760 INIT_ALL_SIZES(dc_pred_high[0][1], highbd_dc_top);
761 INIT_ALL_SIZES(dc_pred_high[1][0], highbd_dc_left);
762 INIT_ALL_SIZES(dc_pred_high[1][1], highbd_dc);
763 #endif // CONFIG_HIGHBITDEPTH
764
765 #undef intra_pred_allsizes
766 }
767
768 #if CONFIG_EXT_INTRA
769 #if CONFIG_INTRA_INTERP
intra_subpel_interp(int base,int shift,const uint8_t * ref,int ref_start_idx,int ref_end_idx,INTRA_FILTER filter_type)770 static int intra_subpel_interp(int base, int shift, const uint8_t *ref,
771 int ref_start_idx, int ref_end_idx,
772 INTRA_FILTER filter_type) {
773 int val, k, idx, filter_idx = 0;
774 const int16_t *filter = NULL;
775
776 if (filter_type == INTRA_FILTER_LINEAR) {
777 val = ref[base] * (256 - shift) + ref[base + 1] * shift;
778 val = ROUND_POWER_OF_TWO(val, 8);
779 } else {
780 filter_idx = ROUND_POWER_OF_TWO(shift, 8 - SUBPEL_BITS);
781 filter = av1_intra_filter_kernels[filter_type][filter_idx];
782
783 if (filter_idx < (1 << SUBPEL_BITS)) {
784 val = 0;
785 for (k = 0; k < SUBPEL_TAPS; ++k) {
786 idx = base + 1 - (SUBPEL_TAPS / 2) + k;
787 idx = AOMMAX(AOMMIN(idx, ref_end_idx), ref_start_idx);
788 val += ref[idx] * filter[k];
789 }
790 val = ROUND_POWER_OF_TWO(val, FILTER_BITS);
791 } else {
792 val = ref[base + 1];
793 }
794 }
795
796 return val;
797 }
798 #endif // CONFIG_INTRA_INTERP
799
800 // Directional prediction, zone 1: 0 < angle < 90
dr_prediction_z1(uint8_t * dst,ptrdiff_t stride,int bw,int bh,const uint8_t * above,const uint8_t * left,INTRA_FILTER filter_type,int upsample_above,int dx,int dy)801 static void dr_prediction_z1(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
802 const uint8_t *above, const uint8_t *left,
803 #if CONFIG_INTRA_INTERP
804 INTRA_FILTER filter_type,
805 #endif // CONFIG_INTRA_INTERP
806 #if CONFIG_INTRA_EDGE_UPSAMPLE
807 int upsample_above,
808 #endif // CONFIG_INTRA_EDGE_UPSAMPLE
809 int dx, int dy) {
810 int r, c, x, base, shift, val;
811
812 (void)left;
813 (void)dy;
814 assert(dy == 1);
815 assert(dx > 0);
816
817 #if !CONFIG_INTRA_EDGE_UPSAMPLE
818 const int upsample_above = 0;
819 #endif // !CONFIG_INTRA_EDGE_UPSAMPLE
820 const int max_base_x = ((bw + bh) - 1) << upsample_above;
821 const int frac_bits = 8 - upsample_above;
822 const int base_inc = 1 << upsample_above;
823 x = dx;
824 for (r = 0; r < bh; ++r, dst += stride, x += dx) {
825 base = x >> frac_bits;
826 shift = (x << upsample_above) & 0xFF;
827
828 if (base >= max_base_x) {
829 for (int i = r; i < bh; ++i) {
830 memset(dst, above[max_base_x], bw * sizeof(dst[0]));
831 dst += stride;
832 }
833 return;
834 }
835
836 for (c = 0; c < bw; ++c, base += base_inc) {
837 if (base < max_base_x) {
838 #if CONFIG_INTRA_INTERP
839 val = intra_subpel_interp(base, shift, above, 0, bw + bh - 1,
840 filter_type);
841 #else // CONFIG_INTRA_INTERP
842 val = above[base] * (256 - shift) + above[base + 1] * shift;
843 val = ROUND_POWER_OF_TWO(val, 8);
844 #endif // CONFIG_INTRA_INTERP
845 dst[c] = clip_pixel(val);
846 } else {
847 dst[c] = above[max_base_x];
848 }
849 }
850 }
851 }
852
853 // Directional prediction, zone 2: 90 < angle < 180
dr_prediction_z2(uint8_t * dst,ptrdiff_t stride,int bw,int bh,const uint8_t * above,const uint8_t * left,INTRA_FILTER filter_type,int upsample_above,int upsample_left,int dx,int dy)854 static void dr_prediction_z2(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
855 const uint8_t *above, const uint8_t *left,
856 #if CONFIG_INTRA_INTERP
857 INTRA_FILTER filter_type,
858 #endif // CONFIG_INTRA_INTERP
859 #if CONFIG_INTRA_EDGE_UPSAMPLE
860 int upsample_above, int upsample_left,
861 #endif // CONFIG_INTRA_EDGE_UPSAMPLE
862 int dx, int dy) {
863 int r, c, x, y, shift1, shift2, val, base1, base2;
864
865 assert(dx > 0);
866 assert(dy > 0);
867
868 #if !CONFIG_INTRA_EDGE_UPSAMPLE
869 const int upsample_above = 0;
870 const int upsample_left = 0;
871 #endif // !CONFIG_INTRA_EDGE_UPSAMPLE
872 const int min_base_x = -(1 << upsample_above);
873 const int frac_bits_x = 8 - upsample_above;
874 const int frac_bits_y = 8 - upsample_left;
875 const int base_inc_x = 1 << upsample_above;
876 x = -dx;
877 for (r = 0; r < bh; ++r, x -= dx, dst += stride) {
878 base1 = x >> frac_bits_x;
879 y = (r << 8) - dy;
880 for (c = 0; c < bw; ++c, base1 += base_inc_x, y -= dy) {
881 if (base1 >= min_base_x) {
882 shift1 = (x * (1 << upsample_above)) & 0xFF;
883 #if CONFIG_INTRA_INTERP
884 val =
885 intra_subpel_interp(base1, shift1, above, -1, bw - 1, filter_type);
886 #else
887 val = above[base1] * (256 - shift1) + above[base1 + 1] * shift1;
888 val = ROUND_POWER_OF_TWO(val, 8);
889 #endif // CONFIG_INTRA_INTERP
890 } else {
891 base2 = y >> frac_bits_y;
892 assert(base2 >= -(1 << upsample_left));
893 shift2 = (y * (1 << upsample_left)) & 0xFF;
894 #if CONFIG_INTRA_INTERP
895 val = intra_subpel_interp(base2, shift2, left, -1, bh - 1, filter_type);
896 #else
897 val = left[base2] * (256 - shift2) + left[base2 + 1] * shift2;
898 val = ROUND_POWER_OF_TWO(val, 8);
899 #endif // CONFIG_INTRA_INTERP
900 }
901 dst[c] = clip_pixel(val);
902 }
903 }
904 }
905
906 // Directional prediction, zone 3: 180 < angle < 270
dr_prediction_z3(uint8_t * dst,ptrdiff_t stride,int bw,int bh,const uint8_t * above,const uint8_t * left,INTRA_FILTER filter_type,int upsample_left,int dx,int dy)907 static void dr_prediction_z3(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
908 const uint8_t *above, const uint8_t *left,
909 #if CONFIG_INTRA_INTERP
910 INTRA_FILTER filter_type,
911 #endif // CONFIG_INTRA_INTERP
912 #if CONFIG_INTRA_EDGE_UPSAMPLE
913 int upsample_left,
914 #endif // CONFIG_INTRA_EDGE_UPSAMPLE
915 int dx, int dy) {
916 int r, c, y, base, shift, val;
917
918 (void)above;
919 (void)dx;
920
921 assert(dx == 1);
922 assert(dy > 0);
923
924 #if !CONFIG_INTRA_EDGE_UPSAMPLE
925 const int upsample_left = 0;
926 #endif // !CONFIG_INTRA_EDGE_UPSAMPLE
927 const int max_base_y = (bw + bh - 1) << upsample_left;
928 const int frac_bits = 8 - upsample_left;
929 const int base_inc = 1 << upsample_left;
930 y = dy;
931 for (c = 0; c < bw; ++c, y += dy) {
932 base = y >> frac_bits;
933 shift = (y << upsample_left) & 0xFF;
934
935 for (r = 0; r < bh; ++r, base += base_inc) {
936 if (base < max_base_y) {
937 #if CONFIG_INTRA_INTERP
938 val =
939 intra_subpel_interp(base, shift, left, 0, bw + bh - 1, filter_type);
940 #else // CONFIG_INTRA_INTERP
941 val = left[base] * (256 - shift) + left[base + 1] * shift;
942 val = ROUND_POWER_OF_TWO(val, 8);
943 #endif // CONFIG_INTRA_INTERP
944 dst[r * stride + c] = clip_pixel(val);
945 } else {
946 for (; r < bh; ++r) dst[r * stride + c] = left[max_base_y];
947 break;
948 }
949 }
950 }
951 }
952
953 // Get the shift (up-scaled by 256) in X w.r.t a unit change in Y.
954 // If angle > 0 && angle < 90, dx = -((int)(256 / t));
955 // If angle > 90 && angle < 180, dx = (int)(256 / t);
956 // If angle > 180 && angle < 270, dx = 1;
get_dx(int angle)957 static INLINE int get_dx(int angle) {
958 if (angle > 0 && angle < 90) {
959 return dr_intra_derivative[angle];
960 } else if (angle > 90 && angle < 180) {
961 return dr_intra_derivative[180 - angle];
962 } else {
963 // In this case, we are not really going to use dx. We may return any value.
964 return 1;
965 }
966 }
967
968 // Get the shift (up-scaled by 256) in Y w.r.t a unit change in X.
969 // If angle > 0 && angle < 90, dy = 1;
970 // If angle > 90 && angle < 180, dy = (int)(256 * t);
971 // If angle > 180 && angle < 270, dy = -((int)(256 * t));
get_dy(int angle)972 static INLINE int get_dy(int angle) {
973 if (angle > 90 && angle < 180) {
974 return dr_intra_derivative[angle - 90];
975 } else if (angle > 180 && angle < 270) {
976 return dr_intra_derivative[270 - angle];
977 } else {
978 // In this case, we are not really going to use dy. We may return any value.
979 return 1;
980 }
981 }
982
dr_predictor(uint8_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint8_t * above,const uint8_t * left,INTRA_FILTER filter_type,int upsample_above,int upsample_left,int angle)983 static void dr_predictor(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size,
984 const uint8_t *above, const uint8_t *left,
985 #if CONFIG_INTRA_INTERP
986 INTRA_FILTER filter_type,
987 #endif // CONFIG_INTRA_INTERP
988 #if CONFIG_INTRA_EDGE_UPSAMPLE
989 int upsample_above, int upsample_left,
990 #endif // CONFIG_INTRA_EDGE_UPSAMPLE
991 int angle) {
992 const int dx = get_dx(angle);
993 const int dy = get_dy(angle);
994 const int bw = tx_size_wide[tx_size];
995 const int bh = tx_size_high[tx_size];
996 assert(angle > 0 && angle < 270);
997
998 if (angle > 0 && angle < 90) {
999 dr_prediction_z1(dst, stride, bw, bh, above, left,
1000 #if CONFIG_INTRA_INTERP
1001 filter_type,
1002 #endif // CONFIG_INTRA_INTERP
1003 #if CONFIG_INTRA_EDGE_UPSAMPLE
1004 upsample_above,
1005 #endif // CONFIG_INTRA_EDGE_UPSAMPLE
1006 dx, dy);
1007 } else if (angle > 90 && angle < 180) {
1008 dr_prediction_z2(dst, stride, bw, bh, above, left,
1009 #if CONFIG_INTRA_INTERP
1010 filter_type,
1011 #endif // CONFIG_INTRA_INTERP
1012 #if CONFIG_INTRA_EDGE_UPSAMPLE
1013 upsample_above, upsample_left,
1014 #endif // CONFIG_INTRA_EDGE_UPSAMPLE
1015 dx, dy);
1016 } else if (angle > 180 && angle < 270) {
1017 dr_prediction_z3(dst, stride, bw, bh, above, left,
1018 #if CONFIG_INTRA_INTERP
1019 filter_type,
1020 #endif // CONFIG_INTRA_INTERP
1021 #if CONFIG_INTRA_EDGE_UPSAMPLE
1022 upsample_left,
1023 #endif // CONFIG_INTRA_EDGE_UPSAMPLE
1024 dx, dy);
1025 } else if (angle == 90) {
1026 pred[V_PRED][tx_size](dst, stride, above, left);
1027 } else if (angle == 180) {
1028 pred[H_PRED][tx_size](dst, stride, above, left);
1029 }
1030 }
1031
1032 #if CONFIG_HIGHBITDEPTH
1033 #if CONFIG_INTRA_INTERP
highbd_intra_subpel_interp(int base,int shift,const uint16_t * ref,int ref_start_idx,int ref_end_idx,INTRA_FILTER filter_type)1034 static int highbd_intra_subpel_interp(int base, int shift, const uint16_t *ref,
1035 int ref_start_idx, int ref_end_idx,
1036 INTRA_FILTER filter_type) {
1037 int val, k, idx, filter_idx = 0;
1038 const int16_t *filter = NULL;
1039
1040 if (filter_type == INTRA_FILTER_LINEAR) {
1041 val = ref[base] * (256 - shift) + ref[base + 1] * shift;
1042 val = ROUND_POWER_OF_TWO(val, 8);
1043 } else {
1044 filter_idx = ROUND_POWER_OF_TWO(shift, 8 - SUBPEL_BITS);
1045 filter = av1_intra_filter_kernels[filter_type][filter_idx];
1046
1047 if (filter_idx < (1 << SUBPEL_BITS)) {
1048 val = 0;
1049 for (k = 0; k < SUBPEL_TAPS; ++k) {
1050 idx = base + 1 - (SUBPEL_TAPS / 2) + k;
1051 idx = AOMMAX(AOMMIN(idx, ref_end_idx), ref_start_idx);
1052 val += ref[idx] * filter[k];
1053 }
1054 val = ROUND_POWER_OF_TWO(val, FILTER_BITS);
1055 } else {
1056 val = ref[base + 1];
1057 }
1058 }
1059
1060 return val;
1061 }
1062 #endif // CONFIG_INTRA_INTERP
1063
1064 // Directional prediction, zone 1: 0 < angle < 90
highbd_dr_prediction_z1(uint16_t * dst,ptrdiff_t stride,int bw,int bh,const uint16_t * above,const uint16_t * left,INTRA_FILTER filter_type,int upsample_above,int dx,int dy,int bd)1065 static void highbd_dr_prediction_z1(uint16_t *dst, ptrdiff_t stride, int bw,
1066 int bh, const uint16_t *above,
1067 const uint16_t *left,
1068 #if CONFIG_INTRA_INTERP
1069 INTRA_FILTER filter_type,
1070 #endif // CONFIG_INTRA_INTERP
1071 #if CONFIG_INTRA_EDGE_UPSAMPLE
1072 int upsample_above,
1073 #endif // CONFIG_INTRA_EDGE_UPSAMPLE
1074 int dx, int dy, int bd) {
1075 int r, c, x, base, shift, val;
1076
1077 (void)left;
1078 (void)dy;
1079 assert(dy == 1);
1080 assert(dx > 0);
1081
1082 #if !CONFIG_INTRA_EDGE_UPSAMPLE
1083 const int upsample_above = 0;
1084 #endif // !CONFIG_INTRA_EDGE_UPSAMPLE
1085 const int max_base_x = ((bw + bh) - 1) << upsample_above;
1086 const int frac_bits = 8 - upsample_above;
1087 const int base_inc = 1 << upsample_above;
1088 x = dx;
1089 for (r = 0; r < bh; ++r, dst += stride, x += dx) {
1090 base = x >> frac_bits;
1091 shift = (x << upsample_above) & 0xFF;
1092
1093 if (base >= max_base_x) {
1094 for (int i = r; i < bh; ++i) {
1095 aom_memset16(dst, above[max_base_x], bw);
1096 dst += stride;
1097 }
1098 return;
1099 }
1100
1101 for (c = 0; c < bw; ++c, base += base_inc) {
1102 if (base < max_base_x) {
1103 #if CONFIG_INTRA_INTERP
1104 val = highbd_intra_subpel_interp(base, shift, above, 0, bw + bh - 1,
1105 filter_type);
1106 #else
1107 val = above[base] * (256 - shift) + above[base + 1] * shift;
1108 val = ROUND_POWER_OF_TWO(val, 8);
1109 #endif // CONFIG_INTRA_INTERP
1110 dst[c] = clip_pixel_highbd(val, bd);
1111 } else {
1112 dst[c] = above[max_base_x];
1113 }
1114 }
1115 }
1116 }
1117
1118 // Directional prediction, zone 2: 90 < angle < 180
highbd_dr_prediction_z2(uint16_t * dst,ptrdiff_t stride,int bw,int bh,const uint16_t * above,const uint16_t * left,INTRA_FILTER filter_type,int upsample_above,int upsample_left,int dx,int dy,int bd)1119 static void highbd_dr_prediction_z2(uint16_t *dst, ptrdiff_t stride, int bw,
1120 int bh, const uint16_t *above,
1121 const uint16_t *left,
1122 #if CONFIG_INTRA_INTERP
1123 INTRA_FILTER filter_type,
1124 #endif // CONFIG_INTRA_INTERP
1125 #if CONFIG_INTRA_EDGE_UPSAMPLE
1126 int upsample_above, int upsample_left,
1127 #endif // CONFIG_INTRA_EDGE_UPSAMPLE
1128 int dx, int dy, int bd) {
1129 int r, c, x, y, shift, val, base;
1130
1131 assert(dx > 0);
1132 assert(dy > 0);
1133
1134 #if !CONFIG_INTRA_EDGE_UPSAMPLE
1135 const int upsample_above = 0;
1136 const int upsample_left = 0;
1137 #endif // !CONFIG_INTRA_EDGE_UPSAMPLE
1138 const int min_base_x = -(1 << upsample_above);
1139 const int frac_bits_x = 8 - upsample_above;
1140 const int frac_bits_y = 8 - upsample_left;
1141 for (r = 0; r < bh; ++r) {
1142 for (c = 0; c < bw; ++c) {
1143 y = r + 1;
1144 x = (c << 8) - y * dx;
1145 base = x >> frac_bits_x;
1146 if (base >= min_base_x) {
1147 shift = (x * (1 << upsample_above)) & 0xFF;
1148 #if CONFIG_INTRA_INTERP
1149 val = highbd_intra_subpel_interp(base, shift, above, -1, bw - 1,
1150 filter_type);
1151 #else
1152 val = above[base] * (256 - shift) + above[base + 1] * shift;
1153 val = ROUND_POWER_OF_TWO(val, 8);
1154 #endif // CONFIG_INTRA_INTERP
1155 } else {
1156 x = c + 1;
1157 y = (r << 8) - x * dy;
1158 base = y >> frac_bits_y;
1159 shift = (y * (1 << upsample_left)) & 0xFF;
1160 #if CONFIG_INTRA_INTERP
1161 val = highbd_intra_subpel_interp(base, shift, left, -1, bh - 1,
1162 filter_type);
1163 #else
1164 val = left[base] * (256 - shift) + left[base + 1] * shift;
1165 val = ROUND_POWER_OF_TWO(val, 8);
1166 #endif // CONFIG_INTRA_INTERP
1167 }
1168 dst[c] = clip_pixel_highbd(val, bd);
1169 }
1170 dst += stride;
1171 }
1172 }
1173
1174 // Directional prediction, zone 3: 180 < angle < 270
highbd_dr_prediction_z3(uint16_t * dst,ptrdiff_t stride,int bw,int bh,const uint16_t * above,const uint16_t * left,INTRA_FILTER filter_type,int upsample_left,int dx,int dy,int bd)1175 static void highbd_dr_prediction_z3(uint16_t *dst, ptrdiff_t stride, int bw,
1176 int bh, const uint16_t *above,
1177 const uint16_t *left,
1178 #if CONFIG_INTRA_INTERP
1179 INTRA_FILTER filter_type,
1180 #endif // CONFIG_INTRA_INTERP
1181 #if CONFIG_INTRA_EDGE_UPSAMPLE
1182 int upsample_left,
1183 #endif // CONFIG_INTRA_EDGE_UPSAMPLE
1184 int dx, int dy, int bd) {
1185 int r, c, y, base, shift, val;
1186
1187 (void)above;
1188 (void)dx;
1189 assert(dx == 1);
1190 assert(dy > 0);
1191
1192 #if !CONFIG_INTRA_EDGE_UPSAMPLE
1193 const int upsample_left = 0;
1194 #endif // !CONFIG_INTRA_EDGE_UPSAMPLE
1195 const int max_base_y = (bw + bh - 1) << upsample_left;
1196 const int frac_bits = 8 - upsample_left;
1197 const int base_inc = 1 << upsample_left;
1198 y = dy;
1199 for (c = 0; c < bw; ++c, y += dy) {
1200 base = y >> frac_bits;
1201 shift = (y << upsample_left) & 0xFF;
1202
1203 for (r = 0; r < bh; ++r, base += base_inc) {
1204 if (base < max_base_y) {
1205 #if CONFIG_INTRA_INTERP
1206 val = highbd_intra_subpel_interp(base, shift, left, 0, bw + bh - 1,
1207 filter_type);
1208 #else
1209 val = left[base] * (256 - shift) + left[base + 1] * shift;
1210 val = ROUND_POWER_OF_TWO(val, 8);
1211 #endif // CONFIG_INTRA_INTERP
1212 dst[r * stride + c] = clip_pixel_highbd(val, bd);
1213 } else {
1214 for (; r < bh; ++r) dst[r * stride + c] = left[max_base_y];
1215 break;
1216 }
1217 }
1218 }
1219 }
1220
highbd_dr_predictor(uint16_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint16_t * above,const uint16_t * left,INTRA_FILTER filter,int upsample_above,int upsample_left,int angle,int bd)1221 static void highbd_dr_predictor(uint16_t *dst, ptrdiff_t stride,
1222 TX_SIZE tx_size, const uint16_t *above,
1223 const uint16_t *left,
1224 #if CONFIG_INTRA_INTERP
1225 INTRA_FILTER filter,
1226 #endif // CONFIG_INTRA_INTERP
1227 #if CONFIG_INTRA_EDGE_UPSAMPLE
1228 int upsample_above, int upsample_left,
1229 #endif // CONFIG_INTRA_EDGE_UPSAMPLE
1230 int angle, int bd) {
1231 const int dx = get_dx(angle);
1232 const int dy = get_dy(angle);
1233 const int bw = tx_size_wide[tx_size];
1234 const int bh = tx_size_high[tx_size];
1235 assert(angle > 0 && angle < 270);
1236
1237 if (angle > 0 && angle < 90) {
1238 highbd_dr_prediction_z1(dst, stride, bw, bh, above, left,
1239 #if CONFIG_INTRA_INTERP
1240 filter,
1241 #endif // CONFIG_INTRA_INTERP
1242 #if CONFIG_INTRA_EDGE_UPSAMPLE
1243 upsample_above,
1244 #endif // CONFIG_INTRA_EDGE_UPSAMPLE
1245 dx, dy, bd);
1246 } else if (angle > 90 && angle < 180) {
1247 highbd_dr_prediction_z2(dst, stride, bw, bh, above, left,
1248 #if CONFIG_INTRA_INTERP
1249 filter,
1250 #endif // CONFIG_INTRA_INTERP
1251 #if CONFIG_INTRA_EDGE_UPSAMPLE
1252 upsample_above, upsample_left,
1253 #endif // CONFIG_INTRA_EDGE_UPSAMPLE
1254 dx, dy, bd);
1255 } else if (angle > 180 && angle < 270) {
1256 highbd_dr_prediction_z3(dst, stride, bw, bh, above, left,
1257 #if CONFIG_INTRA_INTERP
1258 filter,
1259 #endif // CONFIG_INTRA_INTERP
1260 #if CONFIG_INTRA_EDGE_UPSAMPLE
1261 upsample_left,
1262 #endif // CONFIG_INTRA_EDGE_UPSAMPLE
1263 dx, dy, bd);
1264 } else if (angle == 90) {
1265 pred_high[V_PRED][tx_size](dst, stride, above, left, bd);
1266 } else if (angle == 180) {
1267 pred_high[H_PRED][tx_size](dst, stride, above, left, bd);
1268 }
1269 }
1270 #endif // CONFIG_HIGHBITDEPTH
1271 #endif // CONFIG_EXT_INTRA
1272
1273 #if CONFIG_FILTER_INTRA
1274 #if USE_3TAP_INTRA_FILTER
1275 static int filter_intra_taps_3[TX_SIZES_ALL][FILTER_INTRA_MODES][3] = {
1276 #if CONFIG_CHROMA_2X2
1277 {
1278 { 697, 836, -509 },
1279 { 993, 513, -482 },
1280 { 381, 984, -341 },
1281 { 642, 1169, -787 },
1282 { 590, 553, -119 },
1283 { 762, 385, -123 },
1284 { 358, 687, -21 },
1285 { 411, 1083, -470 },
1286 { 912, 814, -702 },
1287 { 883, 902, -761 },
1288 },
1289 #endif
1290 {
1291 { 697, 836, -509 },
1292 { 993, 513, -482 },
1293 { 381, 984, -341 },
1294 { 642, 1169, -787 },
1295 { 590, 553, -119 },
1296 { 762, 385, -123 },
1297 { 358, 687, -21 },
1298 { 411, 1083, -470 },
1299 { 912, 814, -702 },
1300 { 883, 902, -761 },
1301 },
1302 {
1303 { 659, 816, -451 },
1304 { 980, 625, -581 },
1305 { 558, 962, -496 },
1306 { 681, 888, -545 },
1307 { 591, 613, 180 },
1308 { 778, 399, -153 },
1309 { 495, 641, -112 },
1310 { 671, 937, -584 },
1311 { 745, 940, -661 },
1312 { 839, 911, -726 },
1313 },
1314 {
1315 { 539, 927, -442 },
1316 { 1003, 714, -693 },
1317 { 349, 1271, -596 },
1318 { 820, 764, -560 },
1319 { 524, 816, -316 },
1320 { 780, 681, -437 },
1321 { 586, 795, -357 },
1322 { 551, 1135, -663 },
1323 { 593, 1061, -630 },
1324 { 974, 970, -920 },
1325 },
1326 {
1327 { 595, 919, -490 },
1328 { 945, 668, -579 },
1329 { 495, 962, -433 },
1330 { 385, 1551, -912 },
1331 { 455, 554, 15 },
1332 { 852, 478, -306 },
1333 { 177, 760, -87 },
1334 { -65, 1611, -522 },
1335 { 815, 894, -685 },
1336 { 846, 1010, -832 },
1337 },
1338 #if CONFIG_TX64X64
1339 {
1340 { 595, 919, -490 },
1341 { 945, 668, -579 },
1342 { 495, 962, -433 },
1343 { 385, 1551, -912 },
1344 { 455, 554, 15 },
1345 { 852, 478, -306 },
1346 { 177, 760, -87 },
1347 { -65, 1611, -522 },
1348 { 815, 894, -685 },
1349 { 846, 1010, -832 },
1350 },
1351 #endif // CONFIG_TX64X64
1352 {
1353 { 697, 836, -509 },
1354 { 993, 513, -482 },
1355 { 381, 984, -341 },
1356 { 642, 1169, -787 },
1357 { 590, 553, -119 },
1358 { 762, 385, -123 },
1359 { 358, 687, -21 },
1360 { 411, 1083, -470 },
1361 { 912, 814, -702 },
1362 { 883, 902, -761 },
1363 },
1364 {
1365 { 697, 836, -509 },
1366 { 993, 513, -482 },
1367 { 381, 984, -341 },
1368 { 642, 1169, -787 },
1369 { 590, 553, -119 },
1370 { 762, 385, -123 },
1371 { 358, 687, -21 },
1372 { 411, 1083, -470 },
1373 { 912, 814, -702 },
1374 { 883, 902, -761 },
1375 },
1376 {
1377 { 659, 816, -451 },
1378 { 980, 625, -581 },
1379 { 558, 962, -496 },
1380 { 681, 888, -545 },
1381 { 591, 613, 180 },
1382 { 778, 399, -153 },
1383 { 495, 641, -112 },
1384 { 671, 937, -584 },
1385 { 745, 940, -661 },
1386 { 839, 911, -726 },
1387 },
1388 {
1389 { 659, 816, -451 },
1390 { 980, 625, -581 },
1391 { 558, 962, -496 },
1392 { 681, 888, -545 },
1393 { 591, 613, 180 },
1394 { 778, 399, -153 },
1395 { 495, 641, -112 },
1396 { 671, 937, -584 },
1397 { 745, 940, -661 },
1398 { 839, 911, -726 },
1399 },
1400 {
1401 { 539, 927, -442 },
1402 { 1003, 714, -693 },
1403 { 349, 1271, -596 },
1404 { 820, 764, -560 },
1405 { 524, 816, -316 },
1406 { 780, 681, -437 },
1407 { 586, 795, -357 },
1408 { 551, 1135, -663 },
1409 { 593, 1061, -630 },
1410 { 974, 970, -920 },
1411 },
1412 {
1413 { 539, 927, -442 },
1414 { 1003, 714, -693 },
1415 { 349, 1271, -596 },
1416 { 820, 764, -560 },
1417 { 524, 816, -316 },
1418 { 780, 681, -437 },
1419 { 586, 795, -357 },
1420 { 551, 1135, -663 },
1421 { 593, 1061, -630 },
1422 { 974, 970, -920 },
1423 },
1424 {
1425 { 697, 836, -509 },
1426 { 993, 513, -482 },
1427 { 381, 984, -341 },
1428 { 642, 1169, -787 },
1429 { 590, 553, -119 },
1430 { 762, 385, -123 },
1431 { 358, 687, -21 },
1432 { 411, 1083, -470 },
1433 { 912, 814, -702 },
1434 { 883, 902, -761 },
1435 },
1436 {
1437 { 697, 836, -509 },
1438 { 993, 513, -482 },
1439 { 381, 984, -341 },
1440 { 642, 1169, -787 },
1441 { 590, 553, -119 },
1442 { 762, 385, -123 },
1443 { 358, 687, -21 },
1444 { 411, 1083, -470 },
1445 { 912, 814, -702 },
1446 { 883, 902, -761 },
1447 },
1448 {
1449 { 659, 816, -451 },
1450 { 980, 625, -581 },
1451 { 558, 962, -496 },
1452 { 681, 888, -545 },
1453 { 591, 613, 180 },
1454 { 778, 399, -153 },
1455 { 495, 641, -112 },
1456 { 671, 937, -584 },
1457 { 745, 940, -661 },
1458 { 839, 911, -726 },
1459 },
1460 {
1461 { 659, 816, -451 },
1462 { 980, 625, -581 },
1463 { 558, 962, -496 },
1464 { 681, 888, -545 },
1465 { 591, 613, 180 },
1466 { 778, 399, -153 },
1467 { 495, 641, -112 },
1468 { 671, 937, -584 },
1469 { 745, 940, -661 },
1470 { 839, 911, -726 },
1471 }
1472 };
1473 #else
1474 static int filter_intra_taps_4[TX_SIZES_ALL][FILTER_INTRA_MODES][4] = {
1475 #if CONFIG_CHROMA_2X2
1476 {
1477 { 735, 881, -537, -54 },
1478 { 1005, 519, -488, -11 },
1479 { 383, 990, -343, -6 },
1480 { 442, 805, -542, 319 },
1481 { 658, 616, -133, -116 },
1482 { 875, 442, -141, -151 },
1483 { 386, 741, -23, -80 },
1484 { 390, 1027, -446, 51 },
1485 { 679, 606, -523, 262 },
1486 { 903, 922, -778, -23 },
1487 },
1488 #endif
1489 {
1490 { 735, 881, -537, -54 },
1491 { 1005, 519, -488, -11 },
1492 { 383, 990, -343, -6 },
1493 { 442, 805, -542, 319 },
1494 { 658, 616, -133, -116 },
1495 { 875, 442, -141, -151 },
1496 { 386, 741, -23, -80 },
1497 { 390, 1027, -446, 51 },
1498 { 679, 606, -523, 262 },
1499 { 903, 922, -778, -23 },
1500 },
1501 {
1502 { 648, 803, -444, 16 },
1503 { 972, 620, -576, 7 },
1504 { 561, 967, -499, -5 },
1505 { 585, 762, -468, 144 },
1506 { 596, 619, -182, -9 },
1507 { 895, 459, -176, -153 },
1508 { 557, 722, -126, -129 },
1509 { 601, 839, -523, 105 },
1510 { 562, 709, -499, 251 },
1511 { 803, 872, -695, 43 },
1512 },
1513 {
1514 { 423, 728, -347, 111 },
1515 { 963, 685, -665, 23 },
1516 { 281, 1024, -480, 216 },
1517 { 640, 596, -437, 78 },
1518 { 429, 669, -259, 99 },
1519 { 740, 646, -415, 23 },
1520 { 568, 771, -346, 40 },
1521 { 404, 833, -486, 209 },
1522 { 398, 712, -423, 307 },
1523 { 939, 935, -887, 17 },
1524 },
1525 {
1526 { 477, 737, -393, 150 },
1527 { 881, 630, -546, 67 },
1528 { 506, 984, -443, -20 },
1529 { 114, 459, -270, 528 },
1530 { 433, 528, 14, 3 },
1531 { 837, 470, -301, -30 },
1532 { 181, 777, 89, -107 },
1533 { -29, 716, -232, 259 },
1534 { 589, 646, -495, 255 },
1535 { 740, 884, -728, 77 },
1536 },
1537 #if CONFIG_TX64X64
1538 {
1539 { 477, 737, -393, 150 },
1540 { 881, 630, -546, 67 },
1541 { 506, 984, -443, -20 },
1542 { 114, 459, -270, 528 },
1543 { 433, 528, 14, 3 },
1544 { 837, 470, -301, -30 },
1545 { 181, 777, 89, -107 },
1546 { -29, 716, -232, 259 },
1547 { 589, 646, -495, 255 },
1548 { 740, 884, -728, 77 },
1549 },
1550 #endif // CONFIG_TX64X64
1551 {
1552 { 735, 881, -537, -54 },
1553 { 1005, 519, -488, -11 },
1554 { 383, 990, -343, -6 },
1555 { 442, 805, -542, 319 },
1556 { 658, 616, -133, -116 },
1557 { 875, 442, -141, -151 },
1558 { 386, 741, -23, -80 },
1559 { 390, 1027, -446, 51 },
1560 { 679, 606, -523, 262 },
1561 { 903, 922, -778, -23 },
1562 },
1563 {
1564 { 735, 881, -537, -54 },
1565 { 1005, 519, -488, -11 },
1566 { 383, 990, -343, -6 },
1567 { 442, 805, -542, 319 },
1568 { 658, 616, -133, -116 },
1569 { 875, 442, -141, -151 },
1570 { 386, 741, -23, -80 },
1571 { 390, 1027, -446, 51 },
1572 { 679, 606, -523, 262 },
1573 { 903, 922, -778, -23 },
1574 },
1575 {
1576 { 648, 803, -444, 16 },
1577 { 972, 620, -576, 7 },
1578 { 561, 967, -499, -5 },
1579 { 585, 762, -468, 144 },
1580 { 596, 619, -182, -9 },
1581 { 895, 459, -176, -153 },
1582 { 557, 722, -126, -129 },
1583 { 601, 839, -523, 105 },
1584 { 562, 709, -499, 251 },
1585 { 803, 872, -695, 43 },
1586 },
1587 {
1588 { 648, 803, -444, 16 },
1589 { 972, 620, -576, 7 },
1590 { 561, 967, -499, -5 },
1591 { 585, 762, -468, 144 },
1592 { 596, 619, -182, -9 },
1593 { 895, 459, -176, -153 },
1594 { 557, 722, -126, -129 },
1595 { 601, 839, -523, 105 },
1596 { 562, 709, -499, 251 },
1597 { 803, 872, -695, 43 },
1598 },
1599 {
1600 { 423, 728, -347, 111 },
1601 { 963, 685, -665, 23 },
1602 { 281, 1024, -480, 216 },
1603 { 640, 596, -437, 78 },
1604 { 429, 669, -259, 99 },
1605 { 740, 646, -415, 23 },
1606 { 568, 771, -346, 40 },
1607 { 404, 833, -486, 209 },
1608 { 398, 712, -423, 307 },
1609 { 939, 935, -887, 17 },
1610 },
1611 {
1612 { 423, 728, -347, 111 },
1613 { 963, 685, -665, 23 },
1614 { 281, 1024, -480, 216 },
1615 { 640, 596, -437, 78 },
1616 { 429, 669, -259, 99 },
1617 { 740, 646, -415, 23 },
1618 { 568, 771, -346, 40 },
1619 { 404, 833, -486, 209 },
1620 { 398, 712, -423, 307 },
1621 { 939, 935, -887, 17 },
1622 },
1623 {
1624 { 735, 881, -537, -54 },
1625 { 1005, 519, -488, -11 },
1626 { 383, 990, -343, -6 },
1627 { 442, 805, -542, 319 },
1628 { 658, 616, -133, -116 },
1629 { 875, 442, -141, -151 },
1630 { 386, 741, -23, -80 },
1631 { 390, 1027, -446, 51 },
1632 { 679, 606, -523, 262 },
1633 { 903, 922, -778, -23 },
1634 },
1635 {
1636 { 735, 881, -537, -54 },
1637 { 1005, 519, -488, -11 },
1638 { 383, 990, -343, -6 },
1639 { 442, 805, -542, 319 },
1640 { 658, 616, -133, -116 },
1641 { 875, 442, -141, -151 },
1642 { 386, 741, -23, -80 },
1643 { 390, 1027, -446, 51 },
1644 { 679, 606, -523, 262 },
1645 { 903, 922, -778, -23 },
1646 },
1647 {
1648 { 648, 803, -444, 16 },
1649 { 972, 620, -576, 7 },
1650 { 561, 967, -499, -5 },
1651 { 585, 762, -468, 144 },
1652 { 596, 619, -182, -9 },
1653 { 895, 459, -176, -153 },
1654 { 557, 722, -126, -129 },
1655 { 601, 839, -523, 105 },
1656 { 562, 709, -499, 251 },
1657 { 803, 872, -695, 43 },
1658 },
1659 {
1660 { 648, 803, -444, 16 },
1661 { 972, 620, -576, 7 },
1662 { 561, 967, -499, -5 },
1663 { 585, 762, -468, 144 },
1664 { 596, 619, -182, -9 },
1665 { 895, 459, -176, -153 },
1666 { 557, 722, -126, -129 },
1667 { 601, 839, -523, 105 },
1668 { 562, 709, -499, 251 },
1669 { 803, 872, -695, 43 },
1670 }
1671 };
1672 #endif
1673
1674 #if USE_3TAP_INTRA_FILTER
filter_intra_predictors_3tap(uint8_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint8_t * above,const uint8_t * left,int mode)1675 static void filter_intra_predictors_3tap(uint8_t *dst, ptrdiff_t stride,
1676 TX_SIZE tx_size, const uint8_t *above,
1677 const uint8_t *left, int mode) {
1678 int r, c;
1679 int mean, ipred;
1680 #if CONFIG_TX64X64
1681 int buffer[65][65];
1682 #else
1683 int buffer[33][33];
1684 #endif // CONFIG_TX64X64
1685 const int c0 = filter_intra_taps_3[tx_size][mode][0];
1686 const int c1 = filter_intra_taps_3[tx_size][mode][1];
1687 const int c2 = filter_intra_taps_3[tx_size][mode][2];
1688 const int bw = tx_size_wide[tx_size];
1689 const int bh = tx_size_high[tx_size];
1690
1691 mean = 0;
1692 for (r = 0; r < bh; ++r) {
1693 mean += (int)left[r];
1694 }
1695 for (c = 0; c < bw; ++c) {
1696 mean += (int)above[c];
1697 }
1698 mean = (mean + ((bw + bh) >> 1)) / (bw + bh);
1699
1700 for (r = 0; r < bh; ++r) buffer[r + 1][0] = (int)left[r] - mean;
1701
1702 for (c = 0; c < bw + 1; ++c) buffer[0][c] = (int)above[c - 1] - mean;
1703
1704 for (r = 1; r < bh + 1; ++r)
1705 for (c = 1; c < bw + 1; ++c) {
1706 ipred = c0 * buffer[r - 1][c] + c1 * buffer[r][c - 1] +
1707 c2 * buffer[r - 1][c - 1];
1708 buffer[r][c] = ROUND_POWER_OF_TWO_SIGNED(ipred, FILTER_INTRA_PREC_BITS);
1709 buffer[r][c] = clip_pixel(buffer[r][c] + mean) - mean;
1710 }
1711
1712 for (r = 0; r < bh; ++r) {
1713 for (c = 0; c < bw; ++c) {
1714 dst[c] = clip_pixel(buffer[r + 1][c + 1] + mean);
1715 }
1716 dst += stride;
1717 }
1718 }
1719 #else
filter_intra_predictors_4tap(uint8_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint8_t * above,const uint8_t * left,int mode)1720 static void filter_intra_predictors_4tap(uint8_t *dst, ptrdiff_t stride,
1721 TX_SIZE tx_size, const uint8_t *above,
1722 const uint8_t *left, int mode) {
1723 int r, c;
1724 int mean, ipred;
1725 #if CONFIG_TX64X64
1726 int buffer[65][129];
1727 #else
1728 int buffer[33][65];
1729 #endif // CONFIG_TX64X64
1730 const int c0 = filter_intra_taps_4[tx_size][mode][0];
1731 const int c1 = filter_intra_taps_4[tx_size][mode][1];
1732 const int c2 = filter_intra_taps_4[tx_size][mode][2];
1733 const int c3 = filter_intra_taps_4[tx_size][mode][3];
1734 const int bw = tx_size_wide[tx_size];
1735 const int bh = tx_size_high[tx_size];
1736
1737 mean = 0;
1738 for (r = 0; r < bh; ++r) {
1739 mean += (int)left[r];
1740 }
1741 for (c = 0; c < bw; ++c) {
1742 mean += (int)above[c];
1743 }
1744 mean = (mean + ((bw + bh) >> 1)) / (bw + bh);
1745
1746 for (r = 0; r < bh; ++r) buffer[r + 1][0] = (int)left[r] - mean;
1747
1748 for (c = 0; c < 2 * bw + 1; ++c) buffer[0][c] = (int)above[c - 1] - mean;
1749
1750 for (r = 1; r < bh + 1; ++r)
1751 for (c = 1; c < 2 * bw + 1 - r; ++c) {
1752 ipred = c0 * buffer[r - 1][c] + c1 * buffer[r][c - 1] +
1753 c2 * buffer[r - 1][c - 1] + c3 * buffer[r - 1][c + 1];
1754 buffer[r][c] = ROUND_POWER_OF_TWO_SIGNED(ipred, FILTER_INTRA_PREC_BITS);
1755 buffer[r][c] = clip_pixel(buffer[r][c] + mean) - mean;
1756 }
1757
1758 for (r = 0; r < bh; ++r) {
1759 for (c = 0; c < bw; ++c) {
1760 dst[c] = clip_pixel(buffer[r + 1][c + 1] + mean);
1761 }
1762 dst += stride;
1763 }
1764 }
1765 #endif
1766
av1_dc_filter_predictor_c(uint8_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint8_t * above,const uint8_t * left)1767 void av1_dc_filter_predictor_c(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size,
1768 const uint8_t *above, const uint8_t *left) {
1769 #if USE_3TAP_INTRA_FILTER
1770 filter_intra_predictors_3tap(dst, stride, tx_size, above, left,
1771 FILTER_DC_PRED);
1772 #else
1773 filter_intra_predictors_4tap(dst, stride, tx_size, above, left,
1774 FILTER_DC_PRED);
1775 #endif
1776 }
1777
av1_v_filter_predictor_c(uint8_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint8_t * above,const uint8_t * left)1778 void av1_v_filter_predictor_c(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size,
1779 const uint8_t *above, const uint8_t *left) {
1780 #if USE_3TAP_INTRA_FILTER
1781 filter_intra_predictors_3tap(dst, stride, tx_size, above, left,
1782 FILTER_V_PRED);
1783 #else
1784 filter_intra_predictors_4tap(dst, stride, tx_size, above, left,
1785 FILTER_V_PRED);
1786 #endif
1787 }
1788
av1_h_filter_predictor_c(uint8_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint8_t * above,const uint8_t * left)1789 void av1_h_filter_predictor_c(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size,
1790 const uint8_t *above, const uint8_t *left) {
1791 #if USE_3TAP_INTRA_FILTER
1792 filter_intra_predictors_3tap(dst, stride, tx_size, above, left,
1793 FILTER_H_PRED);
1794 #else
1795 filter_intra_predictors_4tap(dst, stride, tx_size, above, left,
1796 FILTER_H_PRED);
1797 #endif
1798 }
1799
av1_d45_filter_predictor_c(uint8_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint8_t * above,const uint8_t * left)1800 void av1_d45_filter_predictor_c(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size,
1801 const uint8_t *above, const uint8_t *left) {
1802 #if USE_3TAP_INTRA_FILTER
1803 filter_intra_predictors_3tap(dst, stride, tx_size, above, left,
1804 FILTER_D45_PRED);
1805 #else
1806 filter_intra_predictors_4tap(dst, stride, tx_size, above, left,
1807 FILTER_D45_PRED);
1808 #endif
1809 }
1810
av1_d135_filter_predictor_c(uint8_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint8_t * above,const uint8_t * left)1811 void av1_d135_filter_predictor_c(uint8_t *dst, ptrdiff_t stride,
1812 TX_SIZE tx_size, const uint8_t *above,
1813 const uint8_t *left) {
1814 #if USE_3TAP_INTRA_FILTER
1815 filter_intra_predictors_3tap(dst, stride, tx_size, above, left,
1816 FILTER_D135_PRED);
1817 #else
1818 filter_intra_predictors_4tap(dst, stride, tx_size, above, left,
1819 FILTER_D135_PRED);
1820 #endif
1821 }
1822
av1_d117_filter_predictor_c(uint8_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint8_t * above,const uint8_t * left)1823 void av1_d117_filter_predictor_c(uint8_t *dst, ptrdiff_t stride,
1824 TX_SIZE tx_size, const uint8_t *above,
1825 const uint8_t *left) {
1826 #if USE_3TAP_INTRA_FILTER
1827 filter_intra_predictors_3tap(dst, stride, tx_size, above, left,
1828 FILTER_D117_PRED);
1829 #else
1830 filter_intra_predictors_4tap(dst, stride, tx_size, above, left,
1831 FILTER_D117_PRED);
1832 #endif
1833 }
1834
av1_d153_filter_predictor_c(uint8_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint8_t * above,const uint8_t * left)1835 void av1_d153_filter_predictor_c(uint8_t *dst, ptrdiff_t stride,
1836 TX_SIZE tx_size, const uint8_t *above,
1837 const uint8_t *left) {
1838 #if USE_3TAP_INTRA_FILTER
1839 filter_intra_predictors_3tap(dst, stride, tx_size, above, left,
1840 FILTER_D153_PRED);
1841 #else
1842 filter_intra_predictors_4tap(dst, stride, tx_size, above, left,
1843 FILTER_D153_PRED);
1844 #endif
1845 }
1846
av1_d207_filter_predictor_c(uint8_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint8_t * above,const uint8_t * left)1847 void av1_d207_filter_predictor_c(uint8_t *dst, ptrdiff_t stride,
1848 TX_SIZE tx_size, const uint8_t *above,
1849 const uint8_t *left) {
1850 #if USE_3TAP_INTRA_FILTER
1851 filter_intra_predictors_3tap(dst, stride, tx_size, above, left,
1852 FILTER_D207_PRED);
1853 #else
1854 filter_intra_predictors_4tap(dst, stride, tx_size, above, left,
1855 FILTER_D207_PRED);
1856 #endif
1857 }
1858
av1_d63_filter_predictor_c(uint8_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint8_t * above,const uint8_t * left)1859 void av1_d63_filter_predictor_c(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size,
1860 const uint8_t *above, const uint8_t *left) {
1861 #if USE_3TAP_INTRA_FILTER
1862 filter_intra_predictors_3tap(dst, stride, tx_size, above, left,
1863 FILTER_D63_PRED);
1864 #else
1865 filter_intra_predictors_4tap(dst, stride, tx_size, above, left,
1866 FILTER_D63_PRED);
1867 #endif
1868 }
1869
av1_tm_filter_predictor_c(uint8_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint8_t * above,const uint8_t * left)1870 void av1_tm_filter_predictor_c(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size,
1871 const uint8_t *above, const uint8_t *left) {
1872 #if USE_3TAP_INTRA_FILTER
1873 filter_intra_predictors_3tap(dst, stride, tx_size, above, left,
1874 FILTER_TM_PRED);
1875 #else
1876 filter_intra_predictors_4tap(dst, stride, tx_size, above, left,
1877 FILTER_TM_PRED);
1878 #endif
1879 }
1880
filter_intra_predictors(FILTER_INTRA_MODE mode,uint8_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint8_t * above,const uint8_t * left)1881 static void filter_intra_predictors(FILTER_INTRA_MODE mode, uint8_t *dst,
1882 ptrdiff_t stride, TX_SIZE tx_size,
1883 const uint8_t *above, const uint8_t *left) {
1884 switch (mode) {
1885 case FILTER_DC_PRED:
1886 av1_dc_filter_predictor(dst, stride, tx_size, above, left);
1887 break;
1888 case FILTER_V_PRED:
1889 av1_v_filter_predictor(dst, stride, tx_size, above, left);
1890 break;
1891 case FILTER_H_PRED:
1892 av1_h_filter_predictor(dst, stride, tx_size, above, left);
1893 break;
1894 case FILTER_D45_PRED:
1895 av1_d45_filter_predictor(dst, stride, tx_size, above, left);
1896 break;
1897 case FILTER_D135_PRED:
1898 av1_d135_filter_predictor(dst, stride, tx_size, above, left);
1899 break;
1900 case FILTER_D117_PRED:
1901 av1_d117_filter_predictor(dst, stride, tx_size, above, left);
1902 break;
1903 case FILTER_D153_PRED:
1904 av1_d153_filter_predictor(dst, stride, tx_size, above, left);
1905 break;
1906 case FILTER_D207_PRED:
1907 av1_d207_filter_predictor(dst, stride, tx_size, above, left);
1908 break;
1909 case FILTER_D63_PRED:
1910 av1_d63_filter_predictor(dst, stride, tx_size, above, left);
1911 break;
1912 case FILTER_TM_PRED:
1913 av1_tm_filter_predictor(dst, stride, tx_size, above, left);
1914 break;
1915 default: assert(0);
1916 }
1917 }
1918 #if CONFIG_HIGHBITDEPTH
1919 #if USE_3TAP_INTRA_FILTER
highbd_filter_intra_predictors_3tap(uint16_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint16_t * above,const uint16_t * left,int mode,int bd)1920 static void highbd_filter_intra_predictors_3tap(uint16_t *dst, ptrdiff_t stride,
1921 TX_SIZE tx_size,
1922 const uint16_t *above,
1923 const uint16_t *left, int mode,
1924 int bd) {
1925 int r, c;
1926 int mean, ipred;
1927 #if CONFIG_TX64X64
1928 int preds[65][65];
1929 #else
1930 int preds[33][33];
1931 #endif // CONFIG_TX64X64
1932 const int c0 = filter_intra_taps_3[tx_size][mode][0];
1933 const int c1 = filter_intra_taps_3[tx_size][mode][1];
1934 const int c2 = filter_intra_taps_3[tx_size][mode][2];
1935 const int bw = tx_size_wide[tx_size];
1936 const int bh = tx_size_high[tx_size];
1937
1938 mean = 0;
1939 for (r = 0; r < bh; ++r) {
1940 mean += (int)left[r];
1941 }
1942 for (c = 0; c < bw; ++c) {
1943 mean += (int)above[c];
1944 }
1945 mean = (mean + ((bw + bh) >> 1)) / (bw + bh);
1946
1947 for (r = 0; r < bh; ++r) preds[r + 1][0] = (int)left[r] - mean;
1948
1949 for (c = 0; c < bw + 1; ++c) preds[0][c] = (int)above[c - 1] - mean;
1950
1951 for (r = 1; r < bh + 1; ++r)
1952 for (c = 1; c < bw + 1; ++c) {
1953 ipred = c0 * preds[r - 1][c] + c1 * preds[r][c - 1] +
1954 c2 * preds[r - 1][c - 1];
1955 preds[r][c] = ROUND_POWER_OF_TWO_SIGNED(ipred, FILTER_INTRA_PREC_BITS);
1956 preds[r][c] = clip_pixel_highbd(preds[r][c] + mean, bd) - mean;
1957 }
1958
1959 for (r = 0; r < bh; ++r) {
1960 for (c = 0; c < bw; ++c) {
1961 dst[c] = clip_pixel_highbd(preds[r + 1][c + 1] + mean, bd);
1962 }
1963 dst += stride;
1964 }
1965 }
1966 #else
highbd_filter_intra_predictors_4tap(uint16_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint16_t * above,const uint16_t * left,int mode,int bd)1967 static void highbd_filter_intra_predictors_4tap(uint16_t *dst, ptrdiff_t stride,
1968 TX_SIZE tx_size,
1969 const uint16_t *above,
1970 const uint16_t *left, int mode,
1971 int bd) {
1972 int r, c;
1973 int mean, ipred;
1974 #if CONFIG_TX64X64
1975 int preds[65][129];
1976 #else
1977 int preds[33][65];
1978 #endif // CONFIG_TX64X64
1979 const int c0 = filter_intra_taps_4[tx_size][mode][0];
1980 const int c1 = filter_intra_taps_4[tx_size][mode][1];
1981 const int c2 = filter_intra_taps_4[tx_size][mode][2];
1982 const int c3 = filter_intra_taps_4[tx_size][mode][3];
1983 const int bw = tx_size_wide[tx_size];
1984 const int bh = tx_size_high[tx_size];
1985
1986 mean = 0;
1987 for (r = 0; r < bh; ++r) {
1988 mean += (int)left[r];
1989 }
1990 for (c = 0; c < bw; ++c) {
1991 mean += (int)above[c];
1992 }
1993 mean = (mean + ((bw + bh) >> 1)) / (bw + bh);
1994
1995 for (r = 0; r < bh; ++r) preds[r + 1][0] = (int)left[r] - mean;
1996
1997 for (c = 0; c < 2 * bw + 1; ++c) preds[0][c] = (int)above[c - 1] - mean;
1998
1999 for (r = 1; r < bh + 1; ++r)
2000 for (c = 1; c < 2 * bw + 1 - r; ++c) {
2001 ipred = c0 * preds[r - 1][c] + c1 * preds[r][c - 1] +
2002 c2 * preds[r - 1][c - 1] + c3 * preds[r - 1][c + 1];
2003 preds[r][c] = ROUND_POWER_OF_TWO_SIGNED(ipred, FILTER_INTRA_PREC_BITS);
2004 preds[r][c] = clip_pixel_highbd(preds[r][c] + mean, bd) - mean;
2005 }
2006
2007 for (r = 0; r < bh; ++r) {
2008 for (c = 0; c < bw; ++c) {
2009 dst[c] = clip_pixel_highbd(preds[r + 1][c + 1] + mean, bd);
2010 }
2011 dst += stride;
2012 }
2013 }
2014 #endif
2015
av1_highbd_dc_filter_predictor_c(uint16_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint16_t * above,const uint16_t * left,int bd)2016 void av1_highbd_dc_filter_predictor_c(uint16_t *dst, ptrdiff_t stride,
2017 TX_SIZE tx_size, const uint16_t *above,
2018 const uint16_t *left, int bd) {
2019 #if USE_3TAP_INTRA_FILTER
2020 highbd_filter_intra_predictors_3tap(dst, stride, tx_size, above, left,
2021 FILTER_DC_PRED, bd);
2022 #else
2023 highbd_filter_intra_predictors_4tap(dst, stride, tx_size, above, left,
2024 FILTER_DC_PRED, bd);
2025 #endif
2026 }
2027
av1_highbd_v_filter_predictor_c(uint16_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint16_t * above,const uint16_t * left,int bd)2028 void av1_highbd_v_filter_predictor_c(uint16_t *dst, ptrdiff_t stride,
2029 TX_SIZE tx_size, const uint16_t *above,
2030 const uint16_t *left, int bd) {
2031 #if USE_3TAP_INTRA_FILTER
2032 highbd_filter_intra_predictors_3tap(dst, stride, tx_size, above, left,
2033 FILTER_V_PRED, bd);
2034 #else
2035 highbd_filter_intra_predictors_4tap(dst, stride, tx_size, above, left,
2036 FILTER_V_PRED, bd);
2037 #endif
2038 }
2039
av1_highbd_h_filter_predictor_c(uint16_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint16_t * above,const uint16_t * left,int bd)2040 void av1_highbd_h_filter_predictor_c(uint16_t *dst, ptrdiff_t stride,
2041 TX_SIZE tx_size, const uint16_t *above,
2042 const uint16_t *left, int bd) {
2043 #if USE_3TAP_INTRA_FILTER
2044 highbd_filter_intra_predictors_3tap(dst, stride, tx_size, above, left,
2045 FILTER_H_PRED, bd);
2046 #else
2047 highbd_filter_intra_predictors_4tap(dst, stride, tx_size, above, left,
2048 FILTER_H_PRED, bd);
2049 #endif
2050 }
2051
av1_highbd_d45_filter_predictor_c(uint16_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint16_t * above,const uint16_t * left,int bd)2052 void av1_highbd_d45_filter_predictor_c(uint16_t *dst, ptrdiff_t stride,
2053 TX_SIZE tx_size, const uint16_t *above,
2054 const uint16_t *left, int bd) {
2055 #if USE_3TAP_INTRA_FILTER
2056 highbd_filter_intra_predictors_3tap(dst, stride, tx_size, above, left,
2057 FILTER_D45_PRED, bd);
2058 #else
2059 highbd_filter_intra_predictors_4tap(dst, stride, tx_size, above, left,
2060 FILTER_D45_PRED, bd);
2061 #endif
2062 }
2063
av1_highbd_d135_filter_predictor_c(uint16_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint16_t * above,const uint16_t * left,int bd)2064 void av1_highbd_d135_filter_predictor_c(uint16_t *dst, ptrdiff_t stride,
2065 TX_SIZE tx_size, const uint16_t *above,
2066 const uint16_t *left, int bd) {
2067 #if USE_3TAP_INTRA_FILTER
2068 highbd_filter_intra_predictors_3tap(dst, stride, tx_size, above, left,
2069 FILTER_D135_PRED, bd);
2070 #else
2071 highbd_filter_intra_predictors_4tap(dst, stride, tx_size, above, left,
2072 FILTER_D135_PRED, bd);
2073 #endif
2074 }
2075
av1_highbd_d117_filter_predictor_c(uint16_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint16_t * above,const uint16_t * left,int bd)2076 void av1_highbd_d117_filter_predictor_c(uint16_t *dst, ptrdiff_t stride,
2077 TX_SIZE tx_size, const uint16_t *above,
2078 const uint16_t *left, int bd) {
2079 #if USE_3TAP_INTRA_FILTER
2080 highbd_filter_intra_predictors_3tap(dst, stride, tx_size, above, left,
2081 FILTER_D117_PRED, bd);
2082 #else
2083 highbd_filter_intra_predictors_4tap(dst, stride, tx_size, above, left,
2084 FILTER_D117_PRED, bd);
2085 #endif
2086 }
2087
av1_highbd_d153_filter_predictor_c(uint16_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint16_t * above,const uint16_t * left,int bd)2088 void av1_highbd_d153_filter_predictor_c(uint16_t *dst, ptrdiff_t stride,
2089 TX_SIZE tx_size, const uint16_t *above,
2090 const uint16_t *left, int bd) {
2091 #if USE_3TAP_INTRA_FILTER
2092 highbd_filter_intra_predictors_3tap(dst, stride, tx_size, above, left,
2093 FILTER_D153_PRED, bd);
2094 #else
2095 highbd_filter_intra_predictors_4tap(dst, stride, tx_size, above, left,
2096 FILTER_D153_PRED, bd);
2097 #endif
2098 }
2099
av1_highbd_d207_filter_predictor_c(uint16_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint16_t * above,const uint16_t * left,int bd)2100 void av1_highbd_d207_filter_predictor_c(uint16_t *dst, ptrdiff_t stride,
2101 TX_SIZE tx_size, const uint16_t *above,
2102 const uint16_t *left, int bd) {
2103 #if USE_3TAP_INTRA_FILTER
2104 highbd_filter_intra_predictors_3tap(dst, stride, tx_size, above, left,
2105 FILTER_D207_PRED, bd);
2106 #else
2107 highbd_filter_intra_predictors_4tap(dst, stride, tx_size, above, left,
2108 FILTER_D207_PRED, bd);
2109 #endif
2110 }
2111
av1_highbd_d63_filter_predictor_c(uint16_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint16_t * above,const uint16_t * left,int bd)2112 void av1_highbd_d63_filter_predictor_c(uint16_t *dst, ptrdiff_t stride,
2113 TX_SIZE tx_size, const uint16_t *above,
2114 const uint16_t *left, int bd) {
2115 #if USE_3TAP_INTRA_FILTER
2116 highbd_filter_intra_predictors_3tap(dst, stride, tx_size, above, left,
2117 FILTER_D63_PRED, bd);
2118 #else
2119 highbd_filter_intra_predictors_4tap(dst, stride, tx_size, above, left,
2120 FILTER_D63_PRED, bd);
2121 #endif
2122 }
2123
av1_highbd_tm_filter_predictor_c(uint16_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint16_t * above,const uint16_t * left,int bd)2124 void av1_highbd_tm_filter_predictor_c(uint16_t *dst, ptrdiff_t stride,
2125 TX_SIZE tx_size, const uint16_t *above,
2126 const uint16_t *left, int bd) {
2127 #if USE_3TAP_INTRA_FILTER
2128 highbd_filter_intra_predictors_3tap(dst, stride, tx_size, above, left,
2129 FILTER_TM_PRED, bd);
2130 #else
2131 highbd_filter_intra_predictors_4tap(dst, stride, tx_size, above, left,
2132 FILTER_TM_PRED, bd);
2133 #endif
2134 }
2135
highbd_filter_intra_predictors(FILTER_INTRA_MODE mode,uint16_t * dst,ptrdiff_t stride,TX_SIZE tx_size,const uint16_t * above,const uint16_t * left,int bd)2136 static void highbd_filter_intra_predictors(FILTER_INTRA_MODE mode,
2137 uint16_t *dst, ptrdiff_t stride,
2138 TX_SIZE tx_size,
2139 const uint16_t *above,
2140 const uint16_t *left, int bd) {
2141 switch (mode) {
2142 case FILTER_DC_PRED:
2143 av1_highbd_dc_filter_predictor(dst, stride, tx_size, above, left, bd);
2144 break;
2145 case FILTER_V_PRED:
2146 av1_highbd_v_filter_predictor(dst, stride, tx_size, above, left, bd);
2147 break;
2148 case FILTER_H_PRED:
2149 av1_highbd_h_filter_predictor(dst, stride, tx_size, above, left, bd);
2150 break;
2151 case FILTER_D45_PRED:
2152 av1_highbd_d45_filter_predictor(dst, stride, tx_size, above, left, bd);
2153 break;
2154 case FILTER_D135_PRED:
2155 av1_highbd_d135_filter_predictor(dst, stride, tx_size, above, left, bd);
2156 break;
2157 case FILTER_D117_PRED:
2158 av1_highbd_d117_filter_predictor(dst, stride, tx_size, above, left, bd);
2159 break;
2160 case FILTER_D153_PRED:
2161 av1_highbd_d153_filter_predictor(dst, stride, tx_size, above, left, bd);
2162 break;
2163 case FILTER_D207_PRED:
2164 av1_highbd_d207_filter_predictor(dst, stride, tx_size, above, left, bd);
2165 break;
2166 case FILTER_D63_PRED:
2167 av1_highbd_d63_filter_predictor(dst, stride, tx_size, above, left, bd);
2168 break;
2169 case FILTER_TM_PRED:
2170 av1_highbd_tm_filter_predictor(dst, stride, tx_size, above, left, bd);
2171 break;
2172 default: assert(0);
2173 }
2174 }
2175 #endif // CONFIG_HIGHBITDEPTH
2176 #endif // CONFIG_FILTER_INTRA
2177
2178 #if CONFIG_INTRA_EDGE
intra_edge_filter_strength(int bsz,int delta)2179 static int intra_edge_filter_strength(int bsz, int delta) {
2180 const int d = abs(delta);
2181 int strength = 0;
2182
2183 switch (bsz) {
2184 case 4:
2185 if (d < 56) {
2186 strength = 0;
2187 } else if (d < 90) {
2188 strength = 1;
2189 }
2190 break;
2191 case 8:
2192 if (d < 8) {
2193 strength = 0;
2194 } else if (d < 32) {
2195 strength = 1;
2196 } else if (d < 90) {
2197 strength = 3;
2198 }
2199 break;
2200 case 16:
2201 if (d < 4) {
2202 strength = 0;
2203 } else if (d < 16) {
2204 strength = 1;
2205 } else if (d < 90) {
2206 strength = 3;
2207 }
2208 break;
2209 case 32:
2210 if (d < 16) {
2211 strength = 2;
2212 } else if (d < 90) {
2213 strength = 3;
2214 }
2215 break;
2216 default: strength = 0; break;
2217 }
2218
2219 return strength;
2220 }
2221
av1_filter_intra_edge_c(uint8_t * p,int sz,int strength)2222 void av1_filter_intra_edge_c(uint8_t *p, int sz, int strength) {
2223 if (!strength) return;
2224
2225 const int kernel[INTRA_EDGE_FILT][INTRA_EDGE_TAPS] = {
2226 { 0, 4, 8, 4, 0 }, { 0, 5, 6, 5, 0 }, { 2, 4, 4, 4, 2 }
2227 };
2228 const int filt = strength - 1;
2229 uint8_t edge[129];
2230
2231 memcpy(edge, p, sz * sizeof(*p));
2232 for (int i = 1; i < sz - 1; i++) {
2233 int s = 0;
2234 for (int j = 0; j < INTRA_EDGE_TAPS; j++) {
2235 int k = i - 2 + j;
2236 k = (k < 0) ? 0 : k;
2237 k = (k > sz - 1) ? sz - 1 : k;
2238 s += edge[k] * kernel[filt][j];
2239 }
2240 s = (s + 8) >> 4;
2241 p[i] = s;
2242 }
2243 }
2244
2245 #if CONFIG_HIGHBITDEPTH
av1_filter_intra_edge_high_c(uint16_t * p,int sz,int strength)2246 void av1_filter_intra_edge_high_c(uint16_t *p, int sz, int strength) {
2247 if (!strength) return;
2248
2249 const int kernel[INTRA_EDGE_FILT][INTRA_EDGE_TAPS] = {
2250 { 0, 4, 8, 4, 0 }, { 0, 5, 6, 5, 0 }, { 2, 4, 4, 4, 2 }
2251 };
2252 const int filt = strength - 1;
2253 uint16_t edge[129];
2254
2255 memcpy(edge, p, sz * sizeof(*p));
2256 for (int i = 1; i < sz - 1; i++) {
2257 int s = 0;
2258 for (int j = 0; j < INTRA_EDGE_TAPS; j++) {
2259 int k = i - 2 + j;
2260 k = (k < 0) ? 0 : k;
2261 k = (k > sz - 1) ? sz - 1 : k;
2262 s += edge[k] * kernel[filt][j];
2263 }
2264 s = (s + 8) >> 4;
2265 p[i] = s;
2266 }
2267 }
2268 #endif // CONFIG_HIGHBITDEPTH
2269
2270 #if CONFIG_INTRA_EDGE_UPSAMPLE
use_intra_edge_upsample(int bsz,int delta)2271 static int use_intra_edge_upsample(int bsz, int delta) {
2272 const int d = abs(delta);
2273 return (bsz == 4 && d > 0 && d < 56);
2274 }
2275
av1_upsample_intra_edge_c(uint8_t * p,int sz)2276 void av1_upsample_intra_edge_c(uint8_t *p, int sz) {
2277 // interpolate half-sample positions
2278 assert(sz <= MAX_UPSAMPLE_SZ);
2279
2280 uint8_t in[MAX_UPSAMPLE_SZ + 3];
2281 // copy p[-1..(sz-1)] and extend first and last samples
2282 in[0] = p[-1];
2283 in[1] = p[-1];
2284 for (int i = 0; i < sz; i++) {
2285 in[i + 2] = p[i];
2286 }
2287 in[sz + 2] = p[sz - 1];
2288
2289 // interpolate half-sample edge positions
2290 p[-2] = in[0];
2291 for (int i = 0; i < sz; i++) {
2292 int s = -in[i] + (9 * in[i + 1]) + (9 * in[i + 2]) - in[i + 3];
2293 s = clip_pixel((s + 8) >> 4);
2294 p[2 * i - 1] = s;
2295 p[2 * i] = in[i + 2];
2296 }
2297 }
2298
2299 #if CONFIG_HIGHBITDEPTH
av1_upsample_intra_edge_high_c(uint16_t * p,int sz,int bd)2300 void av1_upsample_intra_edge_high_c(uint16_t *p, int sz, int bd) {
2301 // interpolate half-sample positions
2302 assert(sz <= MAX_UPSAMPLE_SZ);
2303
2304 uint16_t in[MAX_UPSAMPLE_SZ + 3];
2305 // copy p[-1..(sz-1)] and extend first and last samples
2306 in[0] = p[-1];
2307 in[1] = p[-1];
2308 for (int i = 0; i < sz; i++) {
2309 in[i + 2] = p[i];
2310 }
2311 in[sz + 2] = p[sz - 1];
2312
2313 // interpolate half-sample edge positions
2314 p[-2] = in[0];
2315 for (int i = 0; i < sz; i++) {
2316 int s = -in[i] + (9 * in[i + 1]) + (9 * in[i + 2]) - in[i + 3];
2317 s = (s + 8) >> 4;
2318 s = clip_pixel_highbd(s, bd);
2319 p[2 * i - 1] = s;
2320 p[2 * i] = in[i + 2];
2321 }
2322 }
2323 #endif // CONFIG_HIGHBITDEPTH
2324 #endif // CONFIG_INTRA_EDGE_UPSAMPLE
2325
2326 #endif // CONFIG_INTRA_EDGE
2327
2328 #if CONFIG_HIGHBITDEPTH
build_intra_predictors_high(const MACROBLOCKD * xd,const uint8_t * ref8,int ref_stride,uint8_t * dst8,int dst_stride,PREDICTION_MODE mode,TX_SIZE tx_size,int n_top_px,int n_topright_px,int n_left_px,int n_bottomleft_px,int plane)2329 static void build_intra_predictors_high(
2330 const MACROBLOCKD *xd, const uint8_t *ref8, int ref_stride, uint8_t *dst8,
2331 int dst_stride, PREDICTION_MODE mode, TX_SIZE tx_size, int n_top_px,
2332 int n_topright_px, int n_left_px, int n_bottomleft_px, int plane) {
2333 int i;
2334 uint16_t *dst = CONVERT_TO_SHORTPTR(dst8);
2335 uint16_t *ref = CONVERT_TO_SHORTPTR(ref8);
2336 DECLARE_ALIGNED(16, uint16_t, left_data[MAX_TX_SIZE * 2 + 32]);
2337 DECLARE_ALIGNED(16, uint16_t, above_data[MAX_TX_SIZE * 2 + 32]);
2338 uint16_t *const above_row = above_data + 16;
2339 uint16_t *const left_col = left_data + 16;
2340 const int txwpx = tx_size_wide[tx_size];
2341 const int txhpx = tx_size_high[tx_size];
2342 #if !INTRA_USES_RECT_TRANSFORMS
2343 assert(txwpx == txhpx);
2344 #endif // !INTRA_USES_RECT_TRANSFORMS
2345 int need_left = extend_modes[mode] & NEED_LEFT;
2346 int need_above = extend_modes[mode] & NEED_ABOVE;
2347 int need_above_left = extend_modes[mode] & NEED_ABOVELEFT;
2348 const uint16_t *above_ref = ref - ref_stride;
2349 #if CONFIG_EXT_INTRA
2350 int p_angle = 0;
2351 const int is_dr_mode = av1_is_directional_mode(mode, xd->mi[0]->mbmi.sb_type);
2352 #endif // CONFIG_EXT_INTRA
2353 #if CONFIG_FILTER_INTRA
2354 const FILTER_INTRA_MODE_INFO *filter_intra_mode_info =
2355 &xd->mi[0]->mbmi.filter_intra_mode_info;
2356 const FILTER_INTRA_MODE filter_intra_mode =
2357 filter_intra_mode_info->filter_intra_mode[plane != 0];
2358 #endif // CONFIG_FILTER_INTRA
2359 int base = 128 << (xd->bd - 8);
2360
2361 // base-1 base-1 base-1 .. base-1 base-1 base-1 base-1 base-1 base-1
2362 // base+1 A B .. Y Z
2363 // base+1 C D .. W X
2364 // base+1 E F .. U V
2365 // base+1 G H .. S T T T T T
2366 aom_memset16(left_data, base + 1, sizeof(left_data) / sizeof(*left_data));
2367
2368 #if CONFIG_EXT_INTRA
2369 if (is_dr_mode) {
2370 p_angle = mode_to_angle_map[mode] +
2371 xd->mi[0]->mbmi.angle_delta[plane != 0] * ANGLE_STEP;
2372 if (p_angle <= 90)
2373 need_above = 1, need_left = 0, need_above_left = 1;
2374 else if (p_angle < 180)
2375 need_above = 1, need_left = 1, need_above_left = 1;
2376 else
2377 need_above = 0, need_left = 1, need_above_left = 1;
2378 }
2379 #endif // CONFIG_EXT_INTRA
2380 #if CONFIG_FILTER_INTRA
2381 if (filter_intra_mode_info->use_filter_intra_mode[plane != 0])
2382 need_left = need_above = need_above_left = 1;
2383 #endif // CONFIG_FILTER_INTRA
2384
2385 (void)plane;
2386 assert(n_top_px >= 0);
2387 assert(n_topright_px >= 0);
2388 assert(n_left_px >= 0);
2389 assert(n_bottomleft_px >= 0);
2390
2391 if ((!need_above && n_left_px == 0) || (!need_left && n_top_px == 0)) {
2392 #if CONFIG_INTRA_EDGE
2393 int val;
2394 if (need_left) {
2395 val = (n_top_px > 0) ? above_ref[0] : base + 1;
2396 } else {
2397 val = (n_left_px > 0) ? ref[-1] : base - 1;
2398 }
2399 #else
2400 const int val = need_left ? base + 1 : base - 1;
2401 #endif // CONFIG_INTRA_EDGE
2402 for (i = 0; i < txhpx; ++i) {
2403 aom_memset16(dst, val, txwpx);
2404 dst += dst_stride;
2405 }
2406 return;
2407 }
2408
2409 // NEED_LEFT
2410 if (need_left) {
2411 #if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA
2412 int need_bottom = !!(extend_modes[mode] & NEED_BOTTOMLEFT);
2413 #if CONFIG_FILTER_INTRA
2414 if (filter_intra_mode_info->use_filter_intra_mode[plane != 0])
2415 need_bottom = 0;
2416 #endif // CONFIG_FILTER_INTRA
2417 #if CONFIG_EXT_INTRA
2418 if (is_dr_mode) need_bottom = p_angle > 180;
2419 #endif // CONFIG_EXT_INTRA
2420 #else
2421 const int need_bottom = !!(extend_modes[mode] & NEED_BOTTOMLEFT);
2422 #endif // CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA
2423 const int num_left_pixels_needed = txhpx + (need_bottom ? txwpx : 0);
2424 i = 0;
2425 if (n_left_px > 0) {
2426 for (; i < n_left_px; i++) left_col[i] = ref[i * ref_stride - 1];
2427 if (need_bottom && n_bottomleft_px > 0) {
2428 assert(i == txhpx);
2429 for (; i < txhpx + n_bottomleft_px; i++)
2430 left_col[i] = ref[i * ref_stride - 1];
2431 }
2432 if (i < num_left_pixels_needed)
2433 aom_memset16(&left_col[i], left_col[i - 1], num_left_pixels_needed - i);
2434 } else {
2435 #if CONFIG_INTRA_EDGE
2436 if (n_top_px > 0) {
2437 aom_memset16(left_col, above_ref[0], num_left_pixels_needed);
2438 } else {
2439 #endif // CONFIG_INTRA_EDGE
2440 aom_memset16(left_col, base + 1, num_left_pixels_needed);
2441 #if CONFIG_INTRA_EDGE
2442 }
2443 #endif // CONFIG_INTRA_EDGE
2444 }
2445 }
2446
2447 // NEED_ABOVE
2448 if (need_above) {
2449 #if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA
2450 int need_right = !!(extend_modes[mode] & NEED_ABOVERIGHT);
2451 #if CONFIG_FILTER_INTRA
2452 if (filter_intra_mode_info->use_filter_intra_mode[plane != 0])
2453 need_right = 1;
2454 #endif // CONFIG_FILTER_INTRA
2455 #if CONFIG_EXT_INTRA
2456 if (is_dr_mode) need_right = p_angle < 90;
2457 #endif // CONFIG_EXT_INTRA
2458 #else
2459 const int need_right = !!(extend_modes[mode] & NEED_ABOVERIGHT);
2460 #endif // CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA
2461 const int num_top_pixels_needed = txwpx + (need_right ? txhpx : 0);
2462 if (n_top_px > 0) {
2463 memcpy(above_row, above_ref, n_top_px * sizeof(above_ref[0]));
2464 i = n_top_px;
2465 if (need_right && n_topright_px > 0) {
2466 assert(n_top_px == txwpx);
2467 memcpy(above_row + txwpx, above_ref + txwpx,
2468 n_topright_px * sizeof(above_ref[0]));
2469 i += n_topright_px;
2470 }
2471 if (i < num_top_pixels_needed)
2472 aom_memset16(&above_row[i], above_row[i - 1],
2473 num_top_pixels_needed - i);
2474 } else {
2475 #if CONFIG_INTRA_EDGE
2476 if (n_left_px > 0) {
2477 aom_memset16(above_row, ref[-1], num_top_pixels_needed);
2478 } else {
2479 #endif // CONFIG_INTRA_EDGE
2480 aom_memset16(above_row, base - 1, num_top_pixels_needed);
2481 #if CONFIG_INTRA_EDGE
2482 }
2483 #endif // CONFIG_INTRA_EDGE
2484 }
2485 }
2486
2487 if (need_above_left) {
2488 #if CONFIG_INTRA_EDGE
2489 if (n_top_px > 0 && n_left_px > 0) {
2490 above_row[-1] = above_ref[-1];
2491 } else if (n_top_px > 0) {
2492 above_row[-1] = above_ref[0];
2493 } else if (n_left_px > 0) {
2494 above_row[-1] = ref[-1];
2495 } else {
2496 above_row[-1] = base;
2497 }
2498 #else
2499 above_row[-1] =
2500 n_top_px > 0 ? (n_left_px > 0 ? above_ref[-1] : base + 1) : base - 1;
2501 #endif // CONFIG_INTRA_EDGE
2502 left_col[-1] = above_row[-1];
2503 }
2504
2505 #if CONFIG_FILTER_INTRA
2506 if (filter_intra_mode_info->use_filter_intra_mode[plane != 0]) {
2507 highbd_filter_intra_predictors(filter_intra_mode, dst, dst_stride, tx_size,
2508 above_row, left_col, xd->bd);
2509 return;
2510 }
2511 #endif // CONFIG_FILTER_INTRA
2512
2513 #if CONFIG_EXT_INTRA
2514 if (is_dr_mode) {
2515 #if CONFIG_INTRA_INTERP
2516 INTRA_FILTER filter = INTRA_FILTER_LINEAR;
2517 if (plane == 0 && av1_is_intra_filter_switchable(p_angle))
2518 filter = xd->mi[0]->mbmi.intra_filter;
2519 #endif // CONFIG_INTRA_INTERP
2520 #if CONFIG_INTRA_EDGE
2521 const int need_right = p_angle < 90;
2522 const int need_bottom = p_angle > 180;
2523 if (p_angle != 90 && p_angle != 180) {
2524 const int ab_le = need_above_left ? 1 : 0;
2525 if (need_above && n_top_px > 0) {
2526 const int strength = intra_edge_filter_strength(txwpx, p_angle - 90);
2527 const int n_px = n_top_px + ab_le + (need_right ? n_topright_px : 0);
2528 av1_filter_intra_edge_high(above_row - ab_le, n_px, strength);
2529 }
2530 if (need_left && n_left_px > 0) {
2531 const int strength = intra_edge_filter_strength(txhpx, p_angle - 180);
2532 const int n_px =
2533 n_left_px + ab_le + (need_bottom ? n_bottomleft_px : 0);
2534 av1_filter_intra_edge_high(left_col - ab_le, n_px, strength);
2535 }
2536 }
2537 #if CONFIG_INTRA_EDGE_UPSAMPLE
2538 const int upsample_above = use_intra_edge_upsample(txwpx, p_angle - 90);
2539 if (need_above && upsample_above) {
2540 const int n_px = txwpx + (need_right ? txhpx : 0);
2541 av1_upsample_intra_edge_high(above_row, n_px, xd->bd);
2542 }
2543 const int upsample_left = use_intra_edge_upsample(txhpx, p_angle - 180);
2544 if (need_left && upsample_left) {
2545 const int n_px = txhpx + (need_bottom ? txwpx : 0);
2546 av1_upsample_intra_edge_high(left_col, n_px, xd->bd);
2547 }
2548 #endif // CONFIG_INTRA_EDGE_UPSAMPLE
2549 #endif // CONFIG_INTRA_EDGE
2550 highbd_dr_predictor(dst, dst_stride, tx_size, above_row, left_col,
2551 #if CONFIG_INTRA_INTERP
2552 filter,
2553 #endif // CONFIG_INTRA_INTERP
2554 #if CONFIG_INTRA_EDGE_UPSAMPLE
2555 upsample_above, upsample_left,
2556 #endif // CONFIG_INTRA_EDGE_UPSAMPLE
2557 p_angle, xd->bd);
2558 return;
2559 }
2560 #endif // CONFIG_EXT_INTRA
2561
2562 // predict
2563 if (mode == DC_PRED) {
2564 dc_pred_high[n_left_px > 0][n_top_px > 0][tx_size](
2565 dst, dst_stride, above_row, left_col, xd->bd);
2566 } else {
2567 pred_high[mode][tx_size](dst, dst_stride, above_row, left_col, xd->bd);
2568 }
2569 }
2570 #endif // CONFIG_HIGHBITDEPTH
2571
build_intra_predictors(const MACROBLOCKD * xd,const uint8_t * ref,int ref_stride,uint8_t * dst,int dst_stride,PREDICTION_MODE mode,TX_SIZE tx_size,int n_top_px,int n_topright_px,int n_left_px,int n_bottomleft_px,int plane)2572 static void build_intra_predictors(const MACROBLOCKD *xd, const uint8_t *ref,
2573 int ref_stride, uint8_t *dst, int dst_stride,
2574 PREDICTION_MODE mode, TX_SIZE tx_size,
2575 int n_top_px, int n_topright_px,
2576 int n_left_px, int n_bottomleft_px,
2577 int plane) {
2578 int i;
2579 const uint8_t *above_ref = ref - ref_stride;
2580 DECLARE_ALIGNED(16, uint8_t, left_data[MAX_TX_SIZE * 2 + 32]);
2581 DECLARE_ALIGNED(16, uint8_t, above_data[MAX_TX_SIZE * 2 + 32]);
2582 uint8_t *const above_row = above_data + 16;
2583 uint8_t *const left_col = left_data + 16;
2584 const int txwpx = tx_size_wide[tx_size];
2585 const int txhpx = tx_size_high[tx_size];
2586 #if !INTRA_USES_RECT_TRANSFORMS
2587 assert(txwpx == txhpx);
2588 #endif // !INTRA_USES_RECT_TRANSFORMS
2589 int need_left = extend_modes[mode] & NEED_LEFT;
2590 int need_above = extend_modes[mode] & NEED_ABOVE;
2591 int need_above_left = extend_modes[mode] & NEED_ABOVELEFT;
2592 #if CONFIG_EXT_INTRA
2593 int p_angle = 0;
2594 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
2595 const int is_dr_mode = av1_is_directional_mode(mode, mbmi->sb_type);
2596 #endif // CONFIG_EXT_INTRA
2597 #if CONFIG_FILTER_INTRA
2598 const FILTER_INTRA_MODE_INFO *filter_intra_mode_info =
2599 &xd->mi[0]->mbmi.filter_intra_mode_info;
2600 const FILTER_INTRA_MODE filter_intra_mode =
2601 filter_intra_mode_info->filter_intra_mode[plane != 0];
2602 #endif // CONFIG_FILTER_INTRA
2603
2604 // 127 127 127 .. 127 127 127 127 127 127
2605 // 129 A B .. Y Z
2606 // 129 C D .. W X
2607 // 129 E F .. U V
2608 // 129 G H .. S T T T T T
2609 // ..
2610 memset(left_data, 129, sizeof(left_data));
2611
2612 #if CONFIG_EXT_INTRA
2613 if (is_dr_mode) {
2614 p_angle = mode_to_angle_map[mode] +
2615 xd->mi[0]->mbmi.angle_delta[plane != 0] * ANGLE_STEP;
2616 if (p_angle <= 90)
2617 need_above = 1, need_left = 0, need_above_left = 1;
2618 else if (p_angle < 180)
2619 need_above = 1, need_left = 1, need_above_left = 1;
2620 else
2621 need_above = 0, need_left = 1, need_above_left = 1;
2622 }
2623 #endif // CONFIG_EXT_INTRA
2624 #if CONFIG_FILTER_INTRA
2625 if (filter_intra_mode_info->use_filter_intra_mode[plane != 0])
2626 need_left = need_above = need_above_left = 1;
2627 #endif // CONFIG_FILTER_INTRA
2628
2629 (void)xd;
2630 (void)plane;
2631 assert(n_top_px >= 0);
2632 assert(n_topright_px >= 0);
2633 assert(n_left_px >= 0);
2634 assert(n_bottomleft_px >= 0);
2635
2636 if ((!need_above && n_left_px == 0) || (!need_left && n_top_px == 0)) {
2637 #if CONFIG_INTRA_EDGE
2638 int val;
2639 if (need_left) {
2640 val = (n_top_px > 0) ? above_ref[0] : 129;
2641 } else {
2642 val = (n_left_px > 0) ? ref[-1] : 127;
2643 }
2644 #else
2645 const int val = need_left ? 129 : 127;
2646 #endif // CONFIG_INTRA_EDGE
2647 for (i = 0; i < txhpx; ++i) {
2648 memset(dst, val, txwpx);
2649 dst += dst_stride;
2650 }
2651 return;
2652 }
2653
2654 // NEED_LEFT
2655 if (need_left) {
2656 #if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA
2657 int need_bottom = !!(extend_modes[mode] & NEED_BOTTOMLEFT);
2658 #if CONFIG_FILTER_INTRA
2659 if (filter_intra_mode_info->use_filter_intra_mode[plane != 0])
2660 need_bottom = 0;
2661 #endif // CONFIG_FILTER_INTRA
2662 #if CONFIG_EXT_INTRA
2663 if (is_dr_mode) need_bottom = p_angle > 180;
2664 #endif // CONFIG_EXT_INTRA
2665 #else
2666 const int need_bottom = !!(extend_modes[mode] & NEED_BOTTOMLEFT);
2667 #endif // CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA
2668 const int num_left_pixels_needed = txhpx + (need_bottom ? txwpx : 0);
2669 i = 0;
2670 if (n_left_px > 0) {
2671 for (; i < n_left_px; i++) left_col[i] = ref[i * ref_stride - 1];
2672 if (need_bottom && n_bottomleft_px > 0) {
2673 assert(i == txhpx);
2674 for (; i < txhpx + n_bottomleft_px; i++)
2675 left_col[i] = ref[i * ref_stride - 1];
2676 }
2677 if (i < num_left_pixels_needed)
2678 memset(&left_col[i], left_col[i - 1], num_left_pixels_needed - i);
2679 } else {
2680 #if CONFIG_INTRA_EDGE
2681 if (n_top_px > 0) {
2682 memset(left_col, above_ref[0], num_left_pixels_needed);
2683 } else {
2684 #endif // CONFIG_INTRA_EDGE
2685 memset(left_col, 129, num_left_pixels_needed);
2686 #if CONFIG_INTRA_EDGE
2687 }
2688 #endif // CONFIG_INTRA_EDGE
2689 }
2690 }
2691
2692 // NEED_ABOVE
2693 if (need_above) {
2694 #if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA
2695 int need_right = !!(extend_modes[mode] & NEED_ABOVERIGHT);
2696 #if CONFIG_FILTER_INTRA
2697 if (filter_intra_mode_info->use_filter_intra_mode[plane != 0])
2698 need_right = 1;
2699 #endif // CONFIG_FILTER_INTRA
2700 #if CONFIG_EXT_INTRA
2701 if (is_dr_mode) need_right = p_angle < 90;
2702 #endif // CONFIG_EXT_INTRA
2703 #else
2704 const int need_right = !!(extend_modes[mode] & NEED_ABOVERIGHT);
2705 #endif // CONFIG_EXT_INTRA || CONFIG_FITLER_INTRA
2706 const int num_top_pixels_needed = txwpx + (need_right ? txhpx : 0);
2707 if (n_top_px > 0) {
2708 memcpy(above_row, above_ref, n_top_px);
2709 i = n_top_px;
2710 if (need_right && n_topright_px > 0) {
2711 assert(n_top_px == txwpx);
2712 memcpy(above_row + txwpx, above_ref + txwpx, n_topright_px);
2713 i += n_topright_px;
2714 }
2715 if (i < num_top_pixels_needed)
2716 memset(&above_row[i], above_row[i - 1], num_top_pixels_needed - i);
2717 } else {
2718 #if CONFIG_INTRA_EDGE
2719 if (n_left_px > 0) {
2720 memset(above_row, ref[-1], num_top_pixels_needed);
2721 } else {
2722 #endif // CONFIG_INTRA_EDGE
2723 memset(above_row, 127, num_top_pixels_needed);
2724 #if CONFIG_INTRA_EDGE
2725 }
2726 #endif // CONFIG_INTRA_EDGE
2727 }
2728 }
2729
2730 if (need_above_left) {
2731 #if CONFIG_INTRA_EDGE
2732 if (n_top_px > 0 && n_left_px > 0) {
2733 above_row[-1] = above_ref[-1];
2734 } else if (n_top_px > 0) {
2735 above_row[-1] = above_ref[0];
2736 } else if (n_left_px > 0) {
2737 above_row[-1] = ref[-1];
2738 } else {
2739 above_row[-1] = 128;
2740 }
2741 #else
2742 above_row[-1] = n_top_px > 0 ? (n_left_px > 0 ? above_ref[-1] : 129) : 127;
2743 #endif // CONFIG_INTRA_EDGE
2744 left_col[-1] = above_row[-1];
2745 }
2746
2747 #if CONFIG_FILTER_INTRA
2748 if (filter_intra_mode_info->use_filter_intra_mode[plane != 0]) {
2749 filter_intra_predictors(filter_intra_mode, dst, dst_stride, tx_size,
2750 above_row, left_col);
2751 return;
2752 }
2753 #endif // CONFIG_FILTER_INTRA
2754
2755 #if CONFIG_EXT_INTRA
2756 if (is_dr_mode) {
2757 #if CONFIG_INTRA_INTERP
2758 INTRA_FILTER filter = INTRA_FILTER_LINEAR;
2759 if (plane == 0 && av1_is_intra_filter_switchable(p_angle))
2760 filter = xd->mi[0]->mbmi.intra_filter;
2761 #endif // CONFIG_INTRA_INTERP
2762 #if CONFIG_INTRA_EDGE
2763 const int need_right = p_angle < 90;
2764 const int need_bottom = p_angle > 180;
2765 if (p_angle != 90 && p_angle != 180) {
2766 const int ab_le = need_above_left ? 1 : 0;
2767 if (need_above && n_top_px > 0) {
2768 const int strength = intra_edge_filter_strength(txwpx, p_angle - 90);
2769 const int n_px = n_top_px + ab_le + (need_right ? n_topright_px : 0);
2770 av1_filter_intra_edge(above_row - ab_le, n_px, strength);
2771 }
2772 if (need_left && n_left_px > 0) {
2773 const int strength = intra_edge_filter_strength(txhpx, p_angle - 180);
2774 const int n_px =
2775 n_left_px + ab_le + (need_bottom ? n_bottomleft_px : 0);
2776 av1_filter_intra_edge(left_col - ab_le, n_px, strength);
2777 }
2778 }
2779 #if CONFIG_INTRA_EDGE_UPSAMPLE
2780 const int upsample_above = use_intra_edge_upsample(txwpx, p_angle - 90);
2781 if (need_above && upsample_above) {
2782 const int n_px = txwpx + (need_right ? txhpx : 0);
2783 av1_upsample_intra_edge(above_row, n_px);
2784 }
2785 const int upsample_left = use_intra_edge_upsample(txhpx, p_angle - 180);
2786 if (need_left && upsample_left) {
2787 const int n_px = txhpx + (need_bottom ? txwpx : 0);
2788 av1_upsample_intra_edge(left_col, n_px);
2789 }
2790 #endif // CONFIG_INTRA_EDGE_UPSAMPLE
2791 #endif // CONFIG_INTRA_EDGE
2792 dr_predictor(dst, dst_stride, tx_size, above_row, left_col,
2793 #if CONFIG_INTRA_INTERP
2794 filter,
2795 #endif // CONFIG_INTRA_INTERP
2796 #if CONFIG_INTRA_EDGE_UPSAMPLE
2797 upsample_above, upsample_left,
2798 #endif // CONFIG_INTRA_EDGE_UPSAMPLE
2799 p_angle);
2800 return;
2801 }
2802 #endif // CONFIG_EXT_INTRA
2803
2804 // predict
2805 if (mode == DC_PRED) {
2806 dc_pred[n_left_px > 0][n_top_px > 0][tx_size](dst, dst_stride, above_row,
2807 left_col);
2808 } else {
2809 pred[mode][tx_size](dst, dst_stride, above_row, left_col);
2810 }
2811 }
2812
predict_intra_block_helper(const AV1_COMMON * cm,const MACROBLOCKD * xd,int wpx,int hpx,TX_SIZE tx_size,PREDICTION_MODE mode,const uint8_t * ref,int ref_stride,uint8_t * dst,int dst_stride,int col_off,int row_off,int plane)2813 static void predict_intra_block_helper(const AV1_COMMON *cm,
2814 const MACROBLOCKD *xd, int wpx, int hpx,
2815 TX_SIZE tx_size, PREDICTION_MODE mode,
2816 const uint8_t *ref, int ref_stride,
2817 uint8_t *dst, int dst_stride,
2818 int col_off, int row_off, int plane) {
2819 BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
2820 const struct macroblockd_plane *const pd = &xd->plane[plane];
2821 const int txw = tx_size_wide_unit[tx_size];
2822 #if CONFIG_CB4X4 && CONFIG_CHROMA_SUB8X8
2823 const int have_top = row_off || (pd->subsampling_y ? xd->chroma_up_available
2824 : xd->up_available);
2825 const int have_left =
2826 col_off ||
2827 (pd->subsampling_x ? xd->chroma_left_available : xd->left_available);
2828 #else
2829 const int have_top = row_off || xd->up_available;
2830 const int have_left = col_off || xd->left_available;
2831 #endif
2832 const int x = col_off << tx_size_wide_log2[0];
2833 const int y = row_off << tx_size_high_log2[0];
2834 const int mi_row = -xd->mb_to_top_edge >> (3 + MI_SIZE_LOG2);
2835 const int mi_col = -xd->mb_to_left_edge >> (3 + MI_SIZE_LOG2);
2836 const int txwpx = tx_size_wide[tx_size];
2837 const int txhpx = tx_size_high[tx_size];
2838 #if !INTRA_USES_RECT_TRANSFORMS
2839 assert(txwpx == txhpx);
2840 #endif // !INTRA_USES_RECT_TRANSFORMS
2841 #if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2 && !CONFIG_CHROMA_SUB8X8
2842 const int xr_chr_offset = (pd->subsampling_x && bsize < BLOCK_8X8) ? 2 : 0;
2843 const int yd_chr_offset = (pd->subsampling_y && bsize < BLOCK_8X8) ? 2 : 0;
2844 #else
2845 const int xr_chr_offset = 0;
2846 const int yd_chr_offset = 0;
2847 #endif
2848
2849 // Distance between the right edge of this prediction block to
2850 // the frame right edge
2851 const int xr = (xd->mb_to_right_edge >> (3 + pd->subsampling_x)) +
2852 (wpx - x - txwpx) - xr_chr_offset;
2853 // Distance between the bottom edge of this prediction block to
2854 // the frame bottom edge
2855 const int yd = (xd->mb_to_bottom_edge >> (3 + pd->subsampling_y)) +
2856 (hpx - y - txhpx) - yd_chr_offset;
2857 const int right_available = mi_col + ((col_off + txw) << pd->subsampling_x >>
2858 (MI_SIZE_LOG2 - tx_size_wide_log2[0])) <
2859 xd->tile.mi_col_end;
2860 const int bottom_available = (yd > 0);
2861 #if CONFIG_EXT_PARTITION_TYPES && !CONFIG_EXT_PARTITION_TYPES_AB
2862 const PARTITION_TYPE partition = xd->mi[0]->mbmi.partition;
2863 #endif
2864
2865 #if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
2866 // force 4x4 chroma component block size.
2867 bsize = scale_chroma_bsize(bsize, pd->subsampling_x, pd->subsampling_y);
2868 #endif
2869
2870 const int have_top_right =
2871 has_top_right(cm, bsize, mi_row, mi_col, have_top, right_available,
2872 #if CONFIG_EXT_PARTITION_TYPES && !CONFIG_EXT_PARTITION_TYPES_AB
2873 partition,
2874 #endif // CONFIG_EXT_PARTITION_TYPES && !CONFIG_EXT_PARTITION_TYPES_AB
2875 tx_size, row_off, col_off, pd->subsampling_x);
2876 const int have_bottom_left =
2877 has_bottom_left(cm, bsize, mi_row, mi_col, bottom_available, have_left,
2878 tx_size, row_off, col_off, pd->subsampling_y);
2879 if (xd->mi[0]->mbmi.palette_mode_info.palette_size[plane != 0] > 0) {
2880 const int stride = wpx;
2881 int r, c;
2882 const uint8_t *const map = xd->plane[plane != 0].color_index_map;
2883 uint16_t *palette = xd->mi[0]->mbmi.palette_mode_info.palette_colors +
2884 plane * PALETTE_MAX_SIZE;
2885
2886 #if CONFIG_HIGHBITDEPTH
2887 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2888 uint16_t *dst16 = CONVERT_TO_SHORTPTR(dst);
2889 for (r = 0; r < txhpx; ++r) {
2890 for (c = 0; c < txwpx; ++c) {
2891 dst16[r * dst_stride + c] = palette[map[(r + y) * stride + c + x]];
2892 }
2893 }
2894 } else {
2895 #endif // CONFIG_HIGHBITDEPTH
2896 for (r = 0; r < txhpx; ++r) {
2897 for (c = 0; c < txwpx; ++c) {
2898 dst[r * dst_stride + c] =
2899 (uint8_t)palette[map[(r + y) * stride + c + x]];
2900 }
2901 }
2902 #if CONFIG_HIGHBITDEPTH
2903 }
2904 #endif // CONFIG_HIGHBITDEPTH
2905 return;
2906 }
2907
2908 #if CONFIG_HIGHBITDEPTH
2909 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
2910 build_intra_predictors_high(
2911 xd, ref, ref_stride, dst, dst_stride, mode, tx_size,
2912 have_top ? AOMMIN(txwpx, xr + txwpx) : 0,
2913 have_top_right ? AOMMIN(txwpx, xr) : 0,
2914 have_left ? AOMMIN(txhpx, yd + txhpx) : 0,
2915 have_bottom_left ? AOMMIN(txhpx, yd) : 0, plane);
2916 return;
2917 }
2918 #endif
2919 build_intra_predictors(xd, ref, ref_stride, dst, dst_stride, mode, tx_size,
2920 have_top ? AOMMIN(txwpx, xr + txwpx) : 0,
2921 have_top_right ? AOMMIN(txwpx, xr) : 0,
2922 have_left ? AOMMIN(txhpx, yd + txhpx) : 0,
2923 have_bottom_left ? AOMMIN(txhpx, yd) : 0, plane);
2924 }
2925
av1_predict_intra_block_facade(const AV1_COMMON * cm,MACROBLOCKD * xd,int plane,int block_idx,int blk_col,int blk_row,TX_SIZE tx_size)2926 void av1_predict_intra_block_facade(const AV1_COMMON *cm, MACROBLOCKD *xd,
2927 int plane, int block_idx, int blk_col,
2928 int blk_row, TX_SIZE tx_size) {
2929 const MODE_INFO *mi = xd->mi[0];
2930 const MB_MODE_INFO *const mbmi = &mi->mbmi;
2931 struct macroblockd_plane *const pd = &xd->plane[plane];
2932 const int dst_stride = pd->dst.stride;
2933 uint8_t *dst =
2934 &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
2935 const int block_raster_idx =
2936 av1_block_index_to_raster_order(tx_size, block_idx);
2937 const PREDICTION_MODE mode = (plane == AOM_PLANE_Y)
2938 ? get_y_mode(mi, block_raster_idx)
2939 : get_uv_mode(mbmi->uv_mode);
2940 #if CONFIG_CFL
2941 if (plane != AOM_PLANE_Y && mbmi->uv_mode == UV_CFL_PRED) {
2942 if (plane == AOM_PLANE_U && blk_col == 0 && blk_row == 0) {
2943 // Avoid computing the CfL parameters twice, if they have already been
2944 // computed in cfl_rd_pick_alpha.
2945 if (!xd->cfl->are_parameters_computed)
2946 cfl_compute_parameters(xd, tx_size);
2947 }
2948 cfl_predict_block(xd, dst, dst_stride, blk_row, blk_col, tx_size, plane);
2949 return;
2950 }
2951 #endif
2952
2953 av1_predict_intra_block(cm, xd, pd->width, pd->height,
2954 txsize_to_bsize[tx_size], mode, dst, dst_stride, dst,
2955 dst_stride, blk_col, blk_row, plane);
2956 }
2957
2958 #if INTRA_USES_EXT_TRANSFORMS
2959 // Copy the given row of dst into the equivalent row of ref, saving
2960 // the overwritten data to tmp. Returns zero if no copy happened (so
2961 // no restore is needed)
2962 //
2963 // Note that ref_row and dst_row follow the usual hibd convention
2964 // where you convert to a uint16_t* with CONVERT_TO_SHORTPTR(). tmp
2965 // does not follow that convention: it's a genuine pointer which is
2966 // correctly aligned and sized for either 8 or 16 bit data.
2967 //
2968 // matching_strides is a boolean flag which should be nonzero if ref
2969 // and dst have the same stride.
overwrite_ref_row(int matching_strides,int buf_flags,int block_width,const uint8_t * dst_row,uint8_t * ref_row,uint8_t * tmp_row)2970 static int overwrite_ref_row(int matching_strides, int buf_flags,
2971 int block_width, const uint8_t *dst_row,
2972 uint8_t *ref_row, uint8_t *tmp_row) {
2973 if (ref_row == dst_row && matching_strides) return 0;
2974
2975 int row_bytes = block_width;
2976
2977 #if CONFIG_HIGHBITDEPTH
2978 if (buf_flags & YV12_FLAG_HIGHBITDEPTH) {
2979 row_bytes *= 2;
2980 ref_row = (uint8_t *)CONVERT_TO_SHORTPTR(ref_row);
2981 dst_row = (const uint8_t *)CONVERT_TO_SHORTPTR(dst_row);
2982 }
2983 #else
2984 (void)buf_flags;
2985 #endif // CONFIG_HIGHBITDEPTH
2986
2987 memcpy(tmp_row, ref_row, row_bytes);
2988 memcpy(ref_row, dst_row, row_bytes);
2989 return 1;
2990 }
2991
restore_ref_row(int buf_flags,int block_width,const uint8_t * tmp_row,uint8_t * ref_row)2992 static void restore_ref_row(int buf_flags, int block_width,
2993 const uint8_t *tmp_row, uint8_t *ref_row) {
2994 int row_bytes = block_width;
2995 #if CONFIG_HIGHBITDEPTH
2996 if (buf_flags & YV12_FLAG_HIGHBITDEPTH) {
2997 row_bytes *= 2;
2998 ref_row = (uint8_t *)CONVERT_TO_SHORTPTR(ref_row);
2999 }
3000 #else
3001 (void)buf_flags;
3002 #endif // CONFIG_HIGHBITDEPTH
3003
3004 memcpy(ref_row, tmp_row, row_bytes);
3005 }
3006
3007 // The column equivalent of overwrite_ref_row. ref_row and dst_row
3008 // point at the relevant column of the first row of the block.
overwrite_ref_col(int buf_flags,int block_height,const uint8_t * dst_row,int dst_stride,uint8_t * ref_row,int ref_stride,uint8_t * tmp_row)3009 static int overwrite_ref_col(int buf_flags, int block_height,
3010 const uint8_t *dst_row, int dst_stride,
3011 uint8_t *ref_row, int ref_stride,
3012 uint8_t *tmp_row) {
3013 if (ref_row == dst_row && ref_stride == dst_stride) return 0;
3014
3015 #if CONFIG_HIGHBITDEPTH
3016 if (buf_flags & YV12_FLAG_HIGHBITDEPTH) {
3017 uint16_t *tmp_16 = (uint16_t *)tmp_row;
3018 uint16_t *ref_16 = CONVERT_TO_SHORTPTR(ref_row);
3019 const uint16_t *dst_16 = CONVERT_TO_SHORTPTR(dst_row);
3020
3021 for (int i = 0; i < block_height; ++i) {
3022 tmp_16[i] = ref_16[i * ref_stride];
3023 ref_16[i * ref_stride] = dst_16[i * dst_stride];
3024 }
3025 } else {
3026 #endif // CONFIG_HIGHBITDEPTH
3027 for (int i = 0; i < block_height; ++i) {
3028 tmp_row[i] = ref_row[i * ref_stride];
3029 ref_row[i * ref_stride] = dst_row[i * dst_stride];
3030 }
3031 #if CONFIG_HIGHBITDEPTH
3032 }
3033 #else
3034 (void)buf_flags;
3035 #endif // CONFIG_HIGHBITDEPTH
3036 return 1;
3037 }
3038
restore_ref_col(int buf_flags,int block_height,const uint8_t * tmp_row,uint8_t * ref_row,int ref_stride)3039 static void restore_ref_col(int buf_flags, int block_height,
3040 const uint8_t *tmp_row, uint8_t *ref_row,
3041 int ref_stride) {
3042 #if CONFIG_HIGHBITDEPTH
3043 if (buf_flags & YV12_FLAG_HIGHBITDEPTH) {
3044 const uint16_t *tmp_16 = (const uint16_t *)tmp_row;
3045 uint16_t *ref_16 = CONVERT_TO_SHORTPTR(ref_row);
3046
3047 for (int i = 0; i < block_height; ++i) {
3048 ref_16[i * ref_stride] = tmp_16[i];
3049 }
3050 } else {
3051 #endif // CONFIG_HIGHBITDEPTH
3052 for (int i = 0; i < block_height; ++i) {
3053 ref_row[i * ref_stride] = tmp_row[i];
3054 }
3055 #if CONFIG_HIGHBITDEPTH
3056 }
3057 #else
3058 (void)buf_flags;
3059 #endif // CONFIG_HIGHBITDEPTH
3060 }
3061 #endif // #if INTRA_USES_EXT_TRANSFORMS
3062
av1_predict_intra_block(const AV1_COMMON * cm,const MACROBLOCKD * xd,int wpx,int hpx,BLOCK_SIZE bsize,PREDICTION_MODE mode,const uint8_t * ref,int ref_stride,uint8_t * dst,int dst_stride,int col_off,int row_off,int plane)3063 void av1_predict_intra_block(const AV1_COMMON *cm, const MACROBLOCKD *xd,
3064 int wpx, int hpx, BLOCK_SIZE bsize,
3065 PREDICTION_MODE mode, const uint8_t *ref,
3066 int ref_stride, uint8_t *dst, int dst_stride,
3067 int col_off, int row_off, int plane) {
3068 const int block_width = block_size_wide[bsize];
3069 const int block_height = block_size_high[bsize];
3070 #if INTRA_USES_RECT_TRANSFORMS
3071 const TX_SIZE tx_size = max_txsize_rect_lookup[bsize];
3072 assert(tx_size < TX_SIZES_ALL);
3073 #else
3074 const TX_SIZE tx_size = max_txsize_lookup[bsize];
3075 assert(tx_size < TX_SIZES);
3076 #endif // INTRA_USES_RECT_TRANSFORMS
3077
3078 // Start by running the helper to predict either the entire block
3079 // (if the block is square or the same size as tx_size) or the top
3080 // or left of the block if it's tall and thin or short and wide.
3081 predict_intra_block_helper(cm, xd, wpx, hpx, tx_size, mode, ref, ref_stride,
3082 dst, dst_stride, col_off, row_off, plane);
3083
3084 // If we're not using extended transforms, this function should
3085 // always be called with a square block.
3086 #if !INTRA_USES_EXT_TRANSFORMS
3087 assert(block_width == block_height);
3088 #endif // !INTRA_USES_EXT_TRANSFORMS
3089
3090 // If the block is square, we're done.
3091 if (block_width == block_height) return;
3092
3093 #if INTRA_USES_EXT_TRANSFORMS
3094 // If we're using rectangular transforms, we might be done even
3095 // though the block isn't square.
3096 #if INTRA_USES_RECT_TRANSFORMS
3097 if (block_width == tx_size_wide[tx_size] &&
3098 block_height == tx_size_high[tx_size])
3099 return;
3100
3101 // A block should only fail to have a matching transform if it's
3102 // large and rectangular (such large transform sizes aren't
3103 // available).
3104 assert(block_width >= 32 && block_height >= 32);
3105 #endif // INTRA_USES_RECT_TRANSFORMS
3106
3107 assert((block_width == wpx && block_height == hpx) ||
3108 (block_width == (wpx >> 1) && block_height == hpx) ||
3109 (block_width == wpx && block_height == (hpx >> 1)));
3110
3111 // The tmp buffer needs to be big enough to hold MAX_SB_SIZE samples
3112 // from the image. If CONFIG_HIGHBITDEPTH is enabled, it also needs
3113 // to be big enough and correctly aligned to hold 16-bit entries.
3114 #if CONFIG_HIGHBITDEPTH
3115 uint16_t tmp_buf[MAX_SB_SIZE];
3116 #else
3117 uint8_t tmp_buf[MAX_SB_SIZE];
3118 #endif // CONFIG_HIGHBITDEPTH
3119 uint8_t *tmp = (uint8_t *)tmp_buf;
3120
3121 if (block_width < block_height) {
3122 // The block is tall and thin. We've already done the top part,
3123 // and need to repeat the prediction down the rest of the block.
3124
3125 const int tx_height = tx_size_high[tx_size];
3126 const int tx_height_off = tx_height >> tx_size_wide_log2[0];
3127 assert(tx_height_off << tx_size_wide_log2[0] == tx_height);
3128
3129 int next_row_off = row_off + tx_height_off;
3130 int next_row_idx = tx_height;
3131
3132 while (next_row_idx < block_height) {
3133 const int last_row_idx = next_row_idx - 1;
3134
3135 // Cast away the const to make a mutable pointer to the last
3136 // row of ref. This will be snapshotted and restored later.
3137 uint8_t *last_ref_row = (uint8_t *)ref + last_row_idx * ref_stride;
3138 uint8_t *last_dst_row = dst + last_row_idx * dst_stride;
3139
3140 const int needs_restore =
3141 overwrite_ref_row(ref_stride == dst_stride, xd->cur_buf->flags,
3142 block_width, last_dst_row, last_ref_row, tmp);
3143
3144 const uint8_t *next_ref_row = ref + next_row_idx * ref_stride;
3145 uint8_t *next_dst_row = dst + next_row_idx * dst_stride;
3146
3147 predict_intra_block_helper(cm, xd, wpx, hpx, tx_size, mode, next_ref_row,
3148 ref_stride, next_dst_row, dst_stride, col_off,
3149 next_row_off, plane);
3150
3151 if (needs_restore)
3152 restore_ref_row(xd->cur_buf->flags, block_width, tmp, last_ref_row);
3153
3154 next_row_idx += tx_height;
3155 next_row_off += tx_height_off;
3156 }
3157 } else {
3158 // The block is short and wide. We've already done the left part,
3159 // and need to repeat the prediction to the right.
3160
3161 const int tx_width = tx_size_wide[tx_size];
3162 const int tx_width_off = tx_width >> tx_size_wide_log2[0];
3163 assert(tx_width_off << tx_size_wide_log2[0] == tx_width);
3164
3165 int next_col_off = col_off + tx_width_off;
3166 int next_col_idx = tx_width;
3167
3168 while (next_col_idx < block_width) {
3169 const int last_col_idx = next_col_idx - 1;
3170
3171 // Cast away the const to make a mutable pointer to ref,
3172 // starting at the last column written. This will be
3173 // snapshotted and restored later.
3174 uint8_t *last_ref_col = (uint8_t *)ref + last_col_idx;
3175 uint8_t *last_dst_col = dst + last_col_idx;
3176
3177 const int needs_restore =
3178 overwrite_ref_col(xd->cur_buf->flags, block_height, last_dst_col,
3179 dst_stride, last_ref_col, ref_stride, tmp);
3180
3181 const uint8_t *next_ref_col = ref + next_col_idx;
3182 uint8_t *next_dst_col = dst + next_col_idx;
3183
3184 predict_intra_block_helper(cm, xd, wpx, hpx, tx_size, mode, next_ref_col,
3185 ref_stride, next_dst_col, dst_stride,
3186 next_col_off, row_off, plane);
3187
3188 if (needs_restore)
3189 restore_ref_col(xd->cur_buf->flags, block_height, tmp, last_ref_col,
3190 ref_stride);
3191
3192 next_col_idx += tx_width;
3193 next_col_off += tx_width_off;
3194 }
3195 }
3196 #endif // INTRA_USES_EXT_TRANSFORMS
3197 }
3198
av1_init_intra_predictors(void)3199 void av1_init_intra_predictors(void) {
3200 once(av1_init_intra_predictors_internal);
3201 }
3202