diff options
author | wm4 <wm4@nowhere> | 2018-09-07 23:02:36 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2019-09-19 20:37:04 +0200 |
commit | 5114c69c7f85e7cd38d6928e874c5b44c951be60 (patch) | |
tree | 7aacce1ca7905545cba48c2604071d62bd434135 /demux/demux.c | |
parent | b1c202c12fdd2b53f49e7a9ca5c2f4b84733f511 (diff) | |
download | mpv-5114c69c7f85e7cd38d6928e874c5b44c951be60.tar.bz2 mpv-5114c69c7f85e7cd38d6928e874c5b44c951be60.tar.xz |
demux: change hack for closing subtitle files early
Subtitles (and a few other file types, like playlists) are not streamed,
but fully read on opening. This means keeping the file handle or network
socket open is a waste of resources and could cause other weird
behavior. This is why there's a hack to close them after opening.
Change this hack to make the demuxer itself do this, which is less
weird. (Until recently, demuxer->stream ownership was more complex,
which is why it was done this way.)
There is some evil shit due to a huge ownership/lifetime mess of various
objects. Especially EDL (the currently only nested demuxer case)
requires being careful about mp_cancel and passing down stream pointers.
As one defensive programming measure, stop accessing the "stream"
variable in open_given_type(), even where it would still work. This
includes removing a redundant line of code, and removing the peak call,
which should not be needed anymore, as the remaining demuxers do this
mostly correctly.
Diffstat (limited to 'demux/demux.c')
-rw-r--r-- | demux/demux.c | 41 |
1 files changed, 20 insertions, 21 deletions
diff --git a/demux/demux.c b/demux/demux.c index a7e30e8628..cf94805384 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -2252,20 +2252,23 @@ static void demux_init_cuesheet(struct demuxer *demuxer) } } -static void demux_maybe_replace_stream(struct demuxer *demuxer) +// A demuxer can use this during opening if all data was read from the stream. +// Calling this after opening was completed is not allowed. Also, if opening +// failed, this must not be called (or trying another demuxer would fail). +// Useful so that e.g. subtitles don't keep the file or socket open. +// Replaces it with a dummy stream for dumb reasons. +// If there's ever the situation where we can't allow the demuxer to close +// the stream, this function could ignore the request. +void demux_close_stream(struct demuxer *demuxer) { struct demux_internal *in = demuxer->in; - assert(!in->threading && demuxer == in->d_user); + assert(!in->threading && demuxer == in->d_thread); - if (demuxer->fully_read) { - MP_VERBOSE(demuxer, "assuming demuxer read all data; closing stream\n"); - free_stream(demuxer->stream); - demuxer->stream = open_memory_stream(NULL, 0); // dummy - in->d_thread->stream = demuxer->stream; - - if (demuxer->desc->control) - demuxer->desc->control(in->d_thread, DEMUXER_CTRL_REPLACE_STREAM, NULL); - } + MP_VERBOSE(demuxer, "demuxer read all data; closing stream\n"); + free_stream(demuxer->stream); + demuxer->stream = open_memory_stream(NULL, 0); // dummy + demuxer->stream->cancel = demuxer->cancel; + in->d_user->stream = demuxer->stream; } static void demux_init_ccs(struct demuxer *demuxer, struct demux_opts *opts) @@ -2335,7 +2338,6 @@ static struct demuxer *open_given_type(struct mpv_global *global, .events = DEMUX_EVENT_ALL, .duration = -1, }; - demuxer->seekable = stream->seekable; struct demux_internal *in = demuxer->in = talloc_ptrtype(demuxer, in); *in = (struct demux_internal){ @@ -2370,12 +2372,8 @@ static struct demuxer *open_given_type(struct mpv_global *global, desc->name, d_level(check)); // not for DVD/BD/DVB in particular - if (stream->seekable && (!params || !params->timeline)) - stream_seek(stream, 0); - - // Peek this much data to avoid that stream_read() run by some demuxers - // will flush previous peeked data. - stream_peek(stream, STREAM_BUFFER_SIZE); + if (demuxer->stream->seekable && (!params || !params->timeline)) + stream_seek(demuxer->stream, 0); in->d_thread->params = params; // temporary during open() int ret = demuxer->desc->open(in->d_thread, check); @@ -2414,8 +2412,8 @@ static struct demuxer *open_given_type(struct mpv_global *global, struct demuxer_params params2 = {0}; params2.timeline = tl; struct demuxer *sub = - open_given_type(global, log, &demuxer_desc_timeline, stream, - ¶ms2, DEMUX_CHECK_FORCE); + open_given_type(global, log, &demuxer_desc_timeline, + demuxer->stream, ¶ms2, DEMUX_CHECK_FORCE); if (sub) { demuxer = sub; } else { @@ -2438,6 +2436,7 @@ static const int d_force[] = {DEMUX_CHECK_FORCE, -1}; // If params->does_not_own_stream==false, this does _not_ free the stream if // opening fails. But if it succeeds, a later demux_free() call will free the // stream. +// This may free the stream parameter on success. static struct demuxer *demux_open(struct stream *stream, struct demuxer_params *params, struct mpv_global *global) @@ -2518,7 +2517,7 @@ struct demuxer *demux_open_url(const char *url, struct demuxer *d = demux_open(s, params, global); if (d) { talloc_steal(d->in, priv_cancel); - demux_maybe_replace_stream(d); + assert(d->cancel); } else { params->demuxer_failed = true; free_stream(s); |