[x264-devel] Revise the row VBV algorithm (part 2)
Anton Mitrofanov
git at videolan.org
Sun Jan 17 22:17:56 CET 2016
x264 | branch: master | Anton Mitrofanov <BugMaster at narod.ru> | Tue Jan 5 02:41:43 2016 +0300| [065321c48d0d371c1735b3cc9d368b43e1b64aaa] | committer: Henrik Gramner
Revise the row VBV algorithm (part 2)
Should fix rare cases of VBV emergency mode activation caused by too much trust
to the row predictors.
> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=065321c48d0d371c1735b3cc9d368b43e1b64aaa
---
encoder/ratecontrol.c | 28 ++++++++++++++++------------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/encoder/ratecontrol.c b/encoder/ratecontrol.c
index e4a085c..ab80460 100644
--- a/encoder/ratecontrol.c
+++ b/encoder/ratecontrol.c
@@ -1551,10 +1551,10 @@ static int row_bits_so_far( x264_t *h, int y )
return bits;
}
-static float predict_row_size_sum( x264_t *h, int y, float qp )
+static float predict_row_size_to_end( x264_t *h, int y, float qp )
{
float qscale = qp2qscale( qp );
- float bits = row_bits_so_far( h, y );
+ float bits = 0;
for( int i = y+1; i < h->i_threadslice_end; i++ )
bits += predict_row_size( h, i, qscale );
return bits;
@@ -1606,6 +1606,7 @@ int x264_ratecontrol_mb( x264_t *h, int bits )
float qp_min = X264_MAX( prev_row_qp - h->param.rc.i_qp_step, h->param.rc.i_qp_min );
float step_size = 0.5f;
float slice_size_planned = h->param.b_sliced_threads ? rc->slice_size_planned : rc->frame_size_planned;
+ float bits_so_far = row_bits_so_far( h, y );
float max_frame_error = x264_clip3f( 1.0 / h->mb.i_mb_height, 0.05, 0.25 );
float max_frame_size = rc->frame_size_maximum - rc->frame_size_maximum * max_frame_error;
max_frame_size = X264_MIN( max_frame_size, rc->buffer_fill - rc->buffer_rate * max_frame_error );
@@ -1635,11 +1636,12 @@ int x264_ratecontrol_mb( x264_t *h, int bits )
buffer_left_planned = X264_MAX( buffer_left_planned, 0.f );
/* More threads means we have to be more cautious in letting ratecontrol use up extra bits. */
float rc_tol = buffer_left_planned / h->param.i_threads * rc->rate_tolerance;
- float b1 = predict_row_size_sum( h, y, rc->qpm ) + size_of_other_slices;
+ float b1 = bits_so_far + predict_row_size_to_end( h, y, rc->qpm ) + size_of_other_slices;
+ float trust_coeff = x264_clip3f( bits_so_far / slice_size_planned, 0.0, 1.0 );
/* Don't increase the row QPs until a sufficent amount of the bits of the frame have been processed, in case a flat */
/* area at the top of the frame was measured inaccurately. */
- if( row_bits_so_far( h, y ) < 0.05f * slice_size_planned )
+ if( trust_coeff < 0.05f )
qp_max = qp_absolute_max = prev_row_qp;
if( h->sh.i_type != SLICE_TYPE_I )
@@ -1654,18 +1656,20 @@ int x264_ratecontrol_mb( x264_t *h, int bits )
(b1 > rc->buffer_fill - buffer_left_planned * 0.5f)) )
{
rc->qpm += step_size;
- b1 = predict_row_size_sum( h, y, rc->qpm ) + size_of_other_slices;
+ b1 = bits_so_far + predict_row_size_to_end( h, y, rc->qpm ) + size_of_other_slices;
}
+ float b_max = b1 + ((rc->buffer_fill - rc->buffer_size + rc->buffer_rate) * 0.90f - b1) * trust_coeff;
rc->qpm -= step_size;
+ float b2 = bits_so_far + predict_row_size_to_end( h, y, rc->qpm ) + size_of_other_slices;
while( rc->qpm > qp_min && rc->qpm < prev_row_qp
&& (rc->qpm > h->fdec->f_row_qp[0] || rc->single_frame_vbv)
- && (b1 < max_frame_size)
- && ((b1 < rc->frame_size_planned * 0.8f) ||
- (b1 < (rc->buffer_fill - rc->buffer_size + rc->buffer_rate) * 0.95f)) )
+ && (b2 < max_frame_size)
+ && ((b2 < rc->frame_size_planned * 0.8f) || (b2 < b_max)) )
{
- b1 = predict_row_size_sum( h, y, rc->qpm ) + size_of_other_slices;
+ b1 = b2;
rc->qpm -= step_size;
+ b2 = bits_so_far + predict_row_size_to_end( h, y, rc->qpm ) + size_of_other_slices;
}
rc->qpm += step_size;
@@ -1673,7 +1677,7 @@ int x264_ratecontrol_mb( x264_t *h, int bits )
while( rc->qpm < qp_absolute_max && (b1 > max_frame_size) )
{
rc->qpm += step_size;
- b1 = predict_row_size_sum( h, y, rc->qpm ) + size_of_other_slices;
+ b1 = bits_so_far + predict_row_size_to_end( h, y, rc->qpm ) + size_of_other_slices;
}
h->rc->frame_size_estimated = b1 - size_of_other_slices;
@@ -1692,12 +1696,12 @@ int x264_ratecontrol_mb( x264_t *h, int bits )
}
else
{
- h->rc->frame_size_estimated = predict_row_size_sum( h, y, rc->qpm );
+ h->rc->frame_size_estimated = bits_so_far;
/* Last-ditch attempt: if the last row of the frame underflowed the VBV,
* try again. */
if( rc->qpm < qp_max && can_reencode_row
- && (h->rc->frame_size_estimated + size_of_other_slices > max_frame_size) )
+ && (h->rc->frame_size_estimated + size_of_other_slices > X264_MIN( rc->frame_size_maximum, rc->buffer_fill )) )
{
rc->qpm = qp_max;
rc->qpa_rc = rc->qpa_rc_prev;
More information about the x264-devel
mailing list