diff options
author | wm4 <wm4@nowhere> | 2017-12-10 05:07:36 +0100 |
---|---|---|
committer | avih <avih@users.noreply.github.com> | 2017-12-10 06:37:49 +0200 |
commit | b782c901809a47dddadc33368d66d88d1bd9e9b9 (patch) | |
tree | f6fba66eff401aebf21c681c4982419667e42eff /demux | |
parent | 451a502c1d15ad2c1b60a141c969be06fa10d152 (diff) |
demux_timeline: disable pointless packet cache for sub-demuxers
It seems like there's nothing stopping from sub-demuxers from keeping
packets in the cache, even if it's completely pointless. The top-most
demuxer (demux_timeline) already takes care of caching, so sub-demuxers
only waste space and time with this.
Add a function that can disable the packet cache even at runtime and
after packets are read. (It's not clear whether it really can happen
that packets are read before demux_timeline gets the sub-demuxers, but
there's no reason to make it too fragile.) Call it on all sub-demuxers.
For this to work, it seems we have to move the code for setting the
seekable_cache flag to before demux_timeline is potentially initialized,
because otherwise the cache would be reenabled if the demuxer triggering
timeline support is a timeline segment itself (e.g. ordered chapters).
Diffstat (limited to 'demux')
-rw-r--r-- | demux/demux.c | 34 | ||||
-rw-r--r-- | demux/demux.h | 2 | ||||
-rw-r--r-- | demux/demux_timeline.c | 7 |
3 files changed, 35 insertions, 8 deletions
diff --git a/demux/demux.c b/demux/demux.c index 80f171b757..5a052fc787 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -520,7 +520,7 @@ static void free_empty_cached_ranges(struct demux_internal *in) for (int n = in->num_ranges - 2; n >= 0; n--) { struct demux_cached_range *range = in->ranges[n]; - if (range->seek_start == MP_NOPTS_VALUE) { + if (range->seek_start == MP_NOPTS_VALUE || !in->seekable_cache) { clear_cached_range(in, range); MP_TARRAY_REMOVE_AT(in->ranges, in->num_ranges, n); } else { @@ -2006,6 +2006,13 @@ static struct demuxer *open_given_type(struct mpv_global *global, 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) { + in->min_secs = MPMAX(in->min_secs, opts->min_secs_cache); + if (seekable < 0) + seekable = 1; + } + in->seekable_cache = seekable == 1; if (!(params && params->disable_timeline)) { struct timeline *tl = timeline_load(global, log, demuxer); if (tl) { @@ -2021,13 +2028,6 @@ static struct demuxer *open_given_type(struct mpv_global *global, } } } - int seekable = opts->seekable_cache; - if (demuxer->is_network || stream->caching) { - in->min_secs = MPMAX(in->min_secs, opts->min_secs_cache); - if (seekable < 0) - seekable = 1; - } - in->seekable_cache = seekable == 1; return demuxer; } @@ -2560,6 +2560,24 @@ int demuxer_add_chapter(demuxer_t *demuxer, char *name, return demuxer->num_chapters - 1; } +void demux_disable_cache(demuxer_t *demuxer) +{ + struct demux_internal *in = demuxer->in; + assert(demuxer == in->d_user); + + pthread_mutex_lock(&in->lock); + if (in->seekable_cache) { + MP_VERBOSE(demuxer, "disabling persistent packet cache\n"); + in->seekable_cache = false; + + // Get rid of potential buffered ranges floating around. + free_empty_cached_ranges(in); + // Get rid of potential old packets in the current range. + prune_old_packets(in); + } + pthread_mutex_unlock(&in->lock); +} + // must be called not locked static void update_cache(struct demux_internal *in) { diff --git a/demux/demux.h b/demux/demux.h index 9224ca3a98..aeabd36e99 100644 --- a/demux/demux.h +++ b/demux/demux.h @@ -298,6 +298,8 @@ int demux_stream_control(demuxer_t *demuxer, int ctrl, void *arg); void demux_changed(demuxer_t *demuxer, int events); void demux_update(demuxer_t *demuxer); +void demux_disable_cache(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_timeline.c b/demux/demux_timeline.c index 288e9f750a..4b9b3124fa 100644 --- a/demux/demux_timeline.c +++ b/demux/demux_timeline.c @@ -170,6 +170,8 @@ static void reopen_lazy_segments(struct demuxer *demuxer) demuxer->stream->cancel, demuxer->global); if (!p->current->d && !demux_cancel_test(demuxer)) MP_ERR(demuxer, "failed to load segment\n"); + if (p->current->d) + demux_disable_cache(p->current->d); associate_streams(demuxer, p->current); } @@ -385,6 +387,11 @@ static int d_open(struct demuxer *demuxer, enum demux_check check) struct timeline_part *part = &p->tl->parts[n]; struct timeline_part *next = &p->tl->parts[n + 1]; + // demux_timeline already does caching, doing it for the sub-demuxers + // would be pointless and wasteful. + if (part->source) + demux_disable_cache(part->source); + struct segment *seg = talloc_ptrtype(p, seg); *seg = (struct segment){ .d = part->source, |