diff options
Diffstat (limited to 'demux')
-rw-r--r-- | demux/demux.c | 22 | ||||
-rw-r--r-- | demux/demux.h | 2 | ||||
-rw-r--r-- | demux/demux_lavf.c | 13 |
3 files changed, 34 insertions, 3 deletions
diff --git a/demux/demux.c b/demux/demux.c index cfea29b978..29e13f3344 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -1152,6 +1152,23 @@ static void demux_init_cuesheet(struct demuxer *demuxer) } } +static void demux_maybe_replace_stream(struct demuxer *demuxer) +{ + struct demux_internal *in = demuxer->in; + assert(!in->threading && demuxer == in->d_user); + + 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; + in->d_buffer->stream = demuxer->stream; + + if (demuxer->desc->control) + demuxer->desc->control(in->d_thread, DEMUXER_CTRL_REPLACE_STREAM, NULL); + } +} + static struct demuxer *open_given_type(struct mpv_global *global, struct mp_log *log, const struct demuxer_desc *desc, @@ -1313,6 +1330,7 @@ done: // Convenience function: open the stream, enable the cache (according to params // and global opts.), open the demuxer. // (use free_demuxer_and_stream() to free the underlying stream too) +// Also for some reason may close the opened stream if it's not needed. struct demuxer *demux_open_url(const char *url, struct demuxer_params *params, struct mp_cancel *cancel, @@ -1331,7 +1349,9 @@ struct demuxer *demux_open_url(const char *url, if (!params->disable_cache) stream_enable_cache(&s, &opts->stream_cache); struct demuxer *d = demux_open(s, params, global); - if (!d) { + if (d) { + demux_maybe_replace_stream(d); + } else { params->demuxer_failed = true; free_stream(s); } diff --git a/demux/demux.h b/demux/demux.h index c7d1b8ee1d..9978335cfd 100644 --- a/demux/demux.h +++ b/demux/demux.h @@ -43,6 +43,7 @@ enum demux_ctrl { DEMUXER_CTRL_STREAM_CTRL, DEMUXER_CTRL_GET_READER_STATE, DEMUXER_CTRL_GET_BITRATE_STATS, // double[STREAM_TYPE_COUNT] + DEMUXER_CTRL_REPLACE_STREAM, }; struct demux_ctrl_reader_state { @@ -220,6 +221,7 @@ typedef struct demuxer { // thread-safe, only the demuxer is allowed to access the stream directly. // You can freely use demux_stream_control() to send STREAM_CTRLs, or use // demux_pause() to get exclusive access to the stream. + // Also note that the stream can get replaced if fully_read is set. struct stream *stream; } demuxer_t; diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c index 4b236ee2be..d7dbfe3ff1 100644 --- a/demux/demux_lavf.c +++ b/demux/demux_lavf.c @@ -162,6 +162,7 @@ static const struct format_hack format_hacks[] = { typedef struct lavf_priv { struct stream *stream; + bool own_stream; char *filename; struct format_hack format_hack; AVInputFormat *avif; @@ -290,8 +291,10 @@ static void convert_charset(struct demuxer *demuxer) if (conv.start) data = conv; } - if (data.start) + if (data.start) { priv->stream = open_memory_stream(data.start, data.len); + priv->own_stream = true; + } talloc_free(alloc); } @@ -1068,6 +1071,12 @@ redo: av_seek_frame(priv->avfc, 0, stream_tell(priv->stream), AVSEEK_FLAG_BYTE); return DEMUXER_CTRL_OK; + case DEMUXER_CTRL_REPLACE_STREAM: + if (priv->own_stream) + free_stream(priv->stream); + priv->own_stream = false; + priv->stream = demuxer->stream; + return DEMUXER_CTRL_OK; default: return DEMUXER_CTRL_NOTIMPL; } @@ -1092,7 +1101,7 @@ static void demux_close_lavf(demuxer_t *demuxer) #endif } } - if (priv->stream != demuxer->stream) + if (priv->own_stream) free_stream(priv->stream); talloc_free(priv); demuxer->priv = NULL; |