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.
This commit is contained in:
wm4 2016-03-20 19:48:55 +01:00
parent b9c48ca8f3
commit 5f1ff78516
5 changed files with 71 additions and 15 deletions

View File

@ -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)

View File

@ -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.

View File

@ -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"),
};

View File

@ -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);

View File

@ -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