From: Fiona Glaser Date: Mon, 24 Aug 2009 10:28:11 +0000 (-0700) Subject: 2-pass VBV fixes X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=918808f897cb7e1e401b1f1cba560957985f1682;p=libx264 2-pass VBV fixes Properly run slicetype frame cost with 2pass + MB-tree. Slash the VBV rate tolerance in 2-pass mode; increasing it made sense for the highly reactive 1-pass VBV algorithm, but not for 2-pass. 2-pass's planned frame sizes are guaranteed to be reasonable, since they are based on a real first pass, while 1-pass's, based on lookahead SATD, cannot always be trusted. --- diff --git a/encoder/ratecontrol.c b/encoder/ratecontrol.c index f37747be..a6f864f3 100644 --- a/encoder/ratecontrol.c +++ b/encoder/ratecontrol.c @@ -1060,8 +1060,11 @@ void x264_ratecontrol_mb( x264_t *h, int bits ) int i_qp_max = X264_MIN( prev_row_qp + h->param.rc.i_qp_step, h->param.rc.i_qp_max ); int i_qp_min = X264_MAX( prev_row_qp - h->param.rc.i_qp_step, h->param.rc.i_qp_min ); float buffer_left_planned = rc->buffer_fill - rc->frame_size_planned; - /* 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); + /* More threads means we have to be more cautious in letting ratecontrol use up extra bits. + * In 2-pass mode we can be more trusting of the planned frame sizes, since they were decided + * by actual encoding instead of SATD prediction. */ + float rc_tol = h->param.rc.b_stat_read ? (buffer_left_planned / rc->buffer_size) * rc->frame_size_planned + : (buffer_left_planned / h->param.i_threads); /* Don't modify 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. */ diff --git a/encoder/slicetype.c b/encoder/slicetype.c index 9c8c127b..0fa5b1f4 100644 --- a/encoder/slicetype.c +++ b/encoder/slicetype.c @@ -976,16 +976,13 @@ int x264_rc_analyse_slice( x264_t *h ) frames[p0] = h->fref0[0]; frames[b] = h->fenc; - if( h->param.rc.b_mb_tree ) - cost = x264_slicetype_frame_cost_recalculate( h, frames, p0, p1, b ); - else - { - cost = x264_slicetype_frame_cost( h, &a, frames, p0, p1, b, 0 ); + cost = x264_slicetype_frame_cost( h, &a, frames, p0, p1, b, 0 ); - /* In AQ, use the weighted score instead. */ - if( h->param.rc.i_aq_mode ) - cost = frames[b]->i_cost_est_aq[b-p0][p1-b]; - } + if( h->param.rc.b_mb_tree && !h->param.rc.b_stat_read ) + cost = x264_slicetype_frame_cost_recalculate( h, frames, p0, p1, b ); + /* In AQ, use the weighted score instead. */ + else if( h->param.rc.i_aq_mode ) + cost = frames[b]->i_cost_est_aq[b-p0][p1-b]; h->fenc->i_row_satd = h->fenc->i_row_satds[b-p0][p1-b]; h->fdec->i_row_satd = h->fdec->i_row_satds[b-p0][p1-b];