Commit d4f58d2a authored by François Cartegnie's avatar François Cartegnie 🤞

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

parent 01ff5568
......@@ -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,12 +838,26 @@ 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;
if ( p_sys->b_seekmode )
{
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 )
{
......@@ -849,12 +865,23 @@ static int Demux( demux_t *p_demux )
tk = tk_tmp;
}
}
}
if ( !tk )
{
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;
}
}
......
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