From 2e266391559c2aa867c24593325f07effba97c64 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 5 Mar 2015 11:17:22 +0100 Subject: [PATCH] player, client API: refactor cplayer init, reduce client API differences Move the command line parsing and some other things to the common init routine shared between command line player and client API. This means they're using almost exactly the same code now. The main intended side effect is that the client API will load mpv.conf; though still only if config loading is enabled. (The cplayer still avoids creating an extra thread, passes a command line, and prints an exit status to the terminal. It also has some different defaults.) --- DOCS/client-api-changes.rst | 4 ++ libmpv/client.h | 8 ++-- player/client.c | 4 +- player/core.h | 2 +- player/main.c | 93 +++++++++++++++++++------------------ 5 files changed, 60 insertions(+), 51 deletions(-) diff --git a/DOCS/client-api-changes.rst b/DOCS/client-api-changes.rst index 842dd8500d..e375ae85ba 100644 --- a/DOCS/client-api-changes.rst +++ b/DOCS/client-api-changes.rst @@ -25,6 +25,10 @@ API changes :: + --- mpv 0.9.0 will be released --- + 1.15 - mpv_initialize() will now load config files. This requires setting + the "config" and "config-dir" options. In particular, it will load + mpv.conf. --- mpv 0.8.0 is released --- 1.14 - add mpv_wait_async_requests() - the --msg-level option changes its native type from a flat string to diff --git a/libmpv/client.h b/libmpv/client.h index 0607f9a562..2ace0f54cf 100644 --- a/libmpv/client.h +++ b/libmpv/client.h @@ -195,7 +195,7 @@ extern "C" { * relational operators (<, >, <=, >=). */ #define MPV_MAKE_VERSION(major, minor) (((major) << 16) | (minor) | 0UL) -#define MPV_CLIENT_API_VERSION MPV_MAKE_VERSION(1, 14) +#define MPV_CLIENT_API_VERSION MPV_MAKE_VERSION(1, 15) /** * Return the MPV_CLIENT_API_VERSION the mpv source has been compiled with. @@ -360,8 +360,10 @@ const char *mpv_client_name(mpv_handle *ctx); * equivalent to setting the --no-terminal option. * (Technically, this also suppresses C signal handling.) * - No config files will be loaded. This is roughly equivalent to using - * --no-config (but actually the code path for loading config files is - * disabled). + * --no-config. Since libmpv 1.15, you can actually re-enable this option, + * which will make libmpv load config files during mpv_initialize(). If you + * do this, you are strongly encouraged to set the "config-dir" option too. + * (Otherwise it will load the mpv command line player's config.) * - Idle mode is enabled, which means the playback core will enter idle mode * if there are no more files to play on the internal playlist, instead of * exiting. This is equivalent to the --idle option. diff --git a/player/client.c b/player/client.c index 1c24d5522e..3ed7ea620e 100644 --- a/player/client.c +++ b/player/client.c @@ -516,11 +516,9 @@ static void *playback_thread(void *p) int mpv_initialize(mpv_handle *ctx) { - if (mp_initialize(ctx->mpctx) < 0) + if (mp_initialize(ctx->mpctx, NULL) < 0) return MPV_ERROR_INVALID_PARAMETER; - mp_print_version(ctx->mpctx->log, false); - pthread_t thread; if (pthread_create(&thread, NULL, playback_thread, ctx->mpctx) != 0) return MPV_ERROR_NOMEM; diff --git a/player/core.h b/player/core.h index 7a65270abc..c995c8ab19 100644 --- a/player/core.h +++ b/player/core.h @@ -404,7 +404,7 @@ struct track *select_track(struct MPContext *mpctx, enum stream_type type, // main.c int mpv_main(int argc, char *argv[]); -int mp_initialize(struct MPContext *mpctx); +int mp_initialize(struct MPContext *mpctx, char **argv); struct MPContext *mp_create(void); void mp_destroy(struct MPContext *mpctx); void mp_print_version(struct mp_log *log, int always); diff --git a/player/main.c b/player/main.c index bf684cbae0..f4da0e4698 100644 --- a/player/main.c +++ b/player/main.c @@ -112,6 +112,13 @@ static bool cas_terminal_owner(struct MPContext *old, struct MPContext *new) return r; } +static void update_logging(struct MPContext *mpctx) +{ + mp_msg_update_msglevels(mpctx->global); + if (mpctx->opts->use_terminal && cas_terminal_owner(NULL, mpctx)) + terminal_init(); +} + void mp_print_version(struct mp_log *log, int always) { int v = always ? MSGL_INFO : MSGL_V; @@ -361,9 +368,9 @@ void wakeup_playloop(void *ctx) // Finish mpctx initialization. This must be done after setting up all options. // Some of the initializations depend on the options, and can't be changed or // undone later. -// cplayer: true if called by the command line player, false for client API +// If argv is not NULL, apply them as command line player arguments. // Returns: <0 on error, 0 on success. -int mp_initialize(struct MPContext *mpctx) +int mp_initialize(struct MPContext *mpctx, char **argv) { struct MPOpts *opts = mpctx->opts; @@ -375,10 +382,35 @@ int mp_initialize(struct MPContext *mpctx) } MP_STATS(mpctx, "start init"); - if (mpctx->opts->use_terminal && cas_terminal_owner(NULL, mpctx)) - terminal_init(); + update_logging(mpctx); - mp_msg_update_msglevels(mpctx->global); + if (argv) { + // Preparse the command line, so we can init the terminal early. + m_config_preparse_command_line(mpctx->mconfig, mpctx->global, argv); + + update_logging(mpctx); + + MP_VERBOSE(mpctx, "Command line:"); + for (int i = 0; argv[i]; i++) + MP_VERBOSE(mpctx, " '%s'", argv[i]); + MP_VERBOSE(mpctx, "\n"); + } + + mp_print_version(mpctx->log, false); + + mp_parse_cfgfiles(mpctx); + update_logging(mpctx); + + if (argv) { + int r = m_config_parse_mp_command_line(mpctx->mconfig, mpctx->playlist, + mpctx->global, argv); + if (r < 0) + return r <= M_OPT_EXIT ? -2 : -1; + update_logging(mpctx); + } + + if (handle_help_options(mpctx)) + return -2; if (opts->slave_mode) { MP_WARN(mpctx, "--slave-broken is deprecated (see manpage).\n"); @@ -386,6 +418,9 @@ int mp_initialize(struct MPContext *mpctx) m_config_set_option0(mpctx->mconfig, "input-file", "/dev/stdin"); } + if (!mpctx->playlist->first && !opts->player_idle_mode) + return -3; + mp_input_load(mpctx->input); mp_input_set_cancel(mpctx->input, mpctx->playback_abort); @@ -457,6 +492,11 @@ int mp_initialize(struct MPContext *mpctx) mpctx->ipc_ctx = mp_init_ipc(mpctx->clients, mpctx->global); #endif +#ifdef _WIN32 + if (opts->w32_priority > 0) + SetPriorityClass(GetCurrentProcess(), opts->w32_priority); +#endif + prepare_playlist(mpctx, mpctx->playlist); MP_STATS(mpctx, "end init"); @@ -475,50 +515,15 @@ int mpv_main(int argc, char *argv[]) if (verbose_env) opts->verbose = atoi(verbose_env); - // Preparse the command line - m_config_preparse_command_line(mpctx->mconfig, mpctx->global, argv); - - if (mpctx->opts->use_terminal && cas_terminal_owner(NULL, mpctx)) - terminal_init(); - - mp_msg_update_msglevels(mpctx->global); - - MP_VERBOSE(mpctx, "Command line:"); - for (int i = 0; argv[i]; i++) - MP_VERBOSE(mpctx, " '%s'", argv[i]); - MP_VERBOSE(mpctx, "\n"); - - mp_print_version(mpctx->log, false); - - mp_parse_cfgfiles(mpctx); - - int r = m_config_parse_mp_command_line(mpctx->mconfig, mpctx->playlist, - mpctx->global, argv); - if (r < 0) { - if (r <= M_OPT_EXIT) { - return prepare_exit_cplayer(mpctx, EXIT_NONE); - } else { - return prepare_exit_cplayer(mpctx, EXIT_ERROR); - } - } - - mp_msg_update_msglevels(mpctx->global); - - if (handle_help_options(mpctx)) + int r = mp_initialize(mpctx, argv); + if (r == -2) // help return prepare_exit_cplayer(mpctx, EXIT_NONE); - - if (!mpctx->playlist->first && !opts->player_idle_mode) { + if (r == -3) { // nothing to play mp_print_version(mpctx->log, true); MP_INFO(mpctx, "%s", mp_help_text); return prepare_exit_cplayer(mpctx, EXIT_NONE); } - -#ifdef _WIN32 - if (opts->w32_priority > 0) - SetPriorityClass(GetCurrentProcess(), opts->w32_priority); -#endif - - if (mp_initialize(mpctx) < 0) + if (r < 0) // another error return prepare_exit_cplayer(mpctx, EXIT_ERROR); mp_play_files(mpctx);