diff options
author | jstebbins <[email protected]> | 2011-03-13 21:51:14 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2011-03-13 21:51:14 +0000 |
commit | 9d05a2b4756b2bbffac60eb50fc98e6cb1f4f9f0 (patch) | |
tree | a9f15a7749f49a8cb5e610b47343026f0436797b /libhb | |
parent | 1e6f3e13c431598ea8338fa19dd0f2504e2b3ef5 (diff) |
fix 2 pass cfr x264 crash
An error in interjob->vrate calculation lead to specifying a different
timebase for the 1st and 2nd pass which x264 does not allow. This
improves the interjob->vrate calculation accuracy and also guarantees
the timebase is the same on both passes regardless of the calculations
accuracy.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@3848 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb')
-rw-r--r-- | libhb/encx264.c | 2 | ||||
-rw-r--r-- | libhb/hb.h | 2 | ||||
-rw-r--r-- | libhb/render.c | 20 | ||||
-rw-r--r-- | libhb/sync.c | 2 | ||||
-rw-r--r-- | libhb/work.c | 6 |
5 files changed, 17 insertions, 15 deletions
diff --git a/libhb/encx264.c b/libhb/encx264.c index 67ea45b1a..ed76a1f70 100644 --- a/libhb/encx264.c +++ b/libhb/encx264.c @@ -98,7 +98,7 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job ) param.i_threads = ( hb_get_cpu_count() * 3 / 2 ); param.i_width = job->width; param.i_height = job->height; - if( job->pass == 2 ) + if( job->pass == 2 && job->cfr != 1 ) { hb_interjob_t * interjob = hb_interjob_get( job->h ); param.i_fps_num = interjob->vrate; diff --git a/libhb/hb.h b/libhb/hb.h index 56566f330..5729088cf 100644 --- a/libhb/hb.h +++ b/libhb/hb.h @@ -80,8 +80,8 @@ typedef struct hb_interjob_s { int last_job; /* job->sequence_id & 0xFFFFFF */ int frame_count; /* number of frames counted by sync */ + int out_frame_count; /* number of frames counted by render */ uint64_t total_time; /* real length in 90khz (i.e. / 90000 */ - int render_dropped; /* frames droped by telecine */ int vrate; /* actual measured output vrate from 1st pass */ int vrate_base; /* actual measured output vrate_base from 1st pass */ diff --git a/libhb/render.c b/libhb/render.c index 0af7148c1..0b040fc23 100644 --- a/libhb/render.c +++ b/libhb/render.c @@ -29,7 +29,7 @@ struct hb_work_private_s int chapter_val; int count_frames; // frames output so far double frame_rate; // 90KHz ticks per frame (for CFR/PFR) - double out_last_stop; // where last frame ended (for CFR/PFR) + uint64_t out_last_stop; // where last frame ended (for CFR/PFR) int drops; // frames dropped (for CFR/PFR) int dups; // frames duped (for CFR/PFR) }; @@ -266,6 +266,14 @@ static void adjust_frame_rate( hb_work_private_t *pv, hb_buffer_t **buf_out ) while ( out && out->size > 0 ) { + if ( pv->job->cfr == 0 ) + { + ++pv->count_frames; + pv->out_last_stop = out->stop; + out = out->next; + continue; + } + // this frame has to start where the last one stopped. out->start = pv->out_last_stop; @@ -375,10 +383,7 @@ int renderWork( hb_work_object_t * w, hb_buffer_t ** buf_in, { tail->next = in; *buf_out = head; - if ( job->cfr ) - { - adjust_frame_rate( pv, buf_out ); - } + adjust_frame_rate( pv, buf_out ); } else { *buf_out = in; } @@ -692,7 +697,7 @@ int renderWork( hb_work_object_t * w, hb_buffer_t ** buf_in, } - if ( buf_out && *buf_out && job->cfr ) + if ( buf_out && *buf_out ) { adjust_frame_rate( pv, buf_out ); } @@ -712,7 +717,8 @@ void renderClose( hb_work_object_t * w ) hb_interjob_t * interjob = hb_interjob_get( w->private_data->job->h ); /* Preserve dropped frame count for more accurate framerates in 2nd passes. */ - interjob->render_dropped = pv->dropped_frames; + interjob->out_frame_count = pv->count_frames; + interjob->total_time = pv->out_last_stop; hb_log("render: lost time: %"PRId64" (%i frames)", pv->total_lost_time, pv->dropped_frames); hb_log("render: gained time: %"PRId64" (%i frames) (%"PRId64" not accounted for)", pv->total_gained_time, pv->extended_frames, pv->total_lost_time - pv->total_gained_time); diff --git a/libhb/sync.c b/libhb/sync.c index 9a532a94b..c5071222d 100644 --- a/libhb/sync.c +++ b/libhb/sync.c @@ -218,7 +218,6 @@ void syncVideoClose( hb_work_object_t * w ) hb_interjob_t * interjob = hb_interjob_get( job->h ); interjob->frame_count = pv->common->count_frames; interjob->last_job = job->sequence_id; - interjob->total_time = sync->next_start; } if (sync->drops || sync->dups ) @@ -404,6 +403,7 @@ int syncVideoWork( hb_work_object_t * w, hb_buffer_t ** buf_in, pv->common->first_pts[0] = INT64_MAX - 1; cur->start = sync->next_start; cur->stop = cur->start + 90000. / ((double)job->vrate / (double)job->vrate_base); + sync->next_start += cur->stop - cur->start;; /* Make sure last frame is reflected in frame count */ pv->common->count_frames++; diff --git a/libhb/work.c b/libhb/work.c index 39d926d3c..c8caff7b8 100644 --- a/libhb/work.c +++ b/libhb/work.c @@ -376,17 +376,13 @@ void hb_display_job_info( hb_job_t * job ) /* Corrects framerates when actual duration and frame count numbers are known. */ void correct_framerate( hb_job_t * job ) { - int real_frames; - hb_interjob_t * interjob = hb_interjob_get( job->h ); if( ( job->sequence_id & 0xFFFFFF ) != ( interjob->last_job & 0xFFFFFF) ) return; // Interjob information is for a different encode. // compute actual output vrate from first pass - real_frames = interjob->frame_count - interjob->render_dropped; - - interjob->vrate = job->vrate_base * ( (double)real_frames * 90000 / interjob->total_time ); + interjob->vrate = job->vrate_base * ( (double)interjob->out_frame_count * 90000 / interjob->total_time ); interjob->vrate_base = job->vrate_base; } |