From 559a400ac36e75a8d73ba263fd7fa6736df1c2da Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 31 Aug 2018 12:48:36 +0200 Subject: demux, stream: rip out the classic stream cache The demuxer cache is the only cache now. Might need another change to combat seeking failures in mp4 etc. The only bad thing is the loss of cache-speed, which was sort of nice to have. --- demux/demux.c | 54 ++++++++++++++++++---------------------------- demux/demux.h | 3 +-- demux/demux_disc.c | 7 ++---- demux/demux_mkv_timeline.c | 10 --------- 4 files changed, 24 insertions(+), 50 deletions(-) (limited to 'demux') diff --git a/demux/demux.c b/demux/demux.c index 3e9d897bb2..45f472cfc9 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -86,6 +86,7 @@ const demuxer_desc_t *const demuxer_list[] = { }; struct demux_opts { + int enable_cache; int64_t max_bytes; int64_t max_bytes_bw; double min_secs; @@ -102,6 +103,8 @@ struct demux_opts { const struct m_sub_options demux_conf = { .opts = (const struct m_option[]){ + OPT_CHOICE("cache", enable_cache, 0, + ({"no", 0}, {"auto", -1}, {"yes", 1})), OPT_DOUBLE("demuxer-readahead-secs", min_secs, M_OPT_MIN, .min = 0), // (The MAX_BYTES sizes may not be accurate because the max field is // of double type.) @@ -117,6 +120,7 @@ const struct m_sub_options demux_conf = { }, .size = sizeof(struct demux_opts), .defaults = &(const struct demux_opts){ + .enable_cache = -1, // auto .max_bytes = 150 * 1024 * 1024, .max_bytes_bw = 50 * 1024 * 1024, .min_secs = 1.0, @@ -129,6 +133,8 @@ const struct m_sub_options demux_conf = { struct demux_internal { struct mp_log *log; + struct demux_opts *opts; + // The demuxer runs potentially in another thread, so we keep two demuxer // structs; the real demuxer can access the shadow struct only. struct demuxer *d_thread; // accessed by demuxer impl. (producer) @@ -215,8 +221,6 @@ struct demux_internal { // Transient state. double duration; // Cached state. - bool force_cache_update; - struct stream_cache_info stream_cache_info; int64_t stream_size; // Updated during init only. char *stream_base_filename; @@ -1695,9 +1699,6 @@ static void execute_trackswitch(struct demux_internal *in) if (in->d_thread->desc->control) in->d_thread->desc->control(in->d_thread, DEMUXER_CTRL_SWITCHED_TRACKS, 0); - stream_control(in->d_thread->stream, STREAM_CTRL_SET_READAHEAD, - &(int){any_selected}); - pthread_mutex_lock(&in->lock); } @@ -1746,13 +1747,6 @@ static bool thread_work(struct demux_internal *in) if (read_packet(in)) return true; // read_packet unlocked, so recheck conditions } - if (in->force_cache_update) { - pthread_mutex_unlock(&in->lock); - update_cache(in); - pthread_mutex_lock(&in->lock); - in->force_cache_update = false; - return true; - } return false; } @@ -2276,6 +2270,19 @@ static void fixup_metadata(struct demux_internal *in) } } +// Return whether "heavy" caching on this stream is enabled. By default, this +// corresponds to whether the source stream is considered in the network. The +// only effect should be adjusting display behavior (of cache stats etc.), and +// possibly switching between which set of options influence cache settings. +bool demux_is_network_cached(demuxer_t *demuxer) +{ + struct demux_internal *in = demuxer->in; + bool use_cache = demuxer->is_network; + if (in->opts->enable_cache >= 0) + use_cache = in->opts->enable_cache == 1; + return use_cache; +} + static struct demuxer *open_given_type(struct mpv_global *global, struct mp_log *log, const struct demuxer_desc *desc, @@ -2305,12 +2312,11 @@ static struct demuxer *open_given_type(struct mpv_global *global, .extended_ctrls = stream->extended_ctrls, }; demuxer->seekable = stream->seekable; - if (demuxer->stream->underlying && !demuxer->stream->underlying->seekable) - demuxer->seekable = false; struct demux_internal *in = demuxer->in = talloc_ptrtype(demuxer, in); *in = (struct demux_internal){ .log = demuxer->log, + .opts = opts, .d_thread = talloc(demuxer, struct demuxer), .d_user = demuxer, .min_secs = opts->min_secs, @@ -2371,10 +2377,8 @@ static struct demuxer *open_given_type(struct mpv_global *global, fixup_metadata(in); in->events = DEMUX_EVENT_ALL; demux_update(demuxer); - stream_control(demuxer->stream, STREAM_CTRL_SET_READAHEAD, - &(int){params ? params->initial_readahead : false}); int seekable = opts->seekable_cache; - if (demuxer->is_network || stream->caching) { + if (demux_is_network_cached(demuxer)) { in->min_secs = MPMAX(in->min_secs, opts->min_secs_cache); if (seekable < 0) seekable = 1; @@ -2486,8 +2490,6 @@ struct demuxer *demux_open_url(const char *url, talloc_free(priv_cancel); return NULL; } - if (!params->disable_cache) - stream_enable_cache_defaults(&s); struct demuxer *d = demux_open(s, params, global); if (d) { talloc_steal(d->in, priv_cancel); @@ -3042,15 +3044,12 @@ static void update_cache(struct demux_internal *in) // Don't lock while querying the stream. struct mp_tags *stream_metadata = NULL; - struct stream_cache_info stream_cache_info = {.size = -1}; int64_t stream_size = stream_get_size(stream); stream_control(stream, STREAM_CTRL_GET_METADATA, &stream_metadata); - stream_control(stream, STREAM_CTRL_GET_CACHE_INFO, &stream_cache_info); pthread_mutex_lock(&in->lock); in->stream_size = stream_size; - in->stream_cache_info = stream_cache_info; if (stream_metadata) { for (int n = 0; n < in->num_streams; n++) { struct demux_stream *ds = in->streams[n]->ds; @@ -3065,18 +3064,7 @@ static void update_cache(struct demux_internal *in) // must be called locked 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_info.size >= 0) { - in->force_cache_update = true; - pthread_cond_signal(&in->wakeup); - } - switch (cmd) { - case STREAM_CTRL_GET_CACHE_INFO: - if (in->stream_cache_info.size < 0) - return STREAM_UNSUPPORTED; - *(struct stream_cache_info *)arg = in->stream_cache_info; - return STREAM_OK; case STREAM_CTRL_GET_SIZE: if (in->stream_size < 0) return STREAM_UNSUPPORTED; diff --git a/demux/demux.h b/demux/demux.h index 7d2924000a..5b92e97f49 100644 --- a/demux/demux.h +++ b/demux/demux.h @@ -174,13 +174,11 @@ struct demuxer_params { bool *matroska_was_valid; struct timeline *timeline; bool disable_timeline; - bool initial_readahead; bstr init_fragment; bool skip_lavf_probing; bool does_not_own_stream; // if false, stream is free'd on demux_free() // -- demux_open_url() only int stream_flags; - bool disable_cache; // result bool demuxer_failed; }; @@ -317,6 +315,7 @@ void demux_metadata_changed(demuxer_t *demuxer); void demux_update(demuxer_t *demuxer); void demux_disable_cache(demuxer_t *demuxer); +bool demux_is_network_cached(demuxer_t *demuxer); struct sh_stream *demuxer_stream_by_demuxer_id(struct demuxer *d, enum stream_type t, int id); diff --git a/demux/demux_disc.c b/demux/demux_disc.c index 15ccb2313d..e5c63cea17 100644 --- a/demux/demux_disc.c +++ b/demux/demux_disc.c @@ -292,11 +292,8 @@ static int d_open(demuxer_t *demuxer, enum demux_check check) struct stream *cur = demuxer->stream; const char *sname = ""; - while (cur) { - if (cur->info) - sname = cur->info->name; - cur = cur->underlying; // down the caching chain - } + if (cur->info) + sname = cur->info->name; p->is_cdda = strcmp(sname, "cdda") == 0; p->is_dvd = strcmp(sname, "dvd") == 0 || diff --git a/demux/demux_mkv_timeline.c b/demux/demux_mkv_timeline.c index 32eab2ca8f..69cf26e681 100644 --- a/demux/demux_mkv_timeline.c +++ b/demux/demux_mkv_timeline.c @@ -172,7 +172,6 @@ static bool check_file_seg(struct tl_ctx *ctx, char *filename, int segment) .matroska_wanted_segment = segment, .matroska_was_valid = &was_valid, .disable_timeline = true, - .disable_cache = true, }; struct mp_cancel *cancel = ctx->tl->cancel; if (mp_cancel_test(cancel)) @@ -216,15 +215,6 @@ static bool check_file_seg(struct tl_ctx *ctx, char *filename, int segment) } } - if (stream_wants_cache(d->stream, ctx->opts->stream_cache)) { - demux_free(d); - params.disable_cache = false; - params.matroska_wanted_uids = ctx->uids; // potentially reallocated, same data - d = demux_open_url(filename, ¶ms, cancel, ctx->global); - if (!d) - return false; - } - ctx->sources[i] = d; return true; } -- cgit v1.2.3