diff options
Diffstat (limited to 'player/scripting.c')
-rw-r--r-- | player/scripting.c | 112 |
1 files changed, 96 insertions, 16 deletions
diff --git a/player/scripting.c b/player/scripting.c index 24e2931539..0b200815f1 100644 --- a/player/scripting.c +++ b/player/scripting.c @@ -20,7 +20,6 @@ #include <sys/types.h> #include <dirent.h> #include <math.h> -#include <pthread.h> #include <assert.h> #include <unistd.h> @@ -40,6 +39,8 @@ #include "core.h" #include "client.h" #include "libmpv/client.h" +#include "libmpv/render.h" +#include "libmpv/stream_cb.h" extern const struct mp_scripting mp_scripting_lua; extern const struct mp_scripting mp_scripting_cplugin; @@ -83,26 +84,24 @@ static char *script_name_from_filename(void *talloc_ctx, const char *fname) static void run_script(struct mp_script_args *arg) { - char name[90]; - snprintf(name, sizeof(name), "%s (%s)", arg->backend->name, - mpv_client_name(arg->client)); - mpthread_set_name(name); + char *name = talloc_asprintf(NULL, "%s/%s", arg->backend->name, + mpv_client_name(arg->client)); + mp_thread_set_name(name); + talloc_free(name); if (arg->backend->load(arg) < 0) - MP_ERR(arg, "Could not load %s %s\n", arg->backend->name, arg->filename); + MP_ERR(arg, "Could not load %s script %s\n", arg->backend->name, arg->filename); mpv_destroy(arg->client); talloc_free(arg); } -static void *script_thread(void *p) +static MP_THREAD_VOID script_thread(void *p) { - pthread_detach(pthread_self()); - struct mp_script_args *arg = p; run_script(arg); - return NULL; + MP_THREAD_RETURN(); } static int64_t mp_load_script(struct MPContext *mpctx, const char *fname) @@ -174,9 +173,10 @@ static int64_t mp_load_script(struct MPContext *mpctx, const char *fname) }; talloc_free(tmp); + fname = NULL; // might have been freed so don't touch anymore if (!arg->client) { - MP_ERR(mpctx, "Failed to create client for script: %s\n", fname); + MP_ERR(mpctx, "Failed to create client for script: %s\n", arg->filename); talloc_free(arg); return -1; } @@ -185,17 +185,18 @@ static int64_t mp_load_script(struct MPContext *mpctx, const char *fname) arg->log = mp_client_get_log(arg->client); int64_t id = mpv_client_id(arg->client); - MP_DBG(arg, "Loading %s %s...\n", backend->name, fname); + MP_DBG(arg, "Loading %s script %s...\n", backend->name, arg->filename); if (backend->no_thread) { run_script(arg); } else { - pthread_t thread; - if (pthread_create(&thread, NULL, script_thread, arg)) { + mp_thread thread; + if (mp_thread_create(&thread, script_thread, arg)) { mpv_destroy(arg->client); talloc_free(arg); return -1; } + mp_thread_detach(thread); } return id; @@ -294,11 +295,83 @@ bool mp_load_scripts(struct MPContext *mpctx) #if HAVE_CPLUGINS +#if !HAVE_WIN32 #include <dlfcn.h> +#endif #define MPV_DLOPEN_FN "mpv_open_cplugin" typedef int (*mpv_open_cplugin)(mpv_handle *handle); +static void init_sym_table(struct mp_script_args *args, void *lib) { +#define INIT_SYM(name) \ + { \ + void **sym = (void **)dlsym(lib, "pfn_" #name); \ + if (sym) { \ + if (*sym && *sym != &name) \ + MP_ERR(args, "Overriding already set function " #name "\n"); \ + *sym = &name; \ + } \ + } + + INIT_SYM(mpv_client_api_version); + INIT_SYM(mpv_error_string); + INIT_SYM(mpv_free); + INIT_SYM(mpv_client_name); + INIT_SYM(mpv_client_id); + INIT_SYM(mpv_create); + INIT_SYM(mpv_initialize); + INIT_SYM(mpv_destroy); + INIT_SYM(mpv_terminate_destroy); + INIT_SYM(mpv_create_client); + INIT_SYM(mpv_create_weak_client); + INIT_SYM(mpv_load_config_file); + INIT_SYM(mpv_get_time_us); + INIT_SYM(mpv_free_node_contents); + INIT_SYM(mpv_set_option); + INIT_SYM(mpv_set_option_string); + INIT_SYM(mpv_command); + INIT_SYM(mpv_command_node); + INIT_SYM(mpv_command_ret); + INIT_SYM(mpv_command_string); + INIT_SYM(mpv_command_async); + INIT_SYM(mpv_command_node_async); + INIT_SYM(mpv_abort_async_command); + INIT_SYM(mpv_set_property); + INIT_SYM(mpv_set_property_string); + INIT_SYM(mpv_del_property); + INIT_SYM(mpv_set_property_async); + INIT_SYM(mpv_get_property); + INIT_SYM(mpv_get_property_string); + INIT_SYM(mpv_get_property_osd_string); + INIT_SYM(mpv_get_property_async); + INIT_SYM(mpv_observe_property); + INIT_SYM(mpv_unobserve_property); + INIT_SYM(mpv_event_name); + INIT_SYM(mpv_event_to_node); + INIT_SYM(mpv_request_event); + INIT_SYM(mpv_request_log_messages); + INIT_SYM(mpv_wait_event); + INIT_SYM(mpv_wakeup); + INIT_SYM(mpv_set_wakeup_callback); + INIT_SYM(mpv_wait_async_requests); + INIT_SYM(mpv_hook_add); + INIT_SYM(mpv_hook_continue); + INIT_SYM(mpv_get_wakeup_pipe); + + INIT_SYM(mpv_render_context_create); + INIT_SYM(mpv_render_context_set_parameter); + INIT_SYM(mpv_render_context_get_info); + INIT_SYM(mpv_render_context_set_update_callback); + INIT_SYM(mpv_render_context_update); + INIT_SYM(mpv_render_context_render); + INIT_SYM(mpv_render_context_report_swap); + INIT_SYM(mpv_render_context_free); + + INIT_SYM(mpv_stream_cb_add_ro); + +#undef INIT_SYM +} + static int load_cplugin(struct mp_script_args *args) { void *lib = dlopen(args->filename, RTLD_NOW | RTLD_LOCAL); @@ -309,6 +382,9 @@ static int load_cplugin(struct mp_script_args *args) mpv_open_cplugin sym = (mpv_open_cplugin)dlsym(lib, MPV_DLOPEN_FN); if (!sym) goto error; + + init_sym_table(args, lib); + return sym(args->client) ? -1 : 0; error: ; char *err = dlerror(); @@ -318,8 +394,12 @@ error: ; } const struct mp_scripting mp_scripting_cplugin = { - .name = "SO plugin", + .name = "cplugin", + #if HAVE_WIN32 + .file_ext = "dll", + #else .file_ext = "so", + #endif .load = load_cplugin, }; @@ -375,7 +455,7 @@ static int load_run(struct mp_script_args *args) } const struct mp_scripting mp_scripting_run = { - .name = "spawned IPC process", + .name = "ipc", .file_ext = "run", .no_thread = true, .load = load_run, |