diff options
Diffstat (limited to 'player/main.c')
-rw-r--r-- | player/main.c | 210 |
1 files changed, 89 insertions, 121 deletions
diff --git a/player/main.c b/player/main.c index 67dde3449f..1f32d375bd 100644 --- a/player/main.c +++ b/player/main.c @@ -22,7 +22,6 @@ #include <assert.h> #include <string.h> #include <pthread.h> -#include <signal.h> #include "config.h" #include "mpv_talloc.h" @@ -63,9 +62,9 @@ #include "command.h" #include "screenshot.h" -#ifdef _WIN32 -#include <windows.h> -#endif +static const char def_config[] = +#include "player/builtin_conf.inc" +; #if HAVE_COCOA #include "osdep/macosx_events.h" @@ -75,6 +74,10 @@ #define FULLCONFIG "(missing)\n" #endif +#if !(HAVE_STDATOMIC || HAVE_ATOMIC_BUILTINS || HAVE_SYNC_BUILTINS) +pthread_mutex_t mp_atomic_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + enum exit_reason { EXIT_NONE, EXIT_NORMAL, @@ -93,49 +96,9 @@ const char mp_help_text[] = " --playlist=<file> specify playlist file\n" "\n" " --list-options list all mpv options\n" +" --h=<pat> print options which match the given shell pattern\n" "\n"; -static const char def_config[] = -#if HAVE_RPI - "hwdec=rpi\n" - "fullscreen=yes\n" -#endif - "\n" - "[pseudo-gui]\n" - "terminal=no\n" - "force-window=yes\n" - "idle=once\n" - "screenshot-directory=~~desktop/\n" - "\n" - "[libmpv]\n" - "config=no\n" - "idle=yes\n" - "terminal=no\n" - "input-terminal=no\n" - "osc=no\n" - "ytdl=no\n" - "input-default-bindings=no\n" - "input-vo-keyboard=no\n" - "input-lirc=no\n" - "input-appleremote=no\n" - "input-media-keys=no\n" - "input-app-events=no\n" - "stop-playback-on-init-failure=yes\n" -#if HAVE_ENCODING - "\n" - "[encoding]\n" - "vo=lavc\n" - "ao=lavc\n" - "keep-open=no\n" - "force-window=no\n" - "gapless-audio=yes\n" - "resume-playback=no\n" - "load-scripts=no\n" - "osc=no\n" - "framedrop=no\n" -#endif -; - static pthread_mutex_t terminal_owner_lock = PTHREAD_MUTEX_INITIALIZER; static struct MPContext *terminal_owner; @@ -149,11 +112,24 @@ static bool cas_terminal_owner(struct MPContext *old, struct MPContext *new) return r; } -static void update_logging(struct MPContext *mpctx) +void mp_update_logging(struct MPContext *mpctx, bool preinit) { mp_msg_update_msglevels(mpctx->global); - if (mpctx->opts->use_terminal && cas_terminal_owner(NULL, mpctx)) - terminal_init(); + + bool enable = mpctx->opts->use_terminal; + bool enabled = cas_terminal_owner(mpctx, mpctx); + if (enable != enabled) { + if (enable && cas_terminal_owner(NULL, mpctx)) { + terminal_init(); + enabled = true; + } else if (!enable) { + terminal_uninit(); + cas_terminal_owner(mpctx, NULL); + } + } + + if (enabled && !preinit && mpctx->opts->consolecontrols) + terminal_setup_getch(mpctx->input); } void mp_print_version(struct mp_log *log, int always) @@ -173,21 +149,19 @@ void mp_print_version(struct mp_log *log, int always) static void shutdown_clients(struct MPContext *mpctx) { - while (mpctx->clients && mp_clients_num(mpctx)) { + mp_client_enter_shutdown(mpctx); + while (mp_clients_num(mpctx)) { mp_client_broadcast_event(mpctx, MPV_EVENT_SHUTDOWN, NULL); - mp_dispatch_queue_process(mpctx->dispatch, 0); - mp_wait_events(mpctx, 10000); + mp_wait_events(mpctx); } } void mp_destroy(struct MPContext *mpctx) { -#if !defined(__MINGW32__) + shutdown_clients(mpctx); + mp_uninit_ipc(mpctx->ipc_ctx); mpctx->ipc_ctx = NULL; -#endif - - shutdown_clients(mpctx); uninit_audio_out(mpctx); uninit_video_out(mpctx); @@ -217,7 +191,6 @@ void mp_destroy(struct MPContext *mpctx) cas_terminal_owner(mpctx, NULL); } - mp_dispatch_set_wakeup_fn(mpctx->dispatch, NULL, NULL); mp_input_uninit(mpctx->input); uninit_libav(mpctx->global); @@ -303,6 +276,10 @@ static bool handle_help_options(struct MPContext *mpctx) ao_print_devices(mpctx->global, log); opt_exit = 1; } + if (opts->property_print_help) { + property_print_help(mpctx); + opt_exit = 1; + } #if HAVE_ENCODING if (encode_lavc_showhelp(log, opts->encode_opts)) opt_exit = 1; @@ -310,6 +287,21 @@ static bool handle_help_options(struct MPContext *mpctx) return opt_exit; } +static void handle_deprecated_options(struct MPContext *mpctx) +{ + struct MPOpts *opts = mpctx->opts; + struct m_obj_settings *vo = opts->vo->video_driver_list; + if (vo && vo->name && strcmp(vo->name, "opengl-hq") == 0) { + MP_WARN(mpctx, + "--vo=opengl-hq is deprecated! Use --profile=opengl-hq instead.\n"); + // Fudge it. This will replace the --vo option too, which is why we + // unset/safe it, and later restore it. + talloc_free(vo->name); + vo->name = talloc_strdup(NULL, "opengl"); + m_config_set_profile(mpctx->mconfig, "opengl-hq", 0); + } +} + static int cfg_include(void *ctx, char *filename, int flags) { struct MPContext *mpctx = ctx; @@ -321,6 +313,10 @@ static int cfg_include(void *ctx, char *filename, int flags) struct MPContext *mp_create(void) { + char *enable_talloc = getenv("MPV_LEAK_REPORT"); + if (enable_talloc && strcmp(enable_talloc, "1") == 0) + talloc_enable_leak_report(); + mp_time_init(); struct MPContext *mpctx = talloc(NULL, MPContext); @@ -340,13 +336,9 @@ struct MPContext *mp_create(void) mpctx->log = mp_log_new(mpctx, mpctx->global->log, "!cplayer"); mpctx->statusline = mp_log_new(mpctx, mpctx->log, "!statusline"); - struct MPOpts *def_opts = talloc_ptrtype(mpctx, def_opts); - *def_opts = mp_default_opts; - def_opts->network_useragent = (char *)mpv_version; - // Create the config context and register the options mpctx->mconfig = m_config_new(mpctx, mpctx->log, sizeof(struct MPOpts), - def_opts, mp_opts); + &mp_default_opts, mp_opts); mpctx->opts = mpctx->mconfig->optstruct; mpctx->mconfig->includefunc = cfg_include; mpctx->mconfig->includefunc_ctx = mpctx; @@ -354,26 +346,28 @@ struct MPContext *mp_create(void) mpctx->mconfig->is_toplevel = true; mpctx->mconfig->global = mpctx->global; m_config_parse(mpctx->mconfig, "", bstr0(def_config), NULL, 0); + m_config_create_shadow(mpctx->mconfig); mpctx->global->opts = mpctx->opts; - mpctx->input = mp_input_init(mpctx->global); + mpctx->input = mp_input_init(mpctx->global, mp_wakeup_core_cb, mpctx); screenshot_init(mpctx); command_init(mpctx); init_libav(mpctx->global); mp_clients_init(mpctx); + mpctx->osd = osd_create(mpctx->global); #if HAVE_COCOA cocoa_set_input_context(mpctx->input); #endif - return mpctx; -} + mp_input_set_cancel(mpctx->input, mpctx->playback_abort); -void wakeup_playloop(void *ctx) -{ - struct MPContext *mpctx = ctx; - mp_input_wakeup(mpctx->input); + char *verbose_env = getenv("MPV_VERBOSE"); + if (verbose_env) + mpctx->opts->verbose = atoi(verbose_env); + + return mpctx; } // Finish mpctx initialization. This must be done after setting up all options. @@ -387,35 +381,54 @@ int mp_initialize(struct MPContext *mpctx, char **options) assert(!mpctx->initialized); - if (options) { - // Preparse the command line, so we can init the terminal early. + // Preparse the command line, so we can init the terminal early. + if (options) m_config_preparse_command_line(mpctx->mconfig, mpctx->global, options); - update_logging(mpctx); + mp_update_logging(mpctx, true); + if (options) { MP_VERBOSE(mpctx, "Command line options:"); for (int i = 0; options[i]; i++) MP_VERBOSE(mpctx, " '%s'", options[i]); MP_VERBOSE(mpctx, "\n"); } - update_logging(mpctx); mp_print_version(mpctx->log, false); mp_parse_cfgfiles(mpctx); - update_logging(mpctx); if (options) { int r = m_config_parse_mp_command_line(mpctx->mconfig, mpctx->playlist, mpctx->global, options); if (r < 0) - return r <= M_OPT_EXIT ? -2 : -1; - update_logging(mpctx); + return r == M_OPT_EXIT ? -2 : -1; + } + + if (opts->operation_mode == 1) { + m_config_set_profile(mpctx->mconfig, "builtin-pseudo-gui", + M_SETOPT_NO_OVERWRITE); + m_config_set_profile(mpctx->mconfig, "pseudo-gui", 0); } + mp_get_resume_defaults(mpctx); + + mp_input_load_config(mpctx->input); + + // From this point on, all mpctx members are initialized. + mpctx->initialized = true; + mpctx->mconfig->option_set_callback = mp_on_set_option; + mpctx->mconfig->option_set_callback_cb = mpctx; + mpctx->mconfig->option_change_callback = mp_option_change_callback; + mpctx->mconfig->option_change_callback_ctx = mpctx; + // Run all update handlers. + mp_option_change_callback(mpctx, NULL, UPDATE_OPTS_MASK); + if (handle_help_options(mpctx)) return -2; + handle_deprecated_options(mpctx); + if (!print_libav_versions(mp_null_log, 0)) { // Using mismatched libraries can be legitimate, but even then it's // a bad idea. We don't acknowledge its usefulness and stability. @@ -428,19 +441,10 @@ int mp_initialize(struct MPContext *mpctx, char **options) return -1; } - if (opts->dump_stats && opts->dump_stats[0]) { - if (mp_msg_open_stats_file(mpctx->global, opts->dump_stats) < 0) - MP_ERR(mpctx, "Failed to open stats file '%s'\n", opts->dump_stats); - } - MP_STATS(mpctx, "start init"); - if (!mpctx->playlist->first && !opts->player_idle_mode) return -3; - mp_input_load(mpctx->input); - mp_input_set_cancel(mpctx->input, mpctx->playback_abort); - - mp_dispatch_set_wakeup_fn(mpctx->dispatch, wakeup_playloop, mpctx); + MP_STATS(mpctx, "start init"); #if HAVE_ENCODING if (opts->encode_opts->file && opts->encode_opts->file[0]) { @@ -460,38 +464,11 @@ int mp_initialize(struct MPContext *mpctx, char **options) MP_WARN(mpctx, "There will be no OSD and no text subtitles.\n"); #endif - mpctx->osd = osd_create(mpctx->global); - - // From this point on, all mpctx members are initialized. - mpctx->initialized = true; - - mp_get_resume_defaults(mpctx); - - // Lua user scripts (etc.) can call arbitrary functions. Load them at a point - // where this is safe. mp_load_scripts(mpctx); - if (opts->consolecontrols && cas_terminal_owner(mpctx, mpctx)) - terminal_setup_getch(mpctx->input); - if (opts->force_vo == 2 && handle_force_window(mpctx, false) < 0) return -1; - mpctx->ipc_ctx = mp_init_ipc(mpctx->clients, mpctx->global); - -#ifdef _WIN32 - if (opts->w32_priority > 0) - SetPriorityClass(GetCurrentProcess(), opts->w32_priority); -#endif -#ifndef _WIN32 - // Deal with OpenSSL and GnuTLS not using MSG_NOSIGNAL. - struct sigaction sa = { .sa_handler = SIG_IGN, .sa_flags = SA_RESTART }; - sigfillset(&sa.sa_mask); - sigaction(SIGPIPE, &sa, NULL); -#endif - - prepare_playlist(mpctx, mpctx->playlist); - MP_STATS(mpctx, "end init"); return 0; @@ -499,16 +476,7 @@ int mp_initialize(struct MPContext *mpctx, char **options) int mpv_main(int argc, char *argv[]) { - char *enable_talloc = getenv("MPV_LEAK_REPORT"); - if (enable_talloc && strcmp(enable_talloc, "1") == 0) - talloc_enable_leak_report(); - struct MPContext *mpctx = mp_create(); - struct MPOpts *opts = mpctx->opts; - - char *verbose_env = getenv("MPV_VERBOSE"); - if (verbose_env) - opts->verbose = atoi(verbose_env); char **options = argv && argv[0] ? argv + 1 : NULL; // skips program name int r = mp_initialize(mpctx, options); |