summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-03-20 19:48:55 +0100
committerwm4 <wm4@nowhere>2016-03-20 19:51:22 +0100
commit5f1ff78516bb5aaf6c38a5df55959e1165c059ee (patch)
tree129f6bbb1984c2533a207e0dcf3275eb02892575
parentb9c48ca8f33e63549f51edb08bd50cc6cc8badbb (diff)
downloadmpv-5f1ff78516bb5aaf6c38a5df55959e1165c059ee.tar.bz2
mpv-5f1ff78516bb5aaf6c38a5df55959e1165c059ee.tar.xz
command: add cache-speed property
Should reflect I/O speed. This could go into the terminal status line. But I'm not sure how to put it there, since it already uses too much space, so it's not there yet.
-rw-r--r--DOCS/interface-changes.rst1
-rw-r--r--DOCS/man/input.rst5
-rw-r--r--player/command.c18
-rw-r--r--stream/cache.c61
-rw-r--r--stream/stream.h1
5 files changed, 71 insertions, 15 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst
index 4ef60aa312..7dac36eac9 100644
--- a/DOCS/interface-changes.rst
+++ b/DOCS/interface-changes.rst
@@ -24,6 +24,7 @@ Interface changes
"track-list/N/demux-channel-count" instead)
- remove write access to "stream-pos", and change semantics for read access
- Lua scripts now don't suspend mpv by default while script code is run
+ - add "cache-speed" property
--- mpv 0.16.0 ---
- change --audio-channels default to stereo (use --audio-channels=auto to
get the old default)
diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst
index 79a6790e49..63506e7a4e 100644
--- a/DOCS/man/input.rst
+++ b/DOCS/man/input.rst
@@ -1195,6 +1195,11 @@ Property list
``cache-used`` (R)
Total used cache size in KB.
+``cache-speed`` (R)
+ Current I/O read speed between the cache and the lower layer (like network).
+ This is a float (using ``MPV_FORMAT_DOUBLE`` in the client API) and gives
+ the value bytes per seconds over a 1 second window.
+
``cache-idle`` (R)
Returns ``yes`` if the cache is idle, which means the cache is filled as
much as possible, and is currently not reading more data.
diff --git a/player/command.c b/player/command.c
index 068ab7cf5e..9d8528571a 100644
--- a/player/command.c
+++ b/player/command.c
@@ -1430,6 +1430,21 @@ static int mp_property_cache_free(void *ctx, struct m_property *prop,
return property_int_kb_size((size - size_used) / 1024, action, arg);
}
+static int mp_property_cache_speed(void *ctx, struct m_property *prop,
+ int action, void *arg)
+{
+ MPContext *mpctx = ctx;
+ if (!mpctx->demuxer)
+ return M_PROPERTY_UNAVAILABLE;
+
+ double speed = -1;
+ demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_CACHE_SPEED, &speed);
+ if (speed < 0)
+ return M_PROPERTY_UNAVAILABLE;
+
+ return m_property_double_ro(action, arg, speed);
+}
+
static int mp_property_cache_idle(void *ctx, struct m_property *prop,
int action, void *arg)
{
@@ -3606,6 +3621,7 @@ static const struct m_property mp_properties[] = {
{"cache-used", mp_property_cache_used},
{"cache-size", mp_property_cache_size},
{"cache-idle", mp_property_cache_idle},
+ {"cache-speed", mp_property_cache_speed},
{"demuxer-cache-duration", mp_property_demuxer_cache_duration},
{"demuxer-cache-time", mp_property_demuxer_cache_time},
{"demuxer-cache-idle", mp_property_demuxer_cache_idle},
@@ -3820,7 +3836,7 @@ static const char *const *const mp_event_property_change[] = {
E(MPV_EVENT_CHAPTER_CHANGE, "chapter", "chapter-metadata"),
E(MP_EVENT_CACHE_UPDATE, "cache", "cache-free", "cache-used", "cache-idle",
"demuxer-cache-duration", "demuxer-cache-idle", "paused-for-cache",
- "demuxer-cache-time", "cache-buffering-state"),
+ "demuxer-cache-time", "cache-buffering-state", "cache-speed"),
E(MP_EVENT_WIN_RESIZE, "window-scale", "osd-width", "osd-height", "osd-par"),
E(MP_EVENT_WIN_STATE, "window-minimized", "display-names", "display-fps", "fullscreen"),
};
diff --git a/stream/cache.c b/stream/cache.c
index 8421a6fc33..7fd53c7a6a 100644
--- a/stream/cache.c
+++ b/stream/cache.c
@@ -95,6 +95,9 @@ struct priv {
bool idle; // cache thread has stopped reading
int64_t reads; // number of actual read attempts performed
+ int64_t speed_start; // start time (us) for calculating download speed
+ int64_t speed_amount; // bytes read since speed_start
+ double speed;
bool enable_readahead; // actively read beyond read() position
int64_t read_filepos; // client read position (mirrors cache->pos)
@@ -152,6 +155,16 @@ static void cache_drop_contents(struct priv *s)
s->start_pts = MP_NOPTS_VALUE;
}
+static void update_speed(struct priv *s)
+{
+ int64_t now = mp_time_us();
+ s->speed = 0;
+ if (s->speed_start && s->speed_start < now)
+ s->speed = s->speed_amount * 1e6 / (now - s->speed_start);
+ s->speed_amount = 0;
+ s->speed_start = now;
+}
+
// Copy at most dst_size from the cache at the given absolute file position pos.
// Return number of bytes that could actually be read.
// Does not advance the file position, or change anything else.
@@ -190,6 +203,7 @@ static size_t read_buffer(struct priv *s, unsigned char *dst,
static void cache_fill(struct priv *s)
{
int64_t read = s->read_filepos;
+ bool read_attempted = false;
int len = 0;
// drop cache contents only if seeking backward or too much fwd.
@@ -211,14 +225,17 @@ static void cache_fill(struct priv *s)
goto done;
}
- if (!s->enable_readahead && s->read_min <= s->max_filepos) {
- s->idle = true;
- return;
- }
+ if (!s->enable_readahead && s->read_min <= s->max_filepos)
+ goto done;
if (mp_cancel_test(s->cache->cancel))
goto done;
+ if (!s->speed_start) {
+ s->speed_start = mp_time_us();
+ s->speed_amount = 0;
+ }
+
// number of buffer bytes which should be preserved in backwards direction
int64_t back = MPCLAMP(read - s->min_filepos, 0, s->back_size);
@@ -240,11 +257,8 @@ static void cache_fill(struct priv *s)
if (pos >= s->buffer_size)
pos -= s->buffer_size; // wrap-around
- if (space < FILL_LIMIT) {
- s->idle = true;
- s->reads++; // don't stuck main thread
- return;
- }
+ if (space < FILL_LIMIT)
+ goto done;
// limit to end of buffer (without wrapping)
if (pos + space >= s->buffer_size)
@@ -274,15 +288,30 @@ static void cache_fill(struct priv *s)
s->max_filepos += len;
if (pos + len == s->buffer_size)
s->offset += s->buffer_size; // wrap...
+ s->speed_amount += len;
-done:
+ read_attempted = true;
+
+done: ;
+
+ bool prev_eof = s->eof;
s->eof = len <= 0;
- s->idle = s->eof;
- s->reads++;
- if (s->eof) {
+ if (!prev_eof && s->eof) {
s->eof_pos = stream_tell(s->stream);
- MP_TRACE(s, "EOF reached.\n");
+ s->speed_start = 0;
+ MP_VERBOSE(s, "EOF reached.\n");
}
+ s->idle = s->eof || !read_attempted;
+ s->reads++;
+
+ if (s->idle) {
+ update_speed(s);
+ s->speed_start = 0;
+ }
+
+ int64_t now = mp_time_us();
+ if (s->speed_start && s->speed_start + 1000000 <= now)
+ update_speed(s);
pthread_cond_signal(&s->wakeup);
}
@@ -335,6 +364,7 @@ static int resize_cache(struct priv *s, int64_t size)
s->buffer_size = buffer_size;
s->buffer = buffer;
s->idle = false;
+ s->speed_start = 0;
s->eof = false;
//make sure that we won't wait from cache_fill
@@ -380,6 +410,9 @@ static int cache_get_cached_control(stream_t *cache, int cmd, void *arg)
case STREAM_CTRL_GET_CACHE_IDLE:
*(int *)arg = s->idle;
return STREAM_OK;
+ case STREAM_CTRL_GET_CACHE_SPEED:
+ *(double *)arg = s->speed;
+ return STREAM_OK;
case STREAM_CTRL_SET_READAHEAD:
s->enable_readahead = *(int *)arg;
pthread_cond_signal(&s->wakeup);
diff --git a/stream/stream.h b/stream/stream.h
index c75bb495e4..e6964c2020 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -71,6 +71,7 @@ enum stream_ctrl {
STREAM_CTRL_SET_CACHE_SIZE,
STREAM_CTRL_GET_CACHE_FILL,
STREAM_CTRL_GET_CACHE_IDLE,
+ STREAM_CTRL_GET_CACHE_SPEED,
STREAM_CTRL_SET_READAHEAD,
// stream_memory.c