summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-08-06 15:47:04 +0200
committerwm4 <wm4@nowhere>2016-08-06 15:47:04 +0200
commitd41f0a54b07d855227b63a6b2c4e92794ff7b86f (patch)
tree45837e7bfd3d55e614c3c38a78c937153c0c491d /player
parentd4ee5e5a8ad450d16fb2ede212c536e01970ae16 (diff)
downloadmpv-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')
-rw-r--r--player/loadfile.c29
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) {