[vlc-commits] demux: mp4: switch to seekmode if non interleaved (fix #11707)
Francois Cartegnie
git at videolan.org
Fri Jul 18 11:19:47 CEST 2014
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Fri Jul 18 15:43:06 2014 +0900| [d4f58d2ac6701c72615c3512d64ba894ec41f6b6] | committer: Francois Cartegnie
demux: mp4: switch to seekmode if non interleaved (fix #11707)
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=d4f58d2ac6701c72615c3512d64ba894ec41f6b6
---
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 e720e1b..929992e 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;
}
}
More information about the vlc-commits
mailing list