summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-11-03 19:21:47 +0100
committerwm4 <wm4@nowhere>2013-11-03 19:21:47 +0100
commita49ab7cc2f9548edcfdd8ad9874050bd41e0b551 (patch)
tree31aaafcaaafd38c732155d0f71dde36842b5a210
parent847cbe9d5d03c77491f3139dde6e163426283ccb (diff)
downloadmpv-a49ab7cc2f9548edcfdd8ad9874050bd41e0b551.tar.bz2
mpv-a49ab7cc2f9548edcfdd8ad9874050bd41e0b551.tar.xz
demux: make determining seek capability generic
Instead of having each demuxer do it (only demux_mkv actually did...), let generic code determine whether the file is seekable. This requires adding exceptions to demuxers where the stream is not seekable, but the demuxer is. Sort-of try to improve handling of unseekable files in the player. Exit early if the file is determined to be unseekable, instead of resetting all decoders and then performing a pointless seek. Add an exception to allow seeking if the file is not seekable, but the stream cache is enabled. Print a warning in this case, because seeking outside the cache (which we can't prevent since the demuxer is not aware of this problem) still messes everything up.
-rw-r--r--demux/demux.c11
-rw-r--r--demux/demux_lavf.c11
-rw-r--r--demux/demux_libass.c2
-rw-r--r--demux/demux_mf.c1
-rw-r--r--demux/demux_mkv.c6
-rw-r--r--demux/demux_subreader.c2
-rw-r--r--mpvcore/player/playloop.c5
7 files changed, 25 insertions, 13 deletions
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;