Coverage Report

Created: 2025-11-16 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/aom/av1/common/reconintra.c
Line
Count
Source
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
604M
#define INTRA_EDGE_TAPS 5
36
#define MAX_UPSAMPLE_SZ 16
37
85.6M
#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
17.1M
                                       BLOCK_SIZE bsize) {
183
17.1M
  const uint8_t *ret = NULL;
184
  // If this is a mixed vertical partition, look up bsize in orders_vert.
185
17.1M
  if (partition == PARTITION_VERT_A || partition == PARTITION_VERT_B) {
186
1.37M
    assert(bsize < BLOCK_SIZES);
187
1.37M
    ret = has_tr_vert_tables[bsize];
188
15.8M
  } else {
189
15.8M
    ret = has_tr_tables[bsize];
190
15.8M
  }
191
17.1M
  assert(ret);
192
17.1M
  return ret;
193
17.1M
}
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
42.8M
                         int col_off, int ss_x, int ss_y) {
199
42.8M
  if (!top_available || !right_available) return 0;
200
201
38.7M
  const int bw_unit = mi_size_wide[bsize];
202
38.7M
  const int plane_bw_unit = AOMMAX(bw_unit >> ss_x, 1);
203
38.7M
  const int top_right_count_unit = tx_size_wide_unit[txsz];
204
205
38.7M
  if (row_off > 0) {  // Just need to check if enough pixels on the right.
206
12.1M
    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.65M
      if (row_off == mi_size_high[BLOCK_64X64] >> ss_y &&
211
726k
          col_off + top_right_count_unit == mi_size_wide[BLOCK_64X64] >> ss_x) {
212
207k
        return 1;
213
207k
      }
214
5.44M
      const int plane_bw_unit_64 = mi_size_wide[BLOCK_64X64] >> ss_x;
215
5.44M
      const int col_off_64 = col_off % plane_bw_unit_64;
216
5.44M
      return col_off_64 + top_right_count_unit < plane_bw_unit_64;
217
5.65M
    }
218
6.49M
    return col_off + top_right_count_unit < plane_bw_unit;
219
26.6M
  } else {
220
    // All top-right pixels are in the block above, which is already available.
221
26.6M
    if (col_off + top_right_count_unit < plane_bw_unit) return 1;
222
223
24.3M
    const int bw_in_mi_log2 = mi_size_wide_log2[bsize];
224
24.3M
    const int bh_in_mi_log2 = mi_size_high_log2[bsize];
225
24.3M
    const int sb_mi_size = mi_size_high[sb_size];
226
24.3M
    const int blk_row_in_sb = (mi_row & (sb_mi_size - 1)) >> bh_in_mi_log2;
227
24.3M
    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
24.3M
    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
20.0M
    if (((blk_col_in_sb + 1) << bw_in_mi_log2) >= sb_mi_size) {
236
2.86M
      return 0;
237
2.86M
    }
238
239
    // General case (neither top row nor rightmost column): check if the
240
    // top-right block is coded before the current block.
241
17.1M
    const int this_blk_index =
242
17.1M
        ((blk_row_in_sb + 0) << (MAX_MIB_SIZE_LOG2 - bw_in_mi_log2)) +
243
17.1M
        blk_col_in_sb + 0;
244
17.1M
    const int idx1 = this_blk_index / 8;
245
17.1M
    const int idx2 = this_blk_index % 8;
246
17.1M
    const uint8_t *has_tr_table = get_has_tr_table(partition, bsize);
247
17.1M
    return (has_tr_table[idx1] >> idx2) & 1;
248
20.0M
  }
