diff options
author | jstebbins <[email protected]> | 2014-05-13 10:27:36 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2014-05-13 10:27:36 +0000 |
commit | 4f26df992773986e3134907aabca1efe216c7a59 (patch) | |
tree | 6973bd56e6519c7a5836c156bfec2910c356a7f6 /libhb | |
parent | fbef8a53808d5927abb8bdb1a99fac82d9901505 (diff) |
demux: fix problem with widely spaced SCRs
Fixes this bug report https://forum.handbrake.fr/viewtopic.php?f=12&t=30032
Split MPEG demuxer into TS demuxer and PS demuxer to allow using different
PCR/SCR delta tolerance in each scenario.
We were using a PCR/SCR delta tolerance that was a bit of a compromise
between the max allowed by the specification for TS vs PS streams. But
the spec for TS PCR is 100ms and the spec for PS SCR is 700ms, so we
risked false detection of discontinuities in PS. In PS streams that pack
multiple frames into one PES packet, the detection of a discontinuity
causes recalculation of an scr offset which jumps around wildly.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@6183 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb')
-rw-r--r-- | libhb/bd.c | 2 | ||||
-rw-r--r-- | libhb/common.h | 2 | ||||
-rw-r--r-- | libhb/demuxmpeg.c | 22 | ||||
-rw-r--r-- | libhb/stream.c | 6 |
4 files changed, 25 insertions, 7 deletions
diff --git a/libhb/bd.c b/libhb/bd.c index 586a1fa7b..b0b540ea5 100644 --- a/libhb/bd.c +++ b/libhb/bd.c @@ -246,7 +246,7 @@ hb_title_t * hb_bd_title_scan( hb_bd_t * d, int tt, uint64_t min_duration ) hb_log( "bd: scanning title %d", tt ); title = hb_title_init( d->path, tt ); - title->demuxer = HB_MPEG_DEMUXER; + title->demuxer = HB_TS_DEMUXER; title->type = HB_BD_TYPE; title->reg_desc = STR4_TO_UINT32("HDMV"); diff --git a/libhb/common.h b/libhb/common.h index d85c7224b..236f96895 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -897,7 +897,7 @@ struct hb_title_s int rate; int rate_base; int crop[4]; - enum { HB_DVD_DEMUXER, HB_MPEG_DEMUXER, HB_NULL_DEMUXER } demuxer; + enum {HB_DVD_DEMUXER, HB_TS_DEMUXER, HB_PS_DEMUXER, HB_NULL_DEMUXER} demuxer; int detected_interlacing; int pcr_pid; /* PCR PID for TS streams */ int video_id; /* demuxer stream id for video */ diff --git a/libhb/demuxmpeg.c b/libhb/demuxmpeg.c index ded5ad47b..5a51f42c2 100644 --- a/libhb/demuxmpeg.c +++ b/libhb/demuxmpeg.c @@ -102,7 +102,7 @@ void hb_demux_dvd_ps( hb_buffer_t * buf, hb_list_t * list_es, hb_psdemux_t* stat ((uint64_t)(d[pos+2] & 3) << 13) | ((uint64_t)(d[pos+3]) << 5) | (d[pos+4] >> 3); - check_mpeg_scr( state, scr, 300 ); + check_mpeg_scr( state, scr, 700 ); } pos += 9; /* pack_header */ @@ -245,7 +245,8 @@ void hb_demux_dvd_ps( hb_buffer_t * buf, hb_list_t * list_es, hb_psdemux_t* stat // stripped off and buf has all the info gleaned from them: id is set, // start contains the pts (if any), renderOffset contains the dts (if any) // and stop contains the pcr (if it changed). -void hb_demux_mpeg( hb_buffer_t *buf, hb_list_t *list_es, hb_psdemux_t *state ) +void hb_demux_mpeg(hb_buffer_t *buf, hb_list_t *list_es, + hb_psdemux_t *state, int pcr_tolerance) { while ( buf ) { @@ -266,7 +267,7 @@ void hb_demux_mpeg( hb_buffer_t *buf, hb_list_t *list_es, hb_psdemux_t *state ) if ( buf->s.pcr >= 0 ) { // we have a new pcr - check_mpeg_scr( state, buf->s.pcr, 300 ); + check_mpeg_scr( state, buf->s.pcr, pcr_tolerance ); buf->s.pcr = AV_NOPTS_VALUE; // Some streams have consistantly bad PCRs or SCRs // So filter out the offset @@ -337,6 +338,19 @@ void hb_demux_mpeg( hb_buffer_t *buf, hb_list_t *list_es, hb_psdemux_t *state ) } } +void hb_demux_ts(hb_buffer_t *buf, hb_list_t *list_es, hb_psdemux_t *state) +{ + // Distance between PCRs in TS is up to 100ms, but we have seen + // streams that exceed this, so allow up to 300ms. + hb_demux_mpeg(buf, list_es, state, 300); +} + +void hb_demux_ps(hb_buffer_t *buf, hb_list_t *list_es, hb_psdemux_t *state) +{ + // Distance between SCRs in PS is up to 700ms + hb_demux_mpeg(buf, list_es, state, 700); +} + // "null" demuxer (makes a copy of input buf & returns it in list) // used when the reader for some format includes its own demuxer. // for example, ffmpeg. @@ -370,4 +384,4 @@ void hb_demux_null( hb_buffer_t * buf, hb_list_t * list_es, hb_psdemux_t* state } } -const hb_muxer_t hb_demux[] = { hb_demux_dvd_ps, hb_demux_mpeg, hb_demux_null }; +const hb_muxer_t hb_demux[] = { hb_demux_dvd_ps, hb_demux_ts, hb_demux_ps, hb_demux_null }; diff --git a/libhb/stream.c b/libhb/stream.c index b133dda78..7f411a297 100644 --- a/libhb/stream.c +++ b/libhb/stream.c @@ -1070,14 +1070,18 @@ hb_title_t * hb_stream_title_scan(hb_stream_t *stream, hb_title_t * title) title->video_id = get_id( &stream->pes.list[idx] ); title->video_codec = stream->pes.list[idx].codec; title->video_codec_param = stream->pes.list[idx].codec_param; - title->demuxer = HB_MPEG_DEMUXER; if (stream->hb_stream_type == transport) { + title->demuxer = HB_TS_DEMUXER; // make sure we're grabbing the PCR PID update_ts_streams( stream, stream->pmt_info.PCR_PID, 0, -1, P, NULL ); } + else + { + title->demuxer = HB_PS_DEMUXER; + } // IDRs will be search for in hb_stream_duration stream->has_IDRs = 0; |