[x264-devel] commit: Fix ABR rate control calculations (Anton Mitrofanov )

git at videolan.org git at videolan.org
Wed May 26 19:39:33 CEST 2010


x264 | branch: master | Anton Mitrofanov <BugMaster at narod.ru> | Tue May 25 19:11:42 2010 +0400| [d202981d5c884d7b177320bd74fec3af1d68e5a8] | committer: Jason Garrett-Glaser 

Fix ABR rate control calculations
Incorrect frame numbers were used, resulting in slightly inaccurate ratecontrol.

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

 common/common.h       |    2 +-
 encoder/encoder.c     |    4 ++--
 encoder/ratecontrol.c |   25 ++++++++++++-------------
 3 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/common/common.h b/common/common.h
index c564768..e1f4d0c 100644
--- a/common/common.h
+++ b/common/common.h
@@ -491,7 +491,7 @@ struct x264_t
     /* hrd */
     int initial_cpb_removal_delay;
     int initial_cpb_removal_delay_offset;
-    int64_t first_pts;
+    int64_t i_reordered_pts_delay;
 
     /* Current MB DCT coeffs */
     struct
diff --git a/encoder/encoder.c b/encoder/encoder.c
index de06251..a7ccd3f 100644
--- a/encoder/encoder.c
+++ b/encoder/encoder.c
@@ -2275,8 +2275,8 @@ int     x264_encoder_encode( x264_t *h,
     /* ------------------- Get frame to be encoded ------------------------- */
     /* 4: get picture to encode */
     h->fenc = x264_frame_shift( h->frames.current );
-    if( h->i_frame == 0 )
-        h->first_pts = h->fenc->i_reordered_pts;
+    if( h->i_frame == h->i_thread_frames - 1 )
+        h->i_reordered_pts_delay = h->fenc->i_reordered_pts;
     if( h->fenc->param )
     {
         x264_encoder_reconfig( h, h->fenc->param );
diff --git a/encoder/ratecontrol.c b/encoder/ratecontrol.c
index efa872c..a725a24 100644
--- a/encoder/ratecontrol.c
+++ b/encoder/ratecontrol.c
@@ -1966,8 +1966,8 @@ static float rate_estimate_qscale( x264_t *h )
             int64_t diff;
             int64_t predicted_bits = total_bits;
             /* Adjust ABR buffer based on distance to the end of the video. */
-            if( rcc->num_entries > h->fenc->i_frame )
-                abr_buffer *= 0.5 * sqrt( rcc->num_entries - h->fenc->i_frame );
+            if( rcc->num_entries > h->i_frame )
+                abr_buffer *= 0.5 * sqrt( rcc->num_entries - h->i_frame );
 
             if( rcc->b_vbv )
             {
@@ -1987,8 +1987,8 @@ static float rate_estimate_qscale( x264_t *h )
             }
             else
             {
-                if( h->fenc->i_frame < h->i_thread_frames )
-                    predicted_bits += (int64_t)h->fenc->i_frame * rcc->bitrate / rcc->fps;
+                if( h->i_frame < h->i_thread_frames )
+                    predicted_bits += (int64_t)h->i_frame * rcc->bitrate / rcc->fps;
                 else
                     predicted_bits += (int64_t)(h->i_thread_frames - 1) * rcc->bitrate / rcc->fps;
             }
@@ -1996,12 +1996,12 @@ static float rate_estimate_qscale( x264_t *h )
             diff = predicted_bits - (int64_t)rce.expected_bits;
             q = rce.new_qscale;
             q /= x264_clip3f((double)(abr_buffer - diff) / abr_buffer, .5, 2);
-            if( ((h->fenc->i_frame + 1 - h->i_thread_frames) >= rcc->fps) &&
+            if( ((h->i_frame + 1 - h->i_thread_frames) >= rcc->fps) &&
                 (rcc->expected_bits_sum > 0))
             {
                 /* Adjust quant based on the difference between
                  * achieved and expected bitrate so far */
-                double cur_time = (double)h->fenc->i_frame / rcc->num_entries;
+                double cur_time = (double)h->i_frame / rcc->num_entries;
                 double w = x264_clip3f( cur_time*100, 0.0, 1.0 );
                 q *= pow( (double)total_bits / rcc->expected_bits_sum, w );
             }
@@ -2063,11 +2063,6 @@ static float rate_estimate_qscale( x264_t *h )
             }
             else
             {
-                int i_frame_done = h->fenc->i_frame + 1 - h->i_thread_frames;
-                double i_time_done = i_frame_done / rcc->fps;
-                if( h->param.b_vfr_input )
-                    i_time_done = ((double)(h->fenc->i_reordered_pts - h->first_pts)) * h->param.i_timebase_num / h->param.i_timebase_den;
-
                 q = get_qscale( h, &rce, rcc->wanted_bits_window / rcc->cplxr_sum, h->fenc->i_frame );
 
                 /* ABR code can potentially be counterproductive in CBR, so just don't bother.
@@ -2075,10 +2070,14 @@ static float rate_estimate_qscale( x264_t *h )
                 if( !rcc->b_vbv_min_rate && rcc->last_satd )
                 {
                     // FIXME is it simpler to keep track of wanted_bits in ratecontrol_end?
-                    wanted_bits = i_time_done * rcc->bitrate;
+                    int i_frame_done = h->i_frame + 1 - h->i_thread_frames;
+                    double time_done = i_frame_done / rcc->fps;
+                    if( h->param.b_vfr_input && i_frame_done > 0 )
+                        time_done = ((double)(h->fenc->i_reordered_pts - h->i_reordered_pts_delay)) * h->param.i_timebase_num / h->param.i_timebase_den;
+                    wanted_bits = time_done * rcc->bitrate;
                     if( wanted_bits > 0 )
                     {
-                        abr_buffer *= X264_MAX( 1, sqrt(i_time_done) );
+                        abr_buffer *= X264_MAX( 1, sqrt( time_done ) );
                         overflow = x264_clip3f( 1.0 + (total_bits - wanted_bits) / abr_buffer, .5, 2 );
                         q *= overflow;
                     }



More information about the x264-devel mailing list