summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-01-26 13:46:33 +0100
committerwm4 <wm4@nowhere>2015-01-26 13:46:33 +0100
commit00b261135248be957dd14ae9e8ca26430a39fae0 (patch)
tree4bf6d084daca59b6af930b1126d97ea6332c46af
parent792db4eee3173f15eb5003f571509d9eb7c12dcf (diff)
downloadmpv-00b261135248be957dd14ae9e8ca26430a39fae0.tar.bz2
mpv-00b261135248be957dd14ae9e8ca26430a39fae0.tar.xz
command: export more details about file seekability
If a file is unseekable (consider e.g. a http server without resume functionality), but the stream cache is active, the player will enable seeking anyway. Until know, client API user couldn't know that this happens, and it has implications on how well seeking will work. So add a property which exports whether this situation applies. Fixes #1522.
-rw-r--r--DOCS/man/input.rst8
-rw-r--r--demux/demux.c2
-rw-r--r--demux/demux.h3
-rw-r--r--player/command.c10
4 files changed, 22 insertions, 1 deletions
diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst
index 18235ac687..c33629ee68 100644
--- a/DOCS/man/input.rst
+++ b/DOCS/man/input.rst
@@ -1480,6 +1480,14 @@ Property list
``seekable``
Return whether it's generally possible to seek in the current file.
+``partially-seekable``
+ Return ``yes`` if the current file is considered seekable, but only because
+ the cache is active. This means small relative seeks may be fine, but larger
+ seeks may fail anyway. Whether a seek will succeed or not is generally not
+ known in advance.
+
+ If this property returns true, ``seekable`` will also return true.
+
``playback-abort``
Return whether playback is stopped or is to be stopped. (Useful in obscure
situations like during ``on_load`` hook processing, when the user can
diff --git a/demux/demux.c b/demux/demux.c
index 51131dfd4c..e498895aaf 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -758,6 +758,7 @@ static void demux_copy(struct demuxer *dst, struct demuxer *src)
dst->file_contents = src->file_contents;
dst->playlist = src->playlist;
dst->seekable = src->seekable;
+ dst->partially_seekable = src->partially_seekable;
dst->filetype = src->filetype;
dst->ts_resets_possible = src->ts_resets_possible;
dst->rel_seeks = src->rel_seeks;
@@ -905,6 +906,7 @@ static struct demuxer *open_given_type(struct mpv_global *global,
if (!in->d_thread->seekable && stream->uncached_stream) {
mp_verbose(log, "Enabling seeking because stream cache is active.\n");
in->d_thread->seekable = true;
+ in->d_thread->partially_seekable = true;
}
demux_init_cache(demuxer);
demux_changed(in->d_thread, DEMUX_EVENT_ALL);
diff --git a/demux/demux.h b/demux/demux.h
index b53a30c805..e18c013a5b 100644
--- a/demux/demux.h
+++ b/demux/demux.h
@@ -185,7 +185,8 @@ typedef struct demuxer {
int64_t filepos; // input stream current pos.
char *filename; // same as stream->url
enum demuxer_type type;
- int seekable; // flag
+ bool seekable;
+ bool partially_seekable; // implies seekable=true
double start_time;
// File format allows PTS resets (even if the current file is without)
bool ts_resets_possible;
diff --git a/player/command.c b/player/command.c
index 556a0c4308..397e527ec9 100644
--- a/player/command.c
+++ b/player/command.c
@@ -1438,6 +1438,15 @@ static int mp_property_seekable(void *ctx, struct m_property *prop,
return m_property_flag_ro(action, arg, mpctx->demuxer->seekable);
}
+static int mp_property_partially_seekable(void *ctx, struct m_property *prop,
+ int action, void *arg)
+{
+ MPContext *mpctx = ctx;
+ if (!mpctx->demuxer)
+ return M_PROPERTY_UNAVAILABLE;
+ return m_property_flag_ro(action, arg, mpctx->demuxer->partially_seekable);
+}
+
/// Volume (RW)
static int mp_property_volume(void *ctx, struct m_property *prop,
int action, void *arg)
@@ -3294,6 +3303,7 @@ static const struct m_property mp_properties[] = {
{"hr-seek", mp_property_generic_option},
{"clock", mp_property_clock},
{"seekable", mp_property_seekable},
+ {"partially-seekable", mp_property_partially_seekable},
{"idle", mp_property_idle},
{"chapter-list", mp_property_list_chapters},