| @@ -25,7 +25,7 @@ · 24 unmodified lines |
| 25 | 25 | |
| 26 | 26 | #include <limits.h> |
| 27 | 27 | |
| 28 | | −#include <VSScript4.h> |
| 28 | +#include <vapoursynth/VSScript4.h> |
| 29 | 29 | |
| 30 | 30 | #include "libavutil/avassert.h" |
| 31 | 31 | #include "libavutil/avstring.h" |
| @@ -39,11 +39,26 @@ · 7 unmodified lines |
| 39 | 39 | #include "demux.h" |
| 40 | 40 | #include "internal.h" |
| 41 | 41 | |
| 42 | +/* Platform-specific directives. */ |
| 43 | +#ifdef _WIN32 |
| 44 | + #include <windows.h> |
| 45 | + #include "compat/w32dlfcn.h" |
| 46 | + #include "libavutil/wchar_filename.h" |
| 47 | + #undef EXTERN_C |
| 48 | + #define VSSCRIPT_LIB "VSScript.dll" |
| 49 | +#else |
| 50 | + #include <dlfcn.h> |
| 51 | + #define VSSCRIPT_NAME "libvapoursynth-script" |
| 52 | + #define VSSCRIPT_LIB VSSCRIPT_NAME SLIBSUF |
| 53 | +#endif |
| 54 | + |
| 42 | 55 | struct VSState { |
| 43 | 56 | const VSSCRIPTAPI *vssapi; |
| 44 | 57 | VSScript *vss; |
| 45 | 58 | }; |
| 46 | 59 | |
| 60 | +typedef const VSSCRIPTAPI *(*VSScriptGetAPIFunc)(int version); |
| 61 | + |
| 47 | 62 | typedef struct VSContext { |
| 48 | 63 | const AVClass *class; |
| 49 | 64 | |
| @@ -51,6 +66,7 @@ typedef struct VSContext { · 1 unmodified line |
| 51 | 66 | |
| 52 | 67 | const VSSCRIPTAPI *vssapi; |
| 53 | 68 | const VSAPI *vsapi; |
| 69 | + void *vslibrary; |
| 54 | 70 | |
| 55 | 71 | VSNode *outnode; |
| 56 | 72 | int is_cfr; |
| @@ -70,6 +86,40 @@ static const AVOption options[] = { · 13 unmodified lines |
| 70 | 86 | {NULL} |
| 71 | 87 | }; |
| 72 | 88 | |
| 89 | +static av_cold void* vs_load_library(VSScriptGetAPIFunc *get_vssapi) |
| 90 | +{ |
| 91 | + void *vslibrary = NULL; |
| 92 | +#ifdef _WIN32 |
| 93 | + const HKEY hkeys[] = {HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE}; |
| 94 | + LONG r; |
| 95 | + WCHAR vss_path[512]; |
| 96 | + DWORD buf_size = sizeof(vss_path) - 2; |
| 97 | + char *vss_path_utf8; |
| 98 | + int i; |
| 99 | + |
| 100 | + for (i = 0; i < FF_ARRAY_ELEMS(hkeys); i++) { |
| 101 | + if ((r = RegGetValueW(hkeys[i], L"SOFTWARE\\VapourSynth", |
| 102 | + L"VSScriptDLL", RRF_RT_REG_SZ, NULL, |
| 103 | + &vss_path, &buf_size)) == ERROR_SUCCESS) |
| 104 | + break; |
| 105 | + } |
| 106 | + if (r == ERROR_SUCCESS && wchartoutf8(vss_path, &vss_path_utf8) == 0) { |
| 107 | + vslibrary = dlopen(vss_path_utf8, RTLD_NOW | RTLD_GLOBAL); |
| 108 | + av_free(vss_path_utf8); |
| 109 | + } |
| 110 | + else |
| 111 | +#endif |
| 112 | + vslibrary = dlopen(VSSCRIPT_LIB, RTLD_NOW | RTLD_GLOBAL); |
| 113 | + |
| 114 | + if (vslibrary != NULL) { |
| 115 | + if (!(*get_vssapi = (VSScriptGetAPIFunc)dlsym(vslibrary, "getVSScriptAPI"))) { |
| 116 | + dlclose(vslibrary); |
| 117 | + return NULL; |
| 118 | + } |
| 119 | + } |
| 120 | + return vslibrary; |
| 121 | +} |
| 122 | + |
| 73 | 123 | static void free_vss_state(void *opaque, uint8_t *data) |
| 74 | 124 | { |
| 75 | 125 | struct VSState *vss = opaque; |
| @@ -91,6 +141,9 @@ static av_cold int read_close_vs(AVFormatContext *s) · 15 unmodified lines |
| 91 | 141 | vs->vsapi = NULL; |
| 92 | 142 | vs->outnode = NULL; |
| 93 | 143 | |
| 144 | + if (vs->vslibrary) |
| 145 | + dlclose(vs->vslibrary); |
| 146 | + |
| 94 | 147 | return 0; |
| 95 | 148 | } |
| 96 | 149 | |
| @@ -170,6 +223,7 @@ static av_cold int read_header_vs(AVFormatContext *s) · 73 unmodified lines |
| 170 | 223 | AVStream *st; |
| 171 | 224 | AVIOContext *pb = s->pb; |
| 172 | 225 | VSContext *vs = s->priv_data; |
| 226 | + VSScriptGetAPIFunc get_vssapi; |
| 173 | 227 | int64_t sz = avio_size(pb); |
| 174 | 228 | char *buf = NULL; |
| 175 | 229 | char dummy; |
| @@ -178,7 +232,14 @@ static av_cold int read_header_vs(AVFormatContext *s) · 2 unmodified lines |
| 178 | 232 | struct VSState *vss_state; |
| 179 | 233 | int err = 0; |
| 180 | 234 | |
| 181 | | − if (!(vs->vssapi = getVSScriptAPI(VSSCRIPT_API_VERSION))) { |
| 235 | + if (!(vs->vslibrary = vs_load_library(&get_vssapi))) { |
| 236 | + av_log(s, AV_LOG_ERROR, "Could not open " VSSCRIPT_LIB ". " |
| 237 | + "Check VapourSynth installation.\n"); |
| 238 | + err = AVERROR_EXTERNAL; |
| 239 | + goto done; |
| 240 | + } |
| 241 | + |
| 242 | + if (!(vs->vssapi = get_vssapi(VSSCRIPT_API_VERSION))) { |
| 182 | 243 | av_log(s, AV_LOG_ERROR, "Failed to initialize VSScript (possibly PYTHONPATH not set).\n"); |
| 183 | 244 | err = AVERROR_EXTERNAL; |
| 184 | 245 | goto done; |