summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvan <[email protected]>2008-06-30 05:01:01 +0000
committervan <[email protected]>2008-06-30 05:01:01 +0000
commit9c5ffcd12957fcf93c4addd7ccc478c85304d047 (patch)
tree077a4794221f0705ddae3f3879e13e0b3ad95a08
parentda80bb8d441e3c12260f2f1bc0fff218112cb42d (diff)
- fix an error in the SCR calculation that would cause an extra frame to be dropped at an SCR discontinuity.
- fix a rounding error in the encx264 init_delay computation that would underestimate the delay for progressive content and cause spurious "init_delay too small" messages. - clean up the sync.c "video time didn't advance" logic and try to make the error mgs more useful for debugging frame duration problems. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@1543 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--libhb/demuxmpeg.c2
-rw-r--r--libhb/encx264.c6
-rw-r--r--libhb/internal.h1
-rw-r--r--libhb/reader.c17
-rw-r--r--libhb/sync.c12
5 files changed, 28 insertions, 10 deletions
diff --git a/libhb/demuxmpeg.c b/libhb/demuxmpeg.c
index 053867931..051f2f605 100644
--- a/libhb/demuxmpeg.c
+++ b/libhb/demuxmpeg.c
@@ -62,7 +62,7 @@ int hb_demux_ps( hb_buffer_t * buf_ps, hb_list_t * list_es, hb_psdemux_t* state
if ( scr_delta > (90*700) || scr_delta < 0 )
{
++state->scr_changes;
- state->scr_offset += scr_delta - 1;
+ state->scr_offset += scr_delta - state->frame_duration;
}
state->last_scr = scr;
}
diff --git a/libhb/encx264.c b/libhb/encx264.c
index da8c7f979..57a2fe281 100644
--- a/libhb/encx264.c
+++ b/libhb/encx264.c
@@ -317,9 +317,11 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
/* 23.976-length frames are 3753.75 ticks long on average but the DVD
creates that average rate by repeating 59.95 fields so the max
- frame size is actually 4504.5 (3 field times) */
+ frame size is actually 4504.5 (3 field times). The field durations
+ are computed based on quantized times (see below) so we need an extra
+ two ticks to account for the rounding. */
if (pv->init_delay == 3753)
- pv->init_delay = 4505;
+ pv->init_delay = 4507;
/* frame rates are not exact in the DVD 90KHz PTS clock (they are
exact in the DVD 27MHz system clock but we never see that) so the
diff --git a/libhb/internal.h b/libhb/internal.h
index 95545acc2..15b016b5c 100644
--- a/libhb/internal.h
+++ b/libhb/internal.h
@@ -108,6 +108,7 @@ typedef struct {
int64_t last_scr; /* unadjusted SCR from most recent pack */
int64_t scr_offset; /* discontinuity correction adjustment */
int scr_changes; /* number of SCR discontinuities */
+ int frame_duration; /* frame duration (in 90KHz ticks) */
} hb_psdemux_t;
int hb_demux_ps( hb_buffer_t * ps_buf, hb_list_t * es_list, hb_psdemux_t * );
diff --git a/libhb/reader.c b/libhb/reader.c
index 9ad2867e5..9ce2a806a 100644
--- a/libhb/reader.c
+++ b/libhb/reader.c
@@ -43,6 +43,21 @@ hb_thread_t * hb_reader_init( hb_job_t * job )
r->die = job->die;
r->sequence = 0;
+ /*
+ * when the scr changes we need to base the timing offset change on the
+ * end of the current video frame otherwise we'll map the first frame
+ * following the change over the current frame & it will be discarded.
+ * Since the PTS only gives the start of the frame we need the average
+ * frame duration to get its end. See the comments in the init_delay
+ * setup in libhb/encx264.c to understand the following code.
+ */
+ r->demux.frame_duration = 90000. * (double)job->vrate_base / (double)job->vrate;
+ if ( r->demux.frame_duration == 3753 )
+ {
+ r->demux.frame_duration = 4506;
+ }
+ r->demux.frame_duration += 3;
+
return hb_thread_init( "reader", ReaderFunc, r,
HB_NORMAL_PRIORITY );
}
@@ -158,7 +173,7 @@ static void ReaderFunc( void * _r )
#define p state.param.working
state.state = HB_STATE_WORKING;
- p.progress = (float)chapter / (float)r->job->chapter_end;
+ p.progress = (double)chapter / (double)r->job->chapter_end;
if( p.progress > 1.0 )
{
p.progress = 1.0;
diff --git a/libhb/sync.c b/libhb/sync.c
index 0b0852bc5..58812a7ad 100644
--- a/libhb/sync.c
+++ b/libhb/sync.c
@@ -346,7 +346,7 @@ static int SyncVideo( hb_work_object_t * w )
* can deal with overlaps of up to a frame time but anything larger
* we handle by dropping frames here.
*/
- if ( (int64_t)( next->start - pv->next_pts ) <= 0 )
+ if ( (int64_t)( next->start - cur->start ) <= 0 )
{
if ( pv->first_drop == 0 )
{
@@ -365,9 +365,9 @@ static int SyncVideo( hb_work_object_t * w )
if ( pv->first_drop )
{
hb_log( "sync: video time didn't advance - dropped %d frames "
- "(delta %d ms, current %lld, next %lld)",
- pv->drop_count, (int)( pv->next_pts - pv->first_drop ) / 90,
- pv->next_pts, pv->first_drop );
+ "(delta %d ms, current %lld, next %lld, dur %d)",
+ pv->drop_count, (int)( cur->start - pv->first_drop ) / 90,
+ cur->start, next->start, (int)( next->start - cur->start ) );
pv->first_drop = 0;
pv->drop_count = 0;
}
@@ -583,8 +583,8 @@ static int SyncVideo( hb_work_object_t * w )
*/
buf_tmp = cur;
pv->cur = cur = hb_fifo_get( job->fifo_raw );
- pv->next_pts = next->start;
- duration = next->start - buf_tmp->start;
+ pv->next_pts = cur->start;
+ duration = cur->start - buf_tmp->start;
if ( duration <= 0 )
{
hb_log( "sync: invalid video duration %lld, start %lld, next %lld",