diff options
author | wm4 <wm4@nowhere> | 2016-08-06 15:47:04 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2016-08-06 15:47:04 +0200 |
commit | d41f0a54b07d855227b63a6b2c4e92794ff7b86f (patch) | |
tree | 45837e7bfd3d55e614c3c38a78c937153c0c491d /player/loadfile.c | |
parent | d4ee5e5a8ad450d16fb2ede212c536e01970ae16 (diff) | |
download | mpv-d41f0a54b07d855227b63a6b2c4e92794ff7b86f.tar.bz2 mpv-d41f0a54b07d855227b63a6b2c4e92794ff7b86f.tar.xz |
player: improve instant track switching
When switching tracks, we normally have the problem that data gets lost
due to readahead buffering. (Which in turn is because we're stubborn and
instruct the demuxers to discard data on unselected streams.) The
demuxer layer has a hack that re-reads discarded buffered data if a
stream is enabled mid-stream, so track switching will seem instant.
A somewhat similar problem is when all tracks of an external files were
disabled - when enabling the first track, we have to seek to the target
position.
Handle these with the same mechanism. Pass the "current time" to the
demuxer's stream switch function, and let the demuxer figure out what to
do. The demuxer will issue a refresh seek (if possible) to update the
new stream, or will issue a "normal" seek if there was no active stream
yet.
One case that changes is when a video/audio stream is enabled on an
external file with only a subtitle stream active, and the demuxer does
not support rrefresh seeks. This is a fuzzy case, because subtitles are
sparse, and the demuxer might have skipped large amounts of data. We
used to seek (and send the subtitle decoder some subtitle packets
twice). This case is sort of obscure and insane, and the fix would be
questionable, so we simply don't care.
Should mostly fix #3392.
Diffstat (limited to 'player/loadfile.c')
-rw-r--r-- | player/loadfile.c | 29 |
1 files changed, 5 insertions, 24 deletions
diff --git a/player/loadfile.c b/player/loadfile.c index 3d04a3720d..75c5499369 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -194,24 +194,10 @@ void reselect_demux_stream(struct MPContext *mpctx, struct track *track) { if (!track->stream) return; - demuxer_select_track(track->demuxer, track->stream, track->selected); - // External files may need an explicit seek to the correct position, if - // they were not implicitly advanced during playback. - if (track->selected && track->demuxer != mpctx->demuxer) { - bool position_ok = false; - for (int n = 0; n < demux_get_num_stream(track->demuxer); n++) { - struct sh_stream *stream = demux_get_stream(track->demuxer, n); - if (stream != track->stream && stream->type != STREAM_SUB) - position_ok |= demux_stream_is_selected(stream); - } - if (!position_ok) { - double pts = get_current_time(mpctx); - if (pts == MP_NOPTS_VALUE) - pts = 0; - pts += get_track_seek_offset(mpctx, track); - demux_seek(track->demuxer, pts, 0); - } - } + double pts = get_current_time(mpctx); + if (pts != MP_NOPTS_VALUE) + pts += get_track_seek_offset(mpctx, track); + demuxer_select_track(track->demuxer, track->stream, pts, track->selected); } // Called from the demuxer thread if a new packet is available. @@ -266,7 +252,7 @@ static struct track *add_stream_track(struct MPContext *mpctx, }; MP_TARRAY_APPEND(mpctx, mpctx->tracks, mpctx->num_tracks, track); - demuxer_select_track(track->demuxer, stream, false); + demuxer_select_track(track->demuxer, stream, MP_NOPTS_VALUE, false); mp_notify(mpctx, MPV_EVENT_TRACKS_CHANGED, NULL); @@ -467,9 +453,6 @@ void mp_switch_track_n(struct MPContext *mpctx, int order, enum stream_type type reselect_demux_stream(mpctx, current); } - if (track && track->demuxer == mpctx->demuxer) - demux_set_enable_refresh_seeks(mpctx->demuxer, true); - mpctx->current_track[order][type] = track; if (track) { @@ -477,8 +460,6 @@ void mp_switch_track_n(struct MPContext *mpctx, int order, enum stream_type type reselect_demux_stream(mpctx, track); } - demux_set_enable_refresh_seeks(mpctx->demuxer, false); - if (type == STREAM_VIDEO && order == 0) { reinit_video_chain(mpctx); } else if (type == STREAM_AUDIO && order == 0) { |