diff --git a/demux/demux.c b/demux/demux.c index 2d40643a71..ba2678466f 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -1077,14 +1077,22 @@ struct demuxer *demux_open_url(const char *url, struct mpv_global *global) { struct MPOpts *opts = global->opts; - struct stream *s = stream_create(url, STREAM_READ, cancel, global); + struct demuxer_params dummy = {0}; + if (!params) + params = &dummy; + struct stream *s = stream_create(url, STREAM_READ | params->stream_flags, + cancel, global); if (!s) return NULL; - if (!(params && params->disable_cache)) + if (params->allow_capture) + stream_set_capture_file(s, opts->stream_capture); + if (!params->disable_cache) stream_enable_cache(&s, &opts->stream_cache); struct demuxer *d = demux_open(s, params, global); - if (!d) + if (!d) { + params->demuxer_failed = true; free_stream(s); + } return d; } diff --git a/demux/demux.h b/demux/demux.h index 09b49bbf97..22c7323ef1 100644 --- a/demux/demux.h +++ b/demux/demux.h @@ -169,7 +169,12 @@ struct demuxer_params { int matroska_wanted_segment; bool *matroska_was_valid; bool expect_subtitle; - bool disable_cache; // demux_open_url() only + // -- demux_open_url() only + int stream_flags; + bool allow_capture; + bool disable_cache; + // result + bool demuxer_failed; }; typedef struct demuxer { diff --git a/player/loadfile.c b/player/loadfile.c index 1a6dccd3e4..59b8924948 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -916,55 +916,30 @@ static void load_per_file_options(m_config_t *conf, } } -struct stream_open_args { - struct mp_cancel *cancel; - struct mpv_global *global; // contains copy of global options - char *filename; - int stream_flags; - struct stream *stream; // result -}; - -static void open_stream_thread(void *pctx) -{ - struct stream_open_args *args = pctx; - args->stream = stream_create(args->filename, args->stream_flags, - args->cancel, args->global); -} - -static struct stream *open_stream_reentrant(struct MPContext *mpctx, - char *filename, int stream_flags) -{ - struct stream_open_args args = { - .cancel = mpctx->playback_abort, - .global = create_sub_global(mpctx), - .filename = filename, - .stream_flags = stream_flags, - }; - mpctx_run_reentrant(mpctx, open_stream_thread, &args); - if (args.stream) { - talloc_steal(args.stream, args.global); - } else { - talloc_free(args.global); - } - return args.stream; -} - struct demux_open_args { - struct stream *stream; + int stream_flags; + char *url; struct mpv_global *global; + struct mp_cancel *cancel; struct mp_log *log; // results struct demuxer *demux; struct timeline *tl; + int err; }; static void open_demux_thread(void *pctx) { struct demux_open_args *args = pctx; - struct stream *s = args->stream; struct mpv_global *global = args->global; - struct demuxer_params p = {.force_format = global->opts->demuxer_name}; - args->demux = demux_open(s, &p, global); + struct demuxer_params p = { + .force_format = global->opts->demuxer_name, + .allow_capture = true, + .stream_flags = args->stream_flags, + }; + args->demux = demux_open_url(args->url, &p, args->cancel, global); + if (!args->demux && p.demuxer_failed) + args->err = MPV_ERROR_UNKNOWN_FORMAT; if (args->demux) args->tl = timeline_load(global, args->log, args->demux); } @@ -973,17 +948,23 @@ static void open_demux_reentrant(struct MPContext *mpctx) { struct demux_open_args args = { .global = create_sub_global(mpctx), - .stream = mpctx->stream, + .cancel = mpctx->playback_abort, .log = mpctx->log, + .stream_flags = mpctx->playing->stream_flags, + .url = talloc_strdup(NULL, mpctx->stream_open_filename), }; + if (mpctx->opts->load_unsafe_playlists) + args.stream_flags = 0; mpctx_run_reentrant(mpctx, open_demux_thread, &args); if (args.demux) { talloc_steal(args.demux, args.global); mpctx->master_demuxer = args.demux; mpctx->tl = args.tl; } else { + mpctx->error_playing = args.err; talloc_free(args.global); } + talloc_free(args.url); } static void load_timeline(struct MPContext *mpctx) @@ -1093,29 +1074,9 @@ reopen_file: goto terminate_playback; } - int stream_flags = STREAM_READ; - if (!opts->load_unsafe_playlists) - stream_flags |= mpctx->playing->stream_flags; - mpctx->stream = open_stream_reentrant(mpctx, mpctx->stream_open_filename, - stream_flags); - if (!mpctx->stream) - goto terminate_playback; - - stream_enable_cache(&mpctx->stream, &opts->stream_cache); - - mp_notify(mpctx, MP_EVENT_CHANGE_ALL, NULL); - mp_process_input(mpctx); - if (mpctx->stop_play) - goto terminate_playback; - - stream_set_capture_file(mpctx->stream, opts->stream_capture); - open_demux_reentrant(mpctx); - if (!mpctx->master_demuxer) { - MP_ERR(mpctx, "Failed to recognize file format.\n"); - mpctx->error_playing = MPV_ERROR_UNKNOWN_FORMAT; + if (!mpctx->master_demuxer) goto terminate_playback; - } mpctx->demuxer = mpctx->master_demuxer; load_timeline(mpctx); @@ -1257,8 +1218,6 @@ terminate_playback: mp_cancel_trigger(mpctx->playback_abort); - MP_INFO(mpctx, "\n"); - // time to uninit all, except global stuff: uninit_audio_chain(mpctx); uninit_video_chain(mpctx); @@ -1316,6 +1275,10 @@ terminate_playback: }; mp_notify(mpctx, MPV_EVENT_END_FILE, &end_event); + if (mpctx->error_playing == MPV_ERROR_UNKNOWN_FORMAT) + MP_ERR(mpctx, "Failed to recognize file format.\n"); + MP_INFO(mpctx, "\n"); + if (mpctx->playing) playlist_entry_unref(mpctx->playing); mpctx->playing = NULL;