Commit 6c27b662 authored by boyuanxiao-argondesign's avatar boyuanxiao-argondesign Committed by Ronald S. Bultje

Only do intra edge filtering/upsampling if enable_intra_edge set

See section 7.11.2.4 in AV1 spec. Because frame contexts are not
passed into the ipred_z*_c functions the flag is set as a bit inside
the 'angle' function argument.
parent 2c3eaffd
...@@ -83,9 +83,14 @@ enum IntraPredMode ...@@ -83,9 +83,14 @@ enum IntraPredMode
enum IntraPredMode mode, int *angle, enum IntraPredMode mode, int *angle,
int tw, int th, pixel *topleft_out); int tw, int th, pixel *topleft_out);
// is or'ed with the angle argument into intra predictors to signal that edges // These flags are OR'd with the angle argument into intra predictors.
// are smooth and should use reduced filter strength // ANGLE_USE_EDGE_FILTER_FLAG signals that edges should be convolved
#define ANGLE_SMOOTH_EDGE_FLAG 512 // with a filter before using them to predict values in a block.
// ANGLE_SMOOTH_EDGE_FLAG means that edges are smooth and should use
// reduced filter strength.
#define ANGLE_USE_EDGE_FILTER_FLAG 1024
#define ANGLE_SMOOTH_EDGE_FLAG 512
static inline int sm_flag(const BlockContext *const b, const int idx) { static inline int sm_flag(const BlockContext *const b, const int idx) {
if (!b->intra[idx]) return 0; if (!b->intra[idx]) return 0;
const enum IntraPredMode m = b->mode[idx]; const enum IntraPredMode m = b->mode[idx];
......
...@@ -387,23 +387,24 @@ static void ipred_z1_c(pixel *dst, const ptrdiff_t stride, ...@@ -387,23 +387,24 @@ static void ipred_z1_c(pixel *dst, const ptrdiff_t stride,
const int width, const int height, int angle, const int width, const int height, int angle,
const int max_width, const int max_height) const int max_width, const int max_height)
{ {
const int is_sm = angle >> 9; const int is_sm = (angle >> 9) & 0x1;
const int enable_intra_edge_filter = angle >> 10;
angle &= 511; angle &= 511;
assert(angle < 90); assert(angle < 90);
const int dx = dav1d_dr_intra_derivative[angle]; const int dx = dav1d_dr_intra_derivative[angle];
pixel top_out[(64 + 64) * 2]; pixel top_out[(64 + 64) * 2];
const pixel *top; const pixel *top;
int max_base_x; int max_base_x;
const int upsample_above = get_upsample(width + height, 90 - angle, is_sm); const int upsample_above = enable_intra_edge_filter ?
get_upsample(width + height, 90 - angle, is_sm) : 0;
if (upsample_above) { if (upsample_above) {
upsample_edge(top_out, width + height, upsample_edge(top_out, width + height,
&topleft_in[1], -1, width + imin(width, height)); &topleft_in[1], -1, width + imin(width, height));
top = top_out; top = top_out;
max_base_x = 2 * (width + height) - 2; max_base_x = 2 * (width + height) - 2;
} else { } else {
const int filter_strength = const int filter_strength = enable_intra_edge_filter ?
get_filter_strength(width + height, 90 - angle, is_sm); get_filter_strength(width + height, 90 - angle, is_sm) : 0;
if (filter_strength) { if (filter_strength) {
filter_edge(top_out, width + height, 0, width + height, filter_edge(top_out, width + height, 0, width + height,
&topleft_in[1], -1, width + imin(width, height), &topleft_in[1], -1, width + imin(width, height),
...@@ -440,21 +441,24 @@ static void ipred_z2_c(pixel *dst, const ptrdiff_t stride, ...@@ -440,21 +441,24 @@ static void ipred_z2_c(pixel *dst, const ptrdiff_t stride,
const int width, const int height, int angle, const int width, const int height, int angle,
const int max_width, const int max_height) const int max_width, const int max_height)
{ {
const int is_sm = angle >> 9; const int is_sm = (angle >> 9) & 0x1;
const int enable_intra_edge_filter = angle >> 10;
angle &= 511; angle &= 511;
assert(angle > 90 && angle < 180); assert(angle > 90 && angle < 180);
const int dy = dav1d_dr_intra_derivative[angle - 90]; const int dy = dav1d_dr_intra_derivative[angle - 90];
const int dx = dav1d_dr_intra_derivative[180 - angle]; const int dx = dav1d_dr_intra_derivative[180 - angle];
const int upsample_left = get_upsample(width + height, 180 - angle, is_sm); const int upsample_left = enable_intra_edge_filter ?
const int upsample_above = get_upsample(width + height, angle - 90, is_sm); get_upsample(width + height, 180 - angle, is_sm) : 0;
const int upsample_above = enable_intra_edge_filter ?
get_upsample(width + height, angle - 90, is_sm) : 0;
pixel edge[64 * 2 + 64 * 2 + 1]; pixel edge[64 * 2 + 64 * 2 + 1];
pixel *const topleft = &edge[height * 2]; pixel *const topleft = &edge[height * 2];
if (upsample_above) { if (upsample_above) {
upsample_edge(topleft, width + 1, topleft_in, 0, width + 1); upsample_edge(topleft, width + 1, topleft_in, 0, width + 1);
} else { } else {
const int filter_strength = const int filter_strength = enable_intra_edge_filter ?
get_filter_strength(width + height, angle - 90, is_sm); get_filter_strength(width + height, angle - 90, is_sm) : 0;
if (filter_strength) { if (filter_strength) {
filter_edge(&topleft[1], width, 0, max_width, filter_edge(&topleft[1], width, 0, max_width,
...@@ -467,8 +471,8 @@ static void ipred_z2_c(pixel *dst, const ptrdiff_t stride, ...@@ -467,8 +471,8 @@ static void ipred_z2_c(pixel *dst, const ptrdiff_t stride,
if (upsample_left) { if (upsample_left) {
upsample_edge(edge, height + 1, &topleft_in[-height], 0, height + 1); upsample_edge(edge, height + 1, &topleft_in[-height], 0, height + 1);
} else { } else {
const int filter_strength = const int filter_strength = enable_intra_edge_filter ?
get_filter_strength(width + height, 180 - angle, is_sm); get_filter_strength(width + height, 180 - angle, is_sm) : 0;
if (filter_strength) { if (filter_strength) {
filter_edge(&topleft[-height], height, height - max_height, height, filter_edge(&topleft[-height], height, height - max_height, height,
...@@ -514,14 +518,16 @@ static void ipred_z3_c(pixel *dst, const ptrdiff_t stride, ...@@ -514,14 +518,16 @@ static void ipred_z3_c(pixel *dst, const ptrdiff_t stride,
const int width, const int height, int angle, const int width, const int height, int angle,
const int max_width, const int max_height) const int max_width, const int max_height)
{ {
const int is_sm = angle >> 9; const int is_sm = (angle >> 9) & 0x1;
const int enable_intra_edge_filter = angle >> 10;
angle &= 511; angle &= 511;
assert(angle > 180); assert(angle > 180);
const int dy = dav1d_dr_intra_derivative[270 - angle]; const int dy = dav1d_dr_intra_derivative[270 - angle];
pixel left_out[(64 + 64) * 2]; pixel left_out[(64 + 64) * 2];
const pixel *left; const pixel *left;
int max_base_y; int max_base_y;
const int upsample_left = get_upsample(width + height, angle - 180, is_sm); const int upsample_left = enable_intra_edge_filter ?
get_upsample(width + height, angle - 180, is_sm) : 0;
if (upsample_left) { if (upsample_left) {
upsample_edge(left_out, width + height, upsample_edge(left_out, width + height,
&topleft_in[-(width + height)], &topleft_in[-(width + height)],
...@@ -529,8 +535,8 @@ static void ipred_z3_c(pixel *dst, const ptrdiff_t stride, ...@@ -529,8 +535,8 @@ static void ipred_z3_c(pixel *dst, const ptrdiff_t stride,
left = &left_out[2 * (width + height) - 2]; left = &left_out[2 * (width + height) - 2];
max_base_y = 2 * (width + height) - 2; max_base_y = 2 * (width + height) - 2;
} else { } else {
const int filter_strength = const int filter_strength = enable_intra_edge_filter ?
get_filter_strength(width + height, angle - 180, is_sm); get_filter_strength(width + height, angle - 180, is_sm) : 0;
if (filter_strength) { if (filter_strength) {
filter_edge(left_out, width + height, 0, width + height, filter_edge(left_out, width + height, 0, width + height,
......
...@@ -753,6 +753,8 @@ void bytefn(dav1d_recon_b_intra)(Dav1dTileContext *const t, const enum BlockSize ...@@ -753,6 +753,8 @@ void bytefn(dav1d_recon_b_intra)(Dav1dTileContext *const t, const enum BlockSize
pixel *const edge = edge_buf + 128; pixel *const edge = edge_buf + 128;
const int cbw4 = (bw4 + ss_hor) >> ss_hor, cbh4 = (bh4 + ss_ver) >> ss_ver; const int cbw4 = (bw4 + ss_hor) >> ss_hor, cbh4 = (bh4 + ss_ver) >> ss_ver;
const int intra_edge_filter_flag = f->seq_hdr.intra_edge_filter << 10;
for (int init_y = 0; init_y < h4; init_y += 16) { for (int init_y = 0; init_y < h4; init_y += 16) {
for (int init_x = 0; init_x < w4; init_x += 16) { for (int init_x = 0; init_x < w4; init_x += 16) {
if (b->pal_sz[0]) { if (b->pal_sz[0]) {
...@@ -775,7 +777,9 @@ void bytefn(dav1d_recon_b_intra)(Dav1dTileContext *const t, const enum BlockSize ...@@ -775,7 +777,9 @@ void bytefn(dav1d_recon_b_intra)(Dav1dTileContext *const t, const enum BlockSize
bw4 * 4, bh4 * 4, "y-pal-pred"); bw4 * 4, bh4 * 4, "y-pal-pred");
} }
const int sm_fl = sm_flag(t->a, bx4) | sm_flag(&t->l, by4); const int intra_flags = (sm_flag(t->a, bx4) |
sm_flag(&t->l, by4) |
intra_edge_filter_flag);
const int sb_has_tr = init_x + 16 < w4 ? 1 : init_y ? 0 : const int sb_has_tr = init_x + 16 < w4 ? 1 : init_y ? 0 :
intra_edge_flags & EDGE_I444_TOP_HAS_RIGHT; intra_edge_flags & EDGE_I444_TOP_HAS_RIGHT;
const int sb_has_bl = init_x ? 0 : init_y + 16 < h4 ? 1 : const int sb_has_bl = init_x ? 0 : init_y + 16 < h4 ? 1 :
...@@ -819,7 +823,7 @@ void bytefn(dav1d_recon_b_intra)(Dav1dTileContext *const t, const enum BlockSize ...@@ -819,7 +823,7 @@ void bytefn(dav1d_recon_b_intra)(Dav1dTileContext *const t, const enum BlockSize
t_dim->w, t_dim->h, edge); t_dim->w, t_dim->h, edge);
dsp->ipred.intra_pred[m](dst, f->cur.p.stride[0], edge, dsp->ipred.intra_pred[m](dst, f->cur.p.stride[0], edge,
t_dim->w * 4, t_dim->h * 4, t_dim->w * 4, t_dim->h * 4,
angle | sm_fl, angle | intra_flags,
4 * f->bw - 4 * t->bx, 4 * f->bw - 4 * t->bx,
4 * f->bh - 4 * t->by); 4 * f->bh - 4 * t->by);
...@@ -1033,6 +1037,7 @@ void bytefn(dav1d_recon_b_intra)(Dav1dTileContext *const t, const enum BlockSize ...@@ -1033,6 +1037,7 @@ void bytefn(dav1d_recon_b_intra)(Dav1dTileContext *const t, const enum BlockSize
top_sb_edge, uv_mode, top_sb_edge, uv_mode,
&angle, uv_t_dim->w, &angle, uv_t_dim->w,
uv_t_dim->h, edge); uv_t_dim->h, edge);
angle |= intra_edge_filter_flag;
dsp->ipred.intra_pred[m](dst, stride, edge, dsp->ipred.intra_pred[m](dst, stride, edge,
uv_t_dim->w * 4, uv_t_dim->w * 4,
uv_t_dim->h * 4, uv_t_dim->h * 4,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment