[x264-devel] commit: Deblock-aware RD (Jason Garrett-Glaser )
git at videolan.org
git at videolan.org
Mon Aug 16 12:07:14 CEST 2010
x264 | branch: master | Jason Garrett-Glaser <darkshikari at gmail.com> | Tue Aug 10 16:55:05 2010 -0700| [26c17a1b633107b12493ccecaa77392a5324c52b] | committer: Jason Garrett-Glaser
Deblock-aware RD
Small quality gain (~0.5%) at lower bitrates, potentially larger with QPRD.
May help more with psy, maybe not.
Enabled at subme >= 9. Small speed cost (a few %).
> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=26c17a1b633107b12493ccecaa77392a5324c52b
---
common/common.h | 1 +
common/deblock.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
common/frame.h | 1 +
encoder/analyse.c | 1 +
encoder/rdo.c | 3 +++
5 files changed, 52 insertions(+), 0 deletions(-)
diff --git a/common/common.h b/common/common.h
index 161f053..72fc1d8 100644
--- a/common/common.h
+++ b/common/common.h
@@ -637,6 +637,7 @@ struct x264_t
/* set to true if we are re-encoding a macroblock. */
int b_reencode_mb;
int ip_offset; /* Used by PIR to offset the quantizer of intra-refresh blocks. */
+ int b_deblock_rdo;
struct
{
diff --git a/common/deblock.c b/common/deblock.c
index 55039b5..0b61248 100644
--- a/common/deblock.c
+++ b/common/deblock.c
@@ -383,9 +383,55 @@ void x264_frame_deblock_row( x264_t *h, int mb_y )
FILTER( , 1, 2, qp, qpc );
if( !transform_8x8 ) FILTER( , 1, 3, qp, qpc );
}
+
+ #undef FILTER
}
}
+/* For deblock-aware RD.
+ * TODO:
+ * deblock macroblock edges
+ * support analysis partitions smaller than 16x16
+ * deblock chroma
+ * handle duplicate refs correctly
+ * handle cavlc+8x8dct correctly
+ */
+void x264_macroblock_deblock( x264_t *h )
+{
+ int qp_thresh = 15 - X264_MIN( h->sh.i_alpha_c0_offset, h->sh.i_beta_offset ) - X264_MAX( 0, h->param.analyse.i_chroma_qp_offset );
+ int qp = h->mb.i_qp;
+ if( qp <= qp_thresh || h->mb.i_type == P_SKIP )
+ return;
+
+ uint8_t (*bs)[4][4] = h->deblock_strength[h->mb.i_mb_y&h->sh.b_mbaff][h->mb.i_mb_x];
+ if( IS_INTRA( h->mb.i_type ) )
+ memset( bs, 3, 2*4*4*sizeof(uint8_t) );
+ else
+ h->loopf.deblock_strength( h->mb.cache.non_zero_count, h->mb.cache.ref, h->mb.cache.mv,
+ bs, 4 >> h->sh.b_mbaff, h->sh.i_type == SLICE_TYPE_B );
+
+ int transform_8x8 = h->mb.b_transform_8x8;
+ pixel *fdec = h->mb.pic.p_fdec[0];
+
+ #define FILTER( dir, edge )\
+ do\
+ {\
+ deblock_edge( h, fdec + 4*edge*(dir?FDEC_STRIDE:1),\
+ FDEC_STRIDE, bs[dir][edge], qp, 0,\
+ h->loopf.deblock_luma[dir] );\
+ } while(0)
+
+ if( !transform_8x8 ) FILTER( 0, 1 );
+ FILTER( 0, 2 );
+ if( !transform_8x8 ) FILTER( 0, 3 );
+
+ if( !transform_8x8 ) FILTER( 1, 1 );
+ FILTER( 1, 2 );
+ if( !transform_8x8 ) FILTER( 1, 3 );
+
+ #undef FILTER
+}
+
#if HAVE_MMX
void x264_deblock_v_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
void x264_deblock_h_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 );
diff --git a/common/frame.h b/common/frame.h
index 1e00fc5..fcc28d7 100644
--- a/common/frame.h
+++ b/common/frame.h
@@ -184,6 +184,7 @@ void x264_frame_expand_border_lowres( x264_frame_t *frame );
void x264_frame_expand_border_mod16( x264_t *h, x264_frame_t *frame );
void x264_frame_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 );
diff --git a/encoder/analyse.c b/encoder/analyse.c
index f93a9e0..fdc2498 100644
--- a/encoder/analyse.c
+++ b/encoder/analyse.c
@@ -357,6 +357,7 @@ static void x264_mb_analyse_init( x264_t *h, x264_mb_analysis_t *a, int i_qp )
/* mbrd == 2 -> RD refinement */
/* mbrd == 3 -> QPRD */
a->i_mbrd = (subme>=6) + (subme>=8) + (h->param.analyse.i_subpel_refine>=10);
+ h->mb.b_deblock_rdo = h->param.analyse.i_subpel_refine >= 9;
x264_mb_analyse_init_qp( h, a, i_qp );
diff --git a/encoder/rdo.c b/encoder/rdo.c
index 4fae811..d4e6b0c 100644
--- a/encoder/rdo.c
+++ b/encoder/rdo.c
@@ -157,6 +157,9 @@ static int x264_rd_cost_mb( x264_t *h, int i_lambda2 )
x264_macroblock_encode( h );
+ if( h->mb.b_deblock_rdo )
+ x264_macroblock_deblock( h );
+
i_ssd = ssd_mb( h );
if( IS_SKIP( h->mb.i_type ) )
More information about the x264-devel
mailing list