diff options
-rw-r--r-- | DOCS/man/lua.rst | 9 | ||||
-rw-r--r-- | player/client.c | 22 | ||||
-rw-r--r-- | player/client.h | 1 | ||||
-rw-r--r-- | player/scripting.c | 22 |
4 files changed, 49 insertions, 5 deletions
diff --git a/DOCS/man/lua.rst b/DOCS/man/lua.rst index d8791e7381..147563a964 100644 --- a/DOCS/man/lua.rst +++ b/DOCS/man/lua.rst @@ -47,6 +47,15 @@ The event loop will wait for events and dispatch events registered with ``mp.register_event``. It will also handle timers added with ``mp.add_timeout`` and similar (by waiting with a timeout). +Since mpv 0.6.0, the player will wait until the script is fully loaded before +continuing normal operation. The player considers a script as fully loaded as +soon as it starts waiting for mpv events (or it exits). In practice this means +the player will more or less hang until the script returns from the main chunk +(and ``mp_event_loop`` is called), or the script calls ``mp_event_loop`` or +``mp.dispatch_events`` directly. This is done to make it possible for a script +to fully setup event handlers etc. before playback actually starts. In older +mpv versions, this happened asynchronously. + mp functions ------------ diff --git a/player/client.c b/player/client.c index f1e824fc5d..41f7e12289 100644 --- a/player/client.c +++ b/player/client.c @@ -118,6 +118,7 @@ struct mpv_handle { int properties_updating; uint64_t property_event_masks; // or-ed together event masks of all properties + bool fuzzy_initialized; struct mp_log_buffer *messages; }; @@ -151,6 +152,22 @@ int mp_clients_num(struct MPContext *mpctx) return num_clients; } +// Test for "fuzzy" initialization of all clients. That is, all clients have +// at least called mpv_wait_event() at least once since creation (or exited). +bool mp_clients_all_initialized(struct MPContext *mpctx) +{ + bool all_ok = true; + pthread_mutex_lock(&mpctx->clients->lock); + for (int n = 0; n < mpctx->clients->num_clients; n++) { + struct mpv_handle *ctx = mpctx->clients->clients[n]; + pthread_mutex_lock(&ctx->lock); + all_ok &= ctx->fuzzy_initialized; + pthread_mutex_unlock(&ctx->lock); + } + pthread_mutex_unlock(&mpctx->clients->lock); + return all_ok; +} + static void invalidate_global_event_mask(struct mpv_handle *ctx) { pthread_mutex_lock(&ctx->clients->lock); @@ -377,6 +394,7 @@ mpv_handle *mpv_create(void) mpv_handle *ctx = mp_new_client(mpctx->clients, "main"); if (ctx) { ctx->owner = true; + ctx->fuzzy_initialized = true; // Set some defaults. mpv_set_option_string(ctx, "config", "no"); mpv_set_option_string(ctx, "idle", "yes"); @@ -599,6 +617,10 @@ mpv_event *mpv_wait_event(mpv_handle *ctx, double timeout) pthread_mutex_lock(&ctx->lock); + if (!ctx->fuzzy_initialized && ctx->clients->mpctx->input) + mp_input_wakeup(ctx->clients->mpctx->input); + ctx->fuzzy_initialized = true; + if (timeout < 0) timeout = 1e20; if (ctx->queued_wakeup) diff --git a/player/client.h b/player/client.h index a8804dbf82..0cb4fff43f 100644 --- a/player/client.h +++ b/player/client.h @@ -13,6 +13,7 @@ struct mp_log; void mp_clients_init(struct MPContext *mpctx); void mp_clients_destroy(struct MPContext *mpctx); int mp_clients_num(struct MPContext *mpctx); +bool mp_clients_all_initialized(struct MPContext *mpctx); void mp_client_broadcast_event(struct MPContext *mpctx, int event, void *data); int mp_client_send_event(struct MPContext *mpctx, const char *client_name, diff --git a/player/scripting.c b/player/scripting.c index 3c9829b16d..0b5993c8e5 100644 --- a/player/scripting.c +++ b/player/scripting.c @@ -66,6 +66,7 @@ static char *script_name_from_filename(void *talloc_ctx, const char *fname) } struct thread_arg { + struct mp_log *log; const struct mp_scripting *backend; mpv_handle *client; const char *fname; @@ -76,20 +77,25 @@ static void *script_thread(void *p) pthread_detach(pthread_self()); struct thread_arg *arg = p; - struct mp_log *log = mp_client_get_log(arg->client); - - mp_verbose(log, "Loading script...\n"); if (arg->backend->load(arg->client, arg->fname) < 0) - mp_err(log, "Could not load script %s\n", arg->fname); + MP_ERR(arg, "Could not load script %s\n", arg->fname); - mp_verbose(log, "Exiting...\n"); + MP_VERBOSE(arg, "Exiting...\n"); mpv_detach_destroy(arg->client); talloc_free(arg); return NULL; } +static void wait_loaded(struct MPContext *mpctx) +{ + while (!mp_clients_all_initialized(mpctx)) { + mp_wait_events(mpctx, 1e9); + mp_process_input(mpctx); + } +} + static void mp_load_script(struct MPContext *mpctx, const char *fname) { char *ext = mp_splitext(fname, NULL); @@ -121,11 +127,17 @@ static void mp_load_script(struct MPContext *mpctx, const char *fname) talloc_free(arg); return; } + arg->log = mp_client_get_log(arg->client); + + MP_VERBOSE(arg, "Loading script %s...\n", fname); pthread_t thread; if (pthread_create(&thread, NULL, script_thread, arg)) talloc_free(arg); + wait_loaded(mpctx); + MP_VERBOSE(mpctx, "Done loading %s.\n", fname); + return; } |