diff --git a/meson.build b/meson.build index a40e4f1aec..d7bfd5f3a3 100644 --- a/meson.build +++ b/meson.build @@ -772,11 +772,9 @@ if features['uchardet'] endif vapoursynth = dependency('vapoursynth', version: '>= 56', required: get_option('vapoursynth')) -vapoursynth_script = dependency('vapoursynth-script', version: '>= 56', - required: get_option('vapoursynth')) -features += {'vapoursynth': vapoursynth.found() and vapoursynth_script.found()} +features += {'vapoursynth': vapoursynth.found()} if features['vapoursynth'] - dependencies += [vapoursynth, vapoursynth_script] + dependencies += vapoursynth.partial_dependency(compile_args: true, includes: true) sources += files('video/filter/vf_vapoursynth.c') endif diff --git a/osdep/io.h b/osdep/io.h index cc72e22473..bf672224e7 100644 --- a/osdep/io.h +++ b/osdep/io.h @@ -247,12 +247,13 @@ locale_t newlocale(int, const char *, locale_t); locale_t uselocale(locale_t); void freelocale(locale_t); -#else /* __MINGW32__ */ +#else /* _WIN32 */ +#include #include extern char **environ; -#endif /* __MINGW32__ */ +#endif /* _WIN32 */ #endif diff --git a/video/filter/vf_vapoursynth.c b/video/filter/vf_vapoursynth.c index d2ab916220..22bfa64658 100644 --- a/video/filter/vf_vapoursynth.c +++ b/video/filter/vf_vapoursynth.c @@ -22,7 +22,6 @@ #include #include -#include #include #include @@ -37,11 +36,24 @@ #include "filters/user_filters.h" #include "options/m_option.h" #include "options/path.h" +#include "osdep/io.h" #include "osdep/threads.h" #include "video/img_format.h" #include "video/mp_image.h" #include "video/sws_utils.h" +static const char *const vsscript_lib_names[] = { +#ifdef _WIN32 + "VSScript.dll", +#elif defined(__APPLE__) + "libvsscript.dylib", + "libvapoursynth-script.dylib", +#else + "libvsscript.so", + "libvapoursynth-script.so", +#endif +}; + struct vapoursynth_opts { char *file; int maxbuffer; @@ -804,11 +816,42 @@ static const m_option_t vf_opts_fields[] = { static int drv_vss_init(struct priv *p) { - p->vs_script_api = getVSScriptAPI(VSSCRIPT_API_VERSION); - if (!p->vs_script_api) { - MP_FATAL(p, "Could not initialize VapourSynth scripting.\n"); + const char *vsscript_path = getenv("VSSCRIPT_PATH"); + const int dl_mode = RTLD_NOW | RTLD_LOCAL; + void *vsscript_lib = NULL; + + if (vsscript_path) { + vsscript_lib = dlopen(vsscript_path, dl_mode); + } else { + for (size_t i = 0; i < MP_ARRAY_SIZE(vsscript_lib_names) && !vsscript_lib; ++i) { + vsscript_lib = dlopen(vsscript_lib_names[i], dl_mode); + } + } + + VS_CC const VSSCRIPTAPI *(*getVSScriptAPI_func)(int) = NULL; + VS_CC const char *(*getVSScriptAPILastError_func)(void) = NULL; + const char *unknown_error_msg = "Last error unknown"; + + if (vsscript_lib) { + getVSScriptAPI_func = (void *) dlsym(vsscript_lib, "getVSScriptAPI"); + getVSScriptAPILastError_func = (void *) dlsym(vsscript_lib, "getVSScriptAPILastError"); + } + + if (!getVSScriptAPI_func) { + const char *dl_error_msg = dlerror(); + const char *last_error_msg = dl_error_msg ? dl_error_msg : unknown_error_msg; + MP_FATAL(p, "Failed to load VapourSynth VSScript library: %s\n", last_error_msg); return -1; } + + p->vs_script_api = getVSScriptAPI_func(VSSCRIPT_API_VERSION); + if (!p->vs_script_api) { + const char *vs_error_msg = getVSScriptAPILastError_func ? getVSScriptAPILastError_func() : NULL; + const char *last_error_msg = vs_error_msg ? vs_error_msg : unknown_error_msg; + MP_FATAL(p, "Failed to initialize VapourSynth VSScript library: %s\n", last_error_msg); + return -1; + } + return 0; }