| @@ -25,7 +25,7 @@ · 24 unmodified lines |
| 25 | | 25 | |
| 26 | #include <limits.h> | 26 | #include <limits.h> |
| 27 | | 27 | |
| 28 | #include <VSScript4.h> | 28 | #include <vapoursynth/VSScript4.h> |
| 29 | | 29 | |
| 30 | #include "libavutil/avassert.h" | 30 | #include "libavutil/avassert.h" |
| 31 | #include "libavutil/avstring.h" | 31 | #include "libavutil/avstring.h" |
| @@ -39,11 +39,26 @@ · 7 unmodified lines |
| 39 | #include "demux.h" | 39 | #include "demux.h" |
| 40 | #include "internal.h" | 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 | struct VSState { | 55 | struct VSState { |
| 43 | const VSSCRIPTAPI *vssapi; | 56 | const VSSCRIPTAPI *vssapi; |
| 44 | VSScript *vss; | 57 | VSScript *vss; |
| 45 | }; | 58 | }; |
| 46 | | 59 | |
| | 60 | typedef const VSSCRIPTAPI *(*VSScriptGetAPIFunc)(int version); |
| | 61 | |
| 47 | typedef struct VSContext { | 62 | typedef struct VSContext { |
| 48 | const AVClass *class; | 63 | const AVClass *class; |
| 49 | | 64 | |
| @@ -51,6 +66,7 @@ typedef struct VSContext { · 1 unmodified line |
| 51 | | 66 | |
| 52 | const VSSCRIPTAPI *vssapi; | 67 | const VSSCRIPTAPI *vssapi; |
| 53 | const VSAPI *vsapi; | 68 | const VSAPI *vsapi; |
| | 69 | void *vslibrary; |
| 54 | | 70 | |
| 55 | VSNode *outnode; | 71 | VSNode *outnode; |
| 56 | int is_cfr; | 72 | int is_cfr; |
| @@ -70,6 +86,40 @@ static const AVOption options[] = { · 13 unmodified lines |
| 70 | {NULL} | 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 | static void free_vss_state(void *opaque, uint8_t *data) | 123 | static void free_vss_state(void *opaque, uint8_t *data) |
| 74 | { | 124 | { |
| 75 | struct VSState *vss = opaque; | 125 | struct VSState *vss = opaque; |
| @@ -91,6 +141,9 @@ static av_cold int read_close_vs(AVFormatContext *s) · 15 unmodified lines |
| 91 | vs->vsapi = NULL; | 141 | vs->vsapi = NULL; |
| 92 | vs->outnode = NULL; | 142 | vs->outnode = NULL; |
| 93 | | 143 | |
| | 144 | if (vs->vslibrary) |
| | 145 | dlclose(vs->vslibrary); |
| | 146 | |
| 94 | return 0; | 147 | return 0; |
| 95 | } | 148 | } |
| 96 | | 149 | |
| @@ -170,6 +223,7 @@ static av_cold int read_header_vs(AVFormatContext *s) · 73 unmodified lines |
| 170 | AVStream *st; | 223 | AVStream *st; |
| 171 | AVIOContext *pb = s->pb; | 224 | AVIOContext *pb = s->pb; |
| 172 | VSContext *vs = s->priv_data; | 225 | VSContext *vs = s->priv_data; |
| | 226 | VSScriptGetAPIFunc get_vssapi; |
| 173 | int64_t sz = avio_size(pb); | 227 | int64_t sz = avio_size(pb); |
| 174 | char *buf = NULL; | 228 | char *buf = NULL; |
| 175 | char dummy; | 229 | char dummy; |
| @@ -178,7 +232,14 @@ static av_cold int read_header_vs(AVFormatContext *s) · 2 unmodified lines |
| 178 | struct VSState *vss_state; | 232 | struct VSState *vss_state; |
| 179 | int err = 0; | 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 | av_log(s, AV_LOG_ERROR, "Failed to initialize VSScript (possibly PYTHONPATH not set).\n"); | 243 | av_log(s, AV_LOG_ERROR, "Failed to initialize VSScript (possibly PYTHONPATH not set).\n"); |
| 183 | err = AVERROR_EXTERNAL; | 244 | err = AVERROR_EXTERNAL; |
| 184 | goto done; | 245 | goto done; |