diff --git a/player/audio.c b/player/audio.c index 3a7d26daa7..ab42573fad 100644 --- a/player/audio.c +++ b/player/audio.c @@ -96,7 +96,7 @@ void reinit_audio_chain(struct MPContext *mpctx) { struct MPOpts *opts = mpctx->opts; struct track *track = mpctx->current_track[0][STREAM_AUDIO]; - struct sh_stream *sh = init_demux_stream(mpctx, track); + struct sh_stream *sh = track ? track->stream : NULL; if (!sh) { uninit_player(mpctx, INITIALIZED_AO); goto no_audio; diff --git a/player/core.h b/player/core.h index 49ca1e042c..0c4f50e1d2 100644 --- a/player/core.h +++ b/player/core.h @@ -414,8 +414,6 @@ struct track *mp_track_by_tid(struct MPContext *mpctx, enum stream_type type, int tid); bool timeline_set_part(struct MPContext *mpctx, int i, bool force); double timeline_set_from_time(struct MPContext *mpctx, double pts, bool *need_reset); -struct sh_stream *init_demux_stream(struct MPContext *mpctx, struct track *track); -void reselect_demux_streams(struct MPContext *mpctx); void add_demuxer_tracks(struct MPContext *mpctx, struct demuxer *demuxer); bool mp_remove_track(struct MPContext *mpctx, struct track *track); struct playlist_entry *mp_next_file(struct MPContext *mpctx, int direction, diff --git a/player/loadfile.c b/player/loadfile.c index 657e50f6da..6c89057432 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -60,6 +60,8 @@ #include "command.h" #include "libmpv/client.h" +static void reselect_demux_streams(struct MPContext *mpctx); + static void uninit_sub(struct MPContext *mpctx, int order) { if (mpctx->d_sub[order]) @@ -264,41 +266,41 @@ void update_demuxer_properties(struct MPContext *mpctx) demuxer->events = 0; } +static bool need_init_seek(struct demuxer *demux) +{ + for (int n = 0; n < demux->num_streams; n++) { + struct sh_stream *stream = demux->streams[n]; + // Subtitle streams are not properly interleaved -> force init. seek. + if (stream->type != STREAM_SUB && demux_stream_is_selected(stream)) + return false; + } + return true; +} + // Enable needed streams, disable others. // Note that switching all tracks at once (instead when initializing something) // can be important, because reading from a demuxer stream (e.g. during init) // will implicitly discard interleaved packets from unselected streams. -void reselect_demux_streams(struct MPContext *mpctx) +// Also initializes position for external streams. +static void reselect_demux_streams(struct MPContext *mpctx) { // Note: we assume that all demuxer streams are covered by the track list. for (int t = 0; t < mpctx->num_tracks; t++) { struct track *track = mpctx->tracks[t]; - if (track->demuxer && track->stream) + if (track->demuxer && track->stream) { + bool need_init = track->selected && + mpctx->demuxer != track->demuxer && + need_init_seek(track->demuxer); demuxer_select_track(track->demuxer, track->stream, track->selected); - } -} - -// External demuxers might need a seek to the current playback position. -static void external_track_seek(struct MPContext *mpctx, struct track *track) -{ - if (track && track->demuxer && track->selected && track->is_external) { - for (int t = 0; t < mpctx->num_tracks; t++) { - struct track *other = mpctx->tracks[t]; - if (other->demuxer == track->demuxer && - demux_stream_is_selected(other->stream)) - return; + if (need_init) { + double pts = get_main_demux_pts(mpctx); + if (pts != MP_NOPTS_VALUE) + demux_seek(track->demuxer, pts, SEEK_ABSOLUTE); + } } - double pts = get_main_demux_pts(mpctx); - demux_seek(track->demuxer, pts, SEEK_ABSOLUTE); } } -struct sh_stream *init_demux_stream(struct MPContext *mpctx, struct track *track) -{ - external_track_seek(mpctx, track); - return track ? track->stream : NULL; -} - static struct sh_stream *select_fallback_stream(struct demuxer *d, enum stream_type type, int index) diff --git a/player/misc.c b/player/misc.c index e50ea6b143..3ae4a8ab9a 100644 --- a/player/misc.c +++ b/player/misc.c @@ -100,8 +100,9 @@ double get_main_demux_pts(struct MPContext *mpctx) double main_new_pos = MP_NOPTS_VALUE; if (mpctx->demuxer) { for (int n = 0; n < mpctx->demuxer->num_streams; n++) { - if (main_new_pos == MP_NOPTS_VALUE) - main_new_pos = demux_get_next_pts(mpctx->demuxer->streams[n]); + struct sh_stream *stream = mpctx->demuxer->streams[n]; + if (main_new_pos == MP_NOPTS_VALUE && stream->type != STREAM_SUB) + main_new_pos = demux_get_next_pts(stream); } } return main_new_pos; diff --git a/player/sub.c b/player/sub.c index 2018e6ed7b..2ee928794c 100644 --- a/player/sub.c +++ b/player/sub.c @@ -194,10 +194,7 @@ void reinit_subs(struct MPContext *mpctx, int order) assert(!(mpctx->initialized_flags & init_flag)); - struct sh_stream *sh = init_demux_stream(mpctx, track); - - // No track selected, or lazily added DVD track (will actually be created - // on first sub packet) + struct sh_stream *sh = track ? track->stream : NULL; if (!sh) return; diff --git a/player/video.c b/player/video.c index 40e8e956d3..09fc61fcf0 100644 --- a/player/video.c +++ b/player/video.c @@ -174,7 +174,7 @@ int reinit_video_chain(struct MPContext *mpctx) assert(!(mpctx->initialized_flags & INITIALIZED_VCODEC)); assert(!mpctx->d_video); struct track *track = mpctx->current_track[0][STREAM_VIDEO]; - struct sh_stream *sh = init_demux_stream(mpctx, track); + struct sh_stream *sh = track ? track->stream : NULL; if (!sh) goto no_video;