summaryrefslogtreecommitdiffstats
path: root/libhb
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2011-03-13 21:51:14 +0000
committerjstebbins <[email protected]>2011-03-13 21:51:14 +0000
commit9d05a2b4756b2bbffac60eb50fc98e6cb1f4f9f0 (patch)
treea9f15a7749f49a8cb5e610b47343026f0436797b /libhb
parent1e6f3e13c431598ea8338fa19dd0f2504e2b3ef5 (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.c2
-rw-r--r--libhb/hb.h2
-rw-r--r--libhb/render.c20
-rw-r--r--libhb/sync.c2
-rw-r--r--libhb/work.c6
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;
}