Log in

View Full Version : How to invoke() an external filter?


eac3to_mod
11th February 2024, 14:17
Can someone please explain how to invoke() an external filter? All the examples I have seen for invoke() are for internal filters. Also, I need this for the version 3 plugin API. A code snippet would be greatly appreciated. Thank you.

WolframRhodium
11th February 2024, 14:55
"Reverse URL" refers to the first argument you passed to "configFunc", which is an unique ID for each plugin (generally a DLL).


void filterCreate(...) {
// first calls getPluginByID / getPluginByNS to query the plugin instance
auto plugin = vsapi->getPluginById(...);

// creates a new map
auto args = vsapi->createMap(...);

// and sets arguments to external function
auto clip = vsapi->propGetNode(in, ...);
vsapi->propSetNode(args, "clip", clip, ...);

// other arguments
// vsapi->propSetInt(args, "radius", 0, ...);

// invoke the external function
// in case functions are calling functions in the same plugin, you don't even need to use the "reverse url":
// https://github.com/WolframRhodium/VapourSynth-BM3DCUDA/blob/8ab2b6f64cbafc7151f5271e00d1c70c8fa71070/source/source.cpp#L945
auto ret = vsapi->invoke(plugin, "function_name", args);

// vsapi->getError(ret);

// get the return value
auto ret_clip = vsapi->propGetNode(ret, "clip", ...);

// set as return value
vsapi->propSetNode(out, "clip", ret_clip, ...);
}


Some error checking and object destructions are omitted.

eac3to_mod
11th February 2024, 15:32
Thank you, sir, I will try it straight away.

eac3to_mod
11th February 2024, 15:53
This is what I have so far. It compiles and runs but doesn't invoke the filter.


...
vsapi->createFilter(in, out, "DGSource", VSVideoSource::Init, VSVideoSource::GetFrame, VSVideoSource::Free, fmUnordered, nfMakeLinear, vs, core);

auto plugin = vsapi->getPluginById("com.vapoursynth.dgdecodenv", core);
auto args = vsapi->createMap();
auto clip = vsapi->propGetNode(out, "clip", 0, NULL);
vsapi->propSetNode(args, "clip", clip, paReplace);
auto ret = vsapi->invoke(plugin, "Filter", args);
auto ret_clip = vsapi->propGetNode(args, "clip", 0, NULL);
vsapi->propSetNode(out, "clip", ret_clip, paReplace);


Note that I don't need any arguments to the filter.

Does Vapoursynth insert a cache between them?

Myrsloik
11th February 2024, 17:11
It's crashing at the first propGetNode(). This is what I have so far:


...
vsapi->createFilter(in, out, "DGSource", VSVideoSource::Init, VSVideoSource::GetFrame, VSVideoSource::Free, fmUnordered, nfMakeLinear, vs, core);

auto plugin = vsapi->getPluginById("com.vapoursynth.dgdecodenv", core);
auto args = vsapi->createMap();
auto clip = vsapi->propGetNode(in, "clip", 0, NULL); // crashes here
vsapi->propSetNode(args, "clip", clip, paReplace);
auto ret = vsapi->invoke(plugin, "Filter", args);
auto ret_clip = vsapi->propGetNode(ret, "clip", 0, NULL);
vsapi->propSetNode(out, "clip", ret_clip, paReplace);

I just guessed on what to put where you showed ... What am I doing wrong please? I don't need any arguments to the filter.

Does Vapoursynth insert a cache between them?

auto clip = vsapi->propGetNode(in, "clip", 0, NULL); // crashes here <= in should probably be out here

If the out map already contains what you need (a single clip I guess?) you can pass it directly instead of copying to a new map.

Caches are automatically inserted between filters if running under API4. You can manually add the Cache filter (no op in API4 since it does things differently) if you really need a cache when running under API3 as well.

eac3to_mod
11th February 2024, 18:40
Thank you. I had already changed the in to out and it runs but the filter does not get invoked. Please see the revised code in my first post. After the invoke is working I'll worry about the cache. I'm with API 3. I need a cache because Filter is a temporal filter talking to a source filter that doesn't want to receive out of order requests.

Feel free to just give me the code as I'm a stooge when it comes to Vapoursynth maps and nodes and all that. All of that is not explained anywhere that I can find. So I'm just groping around not knowing the underlying reasons for things. So I'd really appreciate some help. Thank you.

Myrsloik
11th February 2024, 20:31
Call getError() on the map returned from vsapi->invoke(). It should give you a proper error message if anything went wrong.

eac3to_mod
11th February 2024, 23:26
Thank you, that's got me moving again.

HolyWu
12th February 2024, 06:51
This is what I have so far. It compiles and runs but doesn't invoke the filter.


...
vsapi->createFilter(in, out, "DGSource", VSVideoSource::Init, VSVideoSource::GetFrame, VSVideoSource::Free, fmUnordered, nfMakeLinear, vs, core);

auto plugin = vsapi->getPluginById("com.vapoursynth.dgdecodenv", core);
auto args = vsapi->createMap();
auto clip = vsapi->propGetNode(out, "clip", 0, NULL);
vsapi->propSetNode(args, "clip", clip, paReplace);
auto ret = vsapi->invoke(plugin, "Filter", args);
auto ret_clip = vsapi->propGetNode(args, "clip", 0, NULL);
vsapi->propSetNode(out, "clip", ret_clip, paReplace);


Note that I don't need any arguments to the filter.

auto ret_clip = vsapi->propGetNode(ret, "clip", 0, NULL);

eac3to_mod
12th February 2024, 14:22
Thank you, sir.