From 8aabba933bd600ea89924b97d4e5b2361b96f6fa Mon Sep 17 00:00:00 2001 From: Crend King <975235+CrendKing@users.noreply.github.com> Date: Thu, 23 Apr 2026 18:02:38 -0700 Subject: [PATCH] vf_vapoursynth: improve backward compatibility The previous commit to dynamically load VapourSynth R74 would fail to work for VapourSynth R73 and before on Linux due to load mode RTLD_LOCAL. To make it work on all VapourSynth version, switch to use RTLD_GLOBAL mode. Add library handle closing in drv_vss_uninit for completeness. --- osdep/io.c | 5 +++++ osdep/io.h | 3 +++ video/filter/vf_vapoursynth.c | 24 +++++++++++++++--------- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/osdep/io.c b/osdep/io.c index 9401a46805..96e98d72a4 100644 --- a/osdep/io.c +++ b/osdep/io.c @@ -781,6 +781,11 @@ void *mp_dlsym(void *handle, const char *symbol) return (void *)addr; } +int mp_dlclose(void *handle) +{ + return CloseHandle(handle); +} + char *mp_dlerror(void) { if (mp_dl_result.errcode == 0) diff --git a/osdep/io.h b/osdep/io.h index bf672224e7..80426e76d0 100644 --- a/osdep/io.h +++ b/osdep/io.h @@ -138,6 +138,7 @@ off_t mp_lseek64(int fd, off_t offset, int whence); int mp_ftruncate64(int fd, off_t length); void *mp_dlopen(const char *filename, int flag); void *mp_dlsym(void *handle, const char *symbol); +int mp_dlclose(void *handle); char *mp_dlerror(void); // mp_stat types. MSVCRT's dev_t and ino_t are way too short to be unique. @@ -207,8 +208,10 @@ void mp_globfree(mp_glob_t *pglob); #define RTLD_NOW 0 #define RTLD_LOCAL 0 +#define RTLD_GLOBAL 0 #define dlopen(fn,fg) mp_dlopen((fn), (fg)) #define dlsym(h,s) mp_dlsym((h), (s)) +#define dlclose(h) mp_dlclose((h)) #define dlerror mp_dlerror // Affects both "stat()" and "struct stat". diff --git a/video/filter/vf_vapoursynth.c b/video/filter/vf_vapoursynth.c index 22bfa64658..4882565a11 100644 --- a/video/filter/vf_vapoursynth.c +++ b/video/filter/vf_vapoursynth.c @@ -75,6 +75,7 @@ struct priv { const struct script_driver *drv; // drv_vss + void *vs_script_lib; const VSSCRIPTAPI *vs_script_api; VSScript *vs_script; @@ -817,24 +818,24 @@ static const m_option_t vf_opts_fields[] = { static int drv_vss_init(struct priv *p) { const char *vsscript_path = getenv("VSSCRIPT_PATH"); - const int dl_mode = RTLD_NOW | RTLD_LOCAL; - void *vsscript_lib = NULL; + const int dl_mode = RTLD_NOW | RTLD_GLOBAL; + p->vs_script_lib = NULL; if (vsscript_path) { - vsscript_lib = dlopen(vsscript_path, dl_mode); + p->vs_script_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); + for (size_t i = 0; i < MP_ARRAY_SIZE(vsscript_lib_names) && !p->vs_script_lib; ++i) { + p->vs_script_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"; + 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 (p->vs_script_lib) { + getVSScriptAPI_func = (void *) dlsym(p->vs_script_lib, "getVSScriptAPI"); + getVSScriptAPILastError_func = (void *) dlsym(p->vs_script_lib, "getVSScriptAPILastError"); } if (!getVSScriptAPI_func) { @@ -858,6 +859,11 @@ static int drv_vss_init(struct priv *p) static void drv_vss_uninit(struct priv *p) { p->vs_script_api = NULL; + + if (p->vs_script_lib) { + dlclose(p->vs_script_lib); + p->vs_script_lib = NULL; + } } static int drv_vss_load_core(struct priv *p)