summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/lua.rst9
-rw-r--r--player/client.c22
-rw-r--r--player/client.h1
-rw-r--r--player/scripting.c22
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;
}