vlc/vlc-2.2 | branch: master | Francois Cartegnie <[email protected]> | Fri Jul 18 15:43:06 2014 +0900| [6990c1571e5012f55ac756897c48df53c3a438eb] | committer: Jean-Baptiste Kempf
demux: mp4: switch to seekmode if non interleaved (fix #11707) (cherry picked from commit d4f58d2ac6701c72615c3512d64ba894ec41f6b6) Signed-off-by: Jean-Baptiste Kempf <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc/vlc-2.2.git/?a=commit;h=6990c1571e5012f55ac756897c48df53c3a438eb --- modules/demux/mp4/mp4.c | 45 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/modules/demux/mp4/mp4.c b/modules/demux/mp4/mp4.c index df158af..8a6fd0c 100644 --- a/modules/demux/mp4/mp4.c +++ b/modules/demux/mp4/mp4.c @@ -83,6 +83,7 @@ struct demux_sys_t bool b_fragmented; /* fMP4 */ bool b_seekable; bool b_fastseekable; + bool b_seekmode; bool b_smooth; /* Is it Smooth Streaming? */ bool b_index_probed; @@ -440,6 +441,7 @@ static int Open( vlc_object_t * p_this ) return VLC_EGENERIC; } stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &p_sys->b_fastseekable ); + p_sys->b_seekmode = p_sys->b_fastseekable; /*Set exported functions */ p_demux->pf_demux = Demux; @@ -836,17 +838,32 @@ static int Demux( demux_t *p_demux ) /* Find next track matching contiguous data */ mp4_track_t *tk = NULL; uint64_t i_candidate_pos = UINT64_MAX; + mtime_t i_candidate_dts = INT64_MAX; for( i_track = 0; i_track < p_sys->i_tracks; i_track++ ) { mp4_track_t *tk_tmp = &p_sys->track[i_track]; if( !tk_tmp->b_ok || tk_tmp->b_chapter || !tk_tmp->b_selected || tk_tmp->i_sample >= tk_tmp->i_sample_count ) continue; - uint64_t i_pos = MP4_TrackGetPos( tk_tmp ); - if ( i_pos <= i_candidate_pos ) + if ( p_sys->b_seekmode ) { - i_candidate_pos = i_pos; - tk = tk_tmp; + mtime_t i_dts = MP4_TrackGetDTS( p_demux, tk_tmp ); + if ( i_dts <= i_candidate_dts ) + { + tk = tk_tmp; + i_candidate_dts = i_dts; + i_candidate_pos = MP4_TrackGetPos( tk_tmp ); + } + } + else + { + /* Try to avoid seeking on non fastseekable. Will fail with non interleaved content */ + uint64_t i_pos = MP4_TrackGetPos( tk_tmp ); + if ( i_pos <= i_candidate_pos ) + { + i_candidate_pos = i_pos; + tk = tk_tmp; + } } } @@ -855,6 +872,16 @@ static int Demux( demux_t *p_demux ) msg_Dbg( p_demux, "Could not select track by data position" ); goto end; } + else if ( p_sys->b_seekmode ) + { + if( stream_Seek( p_demux->s, i_candidate_pos ) ) + { + msg_Warn( p_demux, "track[0x%x] will be disabled (eof?)", + tk->i_track_ID ); + MP4_TrackUnselect( p_demux, tk ); + goto end; + } + } #if 0 msg_Dbg( p_demux, "tk(%i)=%"PRId64" mv=%"PRId64" pos=%"PRIu64, i_track, @@ -933,7 +960,15 @@ end: if ( !tk->b_ok || !tk->b_selected || (tk->fmt.i_cat != AUDIO_ES && tk->fmt.i_cat != VIDEO_ES) ) continue; - p_sys->i_pcr = __MIN( MP4_TrackGetDTS( p_demux, tk ), p_sys->i_pcr ); + + mtime_t i_dts = MP4_TrackGetDTS( p_demux, tk ); + if ( !p_sys->b_seekmode && i_dts > p_sys->i_pcr + 2*CLOCK_FREQ ) + { + msg_Dbg( p_demux, "that media doesn't look interleaved, will need to seek"); + p_sys->b_seekmode = true; + } + + p_sys->i_pcr = __MIN( i_dts, p_sys->i_pcr ); p_sys->i_time = p_sys->i_pcr * p_sys->i_timescale / CLOCK_FREQ; } } _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
