Coverage Report

Created: 2026-07-25 07:03

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