diff options
author | Boyuan Xiao <boyuan.xiao@argondesign.com> | 2018-11-09 16:43:41 +0300 |
---|---|---|
committer | Ronald S. Bultje <rsbultje@gmail.com> | 2018-11-15 16:25:11 +0300 |
commit | 6c27b662f9ab99125294b50257f7a660684e990d (patch) | |
tree | fcd1ff895f1a9800d915cfaab4ada498dc8ca2bc | |
parent | 2c3eaffd2a32c63330b5afb1bf90847a0e0b0472 (diff) |
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.
-rw-r--r-- | src/ipred_prepare.h | 11 | ||||
-rw-r--r-- | src/ipred_tmpl.c | 38 | ||||
-rw-r--r-- | src/recon_tmpl.c | 9 |
3 files changed, 37 insertions, 21 deletions
diff --git a/src/ipred_prepare.h b/src/ipred_prepare.h index feece41..cd4fa67 100644 --- a/src/ipred_prepare.h +++ b/src/ipred_prepare.h @@ -83,9 +83,14 @@ enum IntraPredMode enum IntraPredMode mode, int *angle, int tw, int th, pixel *topleft_out); -// is or'ed with the angle argument into intra predictors to signal that edges -// are smooth and should use reduced filter strength -#define ANGLE_SMOOTH_EDGE_FLAG 512 +// These flags are OR'd with the angle argument into intra predictors. +// ANGLE_USE_EDGE_FILTER_FLAG signals that edges should be convolved +// 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) { if (!b->intra[idx]) return 0; const enum IntraPredMode m = b->mode[idx]; diff --git a/src/ipred_tmpl.c b/src/ipred_tmpl.c index 9b5ce88..8f5e1a0 100644 --- a/src/ipred_tmpl.c +++ b/src/ipred_tmpl.c @@ -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 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; assert(angle < 90); const int dx = dav1d_dr_intra_derivative[angle]; pixel top_out[(64 + 64) * 2]; const pixel *top; 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) { upsample_edge(top_out, width + height, &topleft_in[1], -1, width + imin(width, height)); top = top_out; max_base_x = 2 * (width + height) - 2; } else { - const int filter_strength = - get_filter_strength(width + height, 90 - angle, is_sm); - + const int filter_strength = enable_intra_edge_filter ? + get_filter_strength(width + height, 90 - angle, is_sm) : 0; if (filter_strength) { filter_edge(top_out, width + height, 0, 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, const int width, const int height, int angle, 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; assert(angle > 90 && angle < 180); const int dy = dav1d_dr_intra_derivative[angle - 90]; const int dx = dav1d_dr_intra_derivative[180 - angle]; - const int upsample_left = get_upsample(width + height, 180 - angle, is_sm); - const int upsample_above = get_upsample(width + height, angle - 90, is_sm); + const int upsample_left = enable_intra_edge_filter ? + 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 *const topleft = &edge[height * 2]; if (upsample_above) { upsample_edge(topleft, width + 1, topleft_in, 0, width + 1); } else { - const int filter_strength = - get_filter_strength(width + height, angle - 90, is_sm); + const int filter_strength = enable_intra_edge_filter ? + get_filter_strength(width + height, angle - 90, is_sm) : 0; if (filter_strength) { filter_edge(&topleft[1], width, 0, max_width, @@ -467,8 +471,8 @@ static void ipred_z2_c(pixel *dst, const ptrdiff_t stride, if (upsample_left) { upsample_edge(edge, height + 1, &topleft_in[-height], 0, height + 1); } else { - const int filter_strength = - get_filter_strength(width + height, 180 - angle, is_sm); + const int filter_strength = enable_intra_edge_filter ? + get_filter_strength(width + height, 180 - angle, is_sm) : 0; if (filter_strength) { filter_edge(&topleft[-height], height, height - max_height, height, @@ -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 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; assert(angle > 180); const int dy = dav1d_dr_intra_derivative[270 - angle]; pixel left_out[(64 + 64) * 2]; const pixel *left; 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) { upsample_edge(left_out, width + height, &topleft_in[-(width + height)], @@ -529,8 +535,8 @@ static void ipred_z3_c(pixel *dst, const ptrdiff_t stride, left = &left_out[2 * (width + height) - 2]; max_base_y = 2 * (width + height) - 2; } else { - const int filter_strength = - get_filter_strength(width + height, angle - 180, is_sm); + const int filter_strength = enable_intra_edge_filter ? + get_filter_strength(width + height, angle - 180, is_sm) : 0; if (filter_strength) { filter_edge(left_out, width + height, 0, width + height, diff --git a/src/recon_tmpl.c b/src/recon_tmpl.c index 31b687a..de0cd60 100644 --- a/src/recon_tmpl.c +++ b/src/recon_tmpl.c @@ -753,6 +753,8 @@ void bytefn(dav1d_recon_b_intra)(Dav1dTileContext *const t, const enum BlockSize pixel *const edge = edge_buf + 128; 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_x = 0; init_x < w4; init_x += 16) { if (b->pal_sz[0]) { @@ -775,7 +777,9 @@ void bytefn(dav1d_recon_b_intra)(Dav1dTileContext *const t, const enum BlockSize 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 : intra_edge_flags & EDGE_I444_TOP_HAS_RIGHT; 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 t_dim->w, t_dim->h, edge); dsp->ipred.intra_pred[m](dst, f->cur.p.stride[0], edge, t_dim->w * 4, t_dim->h * 4, - angle | sm_fl, + angle | intra_flags, 4 * f->bw - 4 * t->bx, 4 * f->bh - 4 * t->by); @@ -1033,6 +1037,7 @@ void bytefn(dav1d_recon_b_intra)(Dav1dTileContext *const t, const enum BlockSize top_sb_edge, uv_mode, &angle, uv_t_dim->w, uv_t_dim->h, edge); + angle |= intra_edge_filter_flag; dsp->ipred.intra_pred[m](dst, stride, edge, uv_t_dim->w * 4, uv_t_dim->h * 4, |