[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