From 57506b27ed0d567c11bd932cf758318fb3b2079c Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 29 Mar 2016 11:29:52 +0200 Subject: cache: use a single STREAM_CTRL for various cache info Instead of having a separate for each, which also requires separate additional caching in the demuxer. (The demuxer adds an indirection, since STREAM_CTRLs are not thread-safe.) Since this includes the cache speed, this should fix #3003. --- demux/demux.c | 34 ++++++++-------------------------- player/command.c | 48 +++++++++++++++++++++--------------------------- player/misc.c | 19 ++++++++----------- player/osd.c | 12 ++++++------ player/playloop.c | 5 +++-- stream/cache.c | 33 ++++++++++++++------------------- stream/stream.h | 13 +++++++++---- 7 files changed, 69 insertions(+), 95 deletions(-) diff --git a/demux/demux.c b/demux/demux.c index fe23d0ac02..bedc2bf294 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -137,10 +137,8 @@ struct demux_internal { bool force_cache_update; double time_length; struct mp_tags *stream_metadata; + struct stream_cache_info stream_cache_info; int64_t stream_size; - int64_t stream_cache_size; - int64_t stream_cache_fill; - int stream_cache_idle; // Updated during init only. char *stream_base_filename; }; @@ -1407,9 +1405,7 @@ static void update_cache(struct demux_internal *in) // Don't lock while querying the stream. double time_length = -1; struct mp_tags *stream_metadata = NULL; - int64_t stream_cache_size = -1; - int64_t stream_cache_fill = -1; - int stream_cache_idle = -1; + struct stream_cache_info stream_cache_info = {.size = -1}; if (demuxer->desc->control) { demuxer->desc->control(demuxer, DEMUXER_CTRL_GET_TIME_LENGTH, @@ -1418,16 +1414,12 @@ static void update_cache(struct demux_internal *in) int64_t stream_size = stream_get_size(stream); stream_control(stream, STREAM_CTRL_GET_METADATA, &stream_metadata); - stream_control(stream, STREAM_CTRL_GET_CACHE_SIZE, &stream_cache_size); - stream_control(stream, STREAM_CTRL_GET_CACHE_FILL, &stream_cache_fill); - stream_control(stream, STREAM_CTRL_GET_CACHE_IDLE, &stream_cache_idle); + stream_control(stream, STREAM_CTRL_GET_CACHE_INFO, &stream_cache_info); pthread_mutex_lock(&in->lock); in->time_length = time_length; in->stream_size = stream_size; - in->stream_cache_size = stream_cache_size; - in->stream_cache_fill = stream_cache_fill; - in->stream_cache_idle = stream_cache_idle; + in->stream_cache_info = stream_cache_info; if (stream_metadata) { talloc_free(in->stream_metadata); in->stream_metadata = talloc_steal(in, stream_metadata); @@ -1440,26 +1432,16 @@ static void update_cache(struct demux_internal *in) static int cached_stream_control(struct demux_internal *in, int cmd, void *arg) { // If the cache is active, wake up the thread to possibly update cache state. - if (in->stream_cache_size >= 0) { + if (in->stream_cache_info.size >= 0) { in->force_cache_update = true; pthread_cond_signal(&in->wakeup); } switch (cmd) { - case STREAM_CTRL_GET_CACHE_SIZE: - if (in->stream_cache_size < 0) + case STREAM_CTRL_GET_CACHE_INFO: + if (in->stream_cache_info.size < 0) return STREAM_UNSUPPORTED; - *(int64_t *)arg = in->stream_cache_size; - return STREAM_OK; - case STREAM_CTRL_GET_CACHE_FILL: - if (in->stream_cache_fill < 0) - return STREAM_UNSUPPORTED; - *(int64_t *)arg = in->stream_cache_fill; - return STREAM_OK; - case STREAM_CTRL_GET_CACHE_IDLE: - if (in->stream_cache_idle < 0) - return STREAM_UNSUPPORTED; - *(int *)arg = in->stream_cache_idle; + *(struct stream_cache_info *)arg = in->stream_cache_info; return STREAM_OK; case STREAM_CTRL_GET_SIZE: if (in->stream_size < 0) diff --git a/player/command.c b/player/command.c index 8ca22eb946..4f6cb1b0ff 100644 --- a/player/command.c +++ b/player/command.c @@ -1370,11 +1370,11 @@ static int mp_property_cache_size(void *ctx, struct m_property *prop, switch (action) { case M_PROPERTY_GET: case M_PROPERTY_PRINT: { - int64_t size = -1; - demux_stream_control(demuxer, STREAM_CTRL_GET_CACHE_SIZE, &size); - if (size <= 0) + struct stream_cache_info info = {0}; + demux_stream_control(demuxer, STREAM_CTRL_GET_CACHE_INFO, &info); + if (info.size <= 0) break; - return property_int_kb_size(size / 1024, action, arg); + return property_int_kb_size(info.size / 1024, action, arg); } case M_PROPERTY_GET_TYPE: *(struct m_option *)arg = (struct m_option){ @@ -1403,11 +1403,11 @@ static int mp_property_cache_used(void *ctx, struct m_property *prop, if (!mpctx->demuxer) return M_PROPERTY_UNAVAILABLE; - int64_t size = -1; - demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_CACHE_FILL, &size); - if (size < 0) + struct stream_cache_info info = {0}; + demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_CACHE_INFO, &info); + if (info.size <= 0) return M_PROPERTY_UNAVAILABLE; - return property_int_kb_size(size / 1024, action, arg); + return property_int_kb_size(info.fill / 1024, action, arg); } static int mp_property_cache_free(void *ctx, struct m_property *prop, @@ -1417,17 +1417,12 @@ static int mp_property_cache_free(void *ctx, struct m_property *prop, if (!mpctx->demuxer) return M_PROPERTY_UNAVAILABLE; - int64_t size_used = -1; - demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_CACHE_FILL, &size_used); - if (size_used < 0) + struct stream_cache_info info = {0}; + demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_CACHE_INFO, &info); + if (info.size <= 0) return M_PROPERTY_UNAVAILABLE; - int64_t size = -1; - demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_CACHE_SIZE, &size); - if (size <= 0) - return M_PROPERTY_UNAVAILABLE; - - return property_int_kb_size((size - size_used) / 1024, action, arg); + return property_int_kb_size((info.size - info.fill) / 1024, action, arg); } static int mp_property_cache_speed(void *ctx, struct m_property *prop, @@ -1437,29 +1432,28 @@ static int mp_property_cache_speed(void *ctx, struct m_property *prop, if (!mpctx->demuxer) return M_PROPERTY_UNAVAILABLE; - double f_speed = -1; - demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_CACHE_SPEED, &f_speed); - if (f_speed < 0) + struct stream_cache_info info = {0}; + demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_CACHE_INFO, &info); + if (info.size <= 0) return M_PROPERTY_UNAVAILABLE; - int64_t speed = llrint(f_speed); if (action == M_PROPERTY_PRINT) { - *(char **)arg = talloc_strdup_append(format_file_size(speed), "/s"); + *(char **)arg = talloc_strdup_append(format_file_size(info.speed), "/s"); return M_PROPERTY_OK; } - return m_property_int64_ro(action, arg, speed); + return m_property_int64_ro(action, arg, info.speed); } static int mp_property_cache_idle(void *ctx, struct m_property *prop, int action, void *arg) { MPContext *mpctx = ctx; - int idle = -1; + struct stream_cache_info info = {0}; if (mpctx->demuxer) - demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_CACHE_IDLE, &idle); - if (idle < 0) + demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_CACHE_INFO, &info); + if (info.size <= 0) return M_PROPERTY_UNAVAILABLE; - return m_property_flag_ro(action, arg, !!idle); + return m_property_flag_ro(action, arg, info.idle); } static int mp_property_demuxer_cache_duration(void *ctx, struct m_property *prop, diff --git a/player/misc.c b/player/misc.c index d68ad1db3e..f14f5a43e3 100644 --- a/player/misc.c +++ b/player/misc.c @@ -95,23 +95,20 @@ double get_play_end_pts(struct MPContext *mpctx) float mp_get_cache_percent(struct MPContext *mpctx) { - if (mpctx->demuxer) { - int64_t size = -1; - int64_t fill = -1; - demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_CACHE_SIZE, &size); - demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_CACHE_FILL, &fill); - if (size > 0 && fill >= 0) - return fill / (size / 100.0); - } + struct stream_cache_info info = {0}; + if (mpctx->demuxer) + demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_CACHE_INFO, &info); + if (info.size > 0 && info.fill >= 0) + return info.fill / (info.size / 100.0); return -1; } bool mp_get_cache_idle(struct MPContext *mpctx) { - int idle = 0; + struct stream_cache_info info = {0}; if (mpctx->demuxer) - demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_CACHE_IDLE, &idle); - return idle; + demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_CACHE_INFO, &info); + return info.idle; } void update_vo_playback_state(struct MPContext *mpctx) diff --git a/player/osd.c b/player/osd.c index 1baf9fb45e..8c6d8a3af1 100644 --- a/player/osd.c +++ b/player/osd.c @@ -257,9 +257,9 @@ static void print_status(struct MPContext *mpctx) } if (mpctx->demuxer) { - int64_t fill = -1; - demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_CACHE_FILL, &fill); - if (fill >= 0) { + struct stream_cache_info info = {0}; + demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_CACHE_INFO, &info); + if (info.fill >= 0) { saddf(&line, " Cache: "); struct demux_ctrl_reader_state s = {.ts_duration = -1}; @@ -270,10 +270,10 @@ static void print_status(struct MPContext *mpctx) } else { saddf(&line, "%2ds", (int)s.ts_duration); } - if (fill >= 1024 * 1024) { - saddf(&line, "+%lldMB", (long long)(fill / 1024 / 1024)); + if (info.fill >= 1024 * 1024) { + saddf(&line, "+%lldMB", (long long)(info.fill / 1024 / 1024)); } else { - saddf(&line, "+%lldKB", (long long)(fill / 1024)); + saddf(&line, "+%lldKB", (long long)(info.fill / 1024)); } } } diff --git a/player/playloop.c b/player/playloop.c index 63234812d4..fcbb86ac04 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -522,8 +522,9 @@ static void handle_pause_on_low_cache(struct MPContext *mpctx) if (!mpctx->demuxer) return; - int idle = -1; - demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_CACHE_IDLE, &idle); + struct stream_cache_info info = {0}; + demux_stream_control(mpctx->demuxer, STREAM_CTRL_GET_CACHE_INFO, &info); + int idle = info.size > 0 ? info.idle : -1; struct demux_ctrl_reader_state s = {.idle = true, .ts_duration = -1}; demux_control(mpctx->demuxer, DEMUXER_CTRL_GET_READER_STATE, &s); diff --git a/stream/cache.c b/stream/cache.c index 7fd53c7a6a..0ed371806d 100644 --- a/stream/cache.c +++ b/stream/cache.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -401,17 +402,13 @@ static int cache_get_cached_control(stream_t *cache, int cmd, void *arg) { struct priv *s = cache->priv; switch (cmd) { - case STREAM_CTRL_GET_CACHE_SIZE: - *(int64_t *)arg = s->buffer_size - s->back_size; - return STREAM_OK; - case STREAM_CTRL_GET_CACHE_FILL: - *(int64_t *)arg = s->max_filepos - s->read_filepos; - return STREAM_OK; - case STREAM_CTRL_GET_CACHE_IDLE: - *(int *)arg = s->idle; - return STREAM_OK; - case STREAM_CTRL_GET_CACHE_SPEED: - *(double *)arg = s->speed; + case STREAM_CTRL_GET_CACHE_INFO: + *(struct stream_cache_info *)arg = (struct stream_cache_info) { + .size = s->buffer_size - s->back_size, + .fill = s->max_filepos - s->read_filepos, + .idle = s->idle, + .speed = llrint(s->speed), + }; return STREAM_OK; case STREAM_CTRL_SET_READAHEAD: s->enable_readahead = *(int *)arg; @@ -712,17 +709,15 @@ int stream_cache_init(stream_t *cache, stream_t *stream, for (;;) { if (mp_cancel_test(cache->cancel)) return -1; - int64_t fill; - int idle; - if (stream_control(s->cache, STREAM_CTRL_GET_CACHE_FILL, &fill) < 0) - break; - if (stream_control(s->cache, STREAM_CTRL_GET_CACHE_IDLE, &idle) < 0) + struct stream_cache_info info; + if (stream_control(s->cache, STREAM_CTRL_GET_CACHE_INFO, &info) < 0) break; MP_INFO(s, "\rCache fill: %5.2f%% " - "(%" PRId64 " bytes) ", 100.0 * fill / s->buffer_size, fill); - if (fill >= min) + "(%" PRId64 " bytes) ", 100.0 * info.fill / s->buffer_size, + info.fill); + if (info.fill >= min) break; - if (idle) + if (info.idle) break; // file is smaller than prefill size // Wake up if the cache is done reading some data (or on timeout/abort) pthread_mutex_lock(&s->mutex); diff --git a/stream/stream.h b/stream/stream.h index e6964c2020..21e497e563 100644 --- a/stream/stream.h +++ b/stream/stream.h @@ -67,11 +67,8 @@ enum stream_ctrl { STREAM_CTRL_GET_SIZE = 1, // Cache - STREAM_CTRL_GET_CACHE_SIZE, + STREAM_CTRL_GET_CACHE_INFO, 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 @@ -122,6 +119,14 @@ enum stream_ctrl { STREAM_CTRL_SET_CURRENT_TITLE, }; +// for STREAM_CTRL_GET_CACHE_INFO +struct stream_cache_info { + int64_t size; + int64_t fill; + bool idle; + int64_t speed; +}; + struct stream_lang_req { int type; // STREAM_AUDIO, STREAM_SUB int id; -- cgit v1.2.3