mirror of
https://github.com/mpv-player/mpv
synced 2025-05-06 02:00:05 +00:00
player: use demux_open_url() to open main files
Instead of opening a stream and then a demuxer, do both at once with demux_open_url(). This requires some awkward additions to demuxer_params, because there are some weird features associated with opening the main file. E.g. the relatively useless --stream-capture features requires enabling capturing on the stream before the demuxer is opened, but on the other hand shouldn't be done on secondary files like external subtitles. Also relatively bad: since demux_open_url() returns just a demuxer pointer or NULL, additional error reporting is done via demuxer_params. Still, at least conceptually, it's ok, and simpler than before.
This commit is contained in:
parent
525ada8c7a
commit
75b1d5043f
@ -1077,14 +1077,22 @@ struct demuxer *demux_open_url(const char *url,
|
|||||||
struct mpv_global *global)
|
struct mpv_global *global)
|
||||||
{
|
{
|
||||||
struct MPOpts *opts = global->opts;
|
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)
|
if (!s)
|
||||||
return NULL;
|
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);
|
stream_enable_cache(&s, &opts->stream_cache);
|
||||||
struct demuxer *d = demux_open(s, params, global);
|
struct demuxer *d = demux_open(s, params, global);
|
||||||
if (!d)
|
if (!d) {
|
||||||
|
params->demuxer_failed = true;
|
||||||
free_stream(s);
|
free_stream(s);
|
||||||
|
}
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +169,12 @@ struct demuxer_params {
|
|||||||
int matroska_wanted_segment;
|
int matroska_wanted_segment;
|
||||||
bool *matroska_was_valid;
|
bool *matroska_was_valid;
|
||||||
bool expect_subtitle;
|
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 {
|
typedef struct demuxer {
|
||||||
|
@ -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 demux_open_args {
|
||||||
struct stream *stream;
|
int stream_flags;
|
||||||
|
char *url;
|
||||||
struct mpv_global *global;
|
struct mpv_global *global;
|
||||||
|
struct mp_cancel *cancel;
|
||||||
struct mp_log *log;
|
struct mp_log *log;
|
||||||
// results
|
// results
|
||||||
struct demuxer *demux;
|
struct demuxer *demux;
|
||||||
struct timeline *tl;
|
struct timeline *tl;
|
||||||
|
int err;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void open_demux_thread(void *pctx)
|
static void open_demux_thread(void *pctx)
|
||||||
{
|
{
|
||||||
struct demux_open_args *args = pctx;
|
struct demux_open_args *args = pctx;
|
||||||
struct stream *s = args->stream;
|
|
||||||
struct mpv_global *global = args->global;
|
struct mpv_global *global = args->global;
|
||||||
struct demuxer_params p = {.force_format = global->opts->demuxer_name};
|
struct demuxer_params p = {
|
||||||
args->demux = demux_open(s, &p, global);
|
.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)
|
if (args->demux)
|
||||||
args->tl = timeline_load(global, args->log, 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 = {
|
struct demux_open_args args = {
|
||||||
.global = create_sub_global(mpctx),
|
.global = create_sub_global(mpctx),
|
||||||
.stream = mpctx->stream,
|
.cancel = mpctx->playback_abort,
|
||||||
.log = mpctx->log,
|
.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);
|
mpctx_run_reentrant(mpctx, open_demux_thread, &args);
|
||||||
if (args.demux) {
|
if (args.demux) {
|
||||||
talloc_steal(args.demux, args.global);
|
talloc_steal(args.demux, args.global);
|
||||||
mpctx->master_demuxer = args.demux;
|
mpctx->master_demuxer = args.demux;
|
||||||
mpctx->tl = args.tl;
|
mpctx->tl = args.tl;
|
||||||
} else {
|
} else {
|
||||||
|
mpctx->error_playing = args.err;
|
||||||
talloc_free(args.global);
|
talloc_free(args.global);
|
||||||
}
|
}
|
||||||
|
talloc_free(args.url);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_timeline(struct MPContext *mpctx)
|
static void load_timeline(struct MPContext *mpctx)
|
||||||
@ -1093,29 +1074,9 @@ reopen_file:
|
|||||||
goto terminate_playback;
|
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);
|
open_demux_reentrant(mpctx);
|
||||||
if (!mpctx->master_demuxer) {
|
if (!mpctx->master_demuxer)
|
||||||
MP_ERR(mpctx, "Failed to recognize file format.\n");
|
|
||||||
mpctx->error_playing = MPV_ERROR_UNKNOWN_FORMAT;
|
|
||||||
goto terminate_playback;
|
goto terminate_playback;
|
||||||
}
|
|
||||||
mpctx->demuxer = mpctx->master_demuxer;
|
mpctx->demuxer = mpctx->master_demuxer;
|
||||||
|
|
||||||
load_timeline(mpctx);
|
load_timeline(mpctx);
|
||||||
@ -1257,8 +1218,6 @@ terminate_playback:
|
|||||||
|
|
||||||
mp_cancel_trigger(mpctx->playback_abort);
|
mp_cancel_trigger(mpctx->playback_abort);
|
||||||
|
|
||||||
MP_INFO(mpctx, "\n");
|
|
||||||
|
|
||||||
// time to uninit all, except global stuff:
|
// time to uninit all, except global stuff:
|
||||||
uninit_audio_chain(mpctx);
|
uninit_audio_chain(mpctx);
|
||||||
uninit_video_chain(mpctx);
|
uninit_video_chain(mpctx);
|
||||||
@ -1316,6 +1275,10 @@ terminate_playback:
|
|||||||
};
|
};
|
||||||
mp_notify(mpctx, MPV_EVENT_END_FILE, &end_event);
|
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)
|
if (mpctx->playing)
|
||||||
playlist_entry_unref(mpctx->playing);
|
playlist_entry_unref(mpctx->playing);
|
||||||
mpctx->playing = NULL;
|
mpctx->playing = NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user