Permalink
Browse files

VP8 normal deblock filter.

  • Loading branch information...
1 parent b29a2ff commit 229355bf6ea14649ea9df5787db86adc972f99ef @saintdev committed Apr 26, 2012
Showing with 362 additions and 8 deletions.
  1. +1 −1 Makefile
  2. +251 −1 common/deblock.c
  3. +4 −1 common/frame.h
  4. +97 −0 common/vp8deblock.c
  5. +5 −2 encoder/encoder.c
  6. +4 −3 encoder/vp8set.c
View
@@ -16,7 +16,7 @@ SRCS = common/mc.c common/predict.c common/pixel.c common/macroblock.c \
common/common.c common/osdep.c common/rectangle.c \
common/set.c common/quant.c common/deblock.c common/vlc.c \
common/mvpred.c common/bitstream.c \
- common/vp8set.c common/vp8rac.c \
+ common/vp8deblock.c common/vp8set.c common/vp8rac.c \
encoder/analyse.c encoder/me.c encoder/ratecontrol.c \
encoder/set.c encoder/macroblock.c encoder/cabac.c \
encoder/cavlc.c encoder/encoder.c encoder/lookahead.c \
View
@@ -303,6 +303,243 @@ static void deblock_strength_c( uint8_t nnz[X264_SCAN8_SIZE], int8_t ref[2][X264
}
}
+/* VP8 */
+static const uint8_t vp8_intra_hev_table[64] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2,
+};
+
+static const uint8_t vp8_interior_limit_table[64][8] =
+{
+ { 1, 1, 1, 1, 1, 1, 1, 1, }, { 1, 1, 1, 1, 1, 1, 1, 1, }, { 2, 1, 1, 1, 1, 1, 1, 1, },
+ { 3, 1, 1, 1, 1, 1, 1, 1, }, { 4, 2, 2, 2, 2, 1, 1, 1, }, { 5, 2, 2, 2, 2, 1, 1, 1, },
+ { 6, 3, 3, 3, 3, 1, 1, 1, }, { 7, 3, 3, 3, 3, 1, 1, 1, }, { 8, 4, 4, 4, 4, 2, 2, 2, },
+ { 9, 4, 4, 4, 4, 2, 2, 2, }, {10, 5, 5, 5, 5, 2, 2, 2, }, {11, 5, 5, 5, 5, 2, 2, 2, },
+ {12, 6, 6, 6, 5, 3, 3, 2, }, {13, 6, 6, 6, 5, 3, 3, 2, }, {14, 7, 7, 6, 5, 3, 3, 2, },
+ {15, 7, 7, 6, 5, 3, 3, 2, }, {16, 8, 7, 6, 5, 4, 3, 2, }, {17, 8, 7, 6, 5, 4, 3, 2, },
+ {18, 8, 7, 6, 5, 4, 3, 2, }, {19, 8, 7, 6, 5, 4, 3, 2, }, {20, 8, 7, 6, 5, 4, 3, 2, },
+ {21, 8, 7, 6, 5, 4, 3, 2, }, {22, 8, 7, 6, 5, 4, 3, 2, }, {23, 8, 7, 6, 5, 4, 3, 2, },
+ {24, 8, 7, 6, 5, 4, 3, 2, }, {25, 8, 7, 6, 5, 4, 3, 2, }, {26, 8, 7, 6, 5, 4, 3, 2, },
+ {27, 8, 7, 6, 5, 4, 3, 2, }, {28, 8, 7, 6, 5, 4, 3, 2, }, {29, 8, 7, 6, 5, 4, 3, 2, },
+ {30, 8, 7, 6, 5, 4, 3, 2, }, {31, 8, 7, 6, 5, 4, 3, 2, }, {32, 8, 7, 6, 5, 4, 3, 2, },
+ {33, 8, 7, 6, 5, 4, 3, 2, }, {34, 8, 7, 6, 5, 4, 3, 2, }, {35, 8, 7, 6, 5, 4, 3, 2, },
+ {36, 8, 7, 6, 5, 4, 3, 2, }, {37, 8, 7, 6, 5, 4, 3, 2, }, {38, 8, 7, 6, 5, 4, 3, 2, },
+ {39, 8, 7, 6, 5, 4, 3, 2, }, {40, 8, 7, 6, 5, 4, 3, 2, }, {41, 8, 7, 6, 5, 4, 3, 2, },
+ {42, 8, 7, 6, 5, 4, 3, 2, }, {43, 8, 7, 6, 5, 4, 3, 2, }, {44, 8, 7, 6, 5, 4, 3, 2, },
+ {45, 8, 7, 6, 5, 4, 3, 2, }, {46, 8, 7, 6, 5, 4, 3, 2, }, {47, 8, 7, 6, 5, 4, 3, 2, },
+ {48, 8, 7, 6, 5, 4, 3, 2, }, {49, 8, 7, 6, 5, 4, 3, 2, }, {50, 8, 7, 6, 5, 4, 3, 2, },
+ {51, 8, 7, 6, 5, 4, 3, 2, }, {52, 8, 7, 6, 5, 4, 3, 2, }, {53, 8, 7, 6, 5, 4, 3, 2, },
+ {54, 8, 7, 6, 5, 4, 3, 2, }, {55, 8, 7, 6, 5, 4, 3, 2, }, {56, 8, 7, 6, 5, 4, 3, 2, },
+ {57, 8, 7, 6, 5, 4, 3, 2, }, {58, 8, 7, 6, 5, 4, 3, 2, }, {59, 8, 7, 6, 5, 4, 3, 2, },
+ {60, 8, 7, 6, 5, 4, 3, 2, }, {61, 8, 7, 6, 5, 4, 3, 2, }, {62, 8, 7, 6, 5, 4, 3, 2, },
+ {63, 8, 7, 6, 5, 4, 3, 2, },
+};
+
+// high edge variance
+static ALWAYS_INLINE int vp8_edge_variance( pixel *pix, intptr_t xstride, int level )
+{
+ int p1 = pix[-2*xstride];
+ int p0 = pix[-1*xstride];
+ int q0 = pix[ 0*xstride];
+ int q1 = pix[ 1*xstride];
+
+ return abs( p1 - p0 ) > vp8_intra_hev_table[level]
+ || abs( q1 - q0 ) > vp8_intra_hev_table[level];
+}
+
+static ALWAYS_INLINE int vp8_simple_limit( pixel *pix, intptr_t xstride, int thresh )
+{
+ int p1 = pix[-2*xstride];
+ int p0 = pix[-1*xstride];
+ int q0 = pix[ 0*xstride];
+ int q1 = pix[ 1*xstride];
+
+ return 2 * abs( p0 - q0 ) + (abs( p1 - q1 ) >> 1) <= thresh;
+}
+
+/**
+ * E - limit at the macroblock edge
+ * I - limit for interior difference
+ */
+static ALWAYS_INLINE int vp8_normal_limit( pixel *pix, intptr_t xstride, int E, int I)
+{
+ int p3 = pix[-4*xstride];
+ int p2 = pix[-3*xstride];
+ int p1 = pix[-2*xstride];
+ int p0 = pix[-1*xstride];
+ int q0 = pix[ 0*xstride];
+ int q1 = pix[ 1*xstride];
+ int q2 = pix[ 2*xstride];
+ int q3 = pix[ 3*xstride];
+
+ return vp8_simple_limit( pix, xstride, E )
+ && abs( p3 - p2 ) <= I && abs( p2 - p1 ) <= I && abs( p1 - p0 ) <= I
+ && abs( q3 - q2 ) <= I && abs( q2 - q1 ) <= I && abs( q1 - q0 ) <= I;
+}
+
+static ALWAYS_INLINE void vp8_deblock_common( pixel *pix, intptr_t xstride, int level )
+{
+ int p1 = pix[-2*xstride];
+ int p0 = pix[-1*xstride];
+ int q0 = pix[ 0*xstride];
+ int q1 = pix[ 1*xstride];
+ int hev = vp8_edge_variance( pix, xstride, level );
+
+ int a = 3 * (q0 - p0);
+
+ if( hev )
+ a += x264_clip3( p1 - q1, -128, 127 );
+
+ a = x264_clip3( a, -128, 127 );
+
+ // We deviate from the spec here with c(a+3) >> 3
+ // since that's what libvpx does.
+ int delta1 = X264_MIN( a+4, 127 ) >> 3;
+ int delta2 = X264_MIN( a+3, 127 ) >> 3;
+
+ // Despite what the spec says, we do need to clamp here to
+ // be bitexact with libvpx.
+ pix[-1*xstride] = x264_clip_pixel( p0 + delta2 );
+ pix[ 0*xstride] = x264_clip_pixel( q0 - delta1 );
+
+ // only used for _inner on blocks without high edge variance
+ if( !hev )
+ {
+ a = (delta1 + 1) >> 1;
+ pix[-2*xstride] = x264_clip_pixel( p1 + a );
+ pix[ 1*xstride] = x264_clip_pixel( q1 - a );
+ }
+}
+
+static inline void vp8_deblock_luma_c( pixel *pix, intptr_t xstride, intptr_t ystride, int level, int sharpness )
+{
+ int interior = vp8_interior_limit_table[level][sharpness];
+ int edge = level * 2 + interior;
+
+ for( int d = 0; d < 16; d++, pix += ystride )
+ if( vp8_normal_limit( pix, xstride, edge, interior ) )
+ vp8_deblock_common( pix, xstride, level );
+}
+static void vp8_deblock_v_luma_c( pixel *pix, intptr_t stride, int level, int sharpness, UNUSED int8_t *tc0 )
+{
+ vp8_deblock_luma_c( pix, stride, 1, level, sharpness );
+}
+static void vp8_deblock_h_luma_c( pixel *pix, intptr_t stride, int level, int sharpness, UNUSED int8_t *tc0 )
+{
+ vp8_deblock_luma_c( pix, 1, stride, level, sharpness );
+}
+
+static ALWAYS_INLINE void vp8_deblock_chroma_c( pixel *pix, int width, int height, intptr_t xstride, intptr_t ystride, int level, int sharpness )
+{
+ int interior = vp8_interior_limit_table[level][sharpness];
+ int edge = level * 2 + interior;
+
+ for( int d = 0; d < height; d++, pix += ystride-2 )
+ for( int e = 0; e < width; e++, pix++ )
+ if( vp8_normal_limit( pix, xstride, edge, interior ) )
+ vp8_deblock_common( pix, xstride, level );
+}
+static void vp8_deblock_v_chroma_c( pixel *pix, intptr_t stride, int level, int sharpness, UNUSED int8_t *tc0 )
+{
+ vp8_deblock_chroma_c( pix, 1, 16, stride, 2, level, sharpness );
+}
+static void vp8_deblock_h_chroma_c( pixel *pix, intptr_t stride, int level, int sharpness, UNUSED int8_t *tc0 )
+{
+ vp8_deblock_chroma_c( pix, 2, 8, 2, stride, level, sharpness );
+}
+
+static ALWAYS_INLINE void vp8_deblock_edge_intra( pixel *pix, intptr_t xstride )
+{
+ int p2 = pix[-3*xstride];
+ int p1 = pix[-2*xstride];
+ int p0 = pix[-1*xstride];
+ int q0 = pix[ 0*xstride];
+ int q1 = pix[ 1*xstride];
+ int q2 = pix[ 2*xstride];
+
+ int w = x264_clip3( p1 - q1, -128, 127 );
+ w = x264_clip3( w + 3 * (q0 - p0), -128, 127 );
+
+ int a0 = (27 * w + 63) >> 7;
+ int a1 = (18 * w + 63) >> 7;
+ int a2 = ( 9 * w + 63) >> 7;
+
+ pix[-3*xstride] = x264_clip_pixel( p2 + a2 );
+ pix[-2*xstride] = x264_clip_pixel( p1 + a1 );
+ pix[-1*xstride] = x264_clip_pixel( p0 + a0 );
+ pix[ 0*xstride] = x264_clip_pixel( q0 - a0 );
+ pix[ 1*xstride] = x264_clip_pixel( q1 - a1 );
+ pix[ 2*xstride] = x264_clip_pixel( q2 - a2 );
+}
+
+static inline void vp8_deblock_luma_intra_c( pixel *pix, intptr_t xstride, intptr_t ystride, int level, int sharpness )
+{
+ int interior = vp8_interior_limit_table[level][sharpness];
+ int edge = (level + 2) * 2 + interior;
+
+ for( int d = 0; d < 16; d++, pix += ystride )
+ if( vp8_normal_limit( pix, xstride, edge, interior ) )
+ {
+ if( vp8_edge_variance( pix, xstride, level ) )
+ vp8_deblock_common( pix, xstride, level );
+ else
+ vp8_deblock_edge_intra( pix, xstride );
+ }
+}
+static void vp8_deblock_v_luma_intra_c( pixel *pix, intptr_t stride, int level, int sharpness )
+{
+ deblock_luma_intra_c( pix, stride, 1, level, sharpness );
+}
+static void vp8_deblock_h_luma_intra_c( pixel *pix, intptr_t stride, int level, int sharpness )
+{
+ deblock_luma_intra_c( pix, 1, stride, level, sharpness );
+}
+
+static ALWAYS_INLINE void vp8_deblock_chroma_intra_c( pixel *pix, int width, int height, intptr_t xstride, intptr_t ystride, int level, int sharpness )
+{
+ int interior = vp8_interior_limit_table[level][sharpness];
+ int edge = (level + 2) * 2 + interior;
+
+ for( int d = 0; d < height; d++, pix += ystride-2 )
+ for( int e = 0; e < width; e++, pix++ )
+ if( vp8_normal_limit( pix, xstride, edge, interior ) )
+ {
+ if( vp8_edge_variance( pix, xstride, level ) )
+ vp8_deblock_common( pix, xstride, level );
+ else
+ vp8_deblock_edge_intra( pix, xstride );
+ }
+}
+static void vp8_deblock_v_chroma_intra_c( pixel *pix, intptr_t stride, int level, int sharpness )
+{
+ deblock_chroma_intra_c( pix, 1, 16, stride, 2, level, sharpness );
+}
+static void vp8_deblock_h_chroma_intra_c( pixel *pix, intptr_t stride, int level, int sharpness )
+{
+ deblock_chroma_intra_c( pix, 2, 8, 2, stride, level, sharpness );
+}
+
+static void vp8_deblock_strength_c( uint8_t nnz[X264_SCAN8_SIZE], UNUSED int8_t ref[2][X264_SCAN8_LUMA_SIZE],
+ UNUSED int16_t mv[2][X264_SCAN8_LUMA_SIZE][2], uint8_t bs[2][8][4],
+ UNUSED int mvy_limit, UNUSED int bframe )
+{
+ int non_zero = 0;
+ for( int i = 0; i < 16; i++ )
+ non_zero |= nnz[x264_scan8[i]];
+
+ for( int dir = 0; dir < 2; dir++ )
+ for( int edge = 0; edge < 4; edge++ )
+ for( int i = 0; i < 4; i++ )
+ bs[dir][edge][i] = non_zero;
+}
+
+
static ALWAYS_INLINE void deblock_edge( x264_t *h, pixel *pix, intptr_t i_stride, uint8_t bS[4], int i_qp,
int a, int b, int b_chroma, x264_deblock_inter_t pf_inter )
{
@@ -733,7 +970,7 @@ void x264_deblock_v_chroma_neon( uint8_t *pix, intptr_t stride, int alpha, int b
void x264_deblock_h_chroma_neon( uint8_t *pix, intptr_t stride, int alpha, int beta, int8_t *tc0 );
#endif
-void x264_deblock_init( int cpu, x264_deblock_function_t *pf, int b_mbaff )
+void x264_deblock_init( x264_t *h, int cpu, x264_deblock_function_t *pf, int b_mbaff )
{
pf->deblock_luma[1] = deblock_v_luma_c;
pf->deblock_luma[0] = deblock_h_luma_c;
@@ -842,4 +1079,17 @@ void x264_deblock_init( int cpu, x264_deblock_function_t *pf, int b_mbaff )
/* These functions are equivalent, so don't duplicate them. */
pf->deblock_chroma_422_mbaff = pf->deblock_h_chroma_420;
pf->deblock_chroma_422_intra_mbaff = pf->deblock_h_chroma_420_intra;
+
+ if( h->param.b_vp8 )
+ {
+ pf->deblock_luma[1] = vp8_deblock_v_luma_c;
+ pf->deblock_luma[0] = vp8_deblock_h_luma_c;
+ pf->deblock_chroma[1] = vp8_deblock_v_chroma_c;
+ pf->deblock_h_chroma_420 = vp8_deblock_h_chroma_c;
+ pf->deblock_luma_intra[1] = vp8_deblock_v_luma_intra_c;
+ pf->deblock_luma_intra[0] = vp8_deblock_h_luma_intra_c;
+ pf->deblock_chroma_intra[1] = vp8_deblock_v_chroma_intra_c;
+ pf->deblock_h_chroma_420_intra = vp8_deblock_h_chroma_intra_c;
+ pf->deblock_strength = vp8_deblock_strength_c;
+ }
}
View
@@ -208,6 +208,8 @@ typedef struct
int bframe );
} x264_deblock_function_t;
+extern const uint8_t x264_vp8_deblock_level_table[VP8_QP_MAX];
+
void x264_frame_delete( x264_frame_t *frame );
int x264_frame_copy_picture( x264_t *h, x264_frame_t *dst, x264_picture_t *src );
@@ -220,12 +222,13 @@ void x264_frame_expand_border_mod16( x264_t *h, x264_frame_t *frame );
void x264_expand_border_mbpair( x264_t *h, int mb_x, int mb_y );
void x264_frame_deblock_row( x264_t *h, int mb_y );
+void x264_vp8_deblock_row( x264_t *h, int mb_y );
void x264_macroblock_deblock( x264_t *h );
void x264_frame_filter( x264_t *h, x264_frame_t *frame, int mb_y, int b_end );
void x264_frame_init_lowres( x264_t *h, x264_frame_t *frame );
-void x264_deblock_init( int cpu, x264_deblock_function_t *pf, int b_mbaff );
+void x264_deblock_init( x264_t *h, int cpu, x264_deblock_function_t *pf, int b_mbaff );
void x264_frame_cond_broadcast( x264_frame_t *frame, int i_lines_completed );
void x264_frame_cond_wait( x264_frame_t *frame, int i_lines_completed );
Oops, something went wrong.

0 comments on commit 229355b

Please sign in to comment.