summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-12-23 22:28:08 +0100
committerMartin Herkt <652892+lachs0r@users.noreply.github.com>2017-12-24 21:45:12 +0100
commitc12d897a3a79fbe4531988a3853b67a5e6042668 (patch)
tree25322760923bffb4bda0746aff2b747826b03287 /player
parentbf111f9c3cccf0a4aefb998558cce67f9b0d6d25 (diff)
downloadmpv-c12d897a3a79fbe4531988a3853b67a5e6042668.tar.bz2
mpv-c12d897a3a79fbe4531988a3853b67a5e6042668.tar.xz
player: allow seeking in cached parts of unseekable streams
Before this change and before the seekable stream cache became a thing, we could possibly seek using the stream cache. But we couldn't know whether the seek would succeed. We knew the available byte range, but could in general not tell whether a demuxer would stay within the range when trying to seek to a specific time position. We preferred to have safe defaults, so seeking in streams that were detected as unseekable were not honored. We allowed overriding this via --force-seekable=yes, in which case it depended on your luck whether the seek would work, or the player crapped its pants. With the demuxer packet cache, we can tell exactly whether a seek will work (at least if there's only 1 seek range). We can just let seeks go through. Everything to allow this is already in place, and this commit just moves around some minor things. Note that the demux_seek() return value was not used before, because low level (i.e. network level) seeks are usually asynchronous, and if they fail, the state is pretty much undefined. We simply repurpose the return value to signal whether cache seeking worked. If it didn't, we can just resume playback normally, because demuxing continues unaffected, and no decoder are reset. This should be particularly helpful to people who for some reason stream data into stdin via streamlink and such.
Diffstat (limited to 'player')
-rw-r--r--player/playloop.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/player/playloop.c b/player/playloop.c
index bf1de03db5..245b49217e 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -253,12 +253,6 @@ static void mp_seek(MPContext *mpctx, struct seek_params seek)
if (!mpctx->demuxer || seek.type == MPSEEK_NONE || seek.amount == MP_NOPTS_VALUE)
return;
- if (!mpctx->demuxer->seekable) {
- MP_ERR(mpctx, "Cannot seek in this file.\n");
- MP_ERR(mpctx, "You can forcibly enable it with '--force-seekable=yes'.\n");
- return;
- }
-
bool hr_seek_very_exact = seek.exact == MPSEEK_VERY_EXACT;
double current_time = get_current_time(mpctx);
if (current_time == MP_NOPTS_VALUE && seek.type == MPSEEK_RELATIVE)
@@ -325,7 +319,16 @@ static void mp_seek(MPContext *mpctx, struct seek_params seek)
demux_flags = (demux_flags | SEEK_HR) & ~SEEK_FORWARD;
}
- demux_seek(mpctx->demuxer, demux_pts, demux_flags);
+ if (!mpctx->demuxer->seekable)
+ demux_flags |= SEEK_CACHED;
+
+ if (!demux_seek(mpctx->demuxer, demux_pts, demux_flags)) {
+ if (!mpctx->demuxer->seekable) {
+ MP_ERR(mpctx, "Cannot seek in this file.\n");
+ MP_ERR(mpctx, "You can force it with '--force-seekable=yes'.\n");
+ }
+ return;
+ }
// Seek external, extra files too:
for (int t = 0; t < mpctx->num_tracks; t++) {