summaryrefslogtreecommitdiffstats
path: root/demux/demux.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2018-09-07 23:02:36 +0200
committerwm4 <wm4@nowhere>2019-09-19 20:37:04 +0200
commit5114c69c7f85e7cd38d6928e874c5b44c951be60 (patch)
tree7aacce1ca7905545cba48c2604071d62bd434135 /demux/demux.c
parentb1c202c12fdd2b53f49e7a9ca5c2f4b84733f511 (diff)
downloadmpv-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.c41
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,
- &params2, DEMUX_CHECK_FORCE);
+ open_given_type(global, log, &demuxer_desc_timeline,
+ demuxer->stream, &params2, 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);