249
38.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
17.2M
                                       BLOCK_SIZE bsize) {
368
17.2M
  const uint8_t *ret = NULL;
369
  // If this is a mixed vertical partition, look up bsize in orders_vert.
370
17.2M
  if (partition == PARTITION_VERT_A || partition == PARTITION_VERT_B) {
371
1.39M
    assert(bsize < BLOCK_SIZES);
372
1.39M
    ret = has_bl_vert_tables[bsize];
373
15.9M
  } else {
374
15.9M
    ret = has_bl_tables[bsize];
375
15.9M
  }
376
17.2M
  assert(ret);
377
17.2M
  return ret;
378
17.2M
}
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
42.8M
                           int col_off, int ss_x, int ss_y) {
384
42.8M
  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
39.5M
  if (block_size_wide[bsize] > block_size_wide[BLOCK_64X64] && col_off > 0) {
390
5.77M
    const int plane_bw_unit_64 = mi_size_wide[BLOCK_64X64] >> ss_x;
391
5.77M
    const int col_off_64 = col_off % plane_bw_unit_64;
392
5.77M
    if (col_off_64 == 0) {
393
      // We are at the left edge of top-right or bottom-right 64x* block.
394
809k
      const int plane_bh_unit_64 = mi_size_high[BLOCK_64X64] >> ss_y;
395
809k
      const int row_off_64 = row_off % plane_bh_unit_64;
396
809k
      const int plane_bh_unit =
397
809k
          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
809k
      return row_off_64 + tx_size_high_unit[txsz] < plane_bh_unit;
401
809k
    }
402
5.77M
  }
403
404
38.7M
  if (col_off > 0) {
405
    // Bottom-left pixels are in the bottom-left block, which is not available.
406
11.1M
    return 0;
407
27.6M
  } else {
408
27.6M
    const int bh_unit = mi_size_high[bsize];
409
27.6M
    const int plane_bh_unit = AOMMAX(bh_unit >> ss_y, 1);
410
27.6M
    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
27.6M
    if (row_off + bottom_left_count_unit < plane_bh_unit) return 1;
414
415
24.9M
    const int bw_in_mi_log2 = mi_size_wide_log2[bsize];
416
24.9M
    const int bh_in_mi_log2 = mi_size_high_log2[bsize];
417
24.9M
    const int sb_mi_size = mi_size_high[sb_size];
418
24.9M
    const int blk_row_in_sb = (mi_row & (sb_mi_size - 1)) >> bh_in_mi_log2;
419
24.9M
    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
24.9M
    if (blk_col_in_sb == 0) {
425
3.92M
      const int blk_start_row_off =
426
3.92M
          blk_row_in_sb << (bh_in_mi_log2 + MI_SIZE_LOG2 - MI_SIZE_LOG2) >>
427
3.92M
          ss_y;
428
3.92M
      const int row_off_in_sb = blk_start_row_off + row_off;
429
3.92M
      const int sb_height_unit = sb_mi_size >> ss_y;
430
3.92M
      return row_off_in_sb + bottom_left_count_unit < sb_height_unit;
431
3.92M
    }
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
20.9M
    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
17.2M
    const int this_blk_index =
440
17.2M
        ((blk_row_in_sb + 0) << (MAX_MIB_SIZE_LOG2 - bw_in_mi_log2)) +
441
17.2M
        blk_col_in_sb + 0;
442
17.2M
    const int idx1 = this_blk_index / 8;
443
17.2M
    const int idx2 = this_blk_index % 8;
444
17.2M
    const uint8_t *has_bl_table = get_has_bl_table(partition, bsize);
445
17.2M
    return (has_bl_table[idx1] >> idx2) & 1;
446
20.9M
  }
447
38.7M
}
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
5
static void init_intra_predictors_internal(void) {
464
5
  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
5
#define INIT_RECTANGULAR(p, type)             \
478
100
  p[TX_4X8] = aom_##type##_predictor_4x8;     \
479
100
  p[TX_8X4] = aom_##type##_predictor_8x4;     \
480
100
  p[TX_8X16] = aom_##type##_predictor_8x16;   \
481
100
  p[TX_16X8] = aom_##type##_predictor_16x8;   \
482
100
  p[TX_16X32] = aom_##type##_predictor_16x32; \
483
100
  p[TX_32X16] = aom_##type##_predictor_32x16; \
484
100
  p[TX_32X64] = aom_##type##_predictor_32x64; \
485
100
  p[TX_64X32] = aom_##type##_predictor_64x32; \
486
100
  p[TX_4X16] = aom_##type##_predictor_4x16;   \
487
100
  p[TX_16X4] = aom_##type##_predictor_16x4;   \
488
100
  p[TX_8X32] = aom_##type##_predictor_8x32;   \
489
100
  p[TX_32X8] = aom_##type##_predictor_32x8;   \
490
100
  p[TX_16X64] = aom_##type##_predictor_16x64; \
491
100
  p[TX_64X16] = aom_##type##_predictor_64x16;
492
5
#endif
493
494
5
#define INIT_NO_4X4(p, type)                  \
495
100
  p[TX_8X8] = aom_##type##_predictor_8x8;     \
496
100
  p[TX_16X16] = aom_##type##_predictor_16x16; \
497
100
  p[TX_32X32] = aom_##type##_predictor_32x32; \
498
100
  p[TX_64X64] = aom_##type##_predictor_64x64; \
499
100
  INIT_RECTANGULAR(p, type)
500
501
5
#define INIT_ALL_SIZES(p, type)           \
502
100
  p[TX_4X4] = aom_##type##_predictor_4x4; \
503
100
  INIT_NO_4X4(p, type)
504
505
5
  INIT_ALL_SIZES(pred[V_PRED], v);
506
5
  INIT_ALL_SIZES(pred[H_PRED], h);
507
5
  INIT_ALL_SIZES(pred[PAETH_PRED], paeth);
508
5
  INIT_ALL_SIZES(pred[SMOOTH_PRED], smooth);
509
5
  INIT_ALL_SIZES(pred[SMOOTH_V_PRED], smooth_v);
510
5
  INIT_ALL_SIZES(pred[SMOOTH_H_PRED], smooth_h);
511
5
  INIT_ALL_SIZES(dc_pred[0][0], dc_128);
512
5
  INIT_ALL_SIZES(dc_pred[0][1], dc_top);
513
5
  INIT_ALL_SIZES(dc_pred[1][0], dc_left);
514
5
  INIT_ALL_SIZES(dc_pred[1][1], dc);
515
5
#if CONFIG_AV1_HIGHBITDEPTH
516
5
  INIT_ALL_SIZES(pred_high[V_PRED], highbd_v);
517
5
  INIT_ALL_SIZES(pred_high[H_PRED], highbd_h);
518
5
  INIT_ALL_SIZES(pred_high[PAETH_PRED], highbd_paeth);
519
5
  INIT_ALL_SIZES(pred_high[SMOOTH_PRED], highbd_smooth);
520
5
  INIT_ALL_SIZES(pred_high[SMOOTH_V_PRED], highbd_smooth_v);
521
5
  INIT_ALL_SIZES(pred_high[SMOOTH_H_PRED], highbd_smooth_h);
522
5
  INIT_ALL_SIZES(dc_pred_high[0][0], highbd_dc_128);
523
5
  INIT_ALL_SIZES(dc_pred_high[0][1], highbd_dc_top);
524
5
  INIT_ALL_SIZES(dc_pred_high[1][0], highbd_dc_left);
525
5
  INIT_ALL_SIZES(dc_pred_high[1][1], highbd_dc);
526
5
#endif
527
5
#undef intra_pred_allsizes
528
5
}
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
1.00M
                            int upsample_above, int dx, int dy) {
534
1.00M
  int r, c, x, base, shift, val;
535
536
1.00M
  (void)left;
537
1.00M
  (void)dy;
538
1.00M
  assert(dy == 1);
539
1.00M
  assert(dx > 0);
540
541
1.00M
  const int max_base_x = ((bw + bh) - 1) << upsample_above;
542
1.00M
  const int frac_bits = 6 - upsample_above;
543
1.00M
  const int base_inc = 1 << upsample_above;
544
1.00M
  x = dx;
545
12.2M
  for (r = 0; r < bh; ++r, dst += stride, x += dx) {
546
11.2M
    base = x >> frac_bits;
547
11.2M
    shift = ((x << upsample_above) & 0x3F) >> 1;
548
549
11.2M
    if (base >= max_base_x) {
550
17.7k
      for (int i = r; i < bh; ++i) {
551
11.9k
        memset(dst, above[max_base_x], bw * sizeof(dst[0]));
552
11.9k
        dst += stride;
553
11.9k
      }
554
5.80k
      return;
555
5.80k
    }
556
557
213M
    for (c = 0; c < bw; ++c, base += base_inc) {
558
201M
      if (base < max_base_x) {
559
200M
        val = above[base] * (32 - shift) + above[base + 1] * shift;
560
200M
        dst[c] = ROUND_POWER_OF_TWO(val, 5);
561
200M
      } else {
562
1.30M
        dst[c] = above[max_base_x];
563
1.30M
      }
564
201M
    }
565
11.2M
  }
566
1.00M
}
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.78M
                            int dy) {
573
1.78M
  assert(dx > 0);
574
1.78M
  assert(dy > 0);
575
576
1.78M
  const int min_base_x = -(1 << upsample_above);
577
1.78M
  const int min_base_y = -(1 << upsample_left);
578
1.78M
  (void)min_base_y;
579
1.78M
  const int frac_bits_x = 6 - upsample_above;
580
1.78M
  const int frac_bits_y = 6 - upsample_left;
581
582
22.7M
  for (int r = 0; r < bh; ++r) {
583
402M
    for (int c = 0; c < bw; ++c) {
584
381M
      int val;
585
381M
      int y = r + 1;
586
381M
      int x = (c << 6) - y * dx;
587
381M
      const int base_x = x >> frac_bits_x;
588
381M
      if (base_x >= min_base_x) {
589
180M
        const int shift = ((x * (1 << upsample_above)) & 0x3F) >> 1;
590
180M
        val = above[base_x] * (32 - shift) + above[base_x + 1] * shift;
591
180M
        val = ROUND_POWER_OF_TWO(val, 5);
592
200M
      } else {
593
200M
        x = c + 1;
594
200M
        y = (r << 6) - x * dy;
595
200M
        const int base_y = y >> frac_bits_y;
596
200M
        assert(base_y >= min_base_y);
597
200M
        const int shift = ((y * (1 << upsample_left)) & 0x3F) >> 1;
598
200M
        val = left[base_y] * (32 - shift) + left[base_y + 1] * shift;
599
200M
        val = ROUND_POWER_OF_TWO(val, 5);
600
200M
      }
601
381M
      dst[c] = val;
602
381M
    }
603
20.9M
    dst += stride;
604
20.9M
  }
605
1.78M
}
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
1.06M
                            int upsample_left, int dx, int dy) {
611
1.06M
  int r, c, y, base, shift, val;
612
613
1.06M
  (void)above;
614
1.06M
  (void)dx;
615
616
1.06M
  assert(dx == 1);
617
1.06M
  assert(dy > 0);
618
619
1.06M
  const int max_base_y = (bw + bh - 1) << upsample_left;
620
1.06M
  const int frac_bits = 6 - upsample_left;
621
1.06M
  const int base_inc = 1 << upsample_left;
622
1.06M
  y = dy;
623
13.9M
  for (c = 0; c < bw; ++c, y += dy) {
624
12.8M
    base = y >> frac_bits;
625
12.8M
    shift = ((y << upsample_left) & 0x3F) >> 1;
626
627
229M
    for (r = 0; r < bh; ++r, base += base_inc) {
628
216M
      if (base < max_base_y) {
629
216M
        val = left[base] * (32 - shift) + left[base + 1] * shift;
630
216M
        dst[r * stride + c] = val = ROUND_POWER_OF_TWO(val, 5);
631
216M
      } else {
632
0
        for (; r < bh; ++r) dst[r * stride + c] = left[max_base_y];
633
0
        break;
634
0
      }
635
216M
    }
636
12.8M
  }
637
1.06M
}
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
5.41M
                         int upsample_above, int upsample_left, int angle) {
642
5.41M
  const int dx = av1_get_dx(angle);
643
5.41M
  const int dy = av1_get_dy(angle);
644
5.41M
  const int bw = tx_size_wide[tx_size];
645
5.41M
  const int bh = tx_size_high[tx_size];
646
5.41M
  assert(angle > 0 && angle < 270);
647
648
5.41M
  if (angle > 0 && angle < 90) {
649
1.00M
    av1_dr_prediction_z1(dst, stride, bw, bh, above, left, upsample_above, dx,
650
1.00M
                         dy);
651
4.41M
  } else if (angle > 90 && angle < 180) {
652
1.78M
    av1_dr_prediction_z2(dst, stride, bw, bh, above, left, upsample_above,
653
1.78M
                         upsample_left, dx, dy);
654
2.62M
  } else if (angle > 180 && angle < 270) {
655
1.06M
    av1_dr_prediction_z3(dst, stride, bw, bh, above, left, upsample_left, dx,
656
1.06M
                         dy);
657
1.56M
  } else if (angle == 90) {
658
652k
    pred[V_PRED][tx_size](dst, stride, above, left);
659
911k
  } else if (angle == 180) {
660
911k
    pred[H_PRED][tx_size](dst, stride, above, left);
661
911k
  }
662
5.41M
}
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
855k
                                   int dx, int dy, int bd) {
670
855k
  int r, c, x, base, shift, val;
671
672
855k
  (void)left;
673
855k
  (void)dy;
674
855k
  (void)bd;
675
855k
  assert(dy == 1);
676
855k
  assert(dx > 0);
677
678
855k
  const int max_base_x = ((bw + bh) - 1) << upsample_above;
679
855k
  const int frac_bits = 6 - upsample_above;
680
855k
  const int base_inc = 1 << upsample_above;
681
855k
  x = dx;
682
10.1M
  for (r = 0; r < bh; ++r, dst += stride, x += dx) {
683
9.28M
    base = x >> frac_bits;
684
9.28M
    shift = ((x << upsample_above) & 0x3F) >> 1;
685
686
9.28M
    if (base >= max_base_x) {
687
14.0k
      for (int i = r; i < bh; ++i) {
688
9.09k
        aom_memset16(dst, above[max_base_x], bw);
689
9.09k
        dst += stride;
690
9.09k
      }
691
4.92k
      return;
692
4.92k
    }
693
694
183M
    for (c = 0; c < bw; ++c, base += base_inc) {
695
174M
      if (base < max_base_x) {
696
173M
        val = above[base] * (32 - shift) + above[base + 1] * shift;
697
173M
        dst[c] = ROUND_POWER_OF_TWO(val, 5);
698
173M
      } else {
699
1.16M
        dst[c] = above[max_base_x];
700
1.16M
      }
701
174M
    }
702
9.27M
  }
703
855k
}
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.65M
                                   int upsample_left, int dx, int dy, int bd) {
710
1.65M
  (void)bd;
711
1.65M
  assert(dx > 0);
712
1.65M
  assert(dy > 0);
713
714
1.65M
  const int min_base_x = -(1 << upsample_above);
715
1.65M
  const int min_base_y = -(1 << upsample_left);
716
1.65M
  (void)min_base_y;
717
1.65M
  const int frac_bits_x = 6 - upsample_above;
718
1.65M
  const int frac_bits_y = 6 - upsample_left;
719
720
18.9M
  for (int r = 0; r < bh; ++r) {
721
348M
    for (int c = 0; c < bw; ++c) {
722
330M
      int val;
723
330M
      int y = r + 1;
724
330M
      int x = (c << 6) - y * dx;
725
330M
      const int base_x = x >> frac_bits_x;
726
330M
      if (base_x >= min_base_x) {
727
153M
        const int shift = ((x * (1 << upsample_above)) & 0x3F) >> 1;
728
153M
        val = above[base_x] * (32 - shift) + above[base_x + 1] * shift;
729
153M
        val = ROUND_POWER_OF_TWO(val, 5);
730
177M
      } else {
731
177M
        x = c + 1;
732
177M
        y = (r << 6) - x * dy;
733
177M
        const int base_y = y >> frac_bits_y;
734
177M
        assert(base_y >= min_base_y);
735
177M
        const int shift = ((y * (1 << upsample_left)) & 0x3F) >> 1;
736
177M
        val = left[base_y] * (32 - shift) + left[base_y + 1] * shift;
737
177M
        val = ROUND_POWER_OF_TWO(val, 5);
738
177M
      }
739
330M
      dst[c] = val;
740
330M
    }
741
17.2M
    dst += stride;
742
17.2M
  }
743
1.65M
}
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
994k
                                   int dx, int dy, int bd) {
750
994k
  int r, c, y, base, shift, val;
751
752
994k
  (void)above;
753
994k
  (void)dx;
754
994k
  (void)bd;
755
994k
  assert(dx == 1);
756
994k
  assert(dy > 0);
757
758
994k
  const int max_base_y = (bw + bh - 1) << upsample_left;
759
994k
  const int frac_bits = 6 - upsample_left;
760
994k
  const int base_inc = 1 << upsample_left;
761
994k
  y = dy;
762
12.1M
  for (c = 0; c < bw; ++c, y += dy) {
763
11.1M
    base = y >> frac_bits;
764
11.1M
    shift = ((y << upsample_left) & 0x3F) >> 1;
765
766
210M
    for (r = 0; r < bh; ++r, base += base_inc) {
767
199M
      if (base < max_base_y) {
768
199M
        val = left[base] * (32 - shift) + left[base + 1] * shift;
769
199M
        dst[r * stride + c] = ROUND_POWER_OF_TWO(val, 5);
770
199M
      } else {
771
0
        for (; r < bh; ++r) dst[r * stride + c] = left[max_base_y];
772
0
        break;
773
0
      }
774
199M
    }
775
11.1M
  }
776
994k
}
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.74M
                                int upsample_left, int angle, int bd) {
782
4.74M
  const int dx = av1_get_dx(angle);
783
4.74M
  const int dy = av1_get_dy(angle);
784
4.74M
  const int bw = tx_size_wide[tx_size];
785
4.74M
  const int bh = tx_size_high[tx_size];
786
4.74M
  assert(angle > 0 && angle < 270);
787
788
4.74M
  if (angle > 0 && angle < 90) {
789
855k
    av1_highbd_dr_prediction_z1(dst, stride, bw, bh, above, left,
790
855k
                                upsample_above, dx, dy, bd);
791
3.89M
  } else if (angle > 90 && angle < 180) {
792
1.65M
    av1_highbd_dr_prediction_z2(dst, stride, bw, bh, above, left,
793
1.65M
                                upsample_above, upsample_left, dx, dy, bd);
794
2.23M
  } else if (angle > 180 && angle < 270) {
795
994k
    av1_highbd_dr_prediction_z3(dst, stride, bw, bh, above, left, upsample_left,
796
994k
                                dx, dy, bd);
797
1.24M
  } else if (angle == 90) {
798
470k
    pred_high[V_PRED][tx_size](dst, stride, above, left, bd);
799
773k
  } else if (angle == 180) {
800
773k
    pred_high[H_PRED][tx_size](dst, stride, above, left, bd);
801
773k
  }
802
4.74M
}
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
1.16M
                                  const uint8_t *left, int mode) {
862
1.16M
  int r, c;
863
1.16M
  uint8_t buffer[33][33];
864
1.16M
  const int bw = tx_size_wide[tx_size];
865
1.16M
  const int bh = tx_size_high[tx_size];
866
867
1.16M
  assert(bw <= 32 && bh <= 32);
868
869
10.9M
  for (r = 0; r < bh; ++r) buffer[r + 1][0] = left[r];
870
1.16M
  memcpy(buffer[0], &above[-1], (bw + 1) * sizeof(uint8_t));
871
872
6.07M
  for (r = 1; r < bh + 1; r += 2)
873
18.5M
    for (c = 1; c < bw + 1; c += 4) {
874
13.6M
      const uint8_t p0 = buffer[r - 1][c - 1];
875
13.6M
      const uint8_t p1 = buffer[r - 1][c];
876
13.6M
      const uint8_t p2 = buffer[r - 1][c + 1];
877
13.6M
      const uint8_t p3 = buffer[r - 1][c + 2];
878
13.6M
      const uint8_t p4 = buffer[r - 1][c + 3];
879
13.6M
      const uint8_t p5 = buffer[r][c - 1];
880
13.6M
      const uint8_t p6 = buffer[r + 1][c - 1];
881
122M
      for (int k = 0; k < 8; ++k) {
882
108M
        int r_offset = k >> 2;
883
108M
        int c_offset = k & 0x03;
884
108M
        int pr = av1_filter_intra_taps[mode][k][0] * p0 +
885
108M
                 av1_filter_intra_taps[mode][k][1] * p1 +
886
108M
                 av1_filter_intra_taps[mode][k][2] * p2 +
887
108M
                 av1_filter_intra_taps[mode][k][3] * p3 +
888
108M
                 av1_filter_intra_taps[mode][k][4] * p4 +
889
108M
                 av1_filter_intra_taps[mode][k][5] * p5 +
890
108M
                 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
108M
        buffer[r + r_offset][c + c_offset] =
896
108M
            clip_pixel(ROUND_POWER_OF_TWO(pr, FILTER_INTRA_SCALE_BITS));
897
108M
      }
898
13.6M
    }
899
900
10.9M
  for (r = 0; r < bh; ++r) {
901
9.81M
    memcpy(dst, &buffer[r + 1][1], bw * sizeof(uint8_t));
902
9.81M
    dst += stride;
903
9.81M
  }
904
1.16M
}
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.12M
                                          int bd) {
912
1.12M
  int r, c;
913
1.12M
  uint16_t buffer[33][33];
914
1.12M
  const int bw = tx_size_wide[tx_size];
915
1.12M
  const int bh = tx_size_high[tx_size];
916
917
1.12M
  assert(bw <= 32 && bh <= 32);
918
919
10.5M
  for (r = 0; r < bh; ++r) buffer[r + 1][0] = left[r];
920
1.12M
  memcpy(buffer[0], &above[-1], (bw + 1) * sizeof(buffer[0][0]));
921
922
5.85M
  for (r = 1; r < bh + 1; r += 2)
923
17.8M
    for (c = 1; c < bw + 1; c += 4) {
924
13.1M
      const uint16_t p0 = buffer[r - 1][c - 1];
925
13.1M
      const uint16_t p1 = buffer[r - 1][c];
926
13.1M
      const uint16_t p2 = buffer[r - 1][c + 1];
927
13.1M
      const uint16_t p3 = buffer[r - 1][c + 2];
928
13.1M
      const uint16_t p4 = buffer[r - 1][c + 3];
929
13.1M
      const uint16_t p5 = buffer[r][c - 1];
930
13.1M
      const uint16_t p6 = buffer[r + 1][c - 1];
931
118M
      for (int k = 0; k < 8; ++k) {
932
105M
        int r_offset = k >> 2;
933
105M
        int c_offset = k & 0x03;
934
105M
        int pr = av1_filter_intra_taps[mode][k][0] * p0 +
935
105M
                 av1_filter_intra_taps[mode][k][1] * p1 +
936
105M
                 av1_filter_intra_taps[mode][k][2] * p2 +
937
105M
                 av1_filter_intra_taps[mode][k][3] * p3 +
938
105M
                 av1_filter_intra_taps[mode][k][4] * p4 +
939
105M
                 av1_filter_intra_taps[mode][k][5] * p5 +
940
105M
                 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
105M
        buffer[r + r_offset][c + c_offset] = clip_pixel_highbd(
946
105M
            ROUND_POWER_OF_TWO(pr, FILTER_INTRA_SCALE_BITS), bd);
947
105M
      }
948
13.1M
    }
949
950
10.5M
  for (r = 0; r < bh; ++r) {
951
9.44M
    memcpy(dst, &buffer[r + 1][1], bw * sizeof(dst[0]));
952
9.44M
    dst += stride;
953
9.44M
  }
954
1.12M
}
955
#endif  // CONFIG_AV1_HIGHBITDEPTH
956
957
74.7M
static int is_smooth(const MB_MODE_INFO *mbmi, int plane) {
958
74.7M
  if (plane == 0) {
959
31.6M
    const PREDICTION_MODE mode = mbmi->mode;
960
31.6M
    return (mode == SMOOTH_PRED || mode == SMOOTH_V_PRED ||
961
28.1M
            mode == SMOOTH_H_PRED);
962
43.1M
  } else {
963
    // uv_mode is not set for inter blocks, so need to explicitly
964
    // detect that case.
965
43.1M
    if (is_inter_block(mbmi)) return 0;
966
967
42.9M
    const UV_PREDICTION_MODE uv_mode = mbmi->uv_mode;
968
42.9M
    return (uv_mode == UV_SMOOTH_PRED || uv_mode == UV_SMOOTH_V_PRED ||
969
38.6M
            uv_mode == UV_SMOOTH_H_PRED);
970
43.1M
  }
971
74.7M
}
972
973
42.8M
static int get_intra_edge_filter_type(const MACROBLOCKD *xd, int plane) {
974
42.8M
  int ab_sm, le_sm;
975
976
42.8M
  if (plane == 0) {
977
18.2M
    const MB_MODE_INFO *ab = xd->above_mbmi;
978
18.2M
    const MB_MODE_INFO *le = xd->left_mbmi;
979
18.2M
    ab_sm = ab ? is_smooth(ab, plane) : 0;
980
18.2M
    le_sm = le ? is_smooth(le, plane) : 0;
981
24.5M
  } else {
982
24.5M
    const MB_MODE_INFO *ab = xd->chroma_above_mbmi;
983
24.5M
    const MB_MODE_INFO *le = xd->chroma_left_mbmi;
984
24.5M
    ab_sm = ab ? is_smooth(ab, plane) : 0;
985
24.5M
    le_sm = le ? is_smooth(le, plane) : 0;
986
24.5M
  }
987
988
42.8M
  return (ab_sm || le_sm) ? 1 : 0;
989
42.8M
}
990
991
8.83M
static int intra_edge_filter_strength(int bs0, int bs1, int delta, int type) {
992
8.83M
  const int d = abs(delta);
993
8.83M
  int strength = 0;
994
995
8.83M
  const int blk_wh = bs0 + bs1;
996
8.83M
  if (type == 0) {
997
6.56M
    if (blk_wh <= 8) {
998
2.14M
      if (d >= 56) strength = 1;
999
4.41M
    } else if (blk_wh <= 12) {
1000
640k
      if (d >= 40) strength = 1;
1001
3.77M
    } else if (blk_wh <= 16) {
1002
1.17M
      if (d >= 40) strength = 1;
1003
2.59M
    } else if (blk_wh <= 24) {
1004
1.09M
      if (d >= 8) strength = 1;
1005
1.09M
      if (d >= 16) strength = 2;
1006
1.09M
      if (d >= 32) strength = 3;
1007
1.49M
    } else if (blk_wh <= 32) {
1008
573k
      if (d >= 1) strength = 1;
1009
573k
      if (d >= 4) strength = 2;
1010
573k
      if (d >= 32) strength = 3;
1011
925k
    } else {
1012
925k
      if (d >= 1) strength = 3;
1013
925k
    }
1014
6.56M
  } else {
1015
2.27M
    if (blk_wh <= 8) {
1016
503k
      if (d >= 40) strength = 1;
1017
503k
      if (d >= 64) strength = 2;
1018
1.76M
    } else if (blk_wh <= 16) {
1019
745k
      if (d >= 20) strength = 1;
1020
745k
      if (d >= 48) strength = 2;
1021
1.02M
    } else if (blk_wh <= 24) {
1022
463k
      if (d >= 4) strength = 3;
1023
560k
    } else {
1024
560k
      if (d >= 1) strength = 3;
1025
560k
    }
1026
2.27M
  }
1027
8.83M
  return strength;
1028
8.83M
}
1029
1030
4.14M
void av1_filter_intra_edge_c(uint8_t *p, int sz, int strength) {
1031
4.14M
  if (!strength) return;
1032
1033
2.68M
  const int kernel[INTRA_EDGE_FILT][INTRA_EDGE_TAPS] = { { 0, 4, 8, 4, 0 },
1034
2.68M
                                                         { 0, 5, 6, 5, 0 },
1035
2.68M
                                                         { 2, 4, 4, 4, 2 } };
1036
2.68M
  const int filt = strength - 1;
1037
2.68M
  uint8_t edge[129];
1038
1039
2.68M
  memcpy(edge, p, sz * sizeof(*p));
1040
56.0M
  for (int i = 1; i < sz; i++) {
1041
53.3M
    int s = 0;
1042
319M
    for (int j = 0; j < INTRA_EDGE_TAPS; j++) {
1043
266M
      int k = i - 2 + j;
1044
266M
      k = (k < 0) ? 0 : k;
1045
266M
      k = (k > sz - 1) ? sz - 1 : k;
1046
266M
      s += edge[k] * kernel[filt][j];
1047
266M
    }
1048
53.3M
    s = (s + 8) >> 4;
1049
53.3M
    p[i] = s;
1050
53.3M
  }
1051
2.68M
}
1052
1053
524k
static void filter_intra_edge_corner(uint8_t *p_above, uint8_t *p_left) {
1054
524k
  const int kernel[3] = { 5, 6, 5 };
1055
1056
524k
  int s = (p_left[0] * kernel[0]) + (p_above[-1] * kernel[1]) +
1057
524k
          (p_above[0] * kernel[2]);
1058
524k
  s = (s + 8) >> 4;
1059
524k
  p_above[-1] = s;
1060
524k
  p_left[-1] = s;
1061
524k
}
1062
1063
4.68M
void av1_filter_intra_edge_high_c(uint16_t *p, int sz, int strength) {
1064
4.68M
  if (!strength) return;
1065
1066
2.53M
  const int kernel[INTRA_EDGE_FILT][INTRA_EDGE_TAPS] = { { 0, 4, 8, 4, 0 },
1067
2.53M
                                                         { 0, 5, 6, 5, 0 },
1068
2.53M
                                                         { 2, 4, 4, 4, 2 } };
1069
2.53M
  const int filt = strength - 1;
1070
2.53M
  uint16_t edge[129];
1071
1072
2.53M
  memcpy(edge, p, sz * sizeof(*p));
1073
49.9M
  for (int i = 1; i < sz; i++) {
1074
47.4M
    int s = 0;
1075
284M
    for (int j = 0; j < INTRA_EDGE_TAPS; j++) {
1076
237M
      int k = i - 2 + j;
1077
237M
      k = (k < 0) ? 0 : k;
1078
237M
      k = (k > sz - 1) ? sz - 1 : k;
1079
237M
      s += edge[k] * kernel[filt][j];
1080
237M
    }
1081
47.4M
    s = (s + 8) >> 4;
1082
47.4M
    p[i] = s;
1083
47.4M
  }
1084
2.53M
}
1085
1086
#if CONFIG_AV1_HIGHBITDEPTH
1087
415k
static void filter_intra_edge_corner_high(uint16_t *p_above, uint16_t *p_left) {
1088
415k
  const int kernel[3] = { 5, 6, 5 };
1089
1090
415k
  int s = (p_left[0] * kernel[0]) + (p_above[-1] * kernel[1]) +
1091
415k
          (p_above[0] * kernel[2]);
1092
415k
  s = (s + 8) >> 4;
1093
415k
  p_above[-1] = s;
1094
415k
  p_left[-1] = s;
1095
415k
}
1096
#endif
1097
1098
1.11M
void av1_upsample_intra_edge_c(uint8_t *p, int sz) {
1099
  // interpolate half-sample positions
1100
1.11M
  assert(sz <= MAX_UPSAMPLE_SZ);
1101
1102
1.11M
  uint8_t in[MAX_UPSAMPLE_SZ + 3];
1103
  // copy p[-1..(sz-1)] and extend first and last samples
1104
1.11M
  in[0] = p[-1];
1105
1.11M
  in[1] = p[-1];
1106
10.7M
  for (int i = 0; i < sz; i++) {
1107
9.67M
    in[i + 2] = p[i];
1108
9.67M
  }
1109
1.11M
  in[sz + 2] = p[sz - 1];
1110
1111
  // interpolate half-sample edge positions
1112
1.11M
  p[-2] = in[0];
1113
10.7M
  for (int i = 0; i < sz; i++) {
1114
9.67M
    int s = -in[i] + (9 * in[i + 1]) + (9 * in[i + 2]) - in[i + 3];
1115
9.67M
    s = clip_pixel((s + 8) >> 4);
1116
9.67M
    p[2 * i - 1] = s;
1117
9.67M
    p[2 * i] = in[i + 2];
1118
9.67M
  }
1119
1.11M
}
1120
1121
1.52M
void av1_upsample_intra_edge_high_c(uint16_t *p, int sz, int bd) {
1122
  // interpolate half-sample positions
1123
1.52M
  assert(sz <= MAX_UPSAMPLE_SZ);
1124
1125
1.52M
  uint16_t in[MAX_UPSAMPLE_SZ + 3];
1126
  // copy p[-1..(sz-1)] and extend first and last samples
1127
1.52M
  in[0] = p[-1];
1128
1.52M
  in[1] = p[-1];
1129
13.9M
  for (int i = 0; i < sz; i++) {
1130
12.4M
    in[i + 2] = p[i];
1131
12.4M
  }
1132
1.52M
  in[sz + 2] = p[sz - 1];
1133
1134
  // interpolate half-sample edge positions
1135
1.52M
  p[-2] = in[0];
1136
13.9M
  for (int i = 0; i < sz; i++) {
1137
12.4M
    int s = -in[i] + (9 * in[i + 1]) + (9 * in[i + 2]) - in[i + 3];
1138
12.4M
    s = (s + 8) >> 4;
1139
12.4M
    s = clip_pixel_highbd(s, bd);
1140
12.4M
    p[2 * i - 1] = s;
1141
12.4M
    p[2 * i] = in[i + 2];
1142
12.4M
  }
1143
1.52M
}
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
19.4M
    int bit_depth) {
1151
19.4M
  int i;
1152
19.4M
  uint16_t *dst = CONVERT_TO_SHORTPTR(dst8);
1153
19.4M
  uint16_t *ref = CONVERT_TO_SHORTPTR(ref8);
1154
19.4M
  DECLARE_ALIGNED(16, uint16_t, left_data[NUM_INTRA_NEIGHBOUR_PIXELS]);
1155
19.4M
  DECLARE_ALIGNED(16, uint16_t, above_data[NUM_INTRA_NEIGHBOUR_PIXELS]);
1156
19.4M
  uint16_t *const above_row = above_data + 16;
1157
19.4M
  uint16_t *const left_col = left_data + 16;
1158
19.4M
  const int txwpx = tx_size_wide[tx_size];
1159
19.4M
  const int txhpx = tx_size_high[tx_size];
1160
19.4M
  int need_left = extend_modes[mode] & NEED_LEFT;
1161
19.4M
  int need_above = extend_modes[mode] & NEED_ABOVE;
1162
19.4M
  int need_above_left = extend_modes[mode] & NEED_ABOVELEFT;
1163
19.4M
  const uint16_t *above_ref = ref - ref_stride;
1164
19.4M
  const uint16_t *left_ref = ref - 1;
1165
19.4M
  int p_angle = 0;
1166
19.4M
  const int is_dr_mode = av1_is_directional_mode(mode);
1167
19.4M
  const int use_filter_intra = filter_intra_mode != FILTER_INTRA_MODES;
1168
19.4M
  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
19.4M
  aom_memset16(left_data, base + 1, NUM_INTRA_NEIGHBOUR_PIXELS);
1174
19.4M
  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
19.4M
  if (is_dr_mode) {
1184
4.86M
    p_angle = mode_to_angle_map[mode] + angle_delta;
1185
4.86M
    if (p_angle <= 90)
1186
1.37M
      need_above = 1, need_left = 0, need_above_left = 1;
1187
3.48M
    else if (p_angle < 180)
1188
1.65M
      need_above = 1, need_left = 1, need_above_left = 1;
1189
1.83M
    else
1190
1.83M
      need_above = 0, need_left = 1, need_above_left = 1;
1191
4.86M
  }
1192
19.4M
  if (use_filter_intra) need_left = need_above = need_above_left = 1;
1193
1194
19.4M
  assert(n_top_px >= 0);
1195
19.4M
  assert(n_topright_px >= 0);
1196
19.4M
  assert(n_left_px >= 0);
1197
19.4M
  assert(n_bottomleft_px >= 0);
1198
1199
19.4M
  if ((!need_above && n_left_px == 0) || (!need_left && n_top_px == 0)) {
1200
114k
    int val;
1201
114k
    if (need_left) {
1202
68.6k
      val = (n_top_px > 0) ? above_ref[0] : base + 1;
1203
68.6k
    } else {
1204
45.4k
      val = (n_left_px > 0) ? left_ref[0] : base - 1;
1205
45.4k
    }
1206
3.03M
    for (i = 0; i < txhpx; ++i) {
1207
2.91M
      aom_memset16(dst, val, txwpx);
1208
2.91M
      dst += dst_stride;
1209
2.91M
    }
1210
114k
    return;
1211
114k
  }
1212
1213
  // NEED_LEFT
1214
19.2M
  if (need_left) {
1215
17.9M
    int need_bottom = extend_modes[mode] & NEED_BOTTOMLEFT;
1216
17.9M
    if (use_filter_intra) need_bottom = 0;
1217
17.9M
    if (is_dr_mode) need_bottom = p_angle > 180;
1218
17.9M
    const int num_left_pixels_needed = txhpx + (need_bottom ? txwpx : 0);
1219
17.9M
    i = 0;
1220
17.9M
    if (n_left_px > 0) {
1221
214M
      for (; i < n_left_px; i++) left_col[i] = left_ref[i * ref_stride];
1222
16.8M
      if (need_bottom && n_bottomleft_px > 0) {
1223
314k
        assert(i == txhpx);
1224
3.29M
        for (; i < txhpx + n_bottomleft_px; i++)
1225
2.98M
          left_col[i] = left_ref[i * ref_stride];
1226
314k
      }
1227
16.8M
      if (i < num_left_pixels_needed)
1228
893k
        aom_memset16(&left_col[i], left_col[i - 1], num_left_pixels_needed - i);
1229
16.8M
    } else if (n_top_px > 0) {
1230
1.02M
      aom_memset16(left_col, above_ref[0], num_left_pixels_needed);
1231
1.02M
    }
1232
17.9M
  }
1233
1234
  // NEED_ABOVE
1235
19.2M
  if (need_above) {
1236
17.5M
    int need_right = extend_modes[mode] & NEED_ABOVERIGHT;
1237
17.5M
    if (use_filter_intra) need_right = 0;
1238
17.5M
    if (is_dr_mode) need_right = p_angle < 90;
1239
17.5M
    const int num_top_pixels_needed = txwpx + (need_right ? txhpx : 0);
1240
17.5M
    if (n_top_px > 0) {
1241
16.8M
      memcpy(above_row, above_ref, n_top_px * sizeof(above_ref[0]));
1242
16.8M
      i = n_top_px;
1243
16.8M
      if (need_right && n_topright_px > 0) {
1244
552k
        assert(n_top_px == txwpx);
1245
552k
        memcpy(above_row + txwpx, above_ref + txwpx,
1246
552k
               n_topright_px * sizeof(above_ref[0]));
1247
552k
        i += n_topright_px;
1248
552k
      }
1249
16.8M
      if (i < num_top_pixels_needed)
1250
701k
        aom_memset16(&above_row[i], above_row[i - 1],
1251
701k
                     num_top_pixels_needed - i);
1252
16.8M
    } else if (n_left_px > 0) {
1253
645k
      aom_memset16(above_row, left_ref[0], num_top_pixels_needed);
1254
645k
    }
1255
17.5M
  }
1256
1257
19.2M
  if (need_above_left) {
1258
8.61M
    if (n_top_px > 0 && n_left_px > 0) {
1259
7.98M
      above_row[-1] = above_ref[-1];
1260
7.98M
    } else if (n_top_px > 0) {
1261
352k
      above_row[-1] = above_ref[0];
1262
352k
    } else if (n_left_px > 0) {
1263
262k
      above_row[-1] = left_ref[0];
1264
262k
    } else {
1265
11.4k
      above_row[-1] = base;
1266
11.4k
    }
1267
8.61M
    left_col[-1] = above_row[-1];
1268
8.61M
  }
1269
1270
19.2M
  if (use_filter_intra) {
1271
1.12M
    highbd_filter_intra_predictor(dst, dst_stride, tx_size, above_row, left_col,
1272
1.12M
                                  filter_intra_mode, bit_depth);
1273
1.12M
    return;
1274
1.12M
  }
1275
1276
18.1M
  if (is_dr_mode) {
1277
4.74M
    int upsample_above = 0;
1278
4.74M
    int upsample_left = 0;
1279
4.74M
    if (!disable_edge_filter) {
1280
4.38M
      const int need_right = p_angle < 90;
1281
4.38M
      const int need_bottom = p_angle > 180;
1282
4.38M
      if (p_angle != 90 && p_angle != 180) {
1283
3.23M
        const int ab_le = need_above_left ? 1 : 0;
1284
3.23M
        if (need_above && need_left && (txwpx + txhpx >= 24)) {
1285
415k
          filter_intra_edge_corner_high(above_row, left_col);
1286
415k
        }
1287
3.23M
        if (need_above && n_top_px > 0) {
1288
2.25M
          const int strength = intra_edge_filter_strength(
1289
2.25M
              txwpx, txhpx, p_angle - 90, intra_edge_filter_type);
1290
2.25M
          const int n_px = n_top_px + ab_le + (need_right ? txhpx : 0);
1291
2.25M
          av1_filter_intra_edge_high(above_row - ab_le, n_px, strength);
1292
2.25M
        }
1293
3.23M
        if (need_left && n_left_px > 0) {
1294
2.42M
          const int strength = intra_edge_filter_strength(
1295
2.42M
              txhpx, txwpx, p_angle - 180, intra_edge_filter_type);
1296
2.42M
          const int n_px = n_left_px + ab_le + (need_bottom ? txwpx : 0);
1297
2.42M
          av1_filter_intra_edge_high(left_col - ab_le, n_px, strength);
1298
2.42M
        }
1299
3.23M
      }
1300
4.38M
      upsample_above = av1_use_intra_edge_upsample(txwpx, txhpx, p_angle - 90,
1301
4.38M
                                                   intra_edge_filter_type);
1302
4.38M
      if (need_above && upsample_above) {
1303
623k
        const int n_px = txwpx + (need_right ? txhpx : 0);
1304
623k
        av1_upsample_intra_edge_high(above_row, n_px, bit_depth);
1305
623k
      }
1306
4.38M
      upsample_left = av1_use_intra_edge_upsample(txhpx, txwpx, p_angle - 180,
1307
4.38M
                                                  intra_edge_filter_type);
1308
4.38M
      if (need_left && upsample_left) {
1309
898k
        const int n_px = txhpx + (need_bottom ? txwpx : 0);
1310
898k
        av1_upsample_intra_edge_high(left_col, n_px, bit_depth);
1311
898k
      }
1312
4.38M
    }
1313
4.74M
    highbd_dr_predictor(dst, dst_stride, tx_size, above_row, left_col,
1314
4.74M
                        upsample_above, upsample_left, p_angle, bit_depth);
1315
4.74M
    return;
1316
4.74M
  }
1317
1318
  // predict
1319
13.4M
  if (mode == DC_PRED) {
1320
7.99M
    dc_pred_high[n_left_px > 0][n_top_px > 0][tx_size](
1321
7.99M
        dst, dst_stride, above_row, left_col, bit_depth);
1322
7.99M
  } else {
1323
5.41M
    pred_high[mode][tx_size](dst, dst_stride, above_row, left_col, bit_depth);
1324
5.41M
  }
1325
13.4M
}
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
23.4M
    int n_left_px, int n_bottomleft_px, int intra_edge_filter_type) {
1333
23.4M
  int i;
1334
23.4M
  const uint8_t *above_ref = ref - ref_stride;
1335
23.4M
  const uint8_t *left_ref = ref - 1;
1336
23.4M
  DECLARE_ALIGNED(16, uint8_t, left_data[NUM_INTRA_NEIGHBOUR_PIXELS]);
1337
23.4M
  DECLARE_ALIGNED(16, uint8_t, above_data[NUM_INTRA_NEIGHBOUR_PIXELS]);
1338
23.4M
  uint8_t *const above_row = above_data + 16;
1339
23.4M
  uint8_t *const left_col = left_data + 16;
1340
23.4M
  const int txwpx = tx_size_wide[tx_size];
1341
23.4M
  const int txhpx = tx_size_high[tx_size];
1342
23.4M
  int need_left = extend_modes[mode] & NEED_LEFT;
1343
23.4M
  int need_above = extend_modes[mode] & NEED_ABOVE;
1344
23.4M
  int need_above_left = extend_modes[mode] & NEED_ABOVELEFT;
1345
23.4M
  int p_angle = 0;
1346
23.4M
  const int is_dr_mode = av1_is_directional_mode(mode);
1347
23.4M
  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
23.4M
  memset(left_data, 129, NUM_INTRA_NEIGHBOUR_PIXELS);
1353
23.4M
  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
23.4M
  if (is_dr_mode) {
1364
5.50M
    p_angle = mode_to_angle_map[mode] + angle_delta;
1365
5.50M
    if (p_angle <= 90)
1366
1.69M
      need_above = 1, need_left = 0, need_above_left = 1;
1367
3.81M
    else if (p_angle < 180)
1368
1.78M
      need_above = 1, need_left = 1, need_above_left = 1;
1369
2.03M
    else
1370
2.03M
      need_above = 0, need_left = 1, need_above_left = 1;
1371
5.50M
  }
1372
23.4M
  if (use_filter_intra) need_left = need_above = need_above_left = 1;
1373
1374
23.4M
  assert(n_top_px >= 0);
1375
23.4M
  assert(n_topright_px >= 0);
1376
23.4M
  assert(n_left_px >= 0);
1377
23.4M
  assert(n_bottomleft_px >= 0);
1378
1379
23.4M
  if ((!need_above && n_left_px == 0) || (!need_left && n_top_px == 0)) {
1380
89.7k
    int val;
1381
89.7k
    if (need_left) {
1382
53.7k
      val = (n_top_px > 0) ? above_ref[0] : 129;
1383
53.7k
    } else {
1384
35.9k
      val = (n_left_px > 0) ? left_ref[0] : 127;
1385
35.9k
    }
1386
2.03M
    for (i = 0; i < txhpx; ++i) {
1387
1.94M
      memset(dst, val, txwpx);
1388
1.94M
      dst += dst_stride;
1389
1.94M
    }
1390
89.7k
    return;
1391
89.7k
  }
1392
1393
  // NEED_LEFT
1394
23.3M
  if (need_left) {
1395
21.6M
    int need_bottom = extend_modes[mode] & NEED_BOTTOMLEFT;
1396
21.6M
    if (use_filter_intra) need_bottom = 0;
1397
21.6M
    if (is_dr_mode) need_bottom = p_angle > 180;
1398
21.6M
    const int num_left_pixels_needed = txhpx + (need_bottom ? txwpx : 0);
1399
21.6M
    i = 0;
1400
21.6M
    if (n_left_px > 0) {
1401
269M
      for (; i < n_left_px; i++) left_col[i] = left_ref[i * ref_stride];
1402
20.6M
      if (need_bottom && n_bottomleft_px > 0) {
1403
370k
        assert(i == txhpx);
1404
3.99M
        for (; i < txhpx + n_bottomleft_px; i++)
1405
3.62M
          left_col[i] = left_ref[i * ref_stride];
1406
370k
      }
1407
20.6M
      if (i < num_left_pixels_needed)
1408
965k
        memset(&left_col[i], left_col[i - 1], num_left_pixels_needed - i);
1409
20.6M
    } else if (n_top_px > 0) {
1410
1.01M
      memset(left_col, above_ref[0], num_left_pixels_needed);
1411
1.01M
    }
1412
21.6M
  }
1413
1414
  // NEED_ABOVE
1415
23.3M
  if (need_above) {
1416
21.3M
    int need_right = extend_modes[mode] & NEED_ABOVERIGHT;
1417
21.3M
    if (use_filter_intra) need_right = 0;
1418
21.3M
    if (is_dr_mode) need_right = p_angle < 90;
1419
21.3M
    const int num_top_pixels_needed = txwpx + (need_right ? txhpx : 0);
1420
21.3M
    if (n_top_px > 0) {
1421
20.6M
      memcpy(above_row, above_ref, n_top_px);
1422
20.6M
      i = n_top_px;
1423
20.6M
      if (need_right && n_topright_px > 0) {
1424
636k
        assert(n_top_px == txwpx);
1425
636k
        memcpy(above_row + txwpx, above_ref + txwpx, n_topright_px);
1426
636k
        i += n_topright_px;
1427
636k
      }
1428
20.6M
      if (i < num_top_pixels_needed)
1429
851k
        memset(&above_row[i], above_row[i - 1], num_top_pixels_needed - i);
1430
20.6M
    } else if (n_left_px > 0) {
1431
622k
      memset(above_row, left_ref[0], num_top_pixels_needed);
1432
622k
    }
1433
21.3M
  }
1434
1435
23.3M
  if (need_above_left) {
1436
10.5M
    if (n_top_px > 0 && n_left_px > 0) {
1437
9.85M
      above_row[-1] = above_ref[-1];
1438
9.85M
    } else if (n_top_px > 0) {
1439
367k
      above_row[-1] = above_ref[0];
1440
367k
    } else if (n_left_px > 0) {
1441
304k
      above_row[-1] = left_ref[0];
1442
304k
    } else {
1443
7.23k
      above_row[-1] = 128;
1444
7.23k
    }
1445
10.5M
    left_col[-1] = above_row[-1];
1446
10.5M
  }
1447
1448
23.3M
  if (use_filter_intra) {
1449
1.16M
    av1_filter_intra_predictor(dst, dst_stride, tx_size, above_row, left_col,
1450
1.16M
                               filter_intra_mode);
1451
1.16M
    return;
1452
1.16M
  }
1453
1454
22.1M
  if (is_dr_mode) {
1455
5.41M
    int upsample_above = 0;
1456
5.41M
    int upsample_left = 0;
1457
5.41M
    if (!disable_edge_filter) {
1458
4.12M
      const int need_right = p_angle < 90;
1459
4.12M
      const int need_bottom = p_angle > 180;
1460
4.12M
      if (p_angle != 90 && p_angle != 180) {
1461
2.90M
        const int ab_le = need_above_left ? 1 : 0;
1462
2.90M
        if (need_above && need_left && (txwpx + txhpx >= 24)) {
1463
524k
          filter_intra_edge_corner(above_row, left_col);
1464
524k
        }
1465
2.90M
        if (need_above && n_top_px > 0) {
1466
2.04M
          const int strength = intra_edge_filter_strength(
1467
2.04M
              txwpx, txhpx, p_angle - 90, intra_edge_filter_type);
1468
2.04M
          const int n_px = n_top_px + ab_le + (need_right ? txhpx : 0);
1469
2.04M
          av1_filter_intra_edge(above_row - ab_le, n_px, strength);
1470
2.04M
        }
1471
2.90M
        if (need_left && n_left_px > 0) {
1472
2.10M
          const int strength = intra_edge_filter_strength(
1473
2.10M
              txhpx, txwpx, p_angle - 180, intra_edge_filter_type);
1474
2.10M
          const int n_px = n_left_px + ab_le + (need_bottom ? txwpx : 0);
1475
2.10M
          av1_filter_intra_edge(left_col - ab_le, n_px, strength);
1476
2.10M
        }
1477
2.90M
      }
1478
4.12M
      upsample_above = av1_use_intra_edge_upsample(txwpx, txhpx, p_angle - 90,
1479
4.12M
                                                   intra_edge_filter_type);
1480
4.12M
      if (need_above && upsample_above) {
1481
505k
        const int n_px = txwpx + (need_right ? txhpx : 0);
1482
505k
        av1_upsample_intra_edge(above_row, n_px);
1483
505k
      }
1484
4.12M
      upsample_left = av1_use_intra_edge_upsample(txhpx, txwpx, p_angle - 180,
1485
4.12M
                                                  intra_edge_filter_type);
1486
4.12M
      if (need_left && upsample_left) {
1487
612k
        const int n_px = txhpx + (need_bottom ? txwpx : 0);
1488
612k
        av1_upsample_intra_edge(left_col, n_px);
1489
612k
      }
1490
4.12M
    }
1491
5.41M
    dr_predictor(dst, dst_stride, tx_size, above_row, left_col, upsample_above,
1492
5.41M
                 upsample_left, p_angle);
1493
5.41M
    return;
1494
5.41M
  }
1495
1496
  // predict
1497
16.7M
  if (mode == DC_PRED) {
1498
9.42M
    dc_pred[n_left_px > 0][n_top_px > 0][tx_size](dst, dst_stride, above_row,
1499
9.42M
                                                  left_col);
1500
9.42M
  } else {
1501
7.30M
    pred[mode][tx_size](dst, dst_stride, above_row, left_col);
1502
7.30M
  }
1503
16.7M
}
1504
1505
static INLINE BLOCK_SIZE scale_chroma_bsize(BLOCK_SIZE bsize, int subsampling_x,
1506
7.79M
                                            int subsampling_y) {
1507
7.79M
  assert(subsampling_x >= 0 && subsampling_x < 2);
1508
7.79M
  assert(subsampling_y >= 0 && subsampling_y < 2);
1509
7.79M
  BLOCK_SIZE bs = bsize;
1510
7.79M
  switch (bsize) {
1511
146k
    case BLOCK_4X4:
1512
146k
      if (subsampling_x == 1 && subsampling_y == 1)
1513
145k
        bs = BLOCK_8X8;
1514
1.13k
      else if (subsampling_x == 1)
1515
1.13k
        bs = BLOCK_8X4;
1516
0
      else if (subsampling_y == 1)
1517
0
        bs = BLOCK_4X8;
1518
146k
      break;
1519
202k
    case BLOCK_4X8:
1520
202k
      if (subsampling_x == 1 && subsampling_y == 1)
1521
202k
        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
202k
      break;
1527
253k
    case BLOCK_8X4:
1528
253k
      if (subsampling_x == 1 && subsampling_y == 1)
1529
251k
        bs = BLOCK_8X8;
1530
1.91k
      else if (subsampling_x == 1)
1531
1.91k
        bs = BLOCK_8X4;
1532
0
      else if (subsampling_y == 1)
1533
0
        bs = BLOCK_8X8;
1534
253k
      break;
1535
296k
    case BLOCK_4X16:
1536
296k
      if (subsampling_x == 1 && subsampling_y == 1)
1537
296k
        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
296k
      break;
1543
330k
    case BLOCK_16X4:
1544
330k
      if (subsampling_x == 1 && subsampling_y == 1)
1545
326k
        bs = BLOCK_16X8;
1546
3.83k
      else if (subsampling_x == 1)
1547
3.83k
        bs = BLOCK_16X4;
1548
0
      else if (subsampling_y == 1)
1549
0
        bs = BLOCK_16X8;
1550
330k
      break;
1551
6.56M
    default: break;
1552
7.79M
  }
1553
7.79M
  return bs;
1554
7.79M
}
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
43.5M
                             int plane) {
1564
43.5M
  const MB_MODE_INFO *const mbmi = xd->mi[0];
1565
43.5M
  const int txwpx = tx_size_wide[tx_size];
1566
43.5M
  const int txhpx = tx_size_high[tx_size];
1567
43.5M
  const int x = col_off << MI_SIZE_LOG2;
1568
43.5M
  const int y = row_off << MI_SIZE_LOG2;
1569
1570
43.5M
  if (use_palette) {
1571
792k
    int r, c;
1572
792k
    const uint8_t *const map = xd->plane[plane != 0].color_index_map +
1573
792k
                               xd->color_index_map_offset[plane != 0];
1574
792k
    const uint16_t *const palette =
1575
792k
        mbmi->palette_mode_info.palette_colors + plane * PALETTE_MAX_SIZE;
1576
792k
    if (is_cur_buf_hbd(xd)) {
1577
57.0k
      uint16_t *dst16 = CONVERT_TO_SHORTPTR(dst);
1578
465k
      for (r = 0; r < txhpx; ++r) {
1579
5.14M
        for (c = 0; c < txwpx; ++c) {
1580
4.74M
          dst16[r * dst_stride + c] = palette[map[(r + y) * wpx + c + x]];
1581
4.74M
        }
1582
408k
      }
1583
735k
    } else {
1584
7.39M
      for (r = 0; r < txhpx; ++r) {
1585
98.8M
        for (c = 0; c < txwpx; ++c) {
1586
92.1M
          dst[r * dst_stride + c] =
1587
92.1M
              (uint8_t)palette[map[(r + y) * wpx + c + x]];
1588
92.1M
        }
1589
6.65M
      }
1590
735k
    }
1591
792k
    return;
1592
792k
  }
1593
1594
42.8M
  const struct macroblockd_plane *const pd = &xd->plane[plane];
1595
42.8M
  const int txw = tx_size_wide_unit[tx_size];
1596
42.8M
  const int txh = tx_size_high_unit[tx_size];
1597
42.8M
  const int ss_x = pd->subsampling_x;
1598
42.8M
  const int ss_y = pd->subsampling_y;
1599
42.8M
  const int have_top =
1600
42.8M
      row_off || (ss_y ? xd->chroma_up_available : xd->up_available);
1601
42.8M
  const int have_left =
1602
42.8M
      col_off || (ss_x ? xd->chroma_left_available : xd->left_available);
1603
42.8M
  const int mi_row = -xd->mb_to_top_edge >> (3 + MI_SIZE_LOG2);
1604
42.8M
  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
42.8M
  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
42.8M
  const int yd = (xd->mb_to_bottom_edge >> (3 + ss_y)) + hpx - y - txhpx;
1612
42.8M
  const int right_available =
1613
42.8M
      mi_col + ((col_off + txw) << ss_x) < xd->tile.mi_col_end;
1614
42.8M
  const int bottom_available =
1615
42.8M
      (yd > 0) && (mi_row + ((row_off + txh) << ss_y) < xd->tile.mi_row_end);
1616
1617
42.8M
  const PARTITION_TYPE partition = mbmi->partition;
1618
1619
42.8M
  BLOCK_SIZE bsize = mbmi->bsize;
1620
  // force 4x4 chroma component block size.
1621
42.8M
  if (ss_x || ss_y) {
1622
7.79M
    bsize = scale_chroma_bsize(bsize, ss_x, ss_y);
1623
7.79M
  }
1624
1625
42.8M
  const int have_top_right =
1626
42.8M
      has_top_right(sb_size, bsize, mi_row, mi_col, have_top, right_available,
1627
42.8M
                    partition, tx_size, row_off, col_off, ss_x, ss_y);
1628
42.8M
  const int have_bottom_left = has_bottom_left(
1629
42.8M
      sb_size, bsize, mi_row, mi_col, bottom_available, have_left, partition,
1630
42.8M
      tx_size, row_off, col_off, ss_x, ss_y);
1631
1632
42.8M
  const int disable_edge_filter = !enable_intra_edge_filter;
1633
42.8M
  const int intra_edge_filter_type = get_intra_edge_filter_type(xd, plane);
1634
42.8M
#if CONFIG_AV1_HIGHBITDEPTH
1635
42.8M
  if (is_cur_buf_hbd(xd)) {
1636
19.4M
    build_intra_predictors_high(
1637
19.4M
        ref, ref_stride, dst, dst_stride, mode, angle_delta, filter_intra_mode,
1638
19.4M
        tx_size, disable_edge_filter, have_top ? AOMMIN(txwpx, xr + txwpx) : 0,
1639
19.4M
        have_top_right ? AOMMIN(txwpx, xr) : 0,
1640
19.4M
        have_left ? AOMMIN(txhpx, yd + txhpx) : 0,
1641
19.4M
        have_bottom_left ? AOMMIN(txhpx, yd) : 0, intra_edge_filter_type,
1642
19.4M
        xd->bd);
1643
19.4M
    return;
1644
19.4M
  }
1645
23.4M
#endif
1646
23.4M
  build_intra_predictors(
1647
23.4M
      ref, ref_stride, dst, dst_stride, mode, angle_delta, filter_intra_mode,
1648
23.4M
      tx_size, disable_edge_filter, have_top ? AOMMIN(txwpx, xr + txwpx) : 0,
1649
23.4M
      have_top_right ? AOMMIN(txwpx, xr) : 0,
1650
23.4M
      have_left ? AOMMIN(txhpx, yd + txhpx) : 0,
1651
23.4M
      have_bottom_left ? AOMMIN(txhpx, yd) : 0, intra_edge_filter_type);
1652
23.4M
}
1653
1654
void av1_predict_intra_block_facade(const AV1_COMMON *cm, MACROBLOCKD *xd,
1655
                                    int plane, int blk_col, int blk_row,
1656
43.5M
                                    TX_SIZE tx_size) {
1657
43.5M
  const MB_MODE_INFO *const mbmi = xd->mi[0];
1658
43.5M
  struct macroblockd_plane *const pd = &xd->plane[plane];
1659
43.5M
  const int dst_stride = pd->dst.stride;
1660
43.5M
  uint8_t *dst = &pd->dst.buf[(blk_row * dst_stride + blk_col) << MI_SIZE_LOG2];
1661
43.5M
  const PREDICTION_MODE mode =
1662
43.5M
      (plane == AOM_PLANE_Y) ? mbmi->mode : get_uv_mode(mbmi->uv_mode);
1663
43.5M
  const int use_palette = mbmi->palette_mode_info.palette_size[plane != 0] > 0;
1664
43.5M
  const FILTER_INTRA_MODE filter_intra_mode =
1665
43.5M
      (plane == AOM_PLANE_Y && mbmi->filter_intra_mode_info.use_filter_intra)
1666
43.5M
          ? mbmi->filter_intra_mode_info.filter_intra_mode
1667
43.5M
          : FILTER_INTRA_MODES;
1668
43.5M
  const int angle_delta = mbmi->angle_delta[plane != AOM_PLANE_Y] * ANGLE_STEP;
1669
43.5M
  const SequenceHeader *seq_params = cm->seq_params;
1670
1671
43.5M
  if (plane != AOM_PLANE_Y && mbmi->uv_mode == UV_CFL_PRED) {
1672
4.59M
#if CONFIG_DEBUG
1673
4.59M
    assert(is_cfl_allowed(xd));
1674
4.59M
    const BLOCK_SIZE plane_bsize =
1675
4.59M
        get_plane_block_size(mbmi->bsize, pd->subsampling_x, pd->subsampling_y);
1676
4.59M
    (void)plane_bsize;
1677
4.59M
    assert(plane_bsize < BLOCK_SIZES_ALL);
1678
4.59M
    if (!xd->lossless[mbmi->segment_id]) {
1679
4.57M
      assert(blk_col == 0);
1680
4.57M
      assert(blk_row == 0);
1681
4.57M
      assert(block_size_wide[plane_bsize] == tx_size_wide[tx_size]);
1682
4.57M
      assert(block_size_high[plane_bsize] == tx_size_high[tx_size]);
1683
4.57M
    }
1684
4.59M
#endif
1685
4.59M
    CFL_CTX *const cfl = &xd->cfl;
1686
4.59M
    CFL_PRED_TYPE pred_plane = get_cfl_pred_type(plane);
1687
4.59M
    if (cfl->dc_pred_is_cached[pred_plane] == 0) {
1688
4.59M
      av1_predict_intra_block(xd, seq_params->sb_size,
1689
4.59M
                              seq_params->enable_intra_edge_filter, pd->width,
1690
4.59M
                              pd->height, tx_size, mode, angle_delta,
1691
4.59M
                              use_palette, filter_intra_mode, dst, dst_stride,
1692
4.59M
                              dst, dst_stride, blk_col, blk_row, plane);
1693
4.59M
      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
4.59M
    } else {
1698
0
      cfl_load_dc_pred(xd, dst, dst_stride, tx_size, pred_plane);
1699
0
    }
1700
4.59M
    cfl_predict_block(xd, dst, dst_stride, tx_size, plane);
1701
4.59M
    return;
1702
4.59M
  }
1703
39.0M
  av1_predict_intra_block(
1704
39.0M
      xd, seq_params->sb_size, seq_params->enable_intra_edge_filter, pd->width,
1705
39.0M
      pd->height, tx_size, mode, angle_delta, use_palette, filter_intra_mode,
1706
39.0M
      dst, dst_stride, dst, dst_stride, blk_col, blk_row, plane);
1707
39.0M
}
1708
1709
5
void av1_init_intra_predictors(void) {
1710
5
  aom_once(init_intra_predictors_internal);
1711
5
}