diff options
Diffstat (limited to 'contrib/patch-x264-vbv-2pass.patch')
-rw-r--r-- | contrib/patch-x264-vbv-2pass.patch | 358 |
1 files changed, 308 insertions, 50 deletions
diff --git a/contrib/patch-x264-vbv-2pass.patch b/contrib/patch-x264-vbv-2pass.patch index ca60d315e..7f4692389 100644 --- a/contrib/patch-x264-vbv-2pass.patch +++ b/contrib/patch-x264-vbv-2pass.patch @@ -1,8 +1,80 @@ +Index: common/frame.c +=================================================================== +--- common/frame.c ++++ common/frame.c +@@ -844,11 +844,39 @@ void x264_frame_cond_wait( x264_frame_t *frame, int i_lines_completed ) + x264_pthread_mutex_unlock( &frame->mutex ); + } + ++void x264_frame_size_estimated_set( x264_t *h, int bits ) ++{ ++ x264_pthread_mutex_lock( &h->fenc->mutex ); ++ x264_ratecontrol_set_estimated_size(h, bits); ++ x264_pthread_mutex_unlock( &h->fenc->mutex ); ++} ++ ++int x264_frame_size_estimated_get( x264_t const *h) ++{ ++ int size; ++ x264_pthread_mutex_lock( &h->fenc->mutex ); ++ size = x264_ratecontrol_get_estimated_size(h); ++ x264_pthread_mutex_unlock( &h->fenc->mutex ); ++ return size; ++} ++ + #else + void x264_frame_cond_broadcast( x264_frame_t *frame, int i_lines_completed ) + {} + void x264_frame_cond_wait( x264_frame_t *frame, int i_lines_completed ) + {} ++ ++void x264_frame_size_estimated_set( x264_t *h, int bits ) ++{ ++ x264_ratecontrol_set_estimated_size(h, bits); ++} ++ ++int x264_frame_size_estimated_get( x264_t const *h) ++{ ++ int size; ++ size = x264_ratecontrol_set_estimated_size(h); ++ return size; ++} + #endif + + +Index: common/frame.h +=================================================================== +--- common/frame.h ++++ common/frame.h +@@ -121,6 +121,9 @@ void x264_deblock_init( int cpu, x264_deblock_function_t *pf ); + void x264_frame_cond_broadcast( x264_frame_t *frame, int i_lines_completed ); + void x264_frame_cond_wait( x264_frame_t *frame, int i_lines_completed ); + ++void x264_frame_size_estimated_set( x264_t *h, int bits ); ++int x264_frame_size_estimated_get( x264_t const *h); ++ + void x264_frame_push( x264_frame_t **list, x264_frame_t *frame ); + x264_frame_t *x264_frame_pop( x264_frame_t **list ); + void x264_frame_unshift( x264_frame_t **list, x264_frame_t *frame ); +Index: encoder/encoder.c +=================================================================== +--- encoder/encoder.c ++++ encoder/encoder.c +@@ -631,6 +631,7 @@ x264_t *x264_encoder_open ( x264_param_t *param ) + || h->param.rc.i_rc_method == X264_RC_CRF + || h->param.b_bframe_adaptive + || h->param.b_pre_scenecut ); ++ h->frames.b_have_lowres |= (h->param.rc.b_stat_read && h->param.rc.i_vbv_buffer_size > 0); + + h->frames.i_last_idr = - h->param.i_keyint_max; + h->frames.i_input = 0; Index: encoder/ratecontrol.c =================================================================== ---- encoder/ratecontrol.c (revision 736) -+++ encoder/ratecontrol.c (working copy) -@@ -43,6 +43,7 @@ +old mode 100644 +new mode 100755 +--- encoder/ratecontrol.c ++++ encoder/ratecontrol.c +@@ -43,6 +43,7 @@ typedef struct int p_tex_bits; int misc_bits; uint64_t expected_bits; @@ -10,16 +82,171 @@ Index: encoder/ratecontrol.c float new_qscale; int new_qp; int i_count; -@@ -1149,7 +1150,7 @@ +@@ -121,6 +122,7 @@ struct x264_ratecontrol_t + int frame_count[5]; /* number of frames of each type */ + + /* MBRC stuff */ ++ double frame_size_estimated; + double frame_size_planned; + predictor_t *row_pred; + predictor_t row_preds[5]; +@@ -331,7 +333,7 @@ int x264_ratecontrol_new( x264_t *h ) + rc->rate_tolerance = 0.01; + } + +- h->mb.b_variable_qp = (rc->b_vbv && !rc->b_2pass) || h->param.rc.i_aq_mode; ++ h->mb.b_variable_qp = rc->b_vbv || h->param.rc.i_aq_mode; + + if( rc->b_abr ) + { +@@ -718,6 +720,16 @@ void x264_ratecontrol_delete( x264_t *h ) + x264_free( rc ); + } + ++void x264_ratecontrol_set_estimated_size( x264_t *h, int bits ) ++{ ++ h->rc->frame_size_estimated = bits; ++} ++ ++int x264_ratecontrol_get_estimated_size( x264_t const *h) ++{ ++ return h->rc->frame_size_estimated; ++} ++ + static void accum_p_qp_update( x264_t *h, float qp ) + { + x264_ratecontrol_t *rc = h->rc; +@@ -851,17 +863,25 @@ double predict_row_size( x264_t *h, int y, int qp ) + return (pred_s + pred_t) / 2; + } + +-double predict_row_size_sum( x264_t *h, int y, int qp ) ++double row_bits_so_far( x264_t *h, int y ) + { + int i; + double bits = 0; + for( i = 0; i <= y; i++ ) + bits += h->fdec->i_row_bits[i]; ++ return bits; ++} ++ ++double predict_row_size_sum( x264_t *h, int y, int qp ) ++{ ++ int i; ++ double bits = row_bits_so_far(h, y); + for( i = y+1; i < h->sps->i_mb_height; i++ ) + bits += predict_row_size( h, i, qp ); + return bits; + } + ++ + void x264_ratecontrol_mb( x264_t *h, int bits ) + { + x264_ratecontrol_t *rc = h->rc; +@@ -873,7 +893,7 @@ void x264_ratecontrol_mb( x264_t *h, int bits ) + rc->qpa_rc += rc->qpm; + rc->qpa_aq += h->mb.i_qp; + +- if( h->mb.i_mb_x != h->sps->i_mb_width - 1 || !rc->b_vbv || rc->b_2pass ) ++ if( h->mb.i_mb_x != h->sps->i_mb_width - 1 || !rc->b_vbv) return; - + + h->fdec->i_row_qp[y] = rc->qpm; +@@ -883,9 +903,13 @@ void x264_ratecontrol_mb( x264_t *h, int bits ) + /* B-frames shouldn't use lower QP than their reference frames */ + if( y < h->sps->i_mb_height-1 ) + { +- rc->qpm = X264_MAX( rc->qp, +- X264_MIN( h->fref0[0]->i_row_qp[y+1], +- h->fref1[0]->i_row_qp[y+1] )); ++ int i_estimated; ++ int avg_qp = X264_MAX(h->fref0[0]->i_row_qp[y+1], h->fref1[0]->i_row_qp[y+1]) ++ + rc->pb_offset * ((h->fenc->i_type == X264_TYPE_BREF) ? 0.5 : 1); ++ rc->qpm = X264_MIN(X264_MAX( rc->qp, avg_qp), 51); //avg_qp could go higher than 51 due to pb_offset ++ i_estimated = row_bits_so_far(h, y); //FIXME: compute full estimated size ++ if (i_estimated > h->rc->frame_size_planned) ++ x264_frame_size_estimated_set(h, i_estimated); + } + } + else +@@ -901,26 +925,49 @@ 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; ++ float rc_tol = 1; ++ float headroom = 0; ++ ++ /* 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. */ ++ if(row_bits_so_far(h,y) < 0.05 * rc->frame_size_planned) ++ { ++ return; ++ } ++ ++ headroom = buffer_left_planned/rc->buffer_size; ++ if(h->sh.i_type != SLICE_TYPE_I) ++ headroom /= 2; ++ rc_tol += headroom; + + if( !rc->b_vbv_min_rate ) + i_qp_min = X264_MAX( i_qp_min, h->sh.i_qp ); + + while( rc->qpm < i_qp_max +- && (b1 > rc->frame_size_planned * 1.15 ++ && (b1 > rc->frame_size_planned * rc_tol + || (rc->buffer_fill - b1 < buffer_left_planned * 0.5))) + { + rc->qpm ++; + b1 = predict_row_size_sum( h, y, rc->qpm ); + } + ++ /* avoid VBV underflow */ ++ while( (rc->qpm < h->param.rc.i_qp_max) ++ && (rc->buffer_fill - b1 < rc->buffer_size * 0.005)) ++ { ++ rc->qpm ++; ++ b1 = predict_row_size_sum( h, y, rc->qpm ); ++ } ++ + while( rc->qpm > i_qp_min +- && buffer_left_planned > rc->buffer_size * 0.4 ++ && ((buffer_left_planned > rc->buffer_size * 0.4) || rc->qpm > h->fdec->i_row_qp[0]) + && ((b1 < rc->frame_size_planned * 0.8 && rc->qpm <= prev_row_qp) + || b1 < (rc->buffer_fill - rc->buffer_size + rc->buffer_rate) * 1.1) ) + { + rc->qpm --; + b1 = predict_row_size_sum( h, y, rc->qpm ); + } ++ x264_frame_size_estimated_set(h, b1); + } + } + } +@@ -1249,7 +1296,7 @@ static void update_vbv( x264_t *h, int bits ) + return; + rct->buffer_fill_final += rct->buffer_rate - bits; - if( rct->buffer_fill_final < 0 && !rct->b_2pass ) + if( rct->buffer_fill_final < 0 ) x264_log( h, X264_LOG_WARNING, "VBV underflow (%.0f bits)\n", rct->buffer_fill_final ); rct->buffer_fill_final = x264_clip3f( rct->buffer_fill_final, 0, rct->buffer_size ); } -@@ -1325,6 +1326,22 @@ +@@ -1269,6 +1316,7 @@ static void update_vbv_plan( x264_t *h ) + double bits = t->rc->frame_size_planned; + if( !t->b_thread_active ) + continue; ++ bits = X264_MAX(bits, x264_frame_size_estimated_get(t)); + rcc->buffer_fill += rcc->buffer_rate - bits; + rcc->buffer_fill = x264_clip3( rcc->buffer_fill, 0, rcc->buffer_size ); + } +@@ -1405,6 +1453,7 @@ static float rate_estimate_qscale( x264_t *h ) + q += rcc->pb_offset; + + rcc->frame_size_planned = predict_size( rcc->pred_b_from_p, q, h->fref1[h->i_ref1-1]->i_satd ); ++ x264_frame_size_estimated_set(h, rcc->frame_size_planned); + rcc->last_satd = 0; + return qp2qscale(q); + } +@@ -1425,6 +1474,24 @@ static float rate_estimate_qscale( x264_t *h ) double w = x264_clip3f( time*100, 0.0, 1.0 ); q *= pow( (double)total_bits / rcc->expected_bits_sum, w ); } @@ -27,27 +254,44 @@ Index: encoder/ratecontrol.c + { + double expected_size = qscale2bits(&rce, q); + double expected_vbv = rcc->buffer_fill + rcc->buffer_rate - expected_size; -+ if( (expected_vbv < rcc->buffer_size*.4) && (expected_vbv < rce.expected_vbv) ) ++ double expected_fullness = rce.expected_vbv / rcc->buffer_size; ++ double qmax = q*(2 - expected_fullness); ++ double size_constraint = 1 + expected_fullness; ++ if (expected_fullness < .05) ++ qmax = lmax; ++ qmax = X264_MIN(qmax, lmax); ++ while( (expected_vbv < rce.expected_vbv/size_constraint) && (q < qmax) ) + { -+ double qmax = (expected_vbv < rcc->buffer_size*.15) ? lmax : q*1.5; -+ double size_constraint = 1 + rce.expected_vbv/rcc->buffer_size; -+ while( (expected_vbv < rce.expected_vbv/size_constraint) && (q < qmax) ) -+ { -+ q *= 1.05; -+ expected_size = qscale2bits(&rce, q); -+ expected_vbv = rcc->buffer_fill + rcc->buffer_rate - expected_size; -+ } ++ q *= 1.05; ++ expected_size = qscale2bits(&rce, q); ++ expected_vbv = rcc->buffer_fill + rcc->buffer_rate - expected_size; + } ++ rcc->last_satd = x264_rc_analyse_slice( h ); + } q = x264_clip3f( q, lmin, lmax ); } else /* 1pass ABR */ -@@ -1455,6 +1472,137 @@ +@@ -1509,10 +1576,14 @@ static float rate_estimate_qscale( x264_t *h ) + rcc->last_qscale_for[pict_type] = + rcc->last_qscale = q; + +- if( !rcc->b_2pass && h->fenc->i_frame == 0 ) ++ if( !(rcc->b_2pass && !rcc->b_vbv) && h->fenc->i_frame == 0 ) + rcc->last_qscale_for[SLICE_TYPE_P] = q; + +- rcc->frame_size_planned = predict_size( &rcc->pred[h->sh.i_type], q, rcc->last_satd ); ++ if( rcc->b_2pass && rcc->b_vbv) ++ rcc->frame_size_planned = qscale2bits(&rce, q); ++ else ++ rcc->frame_size_planned = predict_size( &rcc->pred[h->sh.i_type], q, rcc->last_satd ); ++ x264_frame_size_estimated_set(h, rcc->frame_size_planned); + return q; + } + } +@@ -1555,6 +1626,134 @@ void x264_thread_sync_ratecontrol( x264_t *cur, x264_t *prev, x264_t *next ) /* the rest of the variables are either constant or thread-local */ } - -+FILE *fh_vbv; -+ + +static int find_underflow( x264_t *h, double *fills, int *t0, int *t1, int over ) +{ + /* find an interval ending on an overflow or underflow (depending on whether @@ -78,17 +322,23 @@ Index: encoder/ratecontrol.c + return start>=0 && end>=0; +} + -+static void fix_underflow( x264_t *h, int t0, int t1, double adjustment, double qscale_min, double qscale_max) ++static int fix_underflow( x264_t *h, int t0, int t1, double adjustment, double qscale_min, double qscale_max) +{ + x264_ratecontrol_t *rcc = h->rc; -+ double qscale_new; ++ double qscale_orig, qscale_new; + int i; ++ int adjusted = 0; + if(t0 > 0) + t0++; + for(i=t0; i<=t1; i++) { -+ qscale_new = rcc->entry[i].new_qscale *= adjustment; -+ rcc->entry[i].new_qscale = x264_clip3f(qscale_new, qscale_min, qscale_max); ++ qscale_orig = rcc->entry[i].new_qscale; ++ qscale_orig = x264_clip3f(qscale_orig, qscale_min, qscale_max); ++ qscale_new = qscale_orig * adjustment; ++ qscale_new = x264_clip3f(qscale_new, qscale_min, qscale_max); ++ rcc->entry[i].new_qscale = qscale_new; ++ adjusted = adjusted || (qscale_new != qscale_orig); + } ++ return adjusted; +} + +static double count_expected_bits( x264_t *h ) @@ -105,19 +355,6 @@ Index: encoder/ratecontrol.c + return expected_bits; +} + -+static void debug_dump_vbv( x264_t *h ) -+{ -+ x264_ratecontrol_t *rcc = h->rc; -+ double fill = rcc->buffer_size * h->param.rc.f_vbv_buffer_init; -+ int i; -+ for(i=0; i<rcc->num_entries; i++) -+ { -+ fill += rcc->buffer_rate - qscale2bits(&rcc->entry[i], rcc->entry[i].new_qscale); -+ fill = x264_clip3f(fill, rcc->buffer_size*-.5, rcc->buffer_size); -+ fprintf(fh_vbv, "%d %.0f\n", i, fill); -+ } -+} -+ +static void vbv_pass2( x264_t *h ) +{ + /* foreach interval of buffer_full .. underflow @@ -137,6 +374,7 @@ Index: encoder/ratecontrol.c + double qscale_min = qp2qscale(h->param.rc.i_qp_min); + double qscale_max = qp2qscale(h->param.rc.i_qp_max); + int iterations = 0; ++ int adj_min, adj_max; + + fills++; + @@ -150,9 +388,10 @@ Index: encoder/ratecontrol.c + fills[-1] = rcc->buffer_size * h->param.rc.f_vbv_buffer_init; + t0 = 0; + //fix overflows -+ while(find_underflow(h, fills, &t0, &t1, 1)) ++ adj_min = 1; ++ while(adj_min && find_underflow(h, fills, &t0, &t1, 1)) + { -+ fix_underflow(h, t0, t1, adjustment, qscale_min, qscale_max); ++ adj_min = fix_underflow(h, t0, t1, adjustment, qscale_min, qscale_max); + t0 = t1; + } + } @@ -160,14 +399,18 @@ Index: encoder/ratecontrol.c + fills[-1] = rcc->buffer_size * (1. - h->param.rc.f_vbv_buffer_init); + t0 = 0; + //fix underflows - should be done after overflow, as we'd better undersize target than underflowing VBV -+ while(find_underflow(h, fills, &t0, &t1, 0)) ++ adj_max = 1; ++ while(adj_max && find_underflow(h, fills, &t0, &t1, 0)) + { -+ fix_underflow(h, t0, t1, 1.001, qscale_min, qscale_max); ++ adj_max = fix_underflow(h, t0, t1, 1.001, qscale_min, qscale_max); + } + + expected_bits = count_expected_bits(h); + } while(expected_bits < .995*all_available_bits && expected_bits > prev_bits); + ++ if (!adj_max) ++ x264_log( h, X264_LOG_WARNING, "vbv-maxrate issue, qpmax or vbv-maxrate too low\n"); ++ + //store expected vbv filling values for tracking when encoding + for(i=0; i<rcc->num_entries; i++) + rcc->entry[i].expected_vbv = rcc->buffer_size - fills[i]; @@ -180,15 +423,15 @@ Index: encoder/ratecontrol.c static int init_pass2( x264_t *h ) { x264_ratecontrol_t *rcc = h->rc; -@@ -1543,7 +1691,6 @@ +@@ -1643,7 +1842,6 @@ static int init_pass2( x264_t *h ) rcc->last_non_b_pict_type = -1; rcc->last_accum_p_norm = 1; rcc->accum_p_norm = 0; - rcc->buffer_fill = rcc->buffer_size * h->param.rc.f_vbv_buffer_init; - + /* find qscale */ for(i=0; i<rcc->num_entries; i++){ -@@ -1580,18 +1727,11 @@ +@@ -1680,18 +1878,11 @@ static int init_pass2( x264_t *h ) /* find expected bits */ for(i=0; i<rcc->num_entries; i++){ ratecontrol_entry_t *rce = &rcc->entry[i]; @@ -203,15 +446,15 @@ Index: encoder/ratecontrol.c - rcc->buffer_fill = rcc->buffer_fill_final; + expected_bits += qscale2bits(rce, rce->new_qscale); } - + -//printf("expected:%llu available:%llu factor:%lf avgQ:%lf\n", (uint64_t)expected_bits, all_available_bits, rate_factor); if(expected_bits > all_available_bits) rate_factor -= step; } - -@@ -1599,6 +1739,10 @@ + +@@ -1699,6 +1890,10 @@ static int init_pass2( x264_t *h ) if(filter_size > 1) x264_free(blurred_qscale); - + + if(rcc->b_vbv) + vbv_pass2(h); + expected_bits = count_expected_bits(h); @@ -219,17 +462,17 @@ Index: encoder/ratecontrol.c if(fabs(expected_bits/all_available_bits - 1.0) > 0.01) { double avgq = 0; -@@ -1606,7 +1750,8 @@ +@@ -1706,7 +1901,8 @@ static int init_pass2( x264_t *h ) avgq += rcc->entry[i].new_qscale; avgq = qscale2qp(avgq / rcc->num_entries); - + - x264_log(h, X264_LOG_WARNING, "Error: 2pass curve failed to converge\n"); + if ((expected_bits > all_available_bits) || (!rcc->b_vbv)) + x264_log(h, X264_LOG_WARNING, "Error: 2pass curve failed to converge\n"); x264_log(h, X264_LOG_WARNING, "target: %.2f kbit/s, expected: %.2f kbit/s, avg QP: %.4f\n", (float)h->param.rc.i_bitrate, expected_bits * rcc->fps / (rcc->num_entries * 1000.), -@@ -1625,7 +1770,7 @@ +@@ -1725,7 +1921,7 @@ static int init_pass2( x264_t *h ) else x264_log(h, X264_LOG_WARNING, "try increasing target bitrate\n"); } @@ -237,3 +480,18 @@ Index: encoder/ratecontrol.c + else if(!(rcc->b_2pass && rcc->b_vbv)) x264_log(h, X264_LOG_WARNING, "internal error\n"); } + +Index: encoder/ratecontrol.h +=================================================================== +old mode 100644 +new mode 100755 +--- encoder/ratecontrol.h ++++ encoder/ratecontrol.h +@@ -35,6 +35,8 @@ int x264_ratecontrol_qp( x264_t * ); + void x264_ratecontrol_end( x264_t *, int bits ); + void x264_ratecontrol_summary( x264_t * ); + void x264_adaptive_quant( x264_t * ); ++void x264_ratecontrol_set_estimated_size( x264_t *, int bits ); ++int x264_ratecontrol_get_estimated_size( x264_t const *); + + #endif |