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;
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 );
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 )
(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;
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;
}
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;