Coverage Report

Created: 2025-07-23 08:18

/src/aom/av1/common/reconintra.c
Line
Count
Source (jump to first uncovered line)
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 "config/aom_config.h"
15
#include "config/aom_dsp_rtcd.h"
16
#include "config/av1_rtcd.h"
17
18
#include "aom_dsp/aom_dsp_common.h"
19
#include "aom_mem/aom_mem.h"
20
#include "aom_ports/aom_once.h"
21
#include "aom_ports/mem.h"
22
#include "av1/common/av1_common_int.h"
23
#include "av1/common/cfl.h"
24
#include "av1/common/reconintra.h"
25
26
enum {
27
  NEED_LEFT = 1 << 1,
28
  NEED_ABOVE = 1 << 2,
29
  NEED_ABOVERIGHT = 1 << 3,
30
  NEED_ABOVELEFT = 1 << 4,
31
  NEED_BOTTOMLEFT = 1 << 5,
32
};
33
34
#define INTRA_EDGE_FILT 3
35
524M
#define INTRA_EDGE_TAPS 5
36
#define MAX_UPSAMPLE_SZ 16
37
72.7M
#define NUM_INTRA_NEIGHBOUR_PIXELS (MAX_TX_SIZE * 2 + 32)
38
39
static const uint8_t extend_modes[INTRA_MODES] = {
40
  NEED_ABOVE | NEED_LEFT,                   // DC
41
  NEED_ABOVE,                               // V
42
  NEED_LEFT,                                // H
43
  NEED_ABOVE | NEED_ABOVERIGHT,             // D45
44
  NEED_LEFT | NEED_ABOVE | NEED_ABOVELEFT,  // D135
45
  NEED_LEFT | NEED_ABOVE | NEED_ABOVELEFT,  // D113
46
  NEED_LEFT | NEED_ABOVE | NEED_ABOVELEFT,  // D157
47
  NEED_LEFT | NEED_BOTTOMLEFT,              // D203
48
  NEED_ABOVE | NEED_ABOVERIGHT,             // D67
49
  NEED_LEFT | NEED_ABOVE,                   // SMOOTH
50
  NEED_LEFT | NEED_ABOVE,                   // SMOOTH_V
51
  NEED_LEFT | NEED_ABOVE,                   // SMOOTH_H
52
  NEED_LEFT | NEED_ABOVE | NEED_ABOVELEFT,  // PAETH
53
};
54
55
// Tables to store if the top-right reference pixels are available. The flags
56
// are represented with bits, packed into 8-bit integers. E.g., for the 32x32
57
// blocks in a 128x128 superblock, the index of the "o" block is 10 (in raster
58
// order), so its flag is stored at the 3rd bit of the 2nd entry in the table,
59
// i.e. (table[10 / 8] >> (10 % 8)) & 1.
60
//       . . . .
61
//       . . . .
62
//       . . o .
63
//       . . . .
64
static uint8_t has_tr_4x4[128] = {
65
  255, 255, 255, 255, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85,
66
  127, 127, 127, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85,
67
  255, 127, 255, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85,
68
  127, 127, 127, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85,
69
  255, 255, 255, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85,
70
  127, 127, 127, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85,
71
  255, 127, 255, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85,
72
  127, 127, 127, 127, 85, 85, 85, 85, 119, 119, 119, 119, 85, 85, 85, 85,
73
};
74
static uint8_t has_tr_4x8[64] = {
75
  255, 255, 255, 255, 119, 119, 119, 119, 127, 127, 127, 127, 119,
76
  119, 119, 119, 255, 127, 255, 127, 119, 119, 119, 119, 127, 127,
77
  127, 127, 119, 119, 119, 119, 255, 255, 255, 127, 119, 119, 119,
78
  119, 127, 127, 127, 127, 119, 119, 119, 119, 255, 127, 255, 127,
79
  119, 119, 119, 119, 127, 127, 127, 127, 119, 119, 119, 119,
80
};
81
static uint8_t has_tr_8x4[64] = {
82
  255, 255, 0, 0, 85, 85, 0, 0, 119, 119, 0, 0, 85, 85, 0, 0,
83
  127, 127, 0, 0, 85, 85, 0, 0, 119, 119, 0, 0, 85, 85, 0, 0,
84
  255, 127, 0, 0, 85, 85, 0, 0, 119, 119, 0, 0, 85, 85, 0, 0,
85
  127, 127, 0, 0, 85, 85, 0, 0, 119, 119, 0, 0, 85, 85, 0, 0,
86
};
87
static uint8_t has_tr_8x8[32] = {
88
  255, 255, 85, 85, 119, 119, 85, 85, 127, 127, 85, 85, 119, 119, 85, 85,
89
  255, 127, 85, 85, 119, 119, 85, 85, 127, 127, 85, 85, 119, 119, 85, 85,
90
};
91
static uint8_t has_tr_8x16[16] = {
92
  255, 255, 119, 119, 127, 127, 119, 119,
93
  255, 127, 119, 119, 127, 127, 119, 119,
94
};
95
static uint8_t has_tr_16x8[16] = {
96
  255, 0, 85, 0, 119, 0, 85, 0, 127, 0, 85, 0, 119, 0, 85, 0,
97
};
98
static uint8_t has_tr_16x16[8] = {
99
  255, 85, 119, 85, 127, 85, 119, 85,
100
};
101
static uint8_t has_tr_16x32[4] = { 255, 119, 127, 119 };
102
static uint8_t has_tr_32x16[4] = { 15, 5, 7, 5 };
103
static uint8_t has_tr_32x32[2] = { 95, 87 };
104
static uint8_t has_tr_32x64[1] = { 127 };
105
static uint8_t has_tr_64x32[1] = { 19 };
106
static uint8_t has_tr_64x64[1] = { 7 };
107
static uint8_t has_tr_64x128[1] = { 3 };
108
static uint8_t has_tr_128x64[1] = { 1 };
109
static uint8_t has_tr_128x128[1] = { 1 };
110
static uint8_t has_tr_4x16[32] = {
111
  255, 255, 255, 255, 127, 127, 127, 127, 255, 127, 255,
112
  127, 127, 127, 127, 127, 255, 255, 255, 127, 127, 127,
113
  127, 127, 255, 127, 255, 127, 127, 127, 127, 127,
114
};
115
static uint8_t has_tr_16x4[32] = {
116
  255, 0, 0, 0, 85, 0, 0, 0, 119, 0, 0, 0, 85, 0, 0, 0,
117
  127, 0, 0, 0, 85, 0, 0, 0, 119, 0, 0, 0, 85, 0, 0, 0,
118
};
119
static uint8_t has_tr_8x32[8] = {
120
  255, 255, 127, 127, 255, 127, 127, 127,
121
};
122
static uint8_t has_tr_32x8[8] = {
123
  15, 0, 5, 0, 7, 0, 5, 0,
124
};
125
static uint8_t has_tr_16x64[2] = { 255, 127 };
126
static uint8_t has_tr_64x16[2] = { 3, 1 };
127
128
static const uint8_t *const has_tr_tables[BLOCK_SIZES_ALL] = {
129
  // 4X4
130
  has_tr_4x4,
131
  // 4X8,       8X4,            8X8
132
  has_tr_4x8, has_tr_8x4, has_tr_8x8,
133
  // 8X16,      16X8,           16X16
134
  has_tr_8x16, has_tr_16x8, has_tr_16x16,
135
  // 16X32,     32X16,          32X32
136
  has_tr_16x32, has_tr_32x16, has_tr_32x32,
137
  // 32X64,     64X32,          64X64
138
  has_tr_32x64, has_tr_64x32, has_tr_64x64,
139
  // 64x128,    128x64,         128x128
140
  has_tr_64x128, has_tr_128x64, has_tr_128x128,
141
  // 4x16,      16x4,            8x32
142
  has_tr_4x16, has_tr_16x4, has_tr_8x32,
143
  // 32x8,      16x64,           64x16
144
  has_tr_32x8, has_tr_16x64, has_tr_64x16
145
};
146
147
static uint8_t has_tr_vert_8x8[32] = {
148
  255, 255, 0, 0, 119, 119, 0, 0, 127, 127, 0, 0, 119, 119, 0, 0,
149
  255, 127, 0, 0, 119, 119, 0, 0, 127, 127, 0, 0, 119, 119, 0, 0,
150
};
151
static uint8_t has_tr_vert_16x16[8] = {
152
  255, 0, 119, 0, 127, 0, 119, 0,
153
};
154
static uint8_t has_tr_vert_32x32[2] = { 15, 7 };
155
static uint8_t has_tr_vert_64x64[1] = { 3 };
156
157
// The _vert_* tables are like the ordinary tables above, but describe the
158
// order we visit square blocks when doing a PARTITION_VERT_A or
159
// PARTITION_VERT_B. This is the same order as normal except for on the last
160
// split where we go vertically (TL, BL, TR, BR). We treat the rectangular block
161
// as a pair of squares, which means that these tables work correctly for both
162
// mixed vertical partition types.
163
//
164
// There are tables for each of the square sizes. Vertical rectangles (like
165
// BLOCK_16X32) use their respective "non-vert" table
166
static const uint8_t *const has_tr_vert_tables[BLOCK_SIZES] = {
167
  // 4X4
168
  NULL,
169
  // 4X8,      8X4,         8X8
170
  has_tr_4x8, NULL, has_tr_vert_8x8,
171
  // 8X16,     16X8,        16X16
172
  has_tr_8x16, NULL, has_tr_vert_16x16,
173
  // 16X32,    32X16,       32X32
174
  has_tr_16x32, NULL, has_tr_vert_32x32,
175
  // 32X64,    64X32,       64X64
176
  has_tr_32x64, NULL, has_tr_vert_64x64,
177
  // 64x128,   128x64,      128x128
178
  has_tr_64x128, NULL, has_tr_128x128
179
};
180
181
static const uint8_t *get_has_tr_table(PARTITION_TYPE partition,
182
14.9M
                                       BLOCK_SIZE bsize) {
183
14.9M
  const uint8_t *ret = NULL;
184
  // If this is a mixed vertical partition, look up bsize in orders_vert.
185
14.9M
  if (partition == PARTITION_VERT_A || partition == PARTITION_VERT_B) {
186
1.25M
    assert(bsize < BLOCK_SIZES);
187
1.25M
    ret = has_tr_vert_tables[bsize];
188
13.7M
  } else {
189
13.7M
    ret = has_tr_tables[bsize];
190
13.7M
  }
191
14.9M
  assert(ret);
192
14.9M
  return ret;
193
14.9M
}
194
195
static int has_top_right(BLOCK_SIZE sb_size, BLOCK_SIZE bsize, int mi_row,
196
                         int mi_col, int top_available, int right_available,
197
                         PARTITION_TYPE partition, TX_SIZE txsz, int row_off,
198
36.3M
                         int col_off, int ss_x, int ss_y) {
199
36.3M
  if (!top_available || !right_available) return 0;
200
201
33.7M
  const int bw_unit = mi_size_wide[bsize];
202
33.7M
  const int plane_bw_unit = AOMMAX(bw_unit >> ss_x, 1);
203
33.7M
  const int top_right_count_unit = tx_size_wide_unit[txsz];
204
205
33.7M
  if (row_off > 0) {  // Just need to check if enough pixels on the right.
206
11.0M
    if (block_size_wide[bsize] > block_size_wide[BLOCK_64X64]) {
207
      // Special case: For 128x128 blocks, the transform unit whose
208
      // top-right corner is at the center of the block does in fact have
209
      // pixels available at its top-right corner.
210
5.22M
      if (row_off == mi_size_high[BLOCK_64X64] >> ss_y &&
211
5.22M
          col_off + top_right_count_unit == mi_size_wide[BLOCK_64X64] >> ss_x) {
212
205k
        return 1;
213
205k
      }
214
5.02M
      const int plane_bw_unit_64 = mi_size_wide[BLOCK_64X64] >> ss_x;
215
5.02M
      const int col_off_64 = col_off % plane_bw_unit_64;
216
5.02M
      return col_off_64 + top_right_count_unit < plane_bw_unit_64;
217
5.22M
    }
218
5.77M
    return col_off + top_right_count_unit < plane_bw_unit;
219
22.7M
  } else {
220
    // All top-right pixels are in the block above, which is already available.
221
22.7M
    if (col_off + top_right_count_unit < plane_bw_unit) return 1;
222
223
20.6M
    const int bw_in_mi_log2 = mi_size_wide_log2[bsize];
224
20.6M
    const int bh_in_mi_log2 = mi_size_high_log2[bsize];
225
20.6M
    const int sb_mi_size = mi_size_high[sb_size];
226
20.6M
    const int blk_row_in_sb = (mi_row & (sb_mi_size - 1)) >> bh_in_mi_log2;
227
20.6M
    const int blk_col_in_sb = (mi_col & (sb_mi_size - 1)) >> bw_in_mi_log2;
228
229
    // Top row of superblock: so top-right pixels are in the top and/or
230
    // top-right superblocks, both of which are already available.
231
20.6M
    if (blk_row_in_sb == 0) return 1;
232
233
    // Rightmost column of superblock (and not the top row): so top-right pixels
234
    // fall in the right superblock, which is not available yet.
235
17.3M
    if (((blk_col_in_sb + 1) << bw_in_mi_log2) >= sb_mi_size) {
236
2.35M
      return 0;
237
2.35M
    }
238
239
    // General case (neither top row nor rightmost column): check if the
240
    // top-right block is coded before the current block.
241
14.9M
    const int this_blk_index =
242
14.9M
        ((blk_row_in_sb + 0) << (MAX_MIB_SIZE_LOG2 - bw_in_mi_log2)) +
243
14.9M
        blk_col_in_sb + 0;
244
14.9M
    const int idx1 = this_blk_index / 8;
245
14.9M
    const int idx2 = this_blk_index % 8;
246
14.9M
    const uint8_t *has_tr_table = get_has_tr_table(partition, bsize);
247
14.9M
    return (has_tr_table[idx1] >> idx2) & 1;
248
17.3M
  }
249
33.7M
}
250
251
// Similar to the has_tr_* tables, but store if the bottom-left reference
252
// pixels are available.
253
static uint8_t has_bl_4x4[128] = {
254
  84, 85, 85, 85, 16, 17, 17, 17, 84, 85, 85, 85, 0,  1,  1,  1,  84, 85, 85,
255
  85, 16, 17, 17, 17, 84, 85, 85, 85, 0,  0,  1,  0,  84, 85, 85, 85, 16, 17,
256
  17, 17, 84, 85, 85, 85, 0,  1,  1,  1,  84, 85, 85, 85, 16, 17, 17, 17, 84,
257
  85, 85, 85, 0,  0,  0,  0,  84, 85, 85, 85, 16, 17, 17, 17, 84, 85, 85, 85,
258
  0,  1,  1,  1,  84, 85, 85, 85, 16, 17, 17, 17, 84, 85, 85, 85, 0,  0,  1,
259
  0,  84, 85, 85, 85, 16, 17, 17, 17, 84, 85, 85, 85, 0,  1,  1,  1,  84, 85,
260
  85, 85, 16, 17, 17, 17, 84, 85, 85, 85, 0,  0,  0,  0,
261
};
262
static uint8_t has_bl_4x8[64] = {
263
  16, 17, 17, 17, 0, 1, 1, 1, 16, 17, 17, 17, 0, 0, 1, 0,
264
  16, 17, 17, 17, 0, 1, 1, 1, 16, 17, 17, 17, 0, 0, 0, 0,
265
  16, 17, 17, 17, 0, 1, 1, 1, 16, 17, 17, 17, 0, 0, 1, 0,
266
  16, 17, 17, 17, 0, 1, 1, 1, 16, 17, 17, 17, 0, 0, 0, 0,
267
};
268
static uint8_t has_bl_8x4[64] = {
269
  254, 255, 84, 85, 254, 255, 16, 17, 254, 255, 84, 85, 254, 255, 0, 1,
270
  254, 255, 84, 85, 254, 255, 16, 17, 254, 255, 84, 85, 254, 255, 0, 0,
271
  254, 255, 84, 85, 254, 255, 16, 17, 254, 255, 84, 85, 254, 255, 0, 1,
272
  254, 255, 84, 85, 254, 255, 16, 17, 254, 255, 84, 85, 254, 255, 0, 0,
273
};
274
static uint8_t has_bl_8x8[32] = {
275
  84, 85, 16, 17, 84, 85, 0, 1, 84, 85, 16, 17, 84, 85, 0, 0,
276
  84, 85, 16, 17, 84, 85, 0, 1, 84, 85, 16, 17, 84, 85, 0, 0,
277
};
278
static uint8_t has_bl_8x16[16] = {
279
  16, 17, 0, 1, 16, 17, 0, 0, 16, 17, 0, 1, 16, 17, 0, 0,
280
};
281
static uint8_t has_bl_16x8[16] = {
282
  254, 84, 254, 16, 254, 84, 254, 0, 254, 84, 254, 16, 254, 84, 254, 0,
283
};
284
static uint8_t has_bl_16x16[8] = {
285
  84, 16, 84, 0, 84, 16, 84, 0,
286
};
287
static uint8_t has_bl_16x32[4] = { 16, 0, 16, 0 };
288
static uint8_t has_bl_32x16[4] = { 78, 14, 78, 14 };
289
static uint8_t has_bl_32x32[2] = { 4, 4 };
290
static uint8_t has_bl_32x64[1] = { 0 };
291
static uint8_t has_bl_64x32[1] = { 34 };
292
static uint8_t has_bl_64x64[1] = { 0 };
293
static uint8_t has_bl_64x128[1] = { 0 };
294
static uint8_t has_bl_128x64[1] = { 0 };
295
static uint8_t has_bl_128x128[1] = { 0 };
296
static uint8_t has_bl_4x16[32] = {
297
  0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0,
298
  0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0,
299
};
300
static uint8_t has_bl_16x4[32] = {
301
  254, 254, 254, 84, 254, 254, 254, 16, 254, 254, 254, 84, 254, 254, 254, 0,
302
  254, 254, 254, 84, 254, 254, 254, 16, 254, 254, 254, 84, 254, 254, 254, 0,
303
};
304
static uint8_t has_bl_8x32[8] = {
305
  0, 1, 0, 0, 0, 1, 0, 0,
306
};
307
static uint8_t has_bl_32x8[8] = {
308
  238, 78, 238, 14, 238, 78, 238, 14,
309
};
310
static uint8_t has_bl_16x64[2] = { 0, 0 };
311
static uint8_t has_bl_64x16[2] = { 42, 42 };
312
313
static const uint8_t *const has_bl_tables[BLOCK_SIZES_ALL] = {
314
  // 4X4
315
  has_bl_4x4,
316
  // 4X8,         8X4,         8X8
317
  has_bl_4x8, has_bl_8x4, has_bl_8x8,
318
  // 8X16,        16X8,        16X16
319
  has_bl_8x16, has_bl_16x8, has_bl_16x16,
320
  // 16X32,       32X16,       32X32
321
  has_bl_16x32, has_bl_32x16, has_bl_32x32,
322
  // 32X64,       64X32,       64X64
323
  has_bl_32x64, has_bl_64x32, has_bl_64x64,
324
  // 64x128,      128x64,      128x128
325
  has_bl_64x128, has_bl_128x64, has_bl_128x128,
326
  // 4x16,        16x4,        8x32
327
  has_bl_4x16, has_bl_16x4, has_bl_8x32,
328
  // 32x8,        16x64,       64x16
329
  has_bl_32x8, has_bl_16x64, has_bl_64x16
330
};
331
332
static uint8_t has_bl_vert_8x8[32] = {
333
  254, 255, 16, 17, 254, 255, 0, 1, 254, 255, 16, 17, 254, 255, 0, 0,
334
  254, 255, 16, 17, 254, 255, 0, 1, 254, 255, 16, 17, 254, 255, 0, 0,
335
};
336
static uint8_t has_bl_vert_16x16[8] = {
337
  254, 16, 254, 0, 254, 16, 254, 0,
338
};
339
static uint8_t has_bl_vert_32x32[2] = { 14, 14 };
340
static uint8_t has_bl_vert_64x64[1] = { 2 };
341
342
// The _vert_* tables are like the ordinary tables above, but describe the
343
// order we visit square blocks when doing a PARTITION_VERT_A or
344
// PARTITION_VERT_B. This is the same order as normal except for on the last
345
// split where we go vertically (TL, BL, TR, BR). We treat the rectangular block
346
// as a pair of squares, which means that these tables work correctly for both
347
// mixed vertical partition types.
348
//
349
// There are tables for each of the square sizes. Vertical rectangles (like
350
// BLOCK_16X32) use their respective "non-vert" table
351
static const uint8_t *const has_bl_vert_tables[BLOCK_SIZES] = {
352
  // 4X4
353
  NULL,
354
  // 4X8,     8X4,         8X8
355
  has_bl_4x8, NULL, has_bl_vert_8x8,
356
  // 8X16,    16X8,        16X16
357
  has_bl_8x16, NULL, has_bl_vert_16x16,
358
  // 16X32,   32X16,       32X32
359
  has_bl_16x32, NULL, has_bl_vert_32x32,
360
  // 32X64,   64X32,       64X64
361
  has_bl_32x64, NULL, has_bl_vert_64x64,
362
  // 64x128,  128x64,      128x128
363
  has_bl_64x128, NULL, has_bl_128x128
364
};
365
366
static const uint8_t *get_has_bl_table(PARTITION_TYPE partition,
367
15.0M
                                       BLOCK_SIZE bsize) {
368
15.0M
  const uint8_t *ret = NULL;
369
  // If this is a mixed vertical partition, look up bsize in orders_vert.
370
15.0M
  if (partition == PARTITION_VERT_A || partition == PARTITION_VERT_B) {
371
1.27M
    assert(bsize < BLOCK_SIZES);
372
1.27M
    ret = has_bl_vert_tables[bsize];
373
13.7M
  } else {
374
13.7M
    ret = has_bl_tables[bsize];
375
13.7M
  }
376
15.0M
  assert(ret);
377
15.0M
  return ret;
378
15.0M
}
379
380
static int has_bottom_left(BLOCK_SIZE sb_size, BLOCK_SIZE bsize, int mi_row,
381
                           int mi_col, int bottom_available, int left_available,
382
                           PARTITION_TYPE partition, TX_SIZE txsz, int row_off,
383
36.3M
                           int col_off, int ss_x, int ss_y) {
384
36.3M
  if (!bottom_available || !left_available) return 0;
385
386
  // Special case for 128x* blocks, when col_off is half the block width.
387
  // This is needed because 128x* superblocks are divided into 64x* blocks in
388
  // raster order
389
34.4M
  if (block_size_wide[bsize] > block_size_wide[BLOCK_64X64] && col_off > 0) {
390
5.28M
    const int plane_bw_unit_64 = mi_size_wide[BLOCK_64X64] >> ss_x;
391
5.28M
    const int col_off_64 = col_off % plane_bw_unit_64;
392
5.28M
    if (col_off_64 == 0) {
393
      // We are at the left edge of top-right or bottom-right 64x* block.
394
762k
      const int plane_bh_unit_64 = mi_size_high[BLOCK_64X64] >> ss_y;
395
762k
      const int row_off_64 = row_off % plane_bh_unit_64;
396
762k
      const int plane_bh_unit =
397
762k
          AOMMIN(mi_size_high[bsize] >> ss_y, plane_bh_unit_64);
398
      // Check if all bottom-left pixels are in the left 64x* block (which is
399
      // already coded).
400
762k
      return row_off_64 + tx_size_high_unit[txsz] < plane_bh_unit;
401
762k
    }
402
5.28M
  }
403
404
33.6M
  if (col_off > 0) {
405
    // Bottom-left pixels are in the bottom-left block, which is not available.
406
10.0M
    return 0;
407
23.5M
  } else {
408
23.5M
    const int bh_unit = mi_size_high[bsize];
409
23.5M
    const int plane_bh_unit = AOMMAX(bh_unit >> ss_y, 1);
410
23.5M
    const int bottom_left_count_unit = tx_size_high_unit[txsz];
411
412
    // All bottom-left pixels are in the left block, which is already available.
413
23.5M
    if (row_off + bottom_left_count_unit < plane_bh_unit) return 1;
414
415
21.1M
    const int bw_in_mi_log2 = mi_size_wide_log2[bsize];
416
21.1M
    const int bh_in_mi_log2 = mi_size_high_log2[bsize];
417
21.1M
    const int sb_mi_size = mi_size_high[sb_size];
418
21.1M
    const int blk_row_in_sb = (mi_row & (sb_mi_size - 1)) >> bh_in_mi_log2;
419
21.1M
    const int blk_col_in_sb = (mi_col & (sb_mi_size - 1)) >> bw_in_mi_log2;
420
421
    // Leftmost column of superblock: so bottom-left pixels maybe in the left
422
    // and/or bottom-left superblocks. But only the left superblock is
423
    // available, so check if all required pixels fall in that superblock.
424
21.1M
    if (blk_col_in_sb == 0) {
425
3.23M
      const int blk_start_row_off =
426
3.23M
          blk_row_in_sb << (bh_in_mi_log2 + MI_SIZE_LOG2 - MI_SIZE_LOG2) >>
427
3.23M
          ss_y;
428
3.23M
      const int row_off_in_sb = blk_start_row_off + row_off;
429
3.23M
      const int sb_height_unit = sb_mi_size >> ss_y;
430
3.23M
      return row_off_in_sb + bottom_left_count_unit < sb_height_unit;
431
3.23M
    }
432
433
    // Bottom row of superblock (and not the leftmost column): so bottom-left
434
    // pixels fall in the bottom superblock, which is not available yet.
435
17.8M
    if (((blk_row_in_sb + 1) << bh_in_mi_log2) >= sb_mi_size) return 0;
436
437
    // General case (neither leftmost column nor bottom row): check if the
438
    // bottom-left block is coded before the current block.
439
15.0M
    const int this_blk_index =
440
15.0M
        ((blk_row_in_sb + 0) << (MAX_MIB_SIZE_LOG2 - bw_in_mi_log2)) +
441
15.0M
        blk_col_in_sb + 0;
442
15.0M
    const int idx1 = this_blk_index / 8;
443
15.0M
    const int idx2 = this_blk_index % 8;
444
15.0M
    const uint8_t *has_bl_table = get_has_bl_table(partition, bsize);
445
15.0M
    return (has_bl_table[idx1] >> idx2) & 1;
446
17.8M
  }
447
33.6M
}
448
449
typedef void (*intra_pred_fn)(uint8_t *dst, ptrdiff_t stride,
450
                              const uint8_t *above, const uint8_t *left);
451
452
static intra_pred_fn pred[INTRA_MODES][TX_SIZES_ALL];
453
static intra_pred_fn dc_pred[2][2][TX_SIZES_ALL];
454
455
#if CONFIG_AV1_HIGHBITDEPTH
456
typedef void (*intra_high_pred_fn)(uint16_t *dst, ptrdiff_t stride,
457
                                   const uint16_t *above, const uint16_t *left,
458
                                   int bd);
459
static intra_high_pred_fn pred_high[INTRA_MODES][TX_SIZES_ALL];
460
static intra_high_pred_fn dc_pred_high[2][2][TX_SIZES_ALL];
461
#endif
462
463
3
static void init_intra_predictors_internal(void) {
464
3
  assert(NELEMENTS(mode_to_angle_map) == INTRA_MODES);
465
466
#if CONFIG_REALTIME_ONLY
467
#define INIT_RECTANGULAR(p, type)             \
468
  p[TX_4X8] = aom_##type##_predictor_4x8;     \
469
  p[TX_8X4] = aom_##type##_predictor_8x4;     \
470
  p[TX_8X16] = aom_##type##_predictor_8x16;   \
471
  p[TX_16X8] = aom_##type##_predictor_16x8;   \
472
  p[TX_16X32] = aom_##type##_predictor_16x32; \
473
  p[TX_32X16] = aom_##type##_predictor_32x16; \
474
  p[TX_32X64] = aom_##type##_predictor_32x64; \
475
  p[TX_64X32] = aom_##type##_predictor_64x32;
476
#else
477
3
#define INIT_RECTANGULAR(p, type)             \
478
60
  p[TX_4X8] = aom_##type##_predictor_4x8;     \
479
60
  p[TX_8X4] = aom_##type##_predictor_8x4;     \
480
60
  p[TX_8X16] = aom_##type##_predictor_8x16;   \
481
60
  p[TX_16X8] = aom_##type##_predictor_16x8;   \
482
60
  p[TX_16X32] = aom_##type##_predictor_16x32; \
483
60
  p[TX_32X16] = aom_##type##_predictor_32x16; \
484
60
  p[TX_32X64] = aom_##type##_predictor_32x64; \
485
60
  p[TX_64X32] = aom_##type##_predictor_64x32; \
486
60
  p[TX_4X16] = aom_##type##_predictor_4x16;   \
487
60
  p[TX_16X4] = aom_##type##_predictor_16x4;   \
488
60
  p[TX_8X32] = aom_##type##_predictor_8x32;   \
489
60
  p[TX_32X8] = aom_##type##_predictor_32x8;   \
490
60
  p[TX_16X64] = aom_##type##_predictor_16x64; \
491
60
  p[TX_64X16] = aom_##type##_predictor_64x16;
492
3
#endif
493
494
3
#define INIT_NO_4X4(p, type)                  \
495
60
  p[TX_8X8] = aom_##type##_predictor_8x8;     \
496
60
  p[TX_16X16] = aom_##type##_predictor_16x16; \
497
60
  p[TX_32X32] = aom_##type##_predictor_32x32; \
498
60
  p[TX_64X64] = aom_##type##_predictor_64x64; \
499
60
  INIT_RECTANGULAR(p, type)
500
501
3
#define INIT_ALL_SIZES(p, type)           \
502
60
  p[TX_4X4] = aom_##type##_predictor_4x4; \
503
60
  INIT_NO_4X4(p, type)
504
505
3
  INIT_ALL_SIZES(pred[V_PRED], v);
506
3
  INIT_ALL_SIZES(pred[H_PRED], h);
507
3
  INIT_ALL_SIZES(pred[PAETH_PRED], paeth);
508
3
  INIT_ALL_SIZES(pred[SMOOTH_PRED], smooth);
509
3
  INIT_ALL_SIZES(pred[SMOOTH_V_PRED], smooth_v);
510
3
  INIT_ALL_SIZES(pred[SMOOTH_H_PRED], smooth_h);
511
3
  INIT_ALL_SIZES(dc_pred[0][0], dc_128);
512
3
  INIT_ALL_SIZES(dc_pred[0][1], dc_top);
513
3
  INIT_ALL_SIZES(dc_pred[1][0], dc_left);
514
3
  INIT_ALL_SIZES(dc_pred[1][1], dc);
515
3
#if CONFIG_AV1_HIGHBITDEPTH
516
3
  INIT_ALL_SIZES(pred_high[V_PRED], highbd_v);
517
3
  INIT_ALL_SIZES(pred_high[H_PRED], highbd_h);
518
3
  INIT_ALL_SIZES(pred_high[PAETH_PRED], highbd_paeth);
519
3
  INIT_ALL_SIZES(pred_high[SMOOTH_PRED], highbd_smooth);
520
3
  INIT_ALL_SIZES(pred_high[SMOOTH_V_PRED], highbd_smooth_v);
521
3
  INIT_ALL_SIZES(pred_high[SMOOTH_H_PRED], highbd_smooth_h);
522
3
  INIT_ALL_SIZES(dc_pred_high[0][0], highbd_dc_128);
523
3
  INIT_ALL_SIZES(dc_pred_high[0][1], highbd_dc_top);
524
3
  INIT_ALL_SIZES(dc_pred_high[1][0], highbd_dc_left);
525
3
  INIT_ALL_SIZES(dc_pred_high[1][1], highbd_dc);
526
3
#endif
527
3
#undef intra_pred_allsizes
528
3
}
529
530
// Directional prediction, zone 1: 0 < angle < 90
531
void av1_dr_prediction_z1_c(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
532
                            const uint8_t *above, const uint8_t *left,
533
736k
                            int upsample_above, int dx, int dy) {
534
736k
  int r, c, x, base, shift, val;
535
536
736k
  (void)left;
537
736k
  (void)dy;
538
736k
  assert(dy == 1);
539
736k
  assert(dx > 0);
540
541
736k
  const int max_base_x = ((bw + bh) - 1) << upsample_above;
542
736k
  const int frac_bits = 6 - upsample_above;
543
736k
  const int base_inc = 1 << upsample_above;
544
736k
  x = dx;
545
8.79M
  for (r = 0; r < bh; ++r, dst += stride, x += dx) {
546
8.05M
    base = x >> frac_bits;
547
8.05M
    shift = ((x << upsample_above) & 0x3F) >> 1;
548
549
8.05M
    if (base >= max_base_x) {
550
10.8k
      for (int i = r; i < bh; ++i) {
551
7.34k
        memset(dst, above[max_base_x], bw * sizeof(dst[0]));
552
7.34k
        dst += stride;
553
7.34k
      }
554
3.52k
      return;
555
3.52k
    }
556
557
154M
    for (c = 0; c < bw; ++c, base += base_inc) {
558
146M
      if (base < max_base_x) {
559
145M
        val = above[base] * (32 - shift) + above[base + 1] * shift;
560
145M
        dst[c] = ROUND_POWER_OF_TWO(val, 5);
561
145M
      } else {
562
952k
        dst[c] = above[max_base_x];
563
952k
      }
564
146M
    }
565
8.05M
  }
566
736k
}
567
568
// Directional prediction, zone 2: 90 < angle < 180
569
void av1_dr_prediction_z2_c(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
570
                            const uint8_t *above, const uint8_t *left,
571
                            int upsample_above, int upsample_left, int dx,
572
1.40M
                            int dy) {
573
1.40M
  assert(dx > 0);
574
1.40M
  assert(dy > 0);
575
576
1.40M
  const int min_base_x = -(1 << upsample_above);
577
1.40M
  const int min_base_y = -(1 << upsample_left);
578
1.40M
  (void)min_base_y;
579
1.40M
  const int frac_bits_x = 6 - upsample_above;
580
1.40M
  const int frac_bits_y = 6 - upsample_left;
581
582
17.7M
  for (int r = 0; r < bh; ++r) {
583
322M
    for (int c = 0; c < bw; ++c) {
584
305M
      int val;
585
305M
      int y = r + 1;
586
305M
      int x = (c << 6) - y * dx;
587
305M
      const int base_x = x >> frac_bits_x;
588
305M
      if (base_x >= min_base_x) {
589
139M
        const int shift = ((x * (1 << upsample_above)) & 0x3F) >> 1;
590
139M
        val = above[base_x] * (32 - shift) + above[base_x + 1] * shift;
591
139M
        val = ROUND_POWER_OF_TWO(val, 5);
592
166M
      } else {
593
166M
        x = c + 1;
594
166M
        y = (r << 6) - x * dy;
595
166M
        const int base_y = y >> frac_bits_y;
596
166M
        assert(base_y >= min_base_y);
597
166M
        const int shift = ((y * (1 << upsample_left)) & 0x3F) >> 1;
598
166M
        val = left[base_y] * (32 - shift) + left[base_y + 1] * shift;
599
166M
        val = ROUND_POWER_OF_TWO(val, 5);
600
166M
      }
601
305M
      dst[c] = val;
602
305M
    }
603
16.3M
    dst += stride;
604
16.3M
  }
605
1.40M
}
606
607
// Directional prediction, zone 3: 180 < angle < 270
608
void av1_dr_prediction_z3_c(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
609
                            const uint8_t *above, const uint8_t *left,
610
906k
                            int upsample_left, int dx, int dy) {
611
906k
  int r, c, y, base, shift, val;
612
613
906k
  (void)above;
614
906k
  (void)dx;
615
616
906k
  assert(dx == 1);
617
906k
  assert(dy > 0);
618
619
906k
  const int max_base_y = (bw + bh - 1) << upsample_left;
620
906k
  const int frac_bits = 6 - upsample_left;
621
906k
  const int base_inc = 1 << upsample_left;
622
906k
  y = dy;
623
11.7M
  for (c = 0; c < bw; ++c, y += dy) {
624
10.8M
    base = y >> frac_bits;
625
10.8M
    shift = ((y << upsample_left) & 0x3F) >> 1;
626
627
197M
    for (r = 0; r < bh; ++r, base += base_inc) {
628
186M
      if (base < max_base_y) {
629
186M
        val = left[base] * (32 - shift) + left[base + 1] * shift;
630
186M
        dst[r * stride + c] = val = ROUND_POWER_OF_TWO(val, 5);
631
186M
      } else {
632
0
        for (; r < bh; ++r) dst[r * stride + c] = left[max_base_y];
633
0
        break;
634
0
      }
635
186M
    }
636
10.8M
  }
637
906k
}
638
639
static void dr_predictor(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size,
640
                         const uint8_t *above, const uint8_t *left,
641
4.25M
                         int upsample_above, int upsample_left, int angle) {
642
4.25M
  const int dx = av1_get_dx(angle);
643
4.25M
  const int dy = av1_get_dy(angle);
644
4.25M
  const int bw = tx_size_wide[tx_size];
645
4.25M
  const int bh = tx_size_high[tx_size];
646
4.25M
  assert(angle > 0 && angle < 270);
647
648
4.25M
  if (angle > 0 && angle < 90) {
649
736k
    av1_dr_prediction_z1(dst, stride, bw, bh, above, left, upsample_above, dx,
650
736k
                         dy);
651
3.52M
  } else if (angle > 90 && angle < 180) {
652
1.40M
    av1_dr_prediction_z2(dst, stride, bw, bh, above, left, upsample_above,
653
1.40M
                         upsample_left, dx, dy);
654
2.11M
  } else if (angle > 180 && angle < 270) {
655
906k
    av1_dr_prediction_z3(dst, stride, bw, bh, above, left, upsample_left, dx,
656
906k
                         dy);
657
1.21M
  } else if (angle == 90) {
658
493k
    pred[V_PRED][tx_size](dst, stride, above, left);
659
717k
  } else if (angle == 180) {
660
717k
    pred[H_PRED][tx_size](dst, stride, above, left);
661
717k
  }
662
4.25M
}
663
664
#if CONFIG_AV1_HIGHBITDEPTH
665
// Directional prediction, zone 1: 0 < angle < 90
666
void av1_highbd_dr_prediction_z1_c(uint16_t *dst, ptrdiff_t stride, int bw,
667
                                   int bh, const uint16_t *above,
668
                                   const uint16_t *left, int upsample_above,
669
907k
                                   int dx, int dy, int bd) {
670
907k
  int r, c, x, base, shift, val;
671
672
907k
  (void)left;
673
907k
  (void)dy;
674
907k
  (void)bd;
675
907k
  assert(dy == 1);
676
907k
  assert(dx > 0);
677
678
907k
  const int max_base_x = ((bw + bh) - 1) << upsample_above;
679
907k
  const int frac_bits = 6 - upsample_above;
680
907k
  const int base_inc = 1 << upsample_above;
681
907k
  x = dx;
682
10.1M
  for (r = 0; r < bh; ++r, dst += stride, x += dx) {
683
9.23M
    base = x >> frac_bits;
684
9.23M
    shift = ((x << upsample_above) & 0x3F) >> 1;
685
686
9.23M
    if (base >= max_base_x) {
687
14.8k
      for (int i = r; i < bh; ++i) {
688
9.56k
        aom_memset16(dst, above[max_base_x], bw);
689
9.56k
        dst += stride;
690
9.56k
      }
691
5.30k
      return;
692
5.30k
    }
693
694
168M
    for (c = 0; c < bw; ++c, base += base_inc) {
695
159M
      if (base < max_base_x) {
696
158M
        val = above[base] * (32 - shift) + above[base + 1] * shift;
697
158M
        dst[c] = ROUND_POWER_OF_TWO(val, 5);
698
158M
      } else {
699
1.07M
        dst[c] = above[max_base_x];
700
1.07M
      }
701
159M
    }
702
9.23M
  }
703
907k
}
704
705
// Directional prediction, zone 2: 90 < angle < 180
706
void av1_highbd_dr_prediction_z2_c(uint16_t *dst, ptrdiff_t stride, int bw,
707
                                   int bh, const uint16_t *above,
708
                                   const uint16_t *left, int upsample_above,
709
1.72M
                                   int upsample_left, int dx, int dy, int bd) {
710
1.72M
  (void)bd;
711
1.72M
  assert(dx > 0);
712
1.72M
  assert(dy > 0);
713
714
1.72M
  const int min_base_x = -(1 << upsample_above);
715
1.72M
  const int min_base_y = -(1 << upsample_left);
716
1.72M
  (void)min_base_y;
717
1.72M
  const int frac_bits_x = 6 - upsample_above;
718
1.72M
  const int frac_bits_y = 6 - upsample_left;
719
720
18.9M
  for (int r = 0; r < bh; ++r) {
721
309M
    for (int c = 0; c < bw; ++c) {
722
292M
      int val;
723
292M
      int y = r + 1;
724
292M
      int x = (c << 6) - y * dx;
725
292M
      const int base_x = x >> frac_bits_x;
726
292M
      if (base_x >= min_base_x) {
727
130M
        const int shift = ((x * (1 << upsample_above)) & 0x3F) >> 1;
728
130M
        val = above[base_x] * (32 - shift) + above[base_x + 1] * shift;
729
130M
        val = ROUND_POWER_OF_TWO(val, 5);
730
162M
      } else {
731
162M
        x = c + 1;
732
162M
        y = (r << 6) - x * dy;
733
162M
        const int base_y = y >> frac_bits_y;
734
162M
        assert(base_y >= min_base_y);
735
162M
        const int shift = ((y * (1 << upsample_left)) & 0x3F) >> 1;
736
162M
        val = left[base_y] * (32 - shift) + left[base_y + 1] * shift;
737
162M
        val = ROUND_POWER_OF_TWO(val, 5);
738
162M
      }
739
292M
      dst[c] = val;
740
292M
    }
741
17.1M
    dst += stride;
742
17.1M
  }
743
1.72M
}
744
745
// Directional prediction, zone 3: 180 < angle < 270
746
void av1_highbd_dr_prediction_z3_c(uint16_t *dst, ptrdiff_t stride, int bw,
747
                                   int bh, const uint16_t *above,
748
                                   const uint16_t *left, int upsample_left,
749
1.04M
                                   int dx, int dy, int bd) {
750
1.04M
  int r, c, y, base, shift, val;
751
752
1.04M
  (void)above;
753
1.04M
  (void)dx;
754
1.04M
  (void)bd;
755
1.04M
  assert(dx == 1);
756
1.04M
  assert(dy > 0);
757
758
1.04M
  const int max_base_y = (bw + bh - 1) << upsample_left;
759
1.04M
  const int frac_bits = 6 - upsample_left;
760
1.04M
  const int base_inc = 1 << upsample_left;
761
1.04M
  y = dy;
762
12.4M
  for (c = 0; c < bw; ++c, y += dy) {
763
11.4M
    base = y >> frac_bits;
764
11.4M
    shift = ((y << upsample_left) & 0x3F) >> 1;
765
766
206M
    for (r = 0; r < bh; ++r, base += base_inc) {
767
194M
      if (base < max_base_y) {
768
194M
        val = left[base] * (32 - shift) + left[base + 1] * shift;
769
194M
        dst[r * stride + c] = ROUND_POWER_OF_TWO(val, 5);
770
194M
      } else {
771
0
        for (; r < bh; ++r) dst[r * stride + c] = left[max_base_y];
772
0
        break;
773
0
      }
774
194M
    }
775
11.4M
  }
776
1.04M
}
777
778
static void highbd_dr_predictor(uint16_t *dst, ptrdiff_t stride,
779
                                TX_SIZE tx_size, const uint16_t *above,
780
                                const uint16_t *left, int upsample_above,
781
4.95M
                                int upsample_left, int angle, int bd) {
782
4.95M
  const int dx = av1_get_dx(angle);
783
4.95M
  const int dy = av1_get_dy(angle);
784
4.95M
  const int bw = tx_size_wide[tx_size];
785
4.95M
  const int bh = tx_size_high[tx_size];
786
4.95M
  assert(angle > 0 && angle < 270);
787
788
4.95M
  if (angle > 0 && angle < 90) {
789
907k
    av1_highbd_dr_prediction_z1(dst, stride, bw, bh, above, left,
790
907k
                                upsample_above, dx, dy, bd);
791
4.04M
  } else if (angle > 90 && angle < 180) {
792
1.72M
    av1_highbd_dr_prediction_z2(dst, stride, bw, bh, above, left,
793
1.72M
                                upsample_above, upsample_left, dx, dy, bd);
794
2.31M
  } else if (angle > 180 && angle < 270) {
795
1.04M
    av1_highbd_dr_prediction_z3(dst, stride, bw, bh, above, left, upsample_left,
796
1.04M
                                dx, dy, bd);
797
1.27M
  } else if (angle == 90) {
798
474k
    pred_high[V_PRED][tx_size](dst, stride, above, left, bd);
799
797k
  } else if (angle == 180) {
800
797k
    pred_high[H_PRED][tx_size](dst, stride, above, left, bd);
801
797k
  }
802
4.95M
}
803
#endif  // CONFIG_AV1_HIGHBITDEPTH
804
805
DECLARE_ALIGNED(16, const int8_t,
806
                av1_filter_intra_taps[FILTER_INTRA_MODES][8][8]) = {
807
  {
808
      { -6, 10, 0, 0, 0, 12, 0, 0 },
809
      { -5, 2, 10, 0, 0, 9, 0, 0 },
810
      { -3, 1, 1, 10, 0, 7, 0, 0 },
811
      { -3, 1, 1, 2, 10, 5, 0, 0 },
812
      { -4, 6, 0, 0, 0, 2, 12, 0 },
813
      { -3, 2, 6, 0, 0, 2, 9, 0 },
814
      { -3, 2, 2, 6, 0, 2, 7, 0 },
815
      { -3, 1, 2, 2, 6, 3, 5, 0 },
816
  },
817
  {
818
      { -10, 16, 0, 0, 0, 10, 0, 0 },
819
      { -6, 0, 16, 0, 0, 6, 0, 0 },
820
      { -4, 0, 0, 16, 0, 4, 0, 0 },
821
      { -2, 0, 0, 0, 16, 2, 0, 0 },
822
      { -10, 16, 0, 0, 0, 0, 10, 0 },
823
      { -6, 0, 16, 0, 0, 0, 6, 0 },
824
      { -4, 0, 0, 16, 0, 0, 4, 0 },
825
      { -2, 0, 0, 0, 16, 0, 2, 0 },
826
  },
827
  {
828
      { -8, 8, 0, 0, 0, 16, 0, 0 },
829
      { -8, 0, 8, 0, 0, 16, 0, 0 },
830
      { -8, 0, 0, 8, 0, 16, 0, 0 },
831
      { -8, 0, 0, 0, 8, 16, 0, 0 },
832
      { -4, 4, 0, 0, 0, 0, 16, 0 },
833
      { -4, 0, 4, 0, 0, 0, 16, 0 },
834
      { -4, 0, 0, 4, 0, 0, 16, 0 },
835
      { -4, 0, 0, 0, 4, 0, 16, 0 },
836
  },
837
  {
838
      { -2, 8, 0, 0, 0, 10, 0, 0 },
839
      { -1, 3, 8, 0, 0, 6, 0, 0 },
840
      { -1, 2, 3, 8, 0, 4, 0, 0 },
841
      { 0, 1, 2, 3, 8, 2, 0, 0 },
842
      { -1, 4, 0, 0, 0, 3, 10, 0 },
843
      { -1, 3, 4, 0, 0, 4, 6, 0 },
844
      { -1, 2, 3, 4, 0, 4, 4, 0 },
845
      { -1, 2, 2, 3, 4, 3, 3, 0 },
846
  },
847
  {
848
      { -12, 14, 0, 0, 0, 14, 0, 0 },
849
      { -10, 0, 14, 0, 0, 12, 0, 0 },
850
      { -9, 0, 0, 14, 0, 11, 0, 0 },
851
      { -8, 0, 0, 0, 14, 10, 0, 0 },
852
      { -10, 12, 0, 0, 0, 0, 14, 0 },
853
      { -9, 1, 12, 0, 0, 0, 12, 0 },
854
      { -8, 0, 0, 12, 0, 1, 11, 0 },
855
      { -7, 0, 0, 1, 12, 1, 9, 0 },
856
  },
857
};
858
859
void av1_filter_intra_predictor_c(uint8_t *dst, ptrdiff_t stride,
860
                                  TX_SIZE tx_size, const uint8_t *above,
861
794k
                                  const uint8_t *left, int mode) {
862
794k
  int r, c;
863
794k
  uint8_t buffer[33][33];
864
794k
  const int bw = tx_size_wide[tx_size];
865
794k
  const int bh = tx_size_high[tx_size];
866
867
794k
  assert(bw <= 32 && bh <= 32);
868
869
7.24M
  for (r = 0; r < bh; ++r) buffer[r + 1][0] = left[r];
870
794k
  memcpy(buffer[0], &above[-1], (bw + 1) * sizeof(uint8_t));
871
872
4.01M
  for (r = 1; r < bh + 1; r += 2)
873
12.1M
    for (c = 1; c < bw + 1; c += 4) {
874
8.88M
      const uint8_t p0 = buffer[r - 1][c - 1];
875
8.88M
      const uint8_t p1 = buffer[r - 1][c];
876
8.88M
      const uint8_t p2 = buffer[r - 1][c + 1];
877
8.88M
      const uint8_t p3 = buffer[r - 1][c + 2];
878
8.88M
      const uint8_t p4 = buffer[r - 1][c + 3];
879
8.88M
      const uint8_t p5 = buffer[r][c - 1];
880
8.88M
      const uint8_t p6 = buffer[r + 1][c - 1];
881
79.9M
      for (int k = 0; k < 8; ++k) {
882
71.0M
        int r_offset = k >> 2;
883
71.0M
        int c_offset = k & 0x03;
884
71.0M
        int pr = av1_filter_intra_taps[mode][k][0] * p0 +
885
71.0M
                 av1_filter_intra_taps[mode][k][1] * p1 +
886
71.0M
                 av1_filter_intra_taps[mode][k][2] * p2 +
887
71.0M
                 av1_filter_intra_taps[mode][k][3] * p3 +
888
71.0M
                 av1_filter_intra_taps[mode][k][4] * p4 +
889
71.0M
                 av1_filter_intra_taps[mode][k][5] * p5 +
890
71.0M
                 av1_filter_intra_taps[mode][k][6] * p6;
891
        // Section 7.11.2.3 specifies the right-hand side of the assignment as
892
        //   Clip1( Round2Signed( pr, INTRA_FILTER_SCALE_BITS ) ).
893
        // Since Clip1() clips a negative value to 0, it is safe to replace
894
        // Round2Signed() with Round2().
895
71.0M
        buffer[r + r_offset][c + c_offset] =
896
71.0M
            clip_pixel(ROUND_POWER_OF_TWO(pr, FILTER_INTRA_SCALE_BITS));
897
71.0M
      }
898
8.88M
    }
899
900
7.24M
  for (r = 0; r < bh; ++r) {
901
6.44M
    memcpy(dst, &buffer[r + 1][1], bw * sizeof(uint8_t));
902
6.44M
    dst += stride;
903
6.44M
  }
904
794k
}
905
906
#if CONFIG_AV1_HIGHBITDEPTH
907
static void highbd_filter_intra_predictor(uint16_t *dst, ptrdiff_t stride,
908
                                          TX_SIZE tx_size,
909
                                          const uint16_t *above,
910
                                          const uint16_t *left, int mode,
911
1.24M
                                          int bd) {
912
1.24M
  int r, c;
913
1.24M
  uint16_t buffer[33][33];
914
1.24M
  const int bw = tx_size_wide[tx_size];
915
1.24M
  const int bh = tx_size_high[tx_size];
916
917
1.24M
  assert(bw <= 32 && bh <= 32);
918
919
11.7M
  for (r = 0; r < bh; ++r) buffer[r + 1][0] = left[r];
920
1.24M
  memcpy(buffer[0], &above[-1], (bw + 1) * sizeof(buffer[0][0]));
921
922
6.49M
  for (r = 1; r < bh + 1; r += 2)
923
19.8M
    for (c = 1; c < bw + 1; c += 4) {
924
14.6M
      const uint16_t p0 = buffer[r - 1][c - 1];
925
14.6M
      const uint16_t p1 = buffer[r - 1][c];
926
14.6M
      const uint16_t p2 = buffer[r - 1][c + 1];
927
14.6M
      const uint16_t p3 = buffer[r - 1][c + 2];
928
14.6M
      const uint16_t p4 = buffer[r - 1][c + 3];
929
14.6M
      const uint16_t p5 = buffer[r][c - 1];
930
14.6M
      const uint16_t p6 = buffer[r + 1][c - 1];
931
131M
      for (int k = 0; k < 8; ++k) {
932
117M
        int r_offset = k >> 2;
933
117M
        int c_offset = k & 0x03;
934
117M
        int pr = av1_filter_intra_taps[mode][k][0] * p0 +
935
117M
                 av1_filter_intra_taps[mode][k][1] * p1 +
936
117M
                 av1_filter_intra_taps[mode][k][2] * p2 +
937
117M
                 av1_filter_intra_taps[mode][k][3] * p3 +
938
117M
                 av1_filter_intra_taps[mode][k][4] * p4 +
939
117M
                 av1_filter_intra_taps[mode][k][5] * p5 +
940
117M
                 av1_filter_intra_taps[mode][k][6] * p6;
941
        // Section 7.11.2.3 specifies the right-hand side of the assignment as
942
        //   Clip1( Round2Signed( pr, INTRA_FILTER_SCALE_BITS ) ).
943
        // Since Clip1() clips a negative value to 0, it is safe to replace
944
        // Round2Signed() with Round2().
945
117M
        buffer[r + r_offset][c + c_offset] = clip_pixel_highbd(
946
117M
            ROUND_POWER_OF_TWO(pr, FILTER_INTRA_SCALE_BITS), bd);
947
117M
      }
948
14.6M
    }
949
950
11.7M
  for (r = 0; r < bh; ++r) {
951
10.4M
    memcpy(dst, &buffer[r + 1][1], bw * sizeof(dst[0]));
952
10.4M
    dst += stride;
953
10.4M
  }
954
1.24M
}
955
#endif  // CONFIG_AV1_HIGHBITDEPTH
956
957
63.9M
static int is_smooth(const MB_MODE_INFO *mbmi, int plane) {
958
63.9M
  if (plane == 0) {
959
29.0M
    const PREDICTION_MODE mode = mbmi->mode;
960
29.0M
    return (mode == SMOOTH_PRED || mode == SMOOTH_V_PRED ||
961
29.0M
            mode == SMOOTH_H_PRED);
962
34.9M
  } else {
963
    // uv_mode is not set for inter blocks, so need to explicitly
964
    // detect that case.
965
34.9M
    if (is_inter_block(mbmi)) return 0;
966
967
34.8M
    const UV_PREDICTION_MODE uv_mode = mbmi->uv_mode;
968
34.8M
    return (uv_mode == UV_SMOOTH_PRED || uv_mode == UV_SMOOTH_V_PRED ||
969
34.8M
            uv_mode == UV_SMOOTH_H_PRED);
970
34.9M
  }
971
63.9M
}
972
973
36.3M
static int get_intra_edge_filter_type(const MACROBLOCKD *xd, int plane) {
974
36.3M
  int ab_sm, le_sm;
975
976
36.3M
  if (plane == 0) {
977
16.6M
    const MB_MODE_INFO *ab = xd->above_mbmi;
978
16.6M
    const MB_MODE_INFO *le = xd->left_mbmi;
979
16.6M
    ab_sm = ab ? is_smooth(ab, plane) : 0;
980
16.6M
    le_sm = le ? is_smooth(le, plane) : 0;
981
19.7M
  } else {
982
19.7M
    const MB_MODE_INFO *ab = xd->chroma_above_mbmi;
983
19.7M
    const MB_MODE_INFO *le = xd->chroma_left_mbmi;
984
19.7M
    ab_sm = ab ? is_smooth(ab, plane) : 0;
985
19.7M
    le_sm = le ? is_smooth(le, plane) : 0;
986
19.7M
  }
987
988
36.3M
  return (ab_sm || le_sm) ? 1 : 0;
989
36.3M
}
990
991
7.99M
static int intra_edge_filter_strength(int bs0, int bs1, int delta, int type) {
992
7.99M
  const int d = abs(delta);
993
7.99M
  int strength = 0;
994
995
7.99M
  const int blk_wh = bs0 + bs1;
996
7.99M
  if (type == 0) {
997
5.94M
    if (blk_wh <= 8) {
998
2.06M
      if (d >= 56) strength = 1;
999
3.88M
    } else if (blk_wh <= 12) {
1000
577k
      if (d >= 40) strength = 1;
1001
3.30M
    } else if (blk_wh <= 16) {
1002
1.09M
      if (d >= 40) strength = 1;
1003
2.20M
    } else if (blk_wh <= 24) {
1004
891k
      if (d >= 8) strength = 1;
1005
891k
      if (d >= 16) strength = 2;
1006
891k
      if (d >= 32) strength = 3;
1007
1.31M
    } else if (blk_wh <= 32) {
1008
518k
      if (d >= 1) strength = 1;
1009
518k
      if (d >= 4) strength = 2;
1010
518k
      if (d >= 32) strength = 3;
1011
797k
    } else {
1012
797k
      if (d >= 1) strength = 3;
1013
797k
    }
1014
5.94M
  } else {
1015
2.04M
    if (blk_wh <= 8) {
1016
462k
      if (d >= 40) strength = 1;
1017
462k
      if (d >= 64) strength = 2;
1018
1.58M
    } else if (blk_wh <= 16) {
1019
702k
      if (d >= 20) strength = 1;
1020
702k
      if (d >= 48) strength = 2;
1021
881k
    } else if (blk_wh <= 24) {
1022
380k
      if (d >= 4) strength = 3;
1023
501k
    } else {
1024
501k
      if (d >= 1) strength = 3;
1025
501k
    }
1026
2.04M
  }
1027
7.99M
  return strength;
1028
7.99M
}
1029
1030
2.92M
void av1_filter_intra_edge_c(uint8_t *p, int sz, int strength) {
1031
2.92M
  if (!strength) return;
1032
1033
1.81M
  const int kernel[INTRA_EDGE_FILT][INTRA_EDGE_TAPS] = { { 0, 4, 8, 4, 0 },
1034
1.81M
                                                         { 0, 5, 6, 5, 0 },
1035
1.81M
                                                         { 2, 4, 4, 4, 2 } };
1036
1.81M
  const int filt = strength - 1;
1037
1.81M
  uint8_t edge[129];
1038
1039
1.81M
  memcpy(edge, p, sz * sizeof(*p));
1040
38.0M
  for (int i = 1; i < sz; i++) {
1041
36.2M
    int s = 0;
1042
217M
    for (int j = 0; j < INTRA_EDGE_TAPS; j++) {
1043
181M
      int k = i - 2 + j;
1044
181M
      k = (k < 0) ? 0 : k;
1045
181M
      k = (k > sz - 1) ? sz - 1 : k;
1046
181M
      s += edge[k] * kernel[filt][j];
1047
181M
    }
1048
36.2M
    s = (s + 8) >> 4;
1049
36.2M
    p[i] = s;
1050
36.2M
  }
1051
1.81M
}
1052
1053
358k
static void filter_intra_edge_corner(uint8_t *p_above, uint8_t *p_left) {
1054
358k
  const int kernel[3] = { 5, 6, 5 };
1055
1056
358k
  int s = (p_left[0] * kernel[0]) + (p_above[-1] * kernel[1]) +
1057
358k
          (p_above[0] * kernel[2]);
1058
358k
  s = (s + 8) >> 4;
1059
358k
  p_above[-1] = s;
1060
358k
  p_left[-1] = s;
1061
358k
}
1062
1063
5.07M
void av1_filter_intra_edge_high_c(uint16_t *p, int sz, int strength) {
1064
5.07M
  if (!strength) return;
1065
1066
2.73M
  const int kernel[INTRA_EDGE_FILT][INTRA_EDGE_TAPS] = { { 0, 4, 8, 4, 0 },
1067
2.73M
                                                         { 0, 5, 6, 5, 0 },
1068
2.73M
                                                         { 2, 4, 4, 4, 2 } };
1069
2.73M
  const int filt = strength - 1;
1070
2.73M
  uint16_t edge[129];
1071
1072
2.73M
  memcpy(edge, p, sz * sizeof(*p));
1073
53.9M
  for (int i = 1; i < sz; i++) {
1074
51.2M
    int s = 0;
1075
307M
    for (int j = 0; j < INTRA_EDGE_TAPS; j++) {
1076
256M
      int k = i - 2 + j;
1077
256M
      k = (k < 0) ? 0 : k;
1078
256M
      k = (k > sz - 1) ? sz - 1 : k;
1079
256M
      s += edge[k] * kernel[filt][j];
1080
256M
    }
1081
51.2M
    s = (s + 8) >> 4;
1082
51.2M
    p[i] = s;
1083
51.2M
  }
1084
2.73M
}
1085
1086
#if CONFIG_AV1_HIGHBITDEPTH
1087
459k
static void filter_intra_edge_corner_high(uint16_t *p_above, uint16_t *p_left) {
1088
459k
  const int kernel[3] = { 5, 6, 5 };
1089
1090
459k
  int s = (p_left[0] * kernel[0]) + (p_above[-1] * kernel[1]) +
1091
459k
          (p_above[0] * kernel[2]);
1092
459k
  s = (s + 8) >> 4;
1093
459k
  p_above[-1] = s;
1094
459k
  p_left[-1] = s;
1095
459k
}
1096
#endif
1097
1098
862k
void av1_upsample_intra_edge_c(uint8_t *p, int sz) {
1099
  // interpolate half-sample positions
1100
862k
  assert(sz <= MAX_UPSAMPLE_SZ);
1101
1102
862k
  uint8_t in[MAX_UPSAMPLE_SZ + 3];
1103
  // copy p[-1..(sz-1)] and extend first and last samples
1104
862k
  in[0] = p[-1];
1105
862k
  in[1] = p[-1];
1106
8.14M
  for (int i = 0; i < sz; i++) {
1107
7.28M
    in[i + 2] = p[i];
1108
7.28M
  }
1109
862k
  in[sz + 2] = p[sz - 1];
1110
1111
  // interpolate half-sample edge positions
1112
862k
  p[-2] = in[0];
1113
8.14M
  for (int i = 0; i < sz; i++) {
1114
7.28M
    int s = -in[i] + (9 * in[i + 1]) + (9 * in[i + 2]) - in[i + 3];
1115
7.28M
    s = clip_pixel((s + 8) >> 4);
1116
7.28M
    p[2 * i - 1] = s;
1117
7.28M
    p[2 * i] = in[i + 2];
1118
7.28M
  }
1119
862k
}
1120
1121
1.56M
void av1_upsample_intra_edge_high_c(uint16_t *p, int sz, int bd) {
1122
  // interpolate half-sample positions
1123
1.56M
  assert(sz <= MAX_UPSAMPLE_SZ);
1124
1125
1.56M
  uint16_t in[MAX_UPSAMPLE_SZ + 3];
1126
  // copy p[-1..(sz-1)] and extend first and last samples
1127
1.56M
  in[0] = p[-1];
1128
1.56M
  in[1] = p[-1];
1129
14.7M
  for (int i = 0; i < sz; i++) {
1130
13.1M
    in[i + 2] = p[i];
1131
13.1M
  }
1132
1.56M
  in[sz + 2] = p[sz - 1];
1133
1134
  // interpolate half-sample edge positions
1135
1.56M
  p[-2] = in[0];
1136
14.7M
  for (int i = 0; i < sz; i++) {
1137
13.1M
    int s = -in[i] + (9 * in[i + 1]) + (9 * in[i + 2]) - in[i + 3];
1138
13.1M
    s = (s + 8) >> 4;
1139
13.1M
    s = clip_pixel_highbd(s, bd);
1140
13.1M
    p[2 * i - 1] = s;
1141
13.1M
    p[2 * i] = in[i + 2];
1142
13.1M
  }
1143
1.56M
}
1144
#if CONFIG_AV1_HIGHBITDEPTH
1145
static void build_intra_predictors_high(
1146
    const uint8_t *ref8, int ref_stride, uint8_t *dst8, int dst_stride,
1147
    PREDICTION_MODE mode, int angle_delta, FILTER_INTRA_MODE filter_intra_mode,
1148
    TX_SIZE tx_size, int disable_edge_filter, int n_top_px, int n_topright_px,
1149
    int n_left_px, int n_bottomleft_px, int intra_edge_filter_type,
1150
18.9M
    int bit_depth) {
1151
18.9M
  int i;
1152
18.9M
  uint16_t *dst = CONVERT_TO_SHORTPTR(dst8);
1153
18.9M
  uint16_t *ref = CONVERT_TO_SHORTPTR(ref8);
1154
18.9M
  DECLARE_ALIGNED(16, uint16_t, left_data[NUM_INTRA_NEIGHBOUR_PIXELS]);
1155
18.9M
  DECLARE_ALIGNED(16, uint16_t, above_data[NUM_INTRA_NEIGHBOUR_PIXELS]);
1156
18.9M
  uint16_t *const above_row = above_data + 16;
1157
18.9M
  uint16_t *const left_col = left_data + 16;
1158
18.9M
  const int txwpx = tx_size_wide[tx_size];
1159
18.9M
  const int txhpx = tx_size_high[tx_size];
1160
18.9M
  int need_left = extend_modes[mode] & NEED_LEFT;
1161
18.9M
  int need_above = extend_modes[mode] & NEED_ABOVE;
1162
18.9M
  int need_above_left = extend_modes[mode] & NEED_ABOVELEFT;
1163
18.9M
  const uint16_t *above_ref = ref - ref_stride;
1164
18.9M
  const uint16_t *left_ref = ref - 1;
1165
18.9M
  int p_angle = 0;
1166
18.9M
  const int is_dr_mode = av1_is_directional_mode(mode);
1167
18.9M
  const int use_filter_intra = filter_intra_mode != FILTER_INTRA_MODES;
1168
18.9M
  int base = 128 << (bit_depth - 8);
1169
  // The left_data, above_data buffers must be zeroed to fix some intermittent
1170
  // valgrind errors. Uninitialized reads in intra pred modules (e.g. width = 4
1171
  // path in av1_highbd_dr_prediction_z2_avx2()) from left_data, above_data are
1172
  // seen to be the potential reason for this issue.
1173
18.9M
  aom_memset16(left_data, base + 1, NUM_INTRA_NEIGHBOUR_PIXELS);
1174
18.9M
  aom_memset16(above_data, base - 1, NUM_INTRA_NEIGHBOUR_PIXELS);
1175
1176
  // The default values if ref pixels are not available:
1177
  // base   base-1 base-1 .. base-1 base-1 base-1 base-1 base-1 base-1
1178
  // base+1   A      B  ..     Y      Z
1179
  // base+1   C      D  ..     W      X
1180
  // base+1   E      F  ..     U      V
1181
  // base+1   G      H  ..     S      T      T      T      T      T
1182
1183
18.9M
  if (is_dr_mode) {
1184
5.02M
    p_angle = mode_to_angle_map[mode] + angle_delta;
1185
5.02M
    if (p_angle <= 90)
1186
1.42M
      need_above = 1, need_left = 0, need_above_left = 1;
1187
3.60M
    else if (p_angle < 180)
1188
1.72M
      need_above = 1, need_left = 1, need_above_left = 1;
1189
1.87M
    else
1190
1.87M
      need_above = 0, need_left = 1, need_above_left = 1;
1191
5.02M
  }
1192
18.9M
  if (use_filter_intra) need_left = need_above = need_above_left = 1;
1193
1194
18.9M
  assert(n_top_px >= 0);
1195
18.9M
  assert(n_topright_px >= 0);
1196
18.9M
  assert(n_left_px >= 0);
1197
18.9M
  assert(n_bottomleft_px >= 0);
1198
1199
18.9M
  if ((!need_above && n_left_px == 0) || (!need_left && n_top_px == 0)) {
1200
74.6k
    int val;
1201
74.6k
    if (need_left) {
1202
34.5k
      val = (n_top_px > 0) ? above_ref[0] : base + 1;
1203
40.1k
    } else {
1204
40.1k
      val = (n_left_px > 0) ? left_ref[0] : base - 1;
1205
40.1k
    }
1206
1.78M
    for (i = 0; i < txhpx; ++i) {
1207
1.70M
      aom_memset16(dst, val, txwpx);
1208
1.70M
      dst += dst_stride;
1209
1.70M
    }
1210
74.6k
    return;
1211
74.6k
  }
1212
1213
  // NEED_LEFT
1214
18.8M
  if (need_left) {
1215
17.5M
    int need_bottom = extend_modes[mode] & NEED_BOTTOMLEFT;
1216
17.5M
    if (use_filter_intra) need_bottom = 0;
1217
17.5M
    if (is_dr_mode) need_bottom = p_angle > 180;
1218
17.5M
    const int num_left_pixels_needed = txhpx + (need_bottom ? txwpx : 0);
1219
17.5M
    i = 0;
1220
17.5M
    if (n_left_px > 0) {
1221
210M
      for (; i < n_left_px; i++) left_col[i] = left_ref[i * ref_stride];
1222
16.9M
      if (need_bottom && n_bottomleft_px > 0) {
1223
339k
        assert(i == txhpx);
1224
3.46M
        for (; i < txhpx + n_bottomleft_px; i++)
1225
3.12M
          left_col[i] = left_ref[i * ref_stride];
1226
339k
      }
1227
16.9M
      if (i < num_left_pixels_needed)
1228
900k
        aom_memset16(&left_col[i], left_col[i - 1], num_left_pixels_needed - i);
1229
16.9M
    } else if (n_top_px > 0) {
1230
522k
      aom_memset16(left_col, above_ref[0], num_left_pixels_needed);
1231
522k
    }
1232
17.5M
  }
1233
1234
  // NEED_ABOVE
1235
18.8M
  if (need_above) {
1236
17.0M
    int need_right = extend_modes[mode] & NEED_ABOVERIGHT;
1237
17.0M
    if (use_filter_intra) need_right = 0;
1238
17.0M
    if (is_dr_mode) need_right = p_angle < 90;
1239
17.0M
    const int num_top_pixels_needed = txwpx + (need_right ? txhpx : 0);
1240
17.0M
    if (n_top_px > 0) {
1241
16.4M
      memcpy(above_row, above_ref, n_top_px * sizeof(above_ref[0]));
1242
16.4M
      i = n_top_px;
1243
16.4M
      if (need_right && n_topright_px > 0) {
1244
591k
        assert(n_top_px == txwpx);
1245
591k
        memcpy(above_row + txwpx, above_ref + txwpx,
1246
591k
               n_topright_px * sizeof(above_ref[0]));
1247
591k
        i += n_topright_px;
1248
591k
      }
1249
16.4M
      if (i < num_top_pixels_needed)
1250
554k
        aom_memset16(&above_row[i], above_row[i - 1],
1251
554k
                     num_top_pixels_needed - i);
1252
16.4M
    } else if (n_left_px > 0) {
1253
569k
      aom_memset16(above_row, left_ref[0], num_top_pixels_needed);
1254
569k
    }
1255
17.0M
  }
1256
1257
18.8M
  if (need_above_left) {
1258
8.70M
    if (n_top_px > 0 && n_left_px > 0) {
1259
8.28M
      above_row[-1] = above_ref[-1];
1260
8.28M
    } else if (n_top_px > 0) {
1261
184k
      above_row[-1] = above_ref[0];
1262
242k
    } else if (n_left_px > 0) {
1263
235k
      above_row[-1] = left_ref[0];
1264
235k
    } else {
1265
6.32k
      above_row[-1] = base;
1266
6.32k
    }
1267
8.70M
    left_col[-1] = above_row[-1];
1268
8.70M
  }
1269
1270
18.8M
  if (use_filter_intra) {
1271
1.24M
    highbd_filter_intra_predictor(dst, dst_stride, tx_size, above_row, left_col,
1272
1.24M
                                  filter_intra_mode, bit_depth);
1273
1.24M
    return;
1274
1.24M
  }
1275
1276
17.6M
  if (is_dr_mode) {
1277
4.95M
    int upsample_above = 0;
1278
4.95M
    int upsample_left = 0;
1279
4.95M
    if (!disable_edge_filter) {
1280
4.69M
      const int need_right = p_angle < 90;
1281
4.69M
      const int need_bottom = p_angle > 180;
1282
4.69M
      if (p_angle != 90 && p_angle != 180) {
1283
3.49M
        const int ab_le = need_above_left ? 1 : 0;
1284
3.49M
        if (need_above && need_left && (txwpx + txhpx >= 24)) {
1285
459k
          filter_intra_edge_corner_high(above_row, left_col);
1286
459k
        }
1287
3.49M
        if (need_above && n_top_px > 0) {
1288
2.45M
          const int strength = intra_edge_filter_strength(
1289
2.45M
              txwpx, txhpx, p_angle - 90, intra_edge_filter_type);
1290
2.45M
          const int n_px = n_top_px + ab_le + (need_right ? txhpx : 0);
1291
2.45M
          av1_filter_intra_edge_high(above_row - ab_le, n_px, strength);
1292
2.45M
        }
1293
3.49M
        if (need_left && n_left_px > 0) {
1294
2.62M
          const int strength = intra_edge_filter_strength(
1295
2.62M
              txhpx, txwpx, p_angle - 180, intra_edge_filter_type);
1296
2.62M
          const int n_px = n_left_px + ab_le + (need_bottom ? txwpx : 0);
1297
2.62M
          av1_filter_intra_edge_high(left_col - ab_le, n_px, strength);
1298
2.62M
        }
1299
3.49M
      }
1300
4.69M
      upsample_above = av1_use_intra_edge_upsample(txwpx, txhpx, p_angle - 90,
1301
4.69M
                                                   intra_edge_filter_type);
1302
4.69M
      if (need_above && upsample_above) {
1303
665k
        const int n_px = txwpx + (need_right ? txhpx : 0);
1304
665k
        av1_upsample_intra_edge_high(above_row, n_px, bit_depth);
1305
665k
      }
1306
4.69M
      upsample_left = av1_use_intra_edge_upsample(txhpx, txwpx, p_angle - 180,
1307
4.69M
                                                  intra_edge_filter_type);
1308
4.69M
      if (need_left && upsample_left) {
1309
897k
        const int n_px = txhpx + (need_bottom ? txwpx : 0);
1310
897k
        av1_upsample_intra_edge_high(left_col, n_px, bit_depth);
1311
897k
      }
1312
4.69M
    }
1313
4.95M
    highbd_dr_predictor(dst, dst_stride, tx_size, above_row, left_col,
1314
4.95M
                        upsample_above, upsample_left, p_angle, bit_depth);
1315
4.95M
    return;
1316
4.95M
  }
1317
1318
  // predict
1319
12.6M
  if (mode == DC_PRED) {
1320
7.45M
    dc_pred_high[n_left_px > 0][n_top_px > 0][tx_size](
1321
7.45M
        dst, dst_stride, above_row, left_col, bit_depth);
1322
7.45M
  } else {
1323
5.23M
    pred_high[mode][tx_size](dst, dst_stride, above_row, left_col, bit_depth);
1324
5.23M
  }
1325
12.6M
}
1326
#endif  // CONFIG_AV1_HIGHBITDEPTH
1327
1328
static void build_intra_predictors(
1329
    const uint8_t *ref, int ref_stride, uint8_t *dst, int dst_stride,
1330
    PREDICTION_MODE mode, int angle_delta, FILTER_INTRA_MODE filter_intra_mode,
1331
    TX_SIZE tx_size, int disable_edge_filter, int n_top_px, int n_topright_px,
1332
17.3M
    int n_left_px, int n_bottomleft_px, int intra_edge_filter_type) {
1333
17.3M
  int i;
1334
17.3M
  const uint8_t *above_ref = ref - ref_stride;
1335
17.3M
  const uint8_t *left_ref = ref - 1;
1336
17.3M
  DECLARE_ALIGNED(16, uint8_t, left_data[NUM_INTRA_NEIGHBOUR_PIXELS]);
1337
17.3M
  DECLARE_ALIGNED(16, uint8_t, above_data[NUM_INTRA_NEIGHBOUR_PIXELS]);
1338
17.3M
  uint8_t *const above_row = above_data + 16;
1339
17.3M
  uint8_t *const left_col = left_data + 16;
1340
17.3M
  const int txwpx = tx_size_wide[tx_size];
1341
17.3M
  const int txhpx = tx_size_high[tx_size];
1342
17.3M
  int need_left = extend_modes[mode] & NEED_LEFT;
1343
17.3M
  int need_above = extend_modes[mode] & NEED_ABOVE;
1344
17.3M
  int need_above_left = extend_modes[mode] & NEED_ABOVELEFT;
1345
17.3M
  int p_angle = 0;
1346
17.3M
  const int is_dr_mode = av1_is_directional_mode(mode);
1347
17.3M
  const int use_filter_intra = filter_intra_mode != FILTER_INTRA_MODES;
1348
  // The left_data, above_data buffers must be zeroed to fix some intermittent
1349
  // valgrind errors. Uninitialized reads in intra pred modules (e.g. width = 4
1350
  // path in av1_dr_prediction_z1_avx2()) from left_data, above_data are seen to
1351
  // be the potential reason for this issue.
1352
17.3M
  memset(left_data, 129, NUM_INTRA_NEIGHBOUR_PIXELS);
1353
17.3M
  memset(above_data, 127, NUM_INTRA_NEIGHBOUR_PIXELS);
1354
1355
  // The default values if ref pixels are not available:
1356
  // 128 127 127 .. 127 127 127 127 127 127
1357
  // 129  A   B  ..  Y   Z
1358
  // 129  C   D  ..  W   X
1359
  // 129  E   F  ..  U   V
1360
  // 129  G   H  ..  S   T   T   T   T   T
1361
  // ..
1362
1363
17.3M
  if (is_dr_mode) {
1364
4.31M
    p_angle = mode_to_angle_map[mode] + angle_delta;
1365
4.31M
    if (p_angle <= 90)
1366
1.26M
      need_above = 1, need_left = 0, need_above_left = 1;
1367
3.05M
    else if (p_angle < 180)
1368
1.40M
      need_above = 1, need_left = 1, need_above_left = 1;
1369
1.65M
    else
1370
1.65M
      need_above = 0, need_left = 1, need_above_left = 1;
1371
4.31M
  }
1372
17.3M
  if (use_filter_intra) need_left = need_above = need_above_left = 1;
1373
1374
17.3M
  assert(n_top_px >= 0);
1375
17.3M
  assert(n_topright_px >= 0);
1376
17.3M
  assert(n_left_px >= 0);
1377
17.3M
  assert(n_bottomleft_px >= 0);
1378
1379
17.3M
  if ((!need_above && n_left_px == 0) || (!need_left && n_top_px == 0)) {
1380
59.0k
    int val;
1381
59.0k
    if (need_left) {
1382
26.8k
      val = (n_top_px > 0) ? above_ref[0] : 129;
1383
32.2k
    } else {
1384
32.2k
      val = (n_left_px > 0) ? left_ref[0] : 127;
1385
32.2k
    }
1386
1.31M
    for (i = 0; i < txhpx; ++i) {
1387
1.25M
      memset(dst, val, txwpx);
1388
1.25M
      dst += dst_stride;
1389
1.25M
    }
1390
59.0k
    return;
1391
59.0k
  }
1392
1393
  // NEED_LEFT
1394
17.3M
  if (need_left) {
1395
16.0M
    int need_bottom = extend_modes[mode] & NEED_BOTTOMLEFT;
1396
16.0M
    if (use_filter_intra) need_bottom = 0;
1397
16.0M
    if (is_dr_mode) need_bottom = p_angle > 180;
1398
16.0M
    const int num_left_pixels_needed = txhpx + (need_bottom ? txwpx : 0);
1399
16.0M
    i = 0;
1400
16.0M
    if (n_left_px > 0) {
1401
200M
      for (; i < n_left_px; i++) left_col[i] = left_ref[i * ref_stride];
1402
15.5M
      if (need_bottom && n_bottomleft_px > 0) {
1403
310k
        assert(i == txhpx);
1404
3.45M
        for (; i < txhpx + n_bottomleft_px; i++)
1405
3.14M
          left_col[i] = left_ref[i * ref_stride];
1406
310k
      }
1407
15.5M
      if (i < num_left_pixels_needed)
1408
804k
        memset(&left_col[i], left_col[i - 1], num_left_pixels_needed - i);
1409
15.5M
    } else if (n_top_px > 0) {
1410
546k
      memset(left_col, above_ref[0], num_left_pixels_needed);
1411
546k
    }
1412
16.0M
  }
1413
1414
  // NEED_ABOVE
1415
17.3M
  if (need_above) {
1416
15.7M
    int need_right = extend_modes[mode] & NEED_ABOVERIGHT;
1417
15.7M
    if (use_filter_intra) need_right = 0;
1418
15.7M
    if (is_dr_mode) need_right = p_angle < 90;
1419
15.7M
    const int num_top_pixels_needed = txwpx + (need_right ? txhpx : 0);
1420
15.7M
    if (n_top_px > 0) {
1421
15.1M
      memcpy(above_row, above_ref, n_top_px);
1422
15.1M
      i = n_top_px;
1423
15.1M
      if (need_right && n_topright_px > 0) {
1424
476k
        assert(n_top_px == txwpx);
1425
476k
        memcpy(above_row + txwpx, above_ref + txwpx, n_topright_px);
1426
476k
        i += n_topright_px;
1427
476k
      }
1428
15.1M
      if (i < num_top_pixels_needed)
1429
493k
        memset(&above_row[i], above_row[i - 1], num_top_pixels_needed - i);
1430
15.1M
    } else if (n_left_px > 0) {
1431
513k
      memset(above_row, left_ref[0], num_top_pixels_needed);
1432
513k
    }
1433
15.7M
  }
1434
1435
17.3M
  if (need_above_left) {
1436
7.63M
    if (n_top_px > 0 && n_left_px > 0) {
1437
7.20M
      above_row[-1] = above_ref[-1];
1438
7.20M
    } else if (n_top_px > 0) {
1439
199k
      above_row[-1] = above_ref[0];
1440
237k
    } else if (n_left_px > 0) {
1441
231k
      above_row[-1] = left_ref[0];
1442
231k
    } else {
1443
5.89k
      above_row[-1] = 128;
1444
5.89k
    }
1445
7.63M
    left_col[-1] = above_row[-1];
1446
7.63M
  }
1447
1448
17.3M
  if (use_filter_intra) {
1449
794k
    av1_filter_intra_predictor(dst, dst_stride, tx_size, above_row, left_col,
1450
794k
                               filter_intra_mode);
1451
794k
    return;
1452
794k
  }
1453
1454
16.5M
  if (is_dr_mode) {
1455
4.25M
    int upsample_above = 0;
1456
4.25M
    int upsample_left = 0;
1457
4.25M
    if (!disable_edge_filter) {
1458
2.83M
      const int need_right = p_angle < 90;
1459
2.83M
      const int need_bottom = p_angle > 180;
1460
2.83M
      if (p_angle != 90 && p_angle != 180) {
1461
2.02M
        const int ab_le = need_above_left ? 1 : 0;
1462
2.02M
        if (need_above && need_left && (txwpx + txhpx >= 24)) {
1463
358k
          filter_intra_edge_corner(above_row, left_col);
1464
358k
        }
1465
2.02M
        if (need_above && n_top_px > 0) {
1466
1.40M
          const int strength = intra_edge_filter_strength(
1467
1.40M
              txwpx, txhpx, p_angle - 90, intra_edge_filter_type);
1468
1.40M
          const int n_px = n_top_px + ab_le + (need_right ? txhpx : 0);
1469
1.40M
          av1_filter_intra_edge(above_row - ab_le, n_px, strength);
1470
1.40M
        }
1471
2.02M
        if (need_left && n_left_px > 0) {
1472
1.51M
          const int strength = intra_edge_filter_strength(
1473
1.51M
              txhpx, txwpx, p_angle - 180, intra_edge_filter_type);
1474
1.51M
          const int n_px = n_left_px + ab_le + (need_bottom ? txwpx : 0);
1475
1.51M
          av1_filter_intra_edge(left_col - ab_le, n_px, strength);
1476
1.51M
        }
1477
2.02M
      }
1478
2.83M
      upsample_above = av1_use_intra_edge_upsample(txwpx, txhpx, p_angle - 90,
1479
2.83M
                                                   intra_edge_filter_type);
1480
2.83M
      if (need_above && upsample_above) {
1481
381k
        const int n_px = txwpx + (need_right ? txhpx : 0);
1482
381k
        av1_upsample_intra_edge(above_row, n_px);
1483
381k
      }
1484
2.83M
      upsample_left = av1_use_intra_edge_upsample(txhpx, txwpx, p_angle - 180,
1485
2.83M
                                                  intra_edge_filter_type);
1486
2.83M
      if (need_left && upsample_left) {
1487
481k
        const int n_px = txhpx + (need_bottom ? txwpx : 0);
1488
481k
        av1_upsample_intra_edge(left_col, n_px);
1489
481k
      }
1490
2.83M
    }
1491
4.25M
    dr_predictor(dst, dst_stride, tx_size, above_row, left_col, upsample_above,
1492
4.25M
                 upsample_left, p_angle);
1493
4.25M
    return;
1494
4.25M
  }
1495
1496
  // predict
1497
12.2M
  if (mode == DC_PRED) {
1498
7.22M
    dc_pred[n_left_px > 0][n_top_px > 0][tx_size](dst, dst_stride, above_row,
1499
7.22M
                                                  left_col);
1500
7.22M
  } else {
1501
5.04M
    pred[mode][tx_size](dst, dst_stride, above_row, left_col);
1502
5.04M
  }
1503
12.2M
}
1504
1505
static INLINE BLOCK_SIZE scale_chroma_bsize(BLOCK_SIZE bsize, int subsampling_x,
1506
7.92M
                                            int subsampling_y) {
1507
7.92M
  assert(subsampling_x >= 0 && subsampling_x < 2);
1508
7.92M
  assert(subsampling_y >= 0 && subsampling_y < 2);
1509
7.92M
  BLOCK_SIZE bs = bsize;
1510
7.92M
  switch (bsize) {
1511
148k
    case BLOCK_4X4:
1512
148k
      if (subsampling_x == 1 && subsampling_y == 1)
1513
147k
        bs = BLOCK_8X8;
1514
537
      else if (subsampling_x == 1)
1515
537
        bs = BLOCK_8X4;
1516
0
      else if (subsampling_y == 1)
1517
0
        bs = BLOCK_4X8;
1518
148k
      break;
1519
195k
    case BLOCK_4X8:
1520
195k
      if (subsampling_x == 1 && subsampling_y == 1)
1521
195k
        bs = BLOCK_8X8;
1522
0
      else if (subsampling_x == 1)
1523
0
        bs = BLOCK_8X8;
1524
0
      else if (subsampling_y == 1)
1525
0
        bs = BLOCK_4X8;
1526
195k
      break;
1527
252k
    case BLOCK_8X4:
1528
252k
      if (subsampling_x == 1 && subsampling_y == 1)
1529
251k
        bs = BLOCK_8X8;
1530
1.05k
      else if (subsampling_x == 1)
1531
1.05k
        bs = BLOCK_8X4;
1532
0
      else if (subsampling_y == 1)
1533
0
        bs = BLOCK_8X8;
1534
252k
      break;
1535
272k
    case BLOCK_4X16:
1536
272k
      if (subsampling_x == 1 && subsampling_y == 1)
1537
272k
        bs = BLOCK_8X16;
1538
0
      else if (subsampling_x == 1)
1539
0
        bs = BLOCK_8X16;
1540
0
      else if (subsampling_y == 1)
1541
0
        bs = BLOCK_4X16;
1542
272k
      break;
1543
316k
    case BLOCK_16X4:
1544
316k
      if (subsampling_x == 1 && subsampling_y == 1)
1545
314k
        bs = BLOCK_16X8;
1546
2.18k
      else if (subsampling_x == 1)
1547
2.18k
        bs = BLOCK_16X4;
1548
0
      else if (subsampling_y == 1)
1549
0
        bs = BLOCK_16X8;
1550
316k
      break;
1551
6.73M
    default: break;
1552
7.92M
  }
1553
7.92M
  return bs;
1554
7.92M
}
1555
1556
void av1_predict_intra_block(const MACROBLOCKD *xd, BLOCK_SIZE sb_size,
1557
                             int enable_intra_edge_filter, int wpx, int hpx,
1558
                             TX_SIZE tx_size, PREDICTION_MODE mode,
1559
                             int angle_delta, int use_palette,
1560
                             FILTER_INTRA_MODE filter_intra_mode,
1561
                             const uint8_t *ref, int ref_stride, uint8_t *dst,
1562
                             int dst_stride, int col_off, int row_off,
1563
36.5M
                             int plane) {
1564
36.5M
  const MB_MODE_INFO *const mbmi = xd->mi[0];
1565
36.5M
  const int txwpx = tx_size_wide[tx_size];
1566
36.5M
  const int txhpx = tx_size_high[tx_size];
1567
36.5M
  const int x = col_off << MI_SIZE_LOG2;
1568
36.5M
  const int y = row_off << MI_SIZE_LOG2;
1569
1570
36.5M
  if (use_palette) {
1571
167k
    int r, c;
1572
167k
    const uint8_t *const map = xd->plane[plane != 0].color_index_map +
1573
167k
                               xd->color_index_map_offset[plane != 0];
1574
167k
    const uint16_t *const palette =
1575
167k
        mbmi->palette_mode_info.palette_colors + plane * PALETTE_MAX_SIZE;
1576
167k
    if (is_cur_buf_hbd(xd)) {
1577
38.5k
      uint16_t *dst16 = CONVERT_TO_SHORTPTR(dst);
1578
335k
      for (r = 0; r < txhpx; ++r) {
1579
3.93M
        for (c = 0; c < txwpx; ++c) {
1580
3.64M
          dst16[r * dst_stride + c] = palette[map[(r + y) * wpx + c + x]];
1581
3.64M
        }
1582
297k
      }
1583
128k
    } else {
1584
1.51M
      for (r = 0; r < txhpx; ++r) {
1585
22.1M
        for (c = 0; c < txwpx; ++c) {
1586
20.7M
          dst[r * dst_stride + c] =
1587
20.7M
              (uint8_t)palette[map[(r + y) * wpx + c + x]];
1588
20.7M
        }
1589
1.38M
      }
1590
128k
    }
1591
167k
    return;
1592
167k
  }
1593
1594
36.3M
  const struct macroblockd_plane *const pd = &xd->plane[plane];
1595
36.3M
  const int txw = tx_size_wide_unit[tx_size];
1596
36.3M
  const int txh = tx_size_high_unit[tx_size];
1597
36.3M
  const int ss_x = pd->subsampling_x;
1598
36.3M
  const int ss_y = pd->subsampling_y;
1599
36.3M
  const int have_top =
1600
36.3M
      row_off || (ss_y ? xd->chroma_up_available : xd->up_available);
1601
36.3M
  const int have_left =
1602
36.3M
      col_off || (ss_x ? xd->chroma_left_available : xd->left_available);
1603
36.3M
  const int mi_row = -xd->mb_to_top_edge >> (3 + MI_SIZE_LOG2);
1604
36.3M
  const int mi_col = -xd->mb_to_left_edge >> (3 + MI_SIZE_LOG2);
1605
1606
  // Distance between the right edge of this prediction block to
1607
  // the frame right edge
1608
36.3M
  const int xr = (xd->mb_to_right_edge >> (3 + ss_x)) + wpx - x - txwpx;
1609
  // Distance between the bottom edge of this prediction block to
1610
  // the frame bottom edge
1611
36.3M
  const int yd = (xd->mb_to_bottom_edge >> (3 + ss_y)) + hpx - y - txhpx;
1612
36.3M
  const int right_available =
1613
36.3M
      mi_col + ((col_off + txw) << ss_x) < xd->tile.mi_col_end;
1614
36.3M
  const int bottom_available =
1615
36.3M
      (yd > 0) && (mi_row + ((row_off + txh) << ss_y) < xd->tile.mi_row_end);
1616
1617
36.3M
  const PARTITION_TYPE partition = mbmi->partition;
1618
1619
36.3M
  BLOCK_SIZE bsize = mbmi->bsize;
1620
  // force 4x4 chroma component block size.
1621
36.3M
  if (ss_x || ss_y) {
1622
7.92M
    bsize = scale_chroma_bsize(bsize, ss_x, ss_y);
1623
7.92M
  }
1624
1625
36.3M
  const int have_top_right =
1626
36.3M
      has_top_right(sb_size, bsize, mi_row, mi_col, have_top, right_available,
1627
36.3M
                    partition, tx_size, row_off, col_off, ss_x, ss_y);
1628
36.3M
  const int have_bottom_left = has_bottom_left(
1629
36.3M
      sb_size, bsize, mi_row, mi_col, bottom_available, have_left, partition,
1630
36.3M
      tx_size, row_off, col_off, ss_x, ss_y);
1631
1632
36.3M
  const int disable_edge_filter = !enable_intra_edge_filter;
1633
36.3M
  const int intra_edge_filter_type = get_intra_edge_filter_type(xd, plane);
1634
36.3M
#if CONFIG_AV1_HIGHBITDEPTH
1635
36.3M
  if (is_cur_buf_hbd(xd)) {
1636
18.9M
    build_intra_predictors_high(
1637
18.9M
        ref, ref_stride, dst, dst_stride, mode, angle_delta, filter_intra_mode,
1638
18.9M
        tx_size, disable_edge_filter, have_top ? AOMMIN(txwpx, xr + txwpx) : 0,
1639
18.9M
        have_top_right ? AOMMIN(txwpx, xr) : 0,
1640
18.9M
        have_left ? AOMMIN(txhpx, yd + txhpx) : 0,
1641
18.9M
        have_bottom_left ? AOMMIN(txhpx, yd) : 0, intra_edge_filter_type,
1642
18.9M
        xd->bd);
1643
18.9M
    return;
1644
18.9M
  }
1645
17.3M
#endif
1646
17.3M
  build_intra_predictors(
1647
17.3M
      ref, ref_stride, dst, dst_stride, mode, angle_delta, filter_intra_mode,
1648
17.3M
      tx_size, disable_edge_filter, have_top ? AOMMIN(txwpx, xr + txwpx) : 0,
1649
17.3M
      have_top_right ? AOMMIN(txwpx, xr) : 0,
1650
17.3M
      have_left ? AOMMIN(txhpx, yd + txhpx) : 0,
1651
17.3M
      have_bottom_left ? AOMMIN(txhpx, yd) : 0, intra_edge_filter_type);
1652
17.3M
}
1653
1654
void av1_predict_intra_block_facade(const AV1_COMMON *cm, MACROBLOCKD *xd,
1655
                                    int plane, int blk_col, int blk_row,
1656
36.5M
                                    TX_SIZE tx_size) {
1657
36.5M
  const MB_MODE_INFO *const mbmi = xd->mi[0];
1658
36.5M
  struct macroblockd_plane *const pd = &xd->plane[plane];
1659
36.5M
  const int dst_stride = pd->dst.stride;
1660
36.5M
  uint8_t *dst = &pd->dst.buf[(blk_row * dst_stride + blk_col) << MI_SIZE_LOG2];
1661
36.5M
  const PREDICTION_MODE mode =
1662
36.5M
      (plane == AOM_PLANE_Y) ? mbmi->mode : get_uv_mode(mbmi->uv_mode);
1663
36.5M
  const int use_palette = mbmi->palette_mode_info.palette_size[plane != 0] > 0;
1664
36.5M
  const FILTER_INTRA_MODE filter_intra_mode =
1665
36.5M
      (plane == AOM_PLANE_Y && mbmi->filter_intra_mode_info.use_filter_intra)
1666
36.5M
          ? mbmi->filter_intra_mode_info.filter_intra_mode
1667
36.5M
          : FILTER_INTRA_MODES;
1668
36.5M
  const int angle_delta = mbmi->angle_delta[plane != AOM_PLANE_Y] * ANGLE_STEP;
1669
36.5M
  const SequenceHeader *seq_params = cm->seq_params;
1670
1671
36.5M
  if (plane != AOM_PLANE_Y && mbmi->uv_mode == UV_CFL_PRED) {
1672
3.61M
#if CONFIG_DEBUG
1673
3.61M
    assert(is_cfl_allowed(xd));
1674
3.61M
    const BLOCK_SIZE plane_bsize =
1675
3.61M
        get_plane_block_size(mbmi->bsize, pd->subsampling_x, pd->subsampling_y);
1676
3.61M
    (void)plane_bsize;
1677
3.61M
    assert(plane_bsize < BLOCK_SIZES_ALL);
1678
3.61M
    if (!xd->lossless[mbmi->segment_id]) {
1679
3.61M
      assert(blk_col == 0);
1680
3.61M
      assert(blk_row == 0);
1681
3.61M
      assert(block_size_wide[plane_bsize] == tx_size_wide[tx_size]);
1682
3.61M
      assert(block_size_high[plane_bsize] == tx_size_high[tx_size]);
1683
3.61M
    }
1684
3.61M
#endif
1685
3.61M
    CFL_CTX *const cfl = &xd->cfl;
1686
3.61M
    CFL_PRED_TYPE pred_plane = get_cfl_pred_type(plane);
1687
3.61M
    if (cfl->dc_pred_is_cached[pred_plane] == 0) {
1688
3.61M
      av1_predict_intra_block(xd, seq_params->sb_size,
1689
3.61M
                              seq_params->enable_intra_edge_filter, pd->width,
1690
3.61M
                              pd->height, tx_size, mode, angle_delta,
1691
3.61M
                              use_palette, filter_intra_mode, dst, dst_stride,
1692
3.61M
                              dst, dst_stride, blk_col, blk_row, plane);
1693
3.61M
      if (cfl->use_dc_pred_cache) {
1694
0
        cfl_store_dc_pred(xd, dst, pred_plane, tx_size_wide[tx_size]);
1695
0
        cfl->dc_pred_is_cached[pred_plane] = 1;
1696
0
      }
1697
3.61M
    } else {
1698
0
      cfl_load_dc_pred(xd, dst, dst_stride, tx_size, pred_plane);
1699
0
    }
1700
3.61M
    cfl_predict_block(xd, dst, dst_stride, tx_size, plane);
1701
3.61M
    return;
1702
3.61M
  }
1703
32.9M
  av1_predict_intra_block(
1704
32.9M
      xd, seq_params->sb_size, seq_params->enable_intra_edge_filter, pd->width,
1705
32.9M
      pd->height, tx_size, mode, angle_delta, use_palette, filter_intra_mode,
1706
32.9M
      dst, dst_stride, dst, dst_stride, blk_col, blk_row, plane);
1707
32.9M
}
1708
1709
3
void av1_init_intra_predictors(void) {
1710
3
  aom_once(init_intra_predictors_internal);
1711
3
}