]> git.sesse.net Git - x264/commitdiff
Improve 2-pass bitrate prediction
authorFiona Glaser <fiona@x264.com>
Sat, 19 Jun 2010 08:41:07 +0000 (01:41 -0700)
committerFiona Glaser <fiona@x264.com>
Fri, 25 Jun 2010 06:57:18 +0000 (23:57 -0700)
Adapt based on distance to the end in bits, not in frames.
Helps in videos with absurdly simple end sections, e.g. black frames.

encoder/ratecontrol.c

index d8ec1203c1a136d4005eb515126fe2c4614aef44..adb5bbba34d7c515bc4e60e73cd1021e6df8da88 100644 (file)
@@ -2034,9 +2034,6 @@ static float rate_estimate_qscale( x264_t *h )
             double lmax = rcc->lmax[pict_type];
             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->i_frame )
-                abr_buffer *= 0.5 * sqrt( rcc->num_entries - h->i_frame );
 
             if( rcc->b_vbv )
             {
@@ -2062,6 +2059,15 @@ static float rate_estimate_qscale( x264_t *h )
                     predicted_bits += (int64_t)(h->i_thread_frames - 1) * rcc->bitrate / rcc->fps;
             }
 
+            /* Adjust ABR buffer based on distance to the end of the video. */
+            if( rcc->num_entries > h->i_frame )
+            {
+                double final_bits = rcc->entry[rcc->num_entries-1].expected_bits;
+                double video_pos = rce.expected_bits / final_bits;
+                double scale_factor = sqrt( (1 - video_pos) * rcc->num_entries );
+                abr_buffer *= 0.5 * X264_MAX( scale_factor, 0.5 );
+            }
+
             diff = predicted_bits - (int64_t)rce.expected_bits;
             q = rce.new_qscale;
             q /= x264_clip3f((double)(abr_buffer - diff) / abr_buffer, .5, 2);