Commit 6990c157 authored by Francois Cartegnie's avatar Francois Cartegnie Committed by Jean-Baptiste Kempf

demux: mp4: switch to seekmode if non interleaved (fix #11707)

(cherry picked from commit d4f58d2ac6701c72615c3512d64ba894ec41f6b6)
Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent 97a2bee1
...@@ -83,6 +83,7 @@ struct demux_sys_t ...@@ -83,6 +83,7 @@ struct demux_sys_t
bool b_fragmented; /* fMP4 */ bool b_fragmented; /* fMP4 */
bool b_seekable; bool b_seekable;
bool b_fastseekable; bool b_fastseekable;
bool b_seekmode;
bool b_smooth; /* Is it Smooth Streaming? */ bool b_smooth; /* Is it Smooth Streaming? */
bool b_index_probed; bool b_index_probed;
...@@ -440,6 +441,7 @@ static int Open( vlc_object_t * p_this ) ...@@ -440,6 +441,7 @@ static int Open( vlc_object_t * p_this )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &p_sys->b_fastseekable ); stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &p_sys->b_fastseekable );
p_sys->b_seekmode = p_sys->b_fastseekable;
/*Set exported functions */ /*Set exported functions */
p_demux->pf_demux = Demux; p_demux->pf_demux = Demux;
...@@ -836,17 +838,32 @@ static int Demux( demux_t *p_demux ) ...@@ -836,17 +838,32 @@ static int Demux( demux_t *p_demux )
/* Find next track matching contiguous data */ /* Find next track matching contiguous data */
mp4_track_t *tk = NULL; mp4_track_t *tk = NULL;
uint64_t i_candidate_pos = UINT64_MAX; 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++ ) for( i_track = 0; i_track < p_sys->i_tracks; i_track++ )
{ {
mp4_track_t *tk_tmp = &p_sys->track[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 ) if( !tk_tmp->b_ok || tk_tmp->b_chapter || !tk_tmp->b_selected || tk_tmp->i_sample >= tk_tmp->i_sample_count )
continue; continue;
uint64_t i_pos = MP4_TrackGetPos( tk_tmp ); if ( p_sys->b_seekmode )
if ( i_pos <= i_candidate_pos )
{ {
i_candidate_pos = i_pos; mtime_t i_dts = MP4_TrackGetDTS( p_demux, tk_tmp );
tk = 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 ) ...@@ -855,6 +872,16 @@ static int Demux( demux_t *p_demux )
msg_Dbg( p_demux, "Could not select track by data position" ); msg_Dbg( p_demux, "Could not select track by data position" );
goto end; 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 #if 0
msg_Dbg( p_demux, "tk(%i)=%"PRId64" mv=%"PRId64" pos=%"PRIu64, i_track, msg_Dbg( p_demux, "tk(%i)=%"PRId64" mv=%"PRId64" pos=%"PRIu64, i_track,
...@@ -933,7 +960,15 @@ end: ...@@ -933,7 +960,15 @@ end:
if ( !tk->b_ok || !tk->b_selected || if ( !tk->b_ok || !tk->b_selected ||
(tk->fmt.i_cat != AUDIO_ES && tk->fmt.i_cat != VIDEO_ES) ) (tk->fmt.i_cat != AUDIO_ES && tk->fmt.i_cat != VIDEO_ES) )
continue; 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; p_sys->i_time = p_sys->i_pcr * p_sys->i_timescale / CLOCK_FREQ;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment