diff --git a/encoder/encoder.c b/encoder/encoder.c index b359e3f..0aca87c 100644 --- a/encoder/encoder.c +++ b/encoder/encoder.c @@ -673,7 +673,7 @@ x264_t *x264_encoder_open ( x264_param_t *param ) x264_reduce_fraction( &h->param.i_fps_num, &h->param.i_fps_den ); /* Init x264_t */ - h->i_frame = 0; + h->i_frame = -1; h->i_frame_num = 0; h->i_idr_pic_id = 0; @@ -1038,9 +1038,6 @@ static inline void x264_reference_update( x264_t *h ) { int i; - if( h->fdec->i_frame >= 0 ) - h->i_frame++; - if( !h->fdec->b_kept_as_ref ) { if( h->param.i_threads > 1 ) @@ -1401,6 +1398,7 @@ int x264_encoder_encode( x264_t *h, } } + h->i_frame++; if( h->frames.current[0] == NULL ) { int bframes = 0; @@ -1867,6 +1865,17 @@ void x264_encoder_close ( x264_t *h ) } } + if( h->param.i_threads > 1) + { + x264_t *thread_prev; + + thread_prev = h->thread[ h->i_thread_phase % h->param.i_threads ]; + x264_thread_sync_ratecontrol( h, thread_prev, h ); + x264_thread_sync_ratecontrol( thread_prev, thread_prev, h ); + h->i_frame = thread_prev->i_frame + 1 - h->param.i_threads; + } + h->i_frame++; + /* Slices used and PSNR */ for( i=0; i<5; i++ ) { diff --git a/encoder/ratecontrol.c b/encoder/ratecontrol.c index 2d75471..2a3fe6f 100644 --- a/encoder/ratecontrol.c +++ b/encoder/ratecontrol.c @@ -434,21 +434,19 @@ int x264_ratecontrol_new( x264_t *h ) x264_log( h, X264_LOG_WARNING, "2nd pass has fewer frames than 1st pass (%d vs %d)\n", h->param.i_frame_total, rc->num_entries ); } - if( h->param.i_frame_total > rc->num_entries + h->param.i_bframe ) + if( h->param.i_frame_total > rc->num_entries + h->param.i_bframe*4 + X264_THREAD_MAX ) { x264_log( h, X264_LOG_ERROR, "2nd pass has more frames than 1st pass (%d vs %d)\n", h->param.i_frame_total, rc->num_entries ); return -1; } - /* FIXME: ugly padding because VfW drops delayed B-frames */ - rc->num_entries += h->param.i_bframe; - - rc->entry = (ratecontrol_entry_t*) x264_malloc(rc->num_entries * sizeof(ratecontrol_entry_t)); - memset(rc->entry, 0, rc->num_entries * sizeof(ratecontrol_entry_t)); + /* FIXME: ugly padding because VfW drops delayed B-frames and frames delayed by multithreading */ + rc->entry = (ratecontrol_entry_t*) x264_malloc((rc->num_entries + h->param.i_bframe*4 + X264_THREAD_MAX) * sizeof(ratecontrol_entry_t)); + memset(rc->entry, 0, (rc->num_entries + h->param.i_bframe*4 + X264_THREAD_MAX) * sizeof(ratecontrol_entry_t)); /* init all to skipped p frames */ - for(i=0; inum_entries; i++) + for(i=0; inum_entries + h->param.i_bframe*4 + X264_THREAD_MAX; i++) { ratecontrol_entry_t *rce = &rc->entry[i]; rce->pict_type = SLICE_TYPE_P; @@ -459,7 +457,7 @@ int x264_ratecontrol_new( x264_t *h ) /* read stats */ p = stats_in; - for(i=0; i < rc->num_entries - h->param.i_bframe; i++) + for(i=0; i < rc->num_entries; i++) { ratecontrol_entry_t *rce; int frame_number; @@ -476,7 +474,7 @@ int x264_ratecontrol_new( x264_t *h ) } e = sscanf(p, " in:%d ", &frame_number); - if(frame_number < 0 || frame_number >= rc->num_entries) + if(frame_number < 0 || frame_number >= rc->num_entries + h->param.i_bframe*4 + X264_THREAD_MAX) { x264_log(h, X264_LOG_ERROR, "bad frame number (%d) at stats line %d\n", frame_number, i); return -1; @@ -688,7 +686,7 @@ void x264_ratecontrol_delete( x264_t *h ) if( rc->p_stat_file_out ) { fclose( rc->p_stat_file_out ); - if( h->i_frame >= rc->num_entries - h->param.i_bframe ) + if( h->i_frame >= rc->num_entries ) if( rename( rc->psz_stat_file_tmpname, h->param.rc.psz_stat_out ) != 0 ) { x264_log( h, X264_LOG_ERROR, "failed to rename \"%s\" to \"%s\"\n", @@ -758,7 +756,7 @@ void x264_ratecontrol_start( x264_t *h, int i_force_qp ) if( h->param.rc.b_stat_read ) { int frame = h->fenc->i_frame; - assert( frame >= 0 && frame < rc->num_entries ); + assert( frame >= 0 && frame < rc->num_entries + h->param.i_bframe*4 + X264_THREAD_MAX ); rce = h->rc->rce = &h->rc->entry[frame]; if( h->sh.i_type == SLICE_TYPE_B @@ -976,7 +974,7 @@ int x264_ratecontrol_slice_type( x264_t *h, int frame_num ) x264_ratecontrol_t *rc = h->rc; if( h->param.rc.b_stat_read ) { - if( frame_num >= rc->num_entries ) + if( frame_num >= rc->num_entries + h->param.i_bframe*4 + X264_THREAD_MAX ) { /* We could try to initialize everything required for ABR and * adaptive B-frames, but that would be complicated.