]> git.sesse.net Git - x264/commitdiff
Don't force row QPs to integer values with VBV
authorFiona Glaser <fiona@x264.com>
Tue, 4 May 2010 04:27:16 +0000 (21:27 -0700)
committerFiona Glaser <fiona@x264.com>
Thu, 6 May 2010 05:08:29 +0000 (22:08 -0700)
VBV should no longer raise the bitrate of the video.  That is, at a given quality level or average bitrate, turning on VBV should only lower the bitrate.
This isn't quite true if adaptive quant is off, but nobody should be doing that anyways.
Also may result in slightly more accurate per-row VBV ratecontrol.

common/frame.c
common/frame.h
encoder/analyse.c
encoder/ratecontrol.c
encoder/ratecontrol.h

index 63a8e3f4f684f1d01202a8c8a824539fd7847c52..00702ffc9271ede9bb60b6e1008891cd94e392fe 100644 (file)
@@ -118,7 +118,7 @@ x264_frame_t *x264_frame_new( x264_t *h, int b_fdec )
             frame->ref[1] = NULL;
         }
         CHECKED_MALLOC( frame->i_row_bits, i_lines/16 * sizeof(int) );
-        CHECKED_MALLOC( frame->i_row_qp, i_lines/16 * sizeof(int) );
+        CHECKED_MALLOC( frame->f_row_qp, i_lines/16 * sizeof(float) );
         if( h->param.analyse.i_me_method >= X264_ME_ESA )
         {
             CHECKED_MALLOC( frame->buffer[3],
@@ -202,7 +202,7 @@ void x264_frame_delete( x264_frame_t *frame )
         x264_free( frame->f_qp_offset_aq );
         x264_free( frame->i_inv_qscale_factor );
         x264_free( frame->i_row_bits );
-        x264_free( frame->i_row_qp );
+        x264_free( frame->f_row_qp );
         x264_free( frame->mb_type );
         x264_free( frame->mb_partition );
         x264_free( frame->mv[0] );
index 60930752a96fbc1be1a328afb69c0e49fe3ee118..357929eafe667fa74098012bd371e47cb385a060 100644 (file)
@@ -109,7 +109,7 @@ typedef struct x264_frame
     int     *i_row_satds[X264_BFRAME_MAX+2][X264_BFRAME_MAX+2];
     int     *i_row_satd;
     int     *i_row_bits;
-    int     *i_row_qp;
+    float   *f_row_qp;
     float   *f_qp_offset;
     float   *f_qp_offset_aq;
     int     b_intra_calculated;
index 85a70448a3d3fa7b258cc56596d1343831e10ba8..f14a19b5340acee329eeef4d624fb41e1334e4e0 100644 (file)
@@ -2568,15 +2568,11 @@ void x264_macroblock_analyse( x264_t *h )
     x264_mb_analysis_t analysis;
     int i_cost = COST_MAX;
 
-    h->mb.i_qp = x264_ratecontrol_qp( h );
-    if( h->param.rc.i_aq_mode )
-    {
-        x264_adaptive_quant( h );
-        /* If the QP of this MB is within 1 of the previous MB, code the same QP as the previous MB,
-         * to lower the bit cost of the qp_delta.  Don't do this if QPRD is enabled. */
-        if( h->param.analyse.i_subpel_refine < 10 && abs(h->mb.i_qp - h->mb.i_last_qp) == 1 )
-            h->mb.i_qp = h->mb.i_last_qp;
-    }
+    h->mb.i_qp = x264_ratecontrol_mb_qp( h );
+    /* If the QP of this MB is within 1 of the previous MB, code the same QP as the previous MB,
+     * to lower the bit cost of the qp_delta.  Don't do this if QPRD is enabled. */
+    if( h->param.rc.i_aq_mode && h->param.analyse.i_subpel_refine < 10 && abs(h->mb.i_qp - h->mb.i_last_qp) == 1 )
+        h->mb.i_qp = h->mb.i_last_qp;
 
     x264_mb_analyse_init( h, &analysis, h->mb.i_qp );
 
index 0ebde2631ab3187daafd3a563401bdeb9a60fccb..27975aa7b6265856012d3642e518394570e2f78a 100644 (file)
@@ -83,8 +83,7 @@ struct x264_ratecontrol_t
     /* current frame */
     ratecontrol_entry_t *rce;
     int qp;                     /* qp for current frame */
-    int qpm;                    /* qp for current macroblock */
-    float f_qpm;                /* qp for current macroblock: precise float for AQ */
+    float qpm;                  /* qp for current macroblock: precise float for AQ */
     float qpa_rc;               /* average of macroblocks' qp before aq */
     float qpa_aq;               /* average of macroblocks' qp after aq */
     float qp_novbv;             /* QP for the current frame if 1-pass VBV was disabled. */
@@ -292,22 +291,6 @@ void x264_adaptive_quant_frame( x264_t *h, x264_frame_t *frame )
         }
 }
 
-
-/*****************************************************************************
-* x264_adaptive_quant:
- * adjust macroblock QP based on variance (AC energy) of the MB.
- * high variance  = higher QP
- * low variance = lower QP
- * This generally increases SSIM and lowers PSNR.
-*****************************************************************************/
-void x264_adaptive_quant( x264_t *h )
-{
-    x264_emms();
-    /* MB-tree currently doesn't adjust quantizers in unreferenced frames. */
-    float qp_offset = h->fdec->b_kept_as_ref ? h->fenc->f_qp_offset[h->mb.i_mb_xy] : h->fenc->f_qp_offset_aq[h->mb.i_mb_xy];
-    h->mb.i_qp = x264_clip3( h->rc->f_qpm + qp_offset + .5, h->param.rc.i_qp_min, h->param.rc.i_qp_max );
-}
-
 int x264_macroblock_tree_read( x264_t *h, x264_frame_t *frame )
 {
     x264_ratecontrol_t *rc = h->rc;
@@ -1179,28 +1162,27 @@ void x264_ratecontrol_start( x264_t *h, int i_force_qp, int overhead )
 
     rc->qpa_rc =
     rc->qpa_aq = 0;
-    rc->qpm =
     rc->qp = x264_clip3( (int)(q + 0.5), 0, 51 );
     h->fdec->f_qp_avg_rc =
     h->fdec->f_qp_avg_aq =
-    rc->f_qpm = q;
+    rc->qpm = q;
     if( rce )
         rce->new_qp = rc->qp;
 
-    accum_p_qp_update( h, rc->f_qpm );
+    accum_p_qp_update( h, rc->qpm );
 
     if( h->sh.i_type != SLICE_TYPE_B )
         rc->last_non_b_pict_type = h->sh.i_type;
 }
 
-static double predict_row_size( x264_t *h, int y, int qp )
+static double predict_row_size( x264_t *h, int y, double qp )
 {
     /* average between two predictors:
      * absolute SATD, and scaled bit cost of the colocated row in the previous frame */
     x264_ratecontrol_t *rc = h->rc;
     double pred_s = predict_size( rc->row_pred[0], qp2qscale( qp ), h->fdec->i_row_satd[y] );
     double pred_t = 0;
-    if( h->sh.i_type == SLICE_TYPE_I || qp >= h->fref0[0]->i_row_qp[y] )
+    if( h->sh.i_type == SLICE_TYPE_I || qp >= h->fref0[0]->f_row_qp[y] )
     {
         if( h->sh.i_type == SLICE_TYPE_P
             && h->fref0[0]->i_type == h->fdec->i_type
@@ -1208,7 +1190,7 @@ static double predict_row_size( x264_t *h, int y, int qp )
             && (abs(h->fref0[0]->i_row_satd[y] - h->fdec->i_row_satd[y]) < h->fdec->i_row_satd[y]/2))
         {
             pred_t = h->fref0[0]->i_row_bits[y] * h->fdec->i_row_satd[y] / h->fref0[0]->i_row_satd[y]
-                     * qp2qscale( h->fref0[0]->i_row_qp[y] ) / qp2qscale( qp );
+                     * qp2qscale( h->fref0[0]->f_row_qp[y] ) / qp2qscale( qp );
         }
         if( pred_t == 0 )
             pred_t = pred_s;
@@ -1231,7 +1213,7 @@ static double row_bits_so_far( x264_t *h, int y )
     return bits;
 }
 
-static double predict_row_size_sum( x264_t *h, int y, int qp )
+static double predict_row_size_sum( x264_t *h, int y, double qp )
 {
     double bits = row_bits_so_far(h, y);
     for( int i = y+1; i < h->i_threadslice_end; i++ )
@@ -1248,33 +1230,34 @@ void x264_ratecontrol_mb( x264_t *h, int bits )
     x264_emms();
 
     h->fdec->i_row_bits[y] += bits;
-    rc->qpa_rc += rc->f_qpm;
+    rc->qpa_rc += rc->qpm;
     rc->qpa_aq += h->mb.i_qp;
 
     if( h->mb.i_mb_x != h->sps->i_mb_width - 1 || !rc->b_vbv )
         return;
 
-    h->fdec->i_row_qp[y] = rc->qpm;
+    h->fdec->f_row_qp[y] = rc->qpm;
 
     update_predictor( rc->row_pred[0], qp2qscale( rc->qpm ), h->fdec->i_row_satd[y], h->fdec->i_row_bits[y] );
-    if( h->sh.i_type == SLICE_TYPE_P && rc->qpm < h->fref0[0]->i_row_qp[y] )
+    if( h->sh.i_type == SLICE_TYPE_P && rc->qpm < h->fref0[0]->f_row_qp[y] )
         update_predictor( rc->row_pred[1], qp2qscale( rc->qpm ), h->fdec->i_row_satds[0][0][y], h->fdec->i_row_bits[y] );
 
     /* tweak quality based on difference from predicted size */
     if( y < h->i_threadslice_end-1 )
     {
-        int prev_row_qp = h->fdec->i_row_qp[y];
-        int i_qp_min = X264_MAX( prev_row_qp - h->param.rc.i_qp_step, h->param.rc.i_qp_min );
-        int i_qp_absolute_max = h->param.rc.i_qp_max;
+        float prev_row_qp = h->fdec->f_row_qp[y];
+        float qp_min = X264_MAX( prev_row_qp - h->param.rc.i_qp_step, h->param.rc.i_qp_min );
+        float qp_absolute_max = h->param.rc.i_qp_max;
         if( rc->rate_factor_max_increment )
-            i_qp_absolute_max = X264_MIN( i_qp_absolute_max, rc->qp_novbv + rc->rate_factor_max_increment );
-        int i_qp_max = X264_MIN( prev_row_qp + h->param.rc.i_qp_step, i_qp_absolute_max );
+            qp_absolute_max = X264_MIN( qp_absolute_max, rc->qp_novbv + rc->rate_factor_max_increment );
+        float qp_max = X264_MIN( prev_row_qp + h->param.rc.i_qp_step, qp_absolute_max );
+        float step_size = 0.5;
 
         /* B-frames shouldn't use lower QP than their reference frames. */
         if( h->sh.i_type == SLICE_TYPE_B )
         {
-            i_qp_min = X264_MAX( i_qp_min, X264_MAX( h->fref0[0]->i_row_qp[y+1], h->fref1[0]->i_row_qp[y+1] ) );
-            rc->qpm = X264_MAX( rc->qpm, i_qp_min );
+            qp_min = X264_MAX( qp_min, X264_MAX( h->fref0[0]->f_row_qp[y+1], h->fref1[0]->f_row_qp[y+1] ) );
+            rc->qpm = X264_MAX( rc->qpm, qp_min );
         }
 
         float buffer_left_planned = rc->buffer_fill - rc->frame_size_planned;
@@ -1302,45 +1285,53 @@ void x264_ratecontrol_mb( x264_t *h, int bits )
             rc_tol /= 2;
 
         if( !rc->b_vbv_min_rate )
-            i_qp_min = X264_MAX( i_qp_min, h->sh.i_qp );
+            qp_min = X264_MAX( qp_min, rc->qp_novbv );
 
-        while( rc->qpm < i_qp_max
+        while( rc->qpm < qp_max
                && ((b1 > rc->frame_size_planned + rc_tol) ||
                    (rc->buffer_fill - b1 < buffer_left_planned * 0.5) ||
                    (b1 > rc->frame_size_planned && rc->qpm < rc->qp_novbv)) )
         {
-            rc->qpm ++;
+            rc->qpm += step_size;
             b1 = predict_row_size_sum( h, y, rc->qpm ) + size_of_other_slices;
         }
 
-        while( rc->qpm > i_qp_min
-               && (rc->qpm > h->fdec->i_row_qp[0] || rc->single_frame_vbv)
+        while( rc->qpm > qp_min
+               && (rc->qpm > h->fdec->f_row_qp[0] || rc->single_frame_vbv)
                && ((b1 < rc->frame_size_planned * 0.8 && rc->qpm <= prev_row_qp)
                || b1 < (rc->buffer_fill - rc->buffer_size + rc->buffer_rate) * 1.1) )
         {
-            rc->qpm --;
+            rc->qpm -= step_size;
             b1 = predict_row_size_sum( h, y, rc->qpm ) + size_of_other_slices;
         }
 
         /* avoid VBV underflow or MinCR violation */
-        while( (rc->qpm < i_qp_absolute_max)
+        while( (rc->qpm < qp_absolute_max)
                && ((rc->buffer_fill - b1 < rc->buffer_rate * rc->max_frame_error) ||
                    (rc->frame_size_maximum - b1 < rc->frame_size_maximum * rc->max_frame_error)))
         {
-            rc->qpm ++;
+            rc->qpm += step_size;
             b1 = predict_row_size_sum( h, y, rc->qpm ) + size_of_other_slices;
         }
 
         h->rc->frame_size_estimated = predict_row_size_sum( h, y, rc->qpm );
     }
-
-    /* loses the fractional part of the frame-wise qp */
-    rc->f_qpm = rc->qpm;
 }
 
 int x264_ratecontrol_qp( x264_t *h )
 {
-    return h->rc->qpm;
+    x264_emms();
+    return x264_clip3( h->rc->qpm + .5, h->param.rc.i_qp_min, h->param.rc.i_qp_max );
+}
+
+int x264_ratecontrol_mb_qp( x264_t *h )
+{
+    x264_emms();
+    float qp = h->rc->qpm;
+    if( h->param.rc.i_aq_mode )
+        /* MB-tree currently doesn't adjust quantizers in unreferenced frames. */
+        qp += h->fdec->b_kept_as_ref ? h->fenc->f_qp_offset[h->mb.i_mb_xy] : h->fenc->f_qp_offset_aq[h->mb.i_mb_xy];
+    return x264_clip3( qp + .5, h->param.rc.i_qp_min, h->param.rc.i_qp_max );
 }
 
 /* In 2pass, force the same frame types as in the 1st pass */
index 181ab23870f0a5bcbd629b68b8a5bb0b78425444..e052b2ac61329cd9e9622e7558b39467816c3f0c 100644 (file)
@@ -30,7 +30,6 @@ void x264_ratecontrol_delete( x264_t * );
 void x264_ratecontrol_init_reconfigurable( x264_t *h, int b_init );
 
 void x264_adaptive_quant_frame( x264_t *h, x264_frame_t *frame );
-void x264_adaptive_quant( x264_t * );
 int  x264_macroblock_tree_read( x264_t *h, x264_frame_t *frame );
 int  x264_reference_build_list_optimal( x264_t *h );
 void x264_thread_sync_ratecontrol( x264_t *cur, x264_t *prev, x264_t *next );
@@ -39,6 +38,7 @@ int  x264_ratecontrol_slice_type( x264_t *, int i_frame );
 void x264_ratecontrol_set_weights( x264_t *h, x264_frame_t *frm );
 void x264_ratecontrol_mb( x264_t *, int bits );
 int  x264_ratecontrol_qp( x264_t * );
+int  x264_ratecontrol_mb_qp( x264_t *h );
 int  x264_ratecontrol_end( x264_t *, int bits, int *filler );
 void x264_ratecontrol_summary( x264_t * );
 void x264_ratecontrol_set_estimated_size( x264_t *, int bits );