#include <assert.h>
#include <math.h>
#include "config/aom_config.h"
#include "config/aom_dsp_rtcd.h"
#include "config/av1_rtcd.h"
#include "aom_dsp/aom_dsp_common.h"
#include "aom_mem/aom_mem.h"
#include "aom_ports/aom_once.h"
#include "aom_ports/mem.h"
#include "av1/common/av1_common_int.h"
#include "av1/common/cfl.h"
#include "av1/common/reconintra.h"
enum { … };
#define INTRA_EDGE_FILT …
#define INTRA_EDGE_TAPS …
#define MAX_UPSAMPLE_SZ …
#define NUM_INTRA_NEIGHBOUR_PIXELS …
static const uint8_t extend_modes[INTRA_MODES] = …;
static uint8_t has_tr_4x4[128] = …;
static uint8_t has_tr_4x8[64] = …;
static uint8_t has_tr_8x4[64] = …;
static uint8_t has_tr_8x8[32] = …;
static uint8_t has_tr_8x16[16] = …;
static uint8_t has_tr_16x8[16] = …;
static uint8_t has_tr_16x16[8] = …;
static uint8_t has_tr_16x32[4] = …;
static uint8_t has_tr_32x16[4] = …;
static uint8_t has_tr_32x32[2] = …;
static uint8_t has_tr_32x64[1] = …;
static uint8_t has_tr_64x32[1] = …;
static uint8_t has_tr_64x64[1] = …;
static uint8_t has_tr_64x128[1] = …;
static uint8_t has_tr_128x64[1] = …;
static uint8_t has_tr_128x128[1] = …;
static uint8_t has_tr_4x16[32] = …;
static uint8_t has_tr_16x4[32] = …;
static uint8_t has_tr_8x32[8] = …;
static uint8_t has_tr_32x8[8] = …;
static uint8_t has_tr_16x64[2] = …;
static uint8_t has_tr_64x16[2] = …;
static const uint8_t *const has_tr_tables[BLOCK_SIZES_ALL] = …;
static uint8_t has_tr_vert_8x8[32] = …;
static uint8_t has_tr_vert_16x16[8] = …;
static uint8_t has_tr_vert_32x32[2] = …;
static uint8_t has_tr_vert_64x64[1] = …;
static const uint8_t *const has_tr_vert_tables[BLOCK_SIZES] = …;
static const uint8_t *get_has_tr_table(PARTITION_TYPE partition,
BLOCK_SIZE bsize) { … }
static int has_top_right(BLOCK_SIZE sb_size, BLOCK_SIZE bsize, int mi_row,
int mi_col, int top_available, int right_available,
PARTITION_TYPE partition, TX_SIZE txsz, int row_off,
int col_off, int ss_x, int ss_y) { … }
static uint8_t has_bl_4x4[128] = …;
static uint8_t has_bl_4x8[64] = …;
static uint8_t has_bl_8x4[64] = …;
static uint8_t has_bl_8x8[32] = …;
static uint8_t has_bl_8x16[16] = …;
static uint8_t has_bl_16x8[16] = …;
static uint8_t has_bl_16x16[8] = …;
static uint8_t has_bl_16x32[4] = …;
static uint8_t has_bl_32x16[4] = …;
static uint8_t has_bl_32x32[2] = …;
static uint8_t has_bl_32x64[1] = …;
static uint8_t has_bl_64x32[1] = …;
static uint8_t has_bl_64x64[1] = …;
static uint8_t has_bl_64x128[1] = …;
static uint8_t has_bl_128x64[1] = …;
static uint8_t has_bl_128x128[1] = …;
static uint8_t has_bl_4x16[32] = …;
static uint8_t has_bl_16x4[32] = …;
static uint8_t has_bl_8x32[8] = …;
static uint8_t has_bl_32x8[8] = …;
static uint8_t has_bl_16x64[2] = …;
static uint8_t has_bl_64x16[2] = …;
static const uint8_t *const has_bl_tables[BLOCK_SIZES_ALL] = …;
static uint8_t has_bl_vert_8x8[32] = …;
static uint8_t has_bl_vert_16x16[8] = …;
static uint8_t has_bl_vert_32x32[2] = …;
static uint8_t has_bl_vert_64x64[1] = …;
static const uint8_t *const has_bl_vert_tables[BLOCK_SIZES] = …;
static const uint8_t *get_has_bl_table(PARTITION_TYPE partition,
BLOCK_SIZE bsize) { … }
static int has_bottom_left(BLOCK_SIZE sb_size, BLOCK_SIZE bsize, int mi_row,
int mi_col, int bottom_available, int left_available,
PARTITION_TYPE partition, TX_SIZE txsz, int row_off,
int col_off, int ss_x, int ss_y) { … }
intra_pred_fn;
static intra_pred_fn pred[INTRA_MODES][TX_SIZES_ALL];
static intra_pred_fn dc_pred[2][2][TX_SIZES_ALL];
#if CONFIG_AV1_HIGHBITDEPTH
typedef void (*intra_high_pred_fn)(uint16_t *dst, ptrdiff_t stride,
const uint16_t *above, const uint16_t *left,
int bd);
static intra_high_pred_fn pred_high[INTRA_MODES][TX_SIZES_ALL];
static intra_high_pred_fn dc_pred_high[2][2][TX_SIZES_ALL];
#endif
static void init_intra_predictors_internal(void) { … }
void av1_dr_prediction_z1_c(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
const uint8_t *above, const uint8_t *left,
int upsample_above, int dx, int dy) { … }
void av1_dr_prediction_z2_c(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
const uint8_t *above, const uint8_t *left,
int upsample_above, int upsample_left, int dx,
int dy) { … }
void av1_dr_prediction_z3_c(uint8_t *dst, ptrdiff_t stride, int bw, int bh,
const uint8_t *above, const uint8_t *left,
int upsample_left, int dx, int dy) { … }
static void dr_predictor(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size,
const uint8_t *above, const uint8_t *left,
int upsample_above, int upsample_left, int angle) { … }
#if CONFIG_AV1_HIGHBITDEPTH
void av1_highbd_dr_prediction_z1_c(uint16_t *dst, ptrdiff_t stride, int bw,
int bh, const uint16_t *above,
const uint16_t *left, int upsample_above,
int dx, int dy, int bd) {
int r, c, x, base, shift, val;
(void)left;
(void)dy;
(void)bd;
assert(dy == 1);
assert(dx > 0);
const int max_base_x = ((bw + bh) - 1) << upsample_above;
const int frac_bits = 6 - upsample_above;
const int base_inc = 1 << upsample_above;
x = dx;
for (r = 0; r < bh; ++r, dst += stride, x += dx) {
base = x >> frac_bits;
shift = ((x << upsample_above) & 0x3F) >> 1;
if (base >= max_base_x) {
for (int i = r; i < bh; ++i) {
aom_memset16(dst, above[max_base_x], bw);
dst += stride;
}
return;
}
for (c = 0; c < bw; ++c, base += base_inc) {
if (base < max_base_x) {
val = above[base] * (32 - shift) + above[base + 1] * shift;
dst[c] = ROUND_POWER_OF_TWO(val, 5);
} else {
dst[c] = above[max_base_x];
}
}
}
}
void av1_highbd_dr_prediction_z2_c(uint16_t *dst, ptrdiff_t stride, int bw,
int bh, const uint16_t *above,
const uint16_t *left, int upsample_above,
int upsample_left, int dx, int dy, int bd) {
(void)bd;
assert(dx > 0);
assert(dy > 0);
const int min_base_x = -(1 << upsample_above);
const int min_base_y = -(1 << upsample_left);
(void)min_base_y;
const int frac_bits_x = 6 - upsample_above;
const int frac_bits_y = 6 - upsample_left;
for (int r = 0; r < bh; ++r) {
for (int c = 0; c < bw; ++c) {
int val;
int y = r + 1;
int x = (c << 6) - y * dx;
const int base_x = x >> frac_bits_x;
if (base_x >= min_base_x) {
const int shift = ((x * (1 << upsample_above)) & 0x3F) >> 1;
val = above[base_x] * (32 - shift) + above[base_x + 1] * shift;
val = ROUND_POWER_OF_TWO(val, 5);
} else {
x = c + 1;
y = (r << 6) - x * dy;
const int base_y = y >> frac_bits_y;
assert(base_y >= min_base_y);
const int shift = ((y * (1 << upsample_left)) & 0x3F) >> 1;
val = left[base_y] * (32 - shift) + left[base_y + 1] * shift;
val = ROUND_POWER_OF_TWO(val, 5);
}
dst[c] = val;
}
dst += stride;
}
}
void av1_highbd_dr_prediction_z3_c(uint16_t *dst, ptrdiff_t stride, int bw,
int bh, const uint16_t *above,
const uint16_t *left, int upsample_left,
int dx, int dy, int bd) {
int r, c, y, base, shift, val;
(void)above;
(void)dx;
(void)bd;
assert(dx == 1);
assert(dy > 0);
const int max_base_y = (bw + bh - 1) << upsample_left;
const int frac_bits = 6 - upsample_left;
const int base_inc = 1 << upsample_left;
y = dy;
for (c = 0; c < bw; ++c, y += dy) {
base = y >> frac_bits;
shift = ((y << upsample_left) & 0x3F) >> 1;
for (r = 0; r < bh; ++r, base += base_inc) {
if (base < max_base_y) {
val = left[base] * (32 - shift) + left[base + 1] * shift;
dst[r * stride + c] = ROUND_POWER_OF_TWO(val, 5);
} else {
for (; r < bh; ++r) dst[r * stride + c] = left[max_base_y];
break;
}
}
}
}
static void highbd_dr_predictor(uint16_t *dst, ptrdiff_t stride,
TX_SIZE tx_size, const uint16_t *above,
const uint16_t *left, int upsample_above,
int upsample_left, int angle, int bd) {
const int dx = av1_get_dx(angle);
const int dy = av1_get_dy(angle);
const int bw = tx_size_wide[tx_size];
const int bh = tx_size_high[tx_size];
assert(angle > 0 && angle < 270);
if (angle > 0 && angle < 90) {
av1_highbd_dr_prediction_z1(dst, stride, bw, bh, above, left,
upsample_above, dx, dy, bd);
} else if (angle > 90 && angle < 180) {
av1_highbd_dr_prediction_z2(dst, stride, bw, bh, above, left,
upsample_above, upsample_left, dx, dy, bd);
} else if (angle > 180 && angle < 270) {
av1_highbd_dr_prediction_z3(dst, stride, bw, bh, above, left, upsample_left,
dx, dy, bd);
} else if (angle == 90) {
pred_high[V_PRED][tx_size](dst, stride, above, left, bd);
} else if (angle == 180) {
pred_high[H_PRED][tx_size](dst, stride, above, left, bd);
}
}
#endif
DECLARE_ALIGNED(16, const int8_t,
av1_filter_intra_taps[FILTER_INTRA_MODES][8][8]) = …;
void av1_filter_intra_predictor_c(uint8_t *dst, ptrdiff_t stride,
TX_SIZE tx_size, const uint8_t *above,
const uint8_t *left, int mode) { … }
#if CONFIG_AV1_HIGHBITDEPTH
static void highbd_filter_intra_predictor(uint16_t *dst, ptrdiff_t stride,
TX_SIZE tx_size,
const uint16_t *above,
const uint16_t *left, int mode,
int bd) {
int r, c;
uint16_t buffer[33][33];
const int bw = tx_size_wide[tx_size];
const int bh = tx_size_high[tx_size];
assert(bw <= 32 && bh <= 32);
for (r = 0; r < bh; ++r) buffer[r + 1][0] = left[r];
memcpy(buffer[0], &above[-1], (bw + 1) * sizeof(buffer[0][0]));
for (r = 1; r < bh + 1; r += 2)
for (c = 1; c < bw + 1; c += 4) {
const uint16_t p0 = buffer[r - 1][c - 1];
const uint16_t p1 = buffer[r - 1][c];
const uint16_t p2 = buffer[r - 1][c + 1];
const uint16_t p3 = buffer[r - 1][c + 2];
const uint16_t p4 = buffer[r - 1][c + 3];
const uint16_t p5 = buffer[r][c - 1];
const uint16_t p6 = buffer[r + 1][c - 1];
for (int k = 0; k < 8; ++k) {
int r_offset = k >> 2;
int c_offset = k & 0x03;
int pr = av1_filter_intra_taps[mode][k][0] * p0 +
av1_filter_intra_taps[mode][k][1] * p1 +
av1_filter_intra_taps[mode][k][2] * p2 +
av1_filter_intra_taps[mode][k][3] * p3 +
av1_filter_intra_taps[mode][k][4] * p4 +
av1_filter_intra_taps[mode][k][5] * p5 +
av1_filter_intra_taps[mode][k][6] * p6;
buffer[r + r_offset][c + c_offset] = clip_pixel_highbd(
ROUND_POWER_OF_TWO(pr, FILTER_INTRA_SCALE_BITS), bd);
}
}
for (r = 0; r < bh; ++r) {
memcpy(dst, &buffer[r + 1][1], bw * sizeof(dst[0]));
dst += stride;
}
}
#endif
static int is_smooth(const MB_MODE_INFO *mbmi, int plane) { … }
static int get_intra_edge_filter_type(const MACROBLOCKD *xd, int plane) { … }
static int intra_edge_filter_strength(int bs0, int bs1, int delta, int type) { … }
void av1_filter_intra_edge_c(uint8_t *p, int sz, int strength) { … }
static void filter_intra_edge_corner(uint8_t *p_above, uint8_t *p_left) { … }
void av1_upsample_intra_edge_c(uint8_t *p, int sz) { … }
static void build_directional_and_filter_intra_predictors(
const uint8_t *ref, int ref_stride, uint8_t *dst, int dst_stride,
PREDICTION_MODE mode, int p_angle, FILTER_INTRA_MODE filter_intra_mode,
TX_SIZE tx_size, int disable_edge_filter, int n_top_px, int n_topright_px,
int n_left_px, int n_bottomleft_px, int intra_edge_filter_type) { … }
static void build_non_directional_intra_predictors(
const uint8_t *ref, int ref_stride, uint8_t *dst, int dst_stride,
PREDICTION_MODE mode, TX_SIZE tx_size, int n_top_px, int n_left_px) { … }
#if CONFIG_AV1_HIGHBITDEPTH
void av1_highbd_filter_intra_edge_c(uint16_t *p, int sz, int strength) {
if (!strength) return;
const int kernel[INTRA_EDGE_FILT][INTRA_EDGE_TAPS] = { { 0, 4, 8, 4, 0 },
{ 0, 5, 6, 5, 0 },
{ 2, 4, 4, 4, 2 } };
const int filt = strength - 1;
uint16_t edge[129];
memcpy(edge, p, sz * sizeof(*p));
for (int i = 1; i < sz; i++) {
int s = 0;
for (int j = 0; j < INTRA_EDGE_TAPS; j++) {
int k = i - 2 + j;
k = (k < 0) ? 0 : k;
k = (k > sz - 1) ? sz - 1 : k;
s += edge[k] * kernel[filt][j];
}
s = (s + 8) >> 4;
p[i] = s;
}
}
static void highbd_filter_intra_edge_corner(uint16_t *p_above,
uint16_t *p_left) {
const int kernel[3] = { 5, 6, 5 };
int s = (p_left[0] * kernel[0]) + (p_above[-1] * kernel[1]) +
(p_above[0] * kernel[2]);
s = (s + 8) >> 4;
p_above[-1] = s;
p_left[-1] = s;
}
void av1_highbd_upsample_intra_edge_c(uint16_t *p, int sz, int bd) {
assert(sz <= MAX_UPSAMPLE_SZ);
uint16_t in[MAX_UPSAMPLE_SZ + 3];
in[0] = p[-1];
in[1] = p[-1];
for (int i = 0; i < sz; i++) {
in[i + 2] = p[i];
}
in[sz + 2] = p[sz - 1];
p[-2] = in[0];
for (int i = 0; i < sz; i++) {
int s = -in[i] + (9 * in[i + 1]) + (9 * in[i + 2]) - in[i + 3];
s = (s + 8) >> 4;
s = clip_pixel_highbd(s, bd);
p[2 * i - 1] = s;
p[2 * i] = in[i + 2];
}
}
static void highbd_build_directional_and_filter_intra_predictors(
const uint8_t *ref8, int ref_stride, uint8_t *dst8, int dst_stride,
PREDICTION_MODE mode, int p_angle, FILTER_INTRA_MODE filter_intra_mode,
TX_SIZE tx_size, int disable_edge_filter, int n_top_px, int n_topright_px,
int n_left_px, int n_bottomleft_px, int intra_edge_filter_type,
int bit_depth) {
int i;
uint16_t *dst = CONVERT_TO_SHORTPTR(dst8);
const uint16_t *const ref = CONVERT_TO_SHORTPTR(ref8);
DECLARE_ALIGNED(16, uint16_t, left_data[NUM_INTRA_NEIGHBOUR_PIXELS]);
DECLARE_ALIGNED(16, uint16_t, above_data[NUM_INTRA_NEIGHBOUR_PIXELS]);
uint16_t *const above_row = above_data + 16;
uint16_t *const left_col = left_data + 16;
const int txwpx = tx_size_wide[tx_size];
const int txhpx = tx_size_high[tx_size];
int need_left = extend_modes[mode] & NEED_LEFT;
int need_above = extend_modes[mode] & NEED_ABOVE;
int need_above_left = extend_modes[mode] & NEED_ABOVELEFT;
const uint16_t *above_ref = ref - ref_stride;
const uint16_t *left_ref = ref - 1;
const int is_dr_mode = av1_is_directional_mode(mode);
const int use_filter_intra = filter_intra_mode != FILTER_INTRA_MODES;
assert(use_filter_intra || is_dr_mode);
const int base = 128 << (bit_depth - 8);
aom_memset16(left_data, base + 1, NUM_INTRA_NEIGHBOUR_PIXELS);
aom_memset16(above_data, base - 1, NUM_INTRA_NEIGHBOUR_PIXELS);
if (is_dr_mode) {
if (p_angle <= 90)
need_above = 1, need_left = 0, need_above_left = 1;
else if (p_angle < 180)
need_above = 1, need_left = 1, need_above_left = 1;
else
need_above = 0, need_left = 1, need_above_left = 1;
}
if (use_filter_intra) need_left = need_above = need_above_left = 1;
assert(n_top_px >= 0);
assert(n_topright_px >= -1);
assert(n_left_px >= 0);
assert(n_bottomleft_px >= -1);
if ((!need_above && n_left_px == 0) || (!need_left && n_top_px == 0)) {
int val;
if (need_left) {
val = (n_top_px > 0) ? above_ref[0] : base + 1;
} else {
val = (n_left_px > 0) ? left_ref[0] : base - 1;
}
for (i = 0; i < txhpx; ++i) {
aom_memset16(dst, val, txwpx);
dst += dst_stride;
}
return;
}
if (need_left) {
const int num_left_pixels_needed =
txhpx + (n_bottomleft_px >= 0 ? txwpx : 0);
i = 0;
if (n_left_px > 0) {
for (; i < n_left_px; i++) left_col[i] = left_ref[i * ref_stride];
if (n_bottomleft_px > 0) {
assert(i == txhpx);
for (; i < txhpx + n_bottomleft_px; i++)
left_col[i] = left_ref[i * ref_stride];
}
if (i < num_left_pixels_needed)
aom_memset16(&left_col[i], left_col[i - 1], num_left_pixels_needed - i);
} else if (n_top_px > 0) {
aom_memset16(left_col, above_ref[0], num_left_pixels_needed);
}
}
if (need_above) {
const int num_top_pixels_needed = txwpx + (n_topright_px >= 0 ? txhpx : 0);
if (n_top_px > 0) {
memcpy(above_row, above_ref, n_top_px * sizeof(above_ref[0]));
i = n_top_px;
if (n_topright_px > 0) {
assert(n_top_px == txwpx);
memcpy(above_row + txwpx, above_ref + txwpx,
n_topright_px * sizeof(above_ref[0]));
i += n_topright_px;
}
if (i < num_top_pixels_needed)
aom_memset16(&above_row[i], above_row[i - 1],
num_top_pixels_needed - i);
} else if (n_left_px > 0) {
aom_memset16(above_row, left_ref[0], num_top_pixels_needed);
}
}
if (need_above_left) {
if (n_top_px > 0 && n_left_px > 0) {
above_row[-1] = above_ref[-1];
} else if (n_top_px > 0) {
above_row[-1] = above_ref[0];
} else if (n_left_px > 0) {
above_row[-1] = left_ref[0];
} else {
above_row[-1] = base;
}
left_col[-1] = above_row[-1];
}
if (use_filter_intra) {
highbd_filter_intra_predictor(dst, dst_stride, tx_size, above_row, left_col,
filter_intra_mode, bit_depth);
return;
}
assert(is_dr_mode);
int upsample_above = 0;
int upsample_left = 0;
if (!disable_edge_filter) {
const int need_right = p_angle < 90;
const int need_bottom = p_angle > 180;
if (p_angle != 90 && p_angle != 180) {
assert(need_above_left);
const int ab_le = 1;
if (need_above && need_left && (txwpx + txhpx >= 24)) {
highbd_filter_intra_edge_corner(above_row, left_col);
}
if (need_above && n_top_px > 0) {
const int strength = intra_edge_filter_strength(
txwpx, txhpx, p_angle - 90, intra_edge_filter_type);
const int n_px = n_top_px + ab_le + (need_right ? txhpx : 0);
av1_highbd_filter_intra_edge(above_row - ab_le, n_px, strength);
}
if (need_left && n_left_px > 0) {
const int strength = intra_edge_filter_strength(
txhpx, txwpx, p_angle - 180, intra_edge_filter_type);
const int n_px = n_left_px + ab_le + (need_bottom ? txwpx : 0);
av1_highbd_filter_intra_edge(left_col - ab_le, n_px, strength);
}
}
upsample_above = av1_use_intra_edge_upsample(txwpx, txhpx, p_angle - 90,
intra_edge_filter_type);
if (need_above && upsample_above) {
const int n_px = txwpx + (need_right ? txhpx : 0);
av1_highbd_upsample_intra_edge(above_row, n_px, bit_depth);
}
upsample_left = av1_use_intra_edge_upsample(txhpx, txwpx, p_angle - 180,
intra_edge_filter_type);
if (need_left && upsample_left) {
const int n_px = txhpx + (need_bottom ? txwpx : 0);
av1_highbd_upsample_intra_edge(left_col, n_px, bit_depth);
}
}
highbd_dr_predictor(dst, dst_stride, tx_size, above_row, left_col,
upsample_above, upsample_left, p_angle, bit_depth);
}
static void highbd_build_non_directional_intra_predictors(
const uint8_t *ref8, int ref_stride, uint8_t *dst8, int dst_stride,
PREDICTION_MODE mode, TX_SIZE tx_size, int n_top_px, int n_left_px,
int bit_depth) {
int i = 0;
uint16_t *dst = CONVERT_TO_SHORTPTR(dst8);
const uint16_t *const ref = CONVERT_TO_SHORTPTR(ref8);
const int txwpx = tx_size_wide[tx_size];
const int txhpx = tx_size_high[tx_size];
int need_left = extend_modes[mode] & NEED_LEFT;
int need_above = extend_modes[mode] & NEED_ABOVE;
int need_above_left = extend_modes[mode] & NEED_ABOVELEFT;
const uint16_t *above_ref = ref - ref_stride;
const uint16_t *left_ref = ref - 1;
const int base = 128 << (bit_depth - 8);
assert(n_top_px >= 0);
assert(n_left_px >= 0);
assert(mode == DC_PRED || mode == SMOOTH_PRED || mode == SMOOTH_V_PRED ||
mode == SMOOTH_H_PRED || mode == PAETH_PRED);
if ((!need_above && n_left_px == 0) || (!need_left && n_top_px == 0)) {
int val = 0;
if (need_left) {
val = (n_top_px > 0) ? above_ref[0] : base + 1;
} else {
val = (n_left_px > 0) ? left_ref[0] : base - 1;
}
for (i = 0; i < txhpx; ++i) {
aom_memset16(dst, val, txwpx);
dst += dst_stride;
}
return;
}
DECLARE_ALIGNED(16, uint16_t, left_data[NUM_INTRA_NEIGHBOUR_PIXELS]);
DECLARE_ALIGNED(16, uint16_t, above_data[NUM_INTRA_NEIGHBOUR_PIXELS]);
uint16_t *const above_row = above_data + 16;
uint16_t *const left_col = left_data + 16;
if (need_left) {
aom_memset16(left_data, base + 1, NUM_INTRA_NEIGHBOUR_PIXELS);
if (n_left_px > 0) {
for (i = 0; i < n_left_px; i++) left_col[i] = left_ref[i * ref_stride];
if (i < txhpx) aom_memset16(&left_col[i], left_col[i - 1], txhpx - i);
} else if (n_top_px > 0) {
aom_memset16(left_col, above_ref[0], txhpx);
}
}
if (need_above) {
aom_memset16(above_data, base - 1, NUM_INTRA_NEIGHBOUR_PIXELS);
if (n_top_px > 0) {
memcpy(above_row, above_ref, n_top_px * sizeof(above_ref[0]));
i = n_top_px;
if (i < txwpx) aom_memset16(&above_row[i], above_row[i - 1], (txwpx - i));
} else if (n_left_px > 0) {
aom_memset16(above_row, left_ref[0], txwpx);
}
}
if (need_above_left) {
if (n_top_px > 0 && n_left_px > 0) {
above_row[-1] = above_ref[-1];
} else if (n_top_px > 0) {
above_row[-1] = above_ref[0];
} else if (n_left_px > 0) {
above_row[-1] = left_ref[0];
} else {
above_row[-1] = base;
}
left_col[-1] = above_row[-1];
}
if (mode == DC_PRED) {
dc_pred_high[n_left_px > 0][n_top_px > 0][tx_size](
dst, dst_stride, above_row, left_col, bit_depth);
} else {
pred_high[mode][tx_size](dst, dst_stride, above_row, left_col, bit_depth);
}
}
#endif
static inline BLOCK_SIZE scale_chroma_bsize(BLOCK_SIZE bsize, int subsampling_x,
int subsampling_y) { … }
void av1_predict_intra_block(const MACROBLOCKD *xd, BLOCK_SIZE sb_size,
int enable_intra_edge_filter, int wpx, int hpx,
TX_SIZE tx_size, PREDICTION_MODE mode,
int angle_delta, int use_palette,
FILTER_INTRA_MODE filter_intra_mode,
const uint8_t *ref, int ref_stride, uint8_t *dst,
int dst_stride, int col_off, int row_off,
int plane) { … }
void av1_predict_intra_block_facade(const AV1_COMMON *cm, MACROBLOCKD *xd,
int plane, int blk_col, int blk_row,
TX_SIZE tx_size) { … }
void av1_init_intra_predictors(void) { … }