diff --git a/demux/demux.c b/demux/demux.c index 1ce61da396..c6b0ebeb4e 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -533,7 +533,8 @@ static struct demuxer *open_given_type(struct MPOpts *opts, .type = desc->type, .stream = stream, .stream_pts = MP_NOPTS_VALUE, - .seekable = 1, + .seekable = (stream->flags & MP_STREAM_SEEK) == MP_STREAM_SEEK && + stream->end_pos > 0, .accurate_seek = true, .filepos = -1, .opts = opts, @@ -564,6 +565,12 @@ static struct demuxer *open_given_type(struct MPOpts *opts, add_stream_chapters(demuxer); demuxer_sort_chapters(demuxer); demux_info_update(demuxer); + // Pretend we can seek if we can't seek, but there's a cache. + if (!demuxer->seekable && stream->uncached_stream) { + mp_msg(MSGT_DEMUXER, MSGL_WARN, + "File is not seekable, but there's a cache: enabling seeking.\n"); + demuxer->seekable = true; + } return demuxer; } @@ -632,7 +639,7 @@ void demux_flush(demuxer_t *demuxer) int demux_seek(demuxer_t *demuxer, float rel_seek_secs, int flags) { if (!demuxer->seekable) { - mp_tmsg(MSGT_SEEK, MSGL_WARN, "Cannot seek in this file.\n"); + mp_tmsg(MSGT_DEMUXER, MSGL_WARN, "Cannot seek in this file.\n"); return 0; } diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c index 117dcd48ed..b2dfcb2193 100644 --- a/demux/demux_lavf.c +++ b/demux/demux_lavf.c @@ -584,9 +584,12 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check) } } - if (!(priv->avif->flags & AVFMT_NOFILE) && - demuxer->stream->type != STREAMTYPE_AVDEVICE) + if ((priv->avif->flags & AVFMT_NOFILE) || + demuxer->stream->type == STREAMTYPE_AVDEVICE) { + // This might be incorrect. + demuxer->seekable = true; + } else { void *buffer = av_malloc(lavfdopts->buffersize); if (!buffer) return -1; @@ -597,9 +600,7 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check) return -1; } priv->pb->read_seek = mp_read_seek; - priv->pb->seekable = demuxer->stream->end_pos - && (demuxer->stream->flags & MP_STREAM_SEEK) == MP_STREAM_SEEK - ? AVIO_SEEKABLE_NORMAL : 0; + priv->pb->seekable = demuxer->seekable ? AVIO_SEEKABLE_NORMAL : 0; avfc->pb = priv->pb; } diff --git a/demux/demux_libass.c b/demux/demux_libass.c index d98cdbb5a4..73c8b3a5c8 100644 --- a/demux/demux_libass.c +++ b/demux/demux_libass.c @@ -100,6 +100,8 @@ static int d_check_file(struct demuxer *demuxer, enum demux_check check) sh->sub->track = track; sh->codec = "ass"; + demuxer->seekable = true; + return 0; } diff --git a/demux/demux_mf.c b/demux/demux_mf.c index fe8a249320..50888f59ad 100644 --- a/demux/demux_mf.c +++ b/demux/demux_mf.c @@ -210,6 +210,7 @@ static int demux_open_mf(demuxer_t* demuxer, enum demux_check check) mf->sh = sh_video; demuxer->priv=(void*)mf; + demuxer->seekable = true; return 0; diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c index d6948e9979..4181aa4850 100644 --- a/demux/demux_mkv.c +++ b/demux/demux_mkv.c @@ -1844,12 +1844,6 @@ static int demux_mkv_open(demuxer_t *demuxer, enum demux_check check) display_create_tracks(demuxer); - if (s->end_pos == 0) { - demuxer->seekable = 0; - } else { - demuxer->seekable = 1; - } - return 0; } diff --git a/demux/demux_subreader.c b/demux/demux_subreader.c index cc02e61595..21bcf21614 100644 --- a/demux/demux_subreader.c +++ b/demux/demux_subreader.c @@ -1358,6 +1358,8 @@ static int d_open_file(struct demuxer *demuxer, enum demux_check check) add_sub_data(demuxer, sd); subdata_free(sd); + demuxer->seekable = true; + return 0; } diff --git a/mpvcore/player/playloop.c b/mpvcore/player/playloop.c index 9e5aa1e0b4..90525a5ca2 100644 --- a/mpvcore/player/playloop.c +++ b/mpvcore/player/playloop.c @@ -215,6 +215,11 @@ static int seek(MPContext *mpctx, struct seek_params seek, if (!mpctx->demuxer) return -1; + if (!mpctx->demuxer->seekable) { + MP_ERR(mpctx, "Can't seek in this file.\n"); + return -1; + } + if (mpctx->stop_play == AT_END_OF_FILE) mpctx->stop_play = KEEP_PLAYING; bool hr_seek = mpctx->demuxer->accurate_seek && opts->correct_pts;