[x264-devel] commit: Improve QPRD (Jason Garrett-Glaser )

git version control git at videolan.org
Thu Aug 20 22:10:03 CEST 2009


x264 | branch: master | Jason Garrett-Glaser <darkshikari at gmail.com> | Wed Aug 19 01:49:47 2009 -0700| [441c36cbc814ac13cc565ce5e6566bcbf5f6d6e2] | committer: Jason Garrett-Glaser 

Improve QPRD
Always check the last macroblock's QP, even if the normal search doesn't reach it.
Raise the failure threshold when moving towards the last macroblock's QP.
0.2-1% improved compression.

> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=441c36cbc814ac13cc565ce5e6566bcbf5f6d6e2
---

 encoder/analyse.c |   30 +++++++++++++++++++++++-------
 1 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/encoder/analyse.c b/encoder/analyse.c
index 44a8a50..d95ecdc 100644
--- a/encoder/analyse.c
+++ b/encoder/analyse.c
@@ -2203,17 +2203,30 @@ static inline void x264_mb_analyse_qp_rd( x264_t *h, x264_mb_analysis_t *a )
 {
     int bcost, cost, direction, failures, prevcost, origcost;
     int orig_qp = h->mb.i_qp, bqp = h->mb.i_qp;
+    int last_qp_tried = 0;
     origcost = bcost = x264_rd_cost_mb( h, a->i_lambda2 );
 
     /* If CBP is already zero, don't raise the quantizer any higher. */
     for( direction = h->mb.cbp[h->mb.i_mb_xy] ? 1 : -1; direction >= -1; direction-=2 )
     {
+        /* Without psy-RD, require monotonicity when moving quant away from previous
+         * macroblock's quant; allow 1 failure when moving quant towards previous quant.
+         * With psy-RD, allow 1 failure when moving quant away from previous quant,
+         * allow 2 failures when moving quant towards previous quant.
+         * Psy-RD generally seems to result in more chaotic RD score-vs-quantizer curves. */
+        int threshold = (!!h->mb.i_psy_rd);
+        /* Raise the threshold for failures if we're moving towards the last QP. */
+        if( ( h->mb.i_last_qp < orig_qp && direction == -1 ) ||
+            ( h->mb.i_last_qp > orig_qp && direction ==  1 ) )
+            threshold++;
         h->mb.i_qp = orig_qp;
         failures = 0;
         prevcost = origcost;
         h->mb.i_qp += direction;
         while( h->mb.i_qp >= h->param.rc.i_qp_min && h->mb.i_qp <= h->param.rc.i_qp_max )
         {
+            if( h->mb.i_last_qp == h->mb.i_qp )
+                last_qp_tried = 1;
             h->mb.i_chroma_qp = h->chroma_qp_table[h->mb.i_qp];
             cost = x264_rd_cost_mb( h, a->i_lambda2 );
             COPY2_IF_LT( bcost, cost, bqp, h->mb.i_qp );
@@ -2226,13 +2239,7 @@ static inline void x264_mb_analyse_qp_rd( x264_t *h, x264_mb_analysis_t *a )
                 failures++;
             prevcost = cost;
 
-            /* Without psy-RD, require monotonicity when lowering
-             * quant, allow 1 failure when raising quant.
-             * With psy-RD, allow 1 failure when lowering quant,
-             * allow 2 failures when raising quant.
-             * Psy-RD generally seems to result in more chaotic
-             * RD score-vs-quantizer curves. */
-            if( failures > ((direction + 1)>>1)+(!!h->mb.i_psy_rd) )
+            if( failures > threshold )
                 break;
             if( direction == 1 && !h->mb.cbp[h->mb.i_mb_xy] )
                 break;
@@ -2240,6 +2247,15 @@ static inline void x264_mb_analyse_qp_rd( x264_t *h, x264_mb_analysis_t *a )
         }
     }
 
+    /* Always try the last block's QP. */
+    if( !last_qp_tried )
+    {
+        h->mb.i_qp = h->mb.i_last_qp;
+        h->mb.i_chroma_qp = h->chroma_qp_table[h->mb.i_qp];
+        cost = x264_rd_cost_mb( h, a->i_lambda2 );
+        COPY2_IF_LT( bcost, cost, bqp, h->mb.i_qp );
+    }
+
     h->mb.i_qp = bqp;
     h->mb.i_chroma_qp = h->chroma_qp_table[h->mb.i_qp];
 



More information about the x264-devel mailing list