summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2019-06-30 01:20:06 +0200
committerwm4 <wm4@nowhere>2019-09-19 20:37:05 +0200
commitfb8d240c4d045ca254aa6693c48aecc75954cba0 (patch)
treea7cd07e33d2760c15d646afbbb73d6c86a9fa77b
parentc8b8fe9981c654c0539ca77056ed6451a3da7367 (diff)
downloadmpv-fb8d240c4d045ca254aa6693c48aecc75954cba0.tar.bz2
mpv-fb8d240c4d045ca254aa6693c48aecc75954cba0.tar.xz
vf_vapourynth: remove Lua backend
I once created this because someone wanted to use vapoursynth without the Python dependency. No idea if anyone ever actually used it. It's sort of icky (it calls itself "lazy" to preempt complaints about how much it sucks), and complicates the build process. Kill it. It seems much more promising to have something like this: https://github.com/vapoursynth/vapoursynth/issues/386 This would either solve the build distribution problem by relaxing the Python dependency, and/or allow a Lua backend to be included without pain.
-rw-r--r--DOCS/man/vf.rst25
-rw-r--r--filters/user_filters.c5
-rw-r--r--filters/user_filters.h1
-rw-r--r--video/filter/vf_vapoursynth.c242
-rw-r--r--wscript12
-rw-r--r--wscript_build.py2
6 files changed, 4 insertions, 283 deletions
diff --git a/DOCS/man/vf.rst b/DOCS/man/vf.rst
index 28c2db07d6..5c576e6bad 100644
--- a/DOCS/man/vf.rst
+++ b/DOCS/man/vf.rst
@@ -443,31 +443,6 @@ Available mpv-only filters are:
``display_fps``
Refresh rate of the current display. Note that this value can be 0.
-``vapoursynth-lazy``
- The same as ``vapoursynth``, but doesn't load Python scripts. Instead, a
- custom backend using Lua and the raw VapourSynth API is used. The syntax
- is completely different, and absolutely no convenience features are
- provided. There's no type checking either, and you can trigger crashes.
-
- .. admonition:: Example:
-
- ::
-
- video_out = invoke("morpho", "Open", {clip = video_in})
-
- The special variable ``video_in`` is the mpv video source, while the
- special variable ``video_out`` is used to read video from. The 1st argument
- is the plugin (queried with ``getPluginByNs``), the 2nd is the filter name,
- and the 3rd argument is a table with the arguments. Positional arguments
- are not supported. The types must match exactly. Since Lua is terrible and
- can't distinguish integers and floats, integer arguments must be prefixed
- with ``i_``, in which case the prefix is removed and the argument is cast
- to an integer. Should the argument's name start with ``i_``, you're out of
- luck.
-
- Clips (VSNodeRef) are passed as light userdata, so trying to pass any
- other userdata type will result in hard crashes.
-
``vavpp``
VA-API video post processing. Requires the system to support VA-API,
i.e. Linux/BSD only. Works with ``--vo=vaapi`` and ``--vo=gpu`` only.
diff --git a/filters/user_filters.c b/filters/user_filters.c
index 89d7743d53..e1b7a8bce1 100644
--- a/filters/user_filters.c
+++ b/filters/user_filters.c
@@ -64,12 +64,9 @@ const struct mp_user_filter_entry *vf_list[] = {
&vf_lavfi,
&vf_lavfi_bridge,
&vf_sub,
-#if HAVE_VAPOURSYNTH_CORE && HAVE_VAPOURSYNTH
+#if HAVE_VAPOURSYNTH
&vf_vapoursynth,
#endif
-#if HAVE_VAPOURSYNTH_CORE && HAVE_VAPOURSYNTH_LAZY
- &vf_vapoursynth_lazy,
-#endif
#if HAVE_VDPAU
&vf_vdpaupp,
#endif
diff --git a/filters/user_filters.h b/filters/user_filters.h
index a2cca7cba0..88cb859a71 100644
--- a/filters/user_filters.h
+++ b/filters/user_filters.h
@@ -29,7 +29,6 @@ extern const struct mp_user_filter_entry vf_lavfi;
extern const struct mp_user_filter_entry vf_lavfi_bridge;
extern const struct mp_user_filter_entry vf_sub;
extern const struct mp_user_filter_entry vf_vapoursynth;
-extern const struct mp_user_filter_entry vf_vapoursynth_lazy;
extern const struct mp_user_filter_entry vf_format;
extern const struct mp_user_filter_entry vf_vdpaupp;
extern const struct mp_user_filter_entry vf_vavpp;
diff --git a/video/filter/vf_vapoursynth.c b/video/filter/vf_vapoursynth.c
index 4227ee6fa6..986399c748 100644
--- a/video/filter/vf_vapoursynth.c
+++ b/video/filter/vf_vapoursynth.c
@@ -812,8 +812,6 @@ static const m_option_t vf_opts_fields[] = {
{0}
};
-#if HAVE_VAPOURSYNTH
-
#include <VSScript.h>
static int drv_vss_init(struct priv *p)
@@ -872,7 +870,7 @@ static const struct script_driver drv_vss = {
const struct mp_user_filter_entry vf_vapoursynth = {
.desc = {
- .description = "VapourSynth bridge (Python)",
+ .description = "VapourSynth bridge",
.name = "vapoursynth",
.priv_size = sizeof(OPT_BASE_STRUCT),
.priv_defaults = &(const OPT_BASE_STRUCT){
@@ -882,241 +880,3 @@ const struct mp_user_filter_entry vf_vapoursynth = {
},
.create = vf_vapoursynth_create,
};
-
-#endif
-
-#if HAVE_VAPOURSYNTH_LAZY
-
-#include <lua.h>
-#include <lualib.h>
-#include <lauxlib.h>
-
-#if LUA_VERSION_NUM <= 501
-#define mp_cpcall lua_cpcall
-#define FUCKYOUOHGODWHY(L) lua_pushvalue(L, LUA_GLOBALSINDEX)
-#else
-// Curse whoever had this stupid idea. Curse whoever thought it would be a good
-// idea not to include an emulated lua_cpcall() even more.
-static int mp_cpcall (lua_State *L, lua_CFunction func, void *ud)
-{
- lua_pushcfunction(L, func); // doesn't allocate in 5.2 (but does in 5.1)
- lua_pushlightuserdata(L, ud);
- return lua_pcall(L, 1, 0, 0);
-}
-// Hey, let's replace old mechanisms with something slightly different!
-#define FUCKYOUOHGODWHY lua_pushglobaltable
-#endif
-
-static int drv_lazy_init(struct priv *p)
-{
- p->ls = luaL_newstate();
- if (!p->ls)
- return -1;
- luaL_openlibs(p->ls);
- p->vsapi = getVapourSynthAPI(VAPOURSYNTH_API_VERSION);
- p->vscore = p->vsapi ? p->vsapi->createCore(0) : NULL;
- if (!p->vscore) {
- MP_FATAL(p, "Could not load VapourSynth.\n");
- lua_close(p->ls);
- return -1;
- }
- return 0;
-}
-
-static void drv_lazy_uninit(struct priv *p)
-{
- lua_close(p->ls);
- p->vsapi->freeCore(p->vscore);
-}
-
-static int drv_lazy_load_core(struct priv *p)
-{
- // not needed
- return 0;
-}
-
-static struct priv *get_priv(lua_State *L)
-{
- lua_getfield(L, LUA_REGISTRYINDEX, "p"); // p
- struct priv *p = lua_touserdata(L, -1); // p
- lua_pop(L, 1); // -
- return p;
-}
-
-static void vsmap_to_table(lua_State *L, int index, VSMap *map)
-{
- struct priv *p = get_priv(L);
- const VSAPI *vsapi = p->vsapi;
- for (int n = 0; n < vsapi->propNumKeys(map); n++) {
- const char *key = vsapi->propGetKey(map, n);
- VSPropTypes t = vsapi->propGetType(map, key);
- switch (t) {
- case ptInt:
- lua_pushnumber(L, vsapi->propGetInt(map, key, 0, NULL));
- break;
- case ptFloat:
- lua_pushnumber(L, vsapi->propGetFloat(map, key, 0, NULL));
- break;
- case ptNode: {
- VSNodeRef *r = vsapi->propGetNode(map, key, 0, NULL);
- MP_TARRAY_APPEND(p, p->gc_noderef, p->num_gc_noderef, r);
- lua_pushlightuserdata(L, r);
- break;
- }
- default:
- luaL_error(L, "unknown map type");
- }
- lua_setfield(L, index, key);
- }
-}
-
-static VSMap *table_to_vsmap(lua_State *L, int index)
-{
- struct priv *p = get_priv(L);
- const VSAPI *vsapi = p->vsapi;
- assert(index > 0);
- VSMap *map = vsapi->createMap();
- MP_TARRAY_APPEND(p, p->gc_map, p->num_gc_map, map);
- if (!map)
- luaL_error(L, "out of memory");
- lua_pushnil(L); // nil
- while (lua_next(L, index) != 0) { // key value
- if (lua_type(L, -2) != LUA_TSTRING) {
- luaL_error(L, "key must be a string, but got %s",
- lua_typename(L, -2));
- }
- const char *key = lua_tostring(L, -2);
- switch (lua_type(L, -1)) {
- case LUA_TNUMBER: {
- // gross hack because we hate everything
- if (strncmp(key, "i_", 2) == 0) {
- vsapi->propSetInt(map, key + 2, lua_tointeger(L, -1), 0);
- } else {
- vsapi->propSetFloat(map, key, lua_tonumber(L, -1), 0);
- }
- break;
- }
- case LUA_TSTRING: {
- const char *s = lua_tostring(L, -1);
- vsapi->propSetData(map, key, s, strlen(s), 0);
- break;
- }
- case LUA_TLIGHTUSERDATA: { // assume it's VSNodeRef*
- VSNodeRef *node = lua_touserdata(L, -1);
- vsapi->propSetNode(map, key, node, 0);
- break;
- }
- default:
- luaL_error(L, "unknown type");
- break;
- }
- lua_pop(L, 1); // key
- }
- return map;
-}
-
-static int l_invoke(lua_State *L)
-{
- struct priv *p = get_priv(L);
- const VSAPI *vsapi = p->vsapi;
-
- VSPlugin *plugin = vsapi->getPluginByNs(luaL_checkstring(L, 1), p->vscore);
- if (!plugin)
- luaL_error(L, "plugin not found");
- VSMap *map = table_to_vsmap(L, 3);
- VSMap *r = vsapi->invoke(plugin, luaL_checkstring(L, 2), map);
- MP_TARRAY_APPEND(p, p->gc_map, p->num_gc_map, r);
- if (!r)
- luaL_error(L, "?");
- const char *err = vsapi->getError(r);
- if (err)
- luaL_error(L, "error calling invoke(): %s", err);
- int err2 = 0;
- VSNodeRef *node = vsapi->propGetNode(r, "clip", 0, &err2);
- MP_TARRAY_APPEND(p, p->gc_noderef, p->num_gc_noderef, node);
- if (node)
- lua_pushlightuserdata(L, node);
- return 1;
-}
-
-struct load_ctx {
- struct priv *p;
- VSMap *vars;
- int status;
-};
-
-static int load_stuff(lua_State *L)
-{
- struct load_ctx *ctx = lua_touserdata(L, -1);
- lua_pop(L, 1); // -
- struct priv *p = ctx->p;
-
- // setup stuff; should be idempotent
- lua_pushlightuserdata(L, p);
- lua_setfield(L, LUA_REGISTRYINDEX, "p"); // -
- lua_pushcfunction(L, l_invoke);
- lua_setglobal(L, "invoke");
-
- FUCKYOUOHGODWHY(L);
- vsmap_to_table(L, lua_gettop(L), ctx->vars);
- if (luaL_dofile(L, p->opts->file))
- lua_error(L);
- lua_pop(L, 1);
-
- lua_getglobal(L, "video_out"); // video_out
- if (!lua_islightuserdata(L, -1))
- luaL_error(L, "video_out not set or has wrong type");
- p->out_node = p->vsapi->cloneNodeRef(lua_touserdata(L, -1));
- return 0;
-}
-
-static int drv_lazy_load(struct priv *p, VSMap *vars)
-{
- struct load_ctx ctx = {p, vars, 0};
- if (mp_cpcall(p->ls, load_stuff, &ctx)) {
- MP_FATAL(p, "filter creation failed: %s\n", lua_tostring(p->ls, -1));
- lua_pop(p->ls, 1);
- ctx.status = -1;
- }
- assert(lua_gettop(p->ls) == 0);
- return ctx.status;
-}
-
-static void drv_lazy_unload(struct priv *p)
-{
- for (int n = 0; n < p->num_gc_noderef; n++) {
- VSNodeRef *ref = p->gc_noderef[n];
- if (ref)
- p->vsapi->freeNode(ref);
- }
- p->num_gc_noderef = 0;
- for (int n = 0; n < p->num_gc_map; n++) {
- VSMap *map = p->gc_map[n];
- if (map)
- p->vsapi->freeMap(map);
- }
- p->num_gc_map = 0;
-}
-
-static const struct script_driver drv_lazy = {
- .init = drv_lazy_init,
- .uninit = drv_lazy_uninit,
- .load_core = drv_lazy_load_core,
- .load = drv_lazy_load,
- .unload = drv_lazy_unload,
-};
-
-const struct mp_user_filter_entry vf_vapoursynth_lazy = {
- .desc = {
- .description = "VapourSynth bridge (Lua)",
- .name = "vapoursynth-lazy",
- .priv_size = sizeof(OPT_BASE_STRUCT),
- .priv_defaults = &(const OPT_BASE_STRUCT){
- .drv = &drv_lazy,
- },
- .options = vf_opts_fields,
- },
- .create = vf_vapoursynth_create,
-};
-
-#endif
diff --git a/wscript b/wscript
index f19ba6565a..75e90aceab 100644
--- a/wscript
+++ b/wscript
@@ -392,20 +392,10 @@ iconv support use --disable-iconv.",
'func': check_pkg_config('lcms2', '>= 2.6'),
}, {
'name': '--vapoursynth',
- 'desc': 'VapourSynth filter bridge (Python)',
+ 'desc': 'VapourSynth filter bridge',
'func': check_pkg_config('vapoursynth', '>= 24',
'vapoursynth-script', '>= 23'),
}, {
- 'name': '--vapoursynth-lazy',
- 'desc': 'VapourSynth filter bridge (Lazy Lua)',
- 'deps': 'lua',
- 'func': check_pkg_config('vapoursynth', '>= 24'),
- }, {
- 'name': 'vapoursynth-core',
- 'desc': 'VapourSynth filter bridge (core)',
- 'deps': 'vapoursynth || vapoursynth-lazy',
- 'func': check_true,
- }, {
'name': '--libarchive',
'desc': 'libarchive wrapper for reading zip files and more',
'func': check_pkg_config('libarchive >= 3.0.0'),
diff --git a/wscript_build.py b/wscript_build.py
index 8f2f804a39..56668f1a09 100644
--- a/wscript_build.py
+++ b/wscript_build.py
@@ -391,7 +391,7 @@ def build(ctx):
( "video/filter/vf_d3d11vpp.c", "d3d-hwaccel" ),
( "video/filter/vf_format.c" ),
( "video/filter/vf_sub.c" ),
- ( "video/filter/vf_vapoursynth.c", "vapoursynth-core" ),
+ ( "video/filter/vf_vapoursynth.c", "vapoursynth" ),
( "video/filter/vf_vavpp.c", "vaapi" ),
( "video/filter/vf_vdpaupp.c", "vdpau" ),
( "video/fmt-conversion.c" ),