Log in

View Full Version : Vapoursynth


Pages : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 [86] 87 88 89 90 91 92 93 94 95 96 97 98 99 100

stax76
23rd March 2021, 18:37
@jinkazuya

Yes, it appears it was included by an ex maintainer, but it might not be available in the menu, for that there is documentation here:

https://github.com/staxrip/staxrip/wiki/Usage#video-processing

https://github.com/staxrip/staxrip/wiki/How-to-register-DGDecNV%28DGSource-and-DGIndexNV%29-in-StaxRip

jinkazuya
23rd March 2021, 20:43
It seems it is aready included https://github.com/staxrip/staxrip/wiki/Tools#g41fun

@jinkazuya

Yes, it appears it was included by an ex maintainer, but it might not be available in the menu, for that there is documentation here:

https://github.com/staxrip/staxrip/wiki/Usage#video-processing

https://github.com/staxrip/staxrip/wiki/How-to-register-DGDecNV%28DGSource-and-DGIndexNV%29-in-StaxRip

The github page does not exist anymore for the plugin or script of detailsharpen, which is why if possible, if the plugin is included in the menu in the future release, that would be awesome.

stax76
23rd March 2021, 22:54
@jinkazuya

Please create a new thread (or use the staxrip thread) asking for code and default values and then add this code and values to the following wiki page:

Tool Update Requests (https://github.com/staxrip/staxrip/wiki/Tool-Update-Requests)

jackoneill
24th March 2021, 13:01
I have some problem with MakeDiff in versions 50,51,52 :x
Script evaluation failed:
Python exception: MakeDiff: both clips must have constant format and dimensions, and the same format and dimensions

Traceback (most recent call last):
File "src/cython/vapoursynth.pyx", line 2244, in vapoursynth.vpy_evaluateScript
File "src/cython/vapoursynth.pyx", line 2245, in vapoursynth.vpy_evaluateScript
File "/mnt/dod/04.vpy", line 11, in <module>
clip = haf.QTGMC(clip, TFF=True, Preset="Placebo", ShowSettings=False, opencl=False, device=0, TR0=2, TR1=2, SourceMatch=0, TR2=0, Lossless=0, Sharpness=0 )
File "/usr/lib/python3.6/site-packages/havsfunc.py", line 1281, in QTGMC
noise = core.std.MakeDiff(clip, denoised, planes=CNplanes)
File "src/cython/vapoursynth.pyx", line 2069, in vapoursynth.Function.__call__
vapoursynth.Error: MakeDiff: both clips must have constant format and dimensions, and the same format and dimensions

linux, all compiled today, used LD_PRELOAD to test for plugin errors and there are none, without QTGMC the script works, latest mvsfunc and havsfunc

import vapoursynth as vs
import havsfunc as haf

core = vs.get_core()
core.set_max_cache_size(16000)

clip = core.ffms2.Source("//mnt//dod//movie.mkv")
clip = core.fmtc.bitdepth (clip, bits=16, fulls=False, fulld=True, dmode=1)
clip = haf.QTGMC(clip, TFF=True, Preset="Placebo", ShowSettings=False, opencl=False, device=0, TR0=2, TR1=2, SourceMatch=0, TR2=0, Lossless=0, Sharpness=0 )
clip = haf.MCTemporalDenoise(clip, radius=3, limit=2, twopass=False, limit2=2, refine=True, useTTmpSm=True, stabilize=False, maxr=3, TTstr=3, chroma=False, MVsharp=False, sigma=0, pfMode=-1,search=3, searchparam=4, pel=4, pelsearch=4, bwbh=512, owoh=256, blksize=4, overlap=2, deblock=False, post=0,bt=4,thSAD=2000, thSAD2=2000, thSCD1=1000, thSCD2=200)
clip = core.deblock.Deblock(clip, quant=20, aoffset=0, boffset=0)
clip = core.fmtc.bitdepth (clip, bits=10, fulls=True, fulld=True, dmode=1)
clip.set_output()

tested several older versions of havsfunc no change :x
I removed this code from src/core/mergefilters.c and it started working fine and the video looks correct
if (!isConstantFormat(d.vi) || !isSameFormat(d.vi, vsapi->getVideoInfo(d.node2))) {
vsapi->freeNode(d.node1);
vsapi->freeNode(d.node2);
RETERROR("MakeDiff: both clips must have constant format and dimensions, and the same format and dimensions");
}

strange problem

The error message gives you the line number in havsfunc.py (1281), so right before that line add

print(clip)
print(denoised)

to see what the difference is between those clips.

Patman
27th March 2021, 00:50
Hello everybody. I need your help with the following problem:

I have this code in my avs.c:

h->bit_depth = h->func.avs_bits_per_component(vi);
FAIL_IF_ERROR( h->bit_depth < 8 || h->bit_depth > 16, "unsupported bit depth `%d'\n", h->bit_depth );
if( h->bit_depth & 7 )
{
AVS_Value arg_arr[2];
arg_arr[0] = res;
arg_arr[1] = avs_new_value_int( 16 );
const char *arg_name[] = { NULL, "bits" };
AVS_Value res2 = h->func.avs_invoke( h->env, "ConvertBits", avs_new_value_array( arg_arr, 2 ), arg_name );
FAIL_IF_ERROR( avs_is_error( res2 ), "couldn't convert to 16 bits: %s\n", avs_as_error( res2 ) );
res = update_clip( h, &vi, res2, res );
}

I would now like to store a code with an identical function in my vpy.c, but unfortunately it doesn't work that well. I have the following approach:

h->bit_depth = vi->format->bitsPerSample;
FAIL_IF_ERROR( h->bit_depth < 8 || h->bit_depth > 16, "unsupported bit depth `%d'\n", h->bit_depth );
FAIL_IF_ERROR( vi->format->sampleType == stFloat, "unsupported sample type `float'\n" );
if (h->bit_depth & 7)
{
VSMap* args = h->vsapi->createMap();
const char* error;
VSPlugin* fmtcPlugin = h->vsapi->getPluginById("fmtconv", core);

h->vsapi->propSetNode(args, "clip", h->node, paReplace);
h->vsapi->freeNode(h->node);
const VSFormat* new_format = h->vsapi->registerFormat(vi->format->colorFamily, vi->format->sampleType, 16, vi->format->subSamplingW, vi->format->subSamplingH, core);
h->vsapi->propSetInt(args, "csp", new_format->id, paReplace);
VSMap* ret = h->vsapi->invoke(fmtcPlugin, "bitdepth", args);
error = h->vsapi->getError(ret);
if (error)
{
FAIL_IF_ERROR(1, "failed to convert node to 16 bits: `%s'\n", error);
h->vsapi->freeMap(args);
h->vsapi->freeMap(ret);
return -1;
}
h->node = h->vsapi->propGetNode(ret, "clip", 0, NULL);
h->vsapi->freeMap(ret);
}

The aim is to consider certain plugins when processing. With avs it is 'ConvertBits' and with vpy 'fmtconv'. Does somebody has any idea?

feisty2
27th March 2021, 06:00
if you have a C++20 compiler (I guess GCC11 is currently the only option), you can play with my C++ wrapper for VS API (https://github.com/IFeelBloated/vsFilterScript) and coding a plugin is no more complicated than python scripting.

if you need to invoke an external filter as some sort of preprocessing, you can do it directly in the constructor of the filter

MyFilter(auto Arguments, auto Core) {
auto PreprocessedClip = Core["fmtc"]["bitdepth"]("clip", Arguments["clip"], "bits", 16);
}

alternatively, you can define InitiateCallGraph() (https://github.com/IFeelBloated/vsFilterScript/blob/master/Examples/SeparableConvolution.hxx#L51) if you need to run a more complex filter sequence, where you can invoke external filters for postprocessing, or recursively invoke the filter that is being defined.

feisty2
27th March 2021, 06:17
and no error checking of any sort is required (unless you need to change how your filter behaves based on if an evaluation fails), the error message (plugin not found, evaluation failed, or whatever) will automatically propagate to the console (vsedit, vspipe, etc.)

DJATOM
27th March 2021, 10:13
Since it's about x264, it uses C compiler, not C++.

feisty2
27th March 2021, 11:09
He/She didn't mention what it is that he/she's working on so I wouldn't have known. and since x264 already relies on GCC, it should be pretty handy for him/her to use the C++ wrapper (C99, the standard that x264 seems to be using, is mostly a subset of C++20 after all).

Patman
27th March 2021, 14:05
I'll give your wrapper a try.

As DJATOM already mentioned, the files are written in C (C compiler) and are used to directly support avs / vpy scripts in x264.

feisty2
28th March 2021, 09:53
@Myrsloik
is it safe to delete the user data passed to registerFunction() in Create() like the following?

auto RegisterFunction(auto&& Signature, auto&& Function) {
using FunctionType = std::decay_t<decltype(Function)>;
auto FunctionHandle = new auto{ std::forward<decltype(Function)>(Function) };
auto Create = [](auto in, auto out, auto FunctionHandle, auto core, auto...) {
auto& RegisteredFunction = *reinterpret_cast<FunctionType*>(FunctionHandle);
Console{ out }.Receive(RegisteredFunction(ArgumentList{ in }, CoreProxy{ core }));
delete &RegisteredFunction;
};
::vsapi->registerFunction(DeduceName(Signature), ExtractParamList(Signature), Create, FunctionHandle, ::PluginHandle);
}

RegisterFunction("f(x: int[])", [](auto args, auto Core) { for (auto y : args["x"]) Core.Print(static_cast<int>(y)); return 42; });

I guess what I am actually asking is that will Create() run on mutiple threads which then leads to the risk of use-after-free or double-free?

Myrsloik
28th March 2021, 11:50
@Myrsloik
is it safe to delete the user data passed to registerFunction() in Create() like the following?
[code]
...

No. Filter creation can be multithreaded too (mostly happens when you create and destroy filters in a getframe function).

feisty2
28th March 2021, 12:17
then who deletes the user data? I searched thru avisynth_compat.cpp (https://github.com/vapoursynth/vapoursynth/blob/master/src/avisynth/avisynth_compat.cpp) and didn't find where the WrappedFunction object (https://github.com/vapoursynth/vapoursynth/blob/master/src/avisynth/avisynth_compat.cpp#L724) gets deleted :confused:

jackoneill
28th March 2021, 12:29
Hello everybody. I need your help with the following problem:

I have this code in my avs.c:

h->bit_depth = h->func.avs_bits_per_component(vi);
FAIL_IF_ERROR( h->bit_depth < 8 || h->bit_depth > 16, "unsupported bit depth `%d'\n", h->bit_depth );
if( h->bit_depth & 7 )
{
AVS_Value arg_arr[2];
arg_arr[0] = res;
arg_arr[1] = avs_new_value_int( 16 );
const char *arg_name[] = { NULL, "bits" };
AVS_Value res2 = h->func.avs_invoke( h->env, "ConvertBits", avs_new_value_array( arg_arr, 2 ), arg_name );
FAIL_IF_ERROR( avs_is_error( res2 ), "couldn't convert to 16 bits: %s\n", avs_as_error( res2 ) );
res = update_clip( h, &vi, res2, res );
}

I would now like to store a code with an identical function in my vpy.c, but unfortunately it doesn't work that well. I have the following approach:

h->bit_depth = vi->format->bitsPerSample;
FAIL_IF_ERROR( h->bit_depth < 8 || h->bit_depth > 16, "unsupported bit depth `%d'\n", h->bit_depth );
FAIL_IF_ERROR( vi->format->sampleType == stFloat, "unsupported sample type `float'\n" );
if (h->bit_depth & 7)
{
VSMap* args = h->vsapi->createMap();
const char* error;
VSPlugin* fmtcPlugin = h->vsapi->getPluginById("fmtconv", core);

h->vsapi->propSetNode(args, "clip", h->node, paReplace);
h->vsapi->freeNode(h->node);
const VSFormat* new_format = h->vsapi->registerFormat(vi->format->colorFamily, vi->format->sampleType, 16, vi->format->subSamplingW, vi->format->subSamplingH, core);
h->vsapi->propSetInt(args, "csp", new_format->id, paReplace);
VSMap* ret = h->vsapi->invoke(fmtcPlugin, "bitdepth", args);
error = h->vsapi->getError(ret);
if (error)
{
FAIL_IF_ERROR(1, "failed to convert node to 16 bits: `%s'\n", error);
h->vsapi->freeMap(args);
h->vsapi->freeMap(ret);
return -1;
}
h->node = h->vsapi->propGetNode(ret, "clip", 0, NULL);
h->vsapi->freeMap(ret);
}

The aim is to consider certain plugins when processing. With avs it is 'ConvertBits' and with vpy 'fmtconv'. Does somebody has any idea?

It looks like it should function. What problem did you encounter?

Things I noticed:
- You're leaking the args VSMap. You should free it after you call invoke.
- getPluginById can return NULL if the plugin you want is not loaded. fmtconv is not included with VapourSynth. You could use the built-in resizer (com.vapoursynth.resize (http://www.vapoursynth.com/doc/functions/resize.html)), then you don't really have to check what getPluginById returns.

Myrsloik
28th March 2021, 12:41
then who deletes the user data? I searched thru avisynth_compat.cpp (https://github.com/vapoursynth/vapoursynth/blob/master/src/avisynth/avisynth_compat.cpp) and didn't find where the WrappedFunction object (https://github.com/vapoursynth/vapoursynth/blob/master/src/avisynth/avisynth_compat.cpp#L724) gets deleted :confused:

Nobody deletes it. It's mostly a bad inherited avisynth-ism and should probably never be used.

Myrsloik
28th March 2021, 12:44
R53-RC1 (https://github.com/vapoursynth/vapoursynth/releases/tag/R53-RC1)
updated visual studio 2019 runtime version
updated to python 3.9 for windows
fixed length calculation in y4m header (djatom)
added long path support to vspipe (stax76)
fixed crash in text filter with small resolution clips (jackoneill)
fixed calling wrapped functions through python (IFeelBloated)

Finally doing a bit of development again. Note that the included vsrepo has some fixes too.

l00t
28th March 2021, 13:48
Thanks for the new release!

With the portable version combined with python 3.9.2 embedded I get Failed to initialize VapourSynth environment
(both with vspipe -v and also in vseditor)

Previously I had R52 with 3.8.8 working just fine (portable+embedded). I copied over the fresh files and I get this.

The installed version works fine with the installer version of python 3.9.2...

What did I do wrong? Any suggestions?

I'm on Win10 20H2 x64. Both python and vs are 64-bit variants.

l00t
28th March 2021, 13:55
Hmm, placing vapoursynth.cp39-win_amd64.pyd under Lib\site-packages seems to solve this issue...

Myrsloik
28th March 2021, 13:58
Thanks for the new release!

With the portable version combined with python 3.9.2 embedded I get Failed to initialize VapourSynth environment
(both with vspipe -v and also in vseditor)

Previously I had R52 with 3.8.8 working just fine (portable+embedded). I copied over the fresh files and I get this.

The installed version works fine with the installer version of python 3.9.2...

What did I do wrong? Any suggestions?

I'm on Win10 20H2 x64. Both python and vs are 64-bit variants.

Doh, typo in the portable build script so the actual module didn't get included. Redownload it.

l00t
28th March 2021, 14:02
Ah, now it works like a charm without messing with precompiled files. Thank you!

feisty2
28th March 2021, 15:28
Nobody deletes it. It's mostly a bad inherited avisynth-ism and should probably never be used.

I guess it might be somewhat useful for "bridge" plugins (bridging foreign plugins developed for other video processing software to VS, like core.avs.LoadPlugin), and it allows the user to register stateful lambdas as plugin functions.

I guess I could tie the lifetime of user data to a static variable like the following

struct GlobalRecyler {
using RecordType = std::tuple<auto(*)(void*)->void, void*>;
std::vector<RecordType> Records = {};

GlobalRecyler() = default;
GlobalRecyler(const GlobalRecyler&) = delete;
GlobalRecyler(GlobalRecyler&&) = delete;
auto& operator=(const GlobalRecyler&) = delete;
auto& operator=(GlobalRecyler&&) = delete;

auto Collect(auto Garbage) {
using GarbageType = std::decay_t<decltype(*Garbage)>;
Records.push_back({ [](auto PointerToGarbage) { delete reinterpret_cast<GarbageType*>(PointerToGarbage); }, Garbage });
}

~GlobalRecyler() {
for (auto [Recyler, Garbage] : Records)
Recyler(Garbage);
}
};

auto RegisterFunction(auto&& Signature, auto&& Function) {
using FunctionType = std::decay_t<decltype(Function)>;
static auto Evil = GlobalRecyler{};
auto FunctionHandle = new auto{ std::forward<decltype(Function)>(Function) };
auto Create = [](auto in, auto out, auto FunctionHandle, auto core, auto...) {
auto& RegisteredFunction = *reinterpret_cast<FunctionType*>(FunctionHandle);
Console{ out }.Receive(RegisteredFunction(ArgumentList{ in }, CoreProxy{ core }));
};
Evil.Collect(FunctionHandle);
::vsapi->registerFunction(DeduceName(Signature), ExtractParamList(Signature), Create, FunctionHandle, ::PluginHandle);
}


and the user data will be recycled along with the static variable when the plugin is unloaded, that should work, right?

Myrsloik
31st March 2021, 10:09
and the user data will be recycled along with the static variable when the plugin is unloaded, that should work, right?

Stop the madness!

You have to ask yourself if you're writing a wrapper to create new good plugins or if it's only a programming exercise to sexually please yourself using naughty code. The correct pattern is for the plugin itself to have an internal filter initialization counter or properly free everything on library unload. That pointer is useless if you have any idea what you're doing when writing code.

feisty2
31st March 2021, 14:57
well I'm not doing it just because I can, I'm doing it because I think there is indeed a valid use case. I've excluded quite a few rarely used or deprecated things or things that are not meant to be used by plugin developers from the C API (setMessageHandler, queryCompletedFrame, releaseFrameEarly, arFrameReady, nfIsCache, nfMakeLinear, cmCompat and all Compat formats, also all "map" stuff is invisible to the user). I would have excluded the use of this pointer too if I didn't already find a use case for it.

a while ago @lansing requested an example of a bridge plugin to load Vdubfilters (http://forum.doom9.net/showpost.php?p=1933851&postcount=76), while I never had the time to finish the example he/she asked for, I did take a quick glance over how it's done in avisynth (https://github.com/pinterf/AviSynthPlus/blob/master/plugins/VDubFilter/VDubFilter.cpp#L1544). there's this configuration object (fdl) representing the state of a virtualdub filter that you must pass to a filter instance, I suppose the skeleton of the bridge plugin would be something like

struct VirtualDubProxy {
VirtualDubProxy(auto Arguments, auto& Configurations, auto Core) {
auto& [ReferenceCounter, VirtualDubFunctionHandles, _] = Configurations;
...
}

static auto SpecifySignature(auto& Configurations) {
auto& [_, __, RawSignature] = Configurations;
...
return ... // converts RawSignature to VS signature format
}

....
};

for (auto& x : VirtualDubPlugin.ListFunctions())
PluginAPI::RegisterFilter<VirtualDubProxy>(x.ZipConfigurations());

apparently RegisterFilter() is just a wrapper for vsapi->registerFunction() and Create(), and the only place that allows me to pass that configuration object seems to be that userData pointer. so I don't know how this is possible without using that pointer. the configuration object will have a static lifetime so it can be accessed by all filter instances across threads, and itself may contain a reference counter and some resources may be released as soon as the reference count drops to 0, I don't understand how any of this is madness.

Myrsloik
10th April 2021, 14:50
R53-RC2 (https://github.com/vapoursynth/vapoursynth/releases/tag/R53-RC2)
r53:
updated visual studio 2019 runtime version
updated to python 3.9 for windows
added scale argument to text filters (AkarinVS)
fixed length calculation in y4m header (djatom)
added long path support to vspipe (stax76)
fixed crash in text filter with small resolution clips (jackoneill)
fixed calling wrapped functions through python (IFeelBloated)

Test it a bit. Probably the final RC so this thing gets released.

stax76
10th April 2021, 16:20
I tested portable with Python 3.9.4, it works fine.

Long path support might not be useful currently because original/vanilla x265 builds don't support long path, most builds are modded, mods from DJATOM, Patman and MeteorRain have a vs reader included, Lighs builds are based on synth readers from DJATOM and MeteorRain, links are here:

https://github.com/staxrip/staxrip/wiki/x265

unix
20th April 2021, 19:13
Guys I have an issue, I installed placebo plugin but vsp editor cant recognize it!

Note: I'm using portable Vapoursynth just for tests

Myrsloik
21st April 2021, 17:59
R53 is released (https://github.com/vapoursynth/vapoursynth/releases/tag/R53)!

updated visual studio 2019 runtime version
updated to python 3.9 for windows
added scale argument to text filters (AkarinVS)
fixed length calculation in y4m header (djatom)
added long path support to vspipe (stax76)
fixed crash in text filter with small resolution clips (jackoneill)
fixed calling wrapped functions through python (IFeelBloated)

Hopefully I'll have time to finish the mythic audio branch this summer.

Nico8583
22nd April 2021, 14:21
Thank you Myrsloik ! The Windows portable installation is the same than previous versions (except Python 3.9 instead of 3.8 - Decompress R53 into Python 3.9 embeddable folder) ? Thank you.

vcmohan
23rd April 2021, 08:05
It is a great convenience that vapousynth input script allows arrays. I am however curious whether an array of arrays for example filt:int[[],[],[],...]: opt; can be used in the code of plugin. If its possible how to get input number of arrays and number of elements in each array.

Myrsloik
23rd April 2021, 09:21
It is a great convenience that vapousynth input script allows arrays. I am however curious whether an array of arrays for example filt:int[[],[],[],...]: opt; can be used in the code of plugin. If its possible how to get input number of arrays and number of elements in each array.

No, only 1D arrays are allowed to keep the api simple. If you have a fixed number of dimensions simply add a second argument to specify the row size to get around it. Or implicitly figure out the array dimensions like the convolution filter.

Myrsloik
23rd April 2021, 09:43
Thank you Myrsloik ! The Windows portable installation is the same than previous versions (except Python 3.9 instead of 3.8 - Decompress R53 into Python 3.9 embeddable folder) ? Thank you.

Yes, same procedure as every year.

Selur
19th May 2021, 20:45
Is there anything similar to a 'vibrance' filter in photoshop and similar in Vapoursynth (some sort of restricted saturation filtering)?

Myrsloik
20th May 2021, 17:21
We looked a bit at the mess that is mask handling recently and now I have one simple question:

Is there any script out there that actually passes a YUV clip as the mask argument of MaskedMerge and doesn't set first_plane=1? (and doesn't simply discard the output UV planes later).
MaskedMerge(YUVclipA, YUVclipB, YUVmask)

I think the answer is no. Counterexamples welcome.

feisty2
1st June 2021, 18:52
any plan to replace this (https://github.com/vapoursynth/vapoursynth/blob/master/src/core/ter-116n.h) with a real font? It can't even display tabs...

Myrsloik
1st June 2021, 21:27
any plan to replace this (https://github.com/vapoursynth/vapoursynth/blob/master/src/core/ter-116n.h) with a real font? It can't even display tabs...

Nope, the whole point is that it adds no external dependencies at all for basic printing. If there's particular control shit or a like tabs simply create an issue for it and maybe someone will look at it.

Selur
13th June 2021, 16:23
Hi, I'm trying to get VSGAN running in a fresh portable Vapoursynth setup, see: https://github.com/rlaphoenix/VSGAN/issues/7
at the end I use this script:
# Imports
import os
import sys
import vapoursynth as vs
core = vs.get_core()

# Import scripts folder
scriptPath = 'I:/Hybrid/64bit/vsscripts'
sys.path.append(os.path.abspath(scriptPath))

# Loading Plugins
core.std.LoadPlugin(path="I:/Hybrid/64bit/vsfilters/SourceFilter/FFMS2/ffms2.dll")

# Import scripts
import mvsfunc

# source: 'G:\TestClips&Co\test.avi'
# current color space: YUV420P8, bit depth: 8, resolution: 640x352, fps: 25, color matrix: 470bg, yuv luminance scale: limited, scanorder: progressive
# Loading source using FFMS2
clip = core.ffms2.Source(source="G:/TestClips&Co/test.avi",cachefile="E:/Temp/avi_9dec25d3f707eb4813d42334c7f1a8d6_853323747.ffindex",format=vs.YUV420P8,alpha=False)

# adjusting color space from YUV420P8 to RGB24 for vsVSGAN
clip = core.resize.Bicubic(clip=clip, format=vs.RGB24, matrix_in_s="470bg", range_s="limited")

# resizing using VSGAN
from vsgan import VSGAN
vsgan = VSGAN("cuda")
model = "I:/Hybrid/64bit/vsgan_models/4x_BSRGAN.pth"
vsgan.load_model(model)
clip = vsgan.run(clip=clip)

# Output
clip.set_output()
call it using:
i:\Vapoursynth\VSPipe.exe --info C:\Users\Selur\Desktop\testvsgan.vpy -
and end up with:
Script evaluation failed:
Python exception: cannot import name 'VSGAN' from 'vsgan' (i:\Vapoursynth\Lib\site-packages\vsgan\__init__.py)

Traceback (most recent call last):
File "src\cython\vapoursynth.pyx", line 2242, in vapoursynth.vpy_evaluateScript
File "src\cython\vapoursynth.pyx", line 2243, in vapoursynth.vpy_evaluateScript
File "C:\Users\Selur\Desktop\testvsgan.vpy", line 26, in <module>
from vsgan import VSGAN
ImportError: cannot import name 'VSGAN' from 'vsgan' (i:\Vapoursynth\Lib\site-packages\vsgan\__init__.py)
Problem is I have no clue where to look or what I might need to adjust.

When I use the FATPACK as basis instead of using the portable Python and Vapoursynth the was I did, it does work.
-> does anyone have an idea what I might have to adjust to make this work?

Cu Selur

Selur
13th June 2021, 17:06
Got it working by creating a fake I:\Vapoursynth\Lib\site-packages\VapourSynth-53.dist-info folder with some fake info and uninstalling and reinstalling VSGAN I got it working! :)
Side note: the portable version should contain a Lib\site-packages\VapourSynth-53.dist-info-folder with proper infos.

Cu Selur

EnC
25th June 2021, 04:45
Got it working by creating a fake I:\Vapoursynth\Lib\site-packages\VapourSynth-53.dist-info folder with some fake info and uninstalling and reinstalling VSGAN I got it working! :)
Side note: the portable version should contain a Lib\site-packages\VapourSynth-53.dist-info-folder with proper infos.

Cu Selur

This little trick did work for me too to install awsmfunc (https://git.concertos.live/AHD/awsmfunc) too. Strange it fails during 'requirements' without fake 'VapourSynth-53.dist-info' folder. :rolleyes:

Selur
26th June 2021, 09:13
Since my python skills aren't that high I'm not sure whether I made a mistake or this is a bug. :)
Using vs-placebo (https://github.com/Lypheo/vs-placebo) with shader="path to file" works fine for me, but using 'shader_s' does not.

Calling:

# Imports
import vapoursynth as vs
core = vs.get_core()
# Loading Plugins
core.std.LoadPlugin(path="I:/Hybrid/64bit/vsfilters/Support/libvs_placebo.dll")
core.std.LoadPlugin(path="I:/Hybrid/64bit/vsfilters/SourceFilter/FFMS2/ffms2.dll")
# source: 'G:\TestClips&Co\test.avi'
# current color space: YUV420P8, bit depth: 8, resolution: 640x352, fps: 25, color matrix: 470bg, yuv luminance scale: limited, scanorder: progressive
# Loading source using FFMS2
clip = core.ffms2.Source(source="G:/TestClips&Co/test.avi",cachefile="E:/Temp/avi_9dec25d3f707eb4813d42334c7f1a8d6_853323747.ffindex",format=vs.YUV420P8,alpha=False)
# making sure input color matrix is set as 470bg
clip = core.resize.Point(clip, matrix_in_s="470bg",range_s="limited")
# making sure frame rate is set to 25
clip = core.std.AssumeFPS(clip=clip, fpsnum=25, fpsden=1)
# Setting color range to TV (limited) range.
clip = core.std.SetFrameProp(clip=clip, prop="_ColorRange", intval=1)
# GLSL filter: adaptive-sharpen.glsl
# adjusting color space from YUV420P8 to YUV444P16 for VsGLSLFilter
clip = core.resize.Bicubic(clip=clip, format=vs.YUV444P16, range_s="limited")
with open("I:/Hybrid/64bit/vsfilters/GLSL/adaptive-sharpen.glsl") as glslf:
glsl = glslf.read()
glsl = glsl.replace('#define curve_height 1.0', '#define curve_height 2.0');
clip = core.placebo.Shader(clip=clip, shader_s=glsl, width=640, height=352)
# adjusting output color from: YUV444P16 to YUV420P10 for x265Model (i420@8)
clip = core.resize.Bicubic(clip=clip, format=vs.YUV420P10, range_s="limited")
# set output frame rate to 25.000fps
clip = core.std.AssumeFPS(clip=clip, fpsnum=25, fpsden=1)
# Output
clip.set_output()

I get:

Failed to evaluate the script:
Python exception: Shader: Function does not take argument(s) named shader_s

Traceback (most recent call last):
File "src\cython\vapoursynth.pyx", line 2242, in vapoursynth.vpy_evaluateScript
File "src\cython\vapoursynth.pyx", line 2243, in vapoursynth.vpy_evaluateScript
File "C:\Users\Selur\Desktop\test.vpy", line 23, in <module>
clip = core.placebo.Shader(clip=clip, shader_s=glsl, width=640, height=352)
File "src\cython\vapoursynth.pyx", line 2040, in vapoursynth.Function.__call__vapoursynth.Error: Shader: Function does not take argument(s) named shader_s

according to:
placebo.Shader(clip clip, [string shader, int width, int height, int chroma_loc = 1, int matrix = 2, int trc = 1, string filter = "ewa_lanczos", float radius, float clamp, float taper, float blur, float param1, float param2, float antiring = 0.0, int lut_entries = 64, float cutoff = 0.001, bool sigmoidize = 1, bool linearize = 1, float sigmoid_center = 0.75, float sigmoid_slope = 6.5, string shader_s])
this should work, shouldn't it?

Cu Selur

Ps.: I also posted this to the vs-placebo github issue tracker (https://github.com/Lypheo/vs-placebo/issues/12).

Selur
26th June 2021, 10:02
Okay, that got solved, only master contained the shader_s-path not the current (1.1.0) release,..
-> if someone got a build environment for this would be nice if he could build and share a current 64bit Windows build of VSGAN

feisty2
27th June 2021, 14:18
anyone wants a general remap filter?

clip = core.std.Remap(clip, lambda y, x: [clip.height - y - 1, x]) # equivalent to FlipVertical
clip = core.std.Remap(clip, lambda y, x: [y, clip.width - x - 1]) # equivalent to FlipHorizontal

clip = core.std.StackVertical([clip, clip])
clip = core.std.StackHorizontal([clip, clip])
clip = core.std.Remap(clip, lambda y, x: [y // 2, x // 2]) # equivalent to 2x upscale by point resize

Myrsloik
27th June 2021, 14:27
anyone wants a general remap filter?

clip = core.std.Remap(clip, lambda y, x: [clip.height - y - 1, x]) # equivalent to FlipVertical
clip = core.std.Remap(clip, lambda y, x: [y, clip.width - x - 1]) # equivalent to FlipHorizontal

clip = core.std.StackVertical([clip, clip])
clip = core.std.StackHorizontal([clip, clip])
clip = core.std.Remap(clip, lambda y, x: [y // 2, x // 2]) # equivalent to 2x upscale by point resize


That's a fun thing to have. I think you should have destination width/height arguments so the point resize-ish cases don't require the dummy steps.

Selur
10th July 2021, 18:28
hi, I'm trying to convert the Avisynth function:
function filldrops(clip c, float "thresh")
{
thresh = default(thresh, 0.1)

super=MSuper(c,pel=2)
vfe=MAnalyse(super,truemotion=true,isb=false,delta =1)
vbe=MAnalyse(super,truemotion=true,isb=true,delta= 1)
filldrops = MFlowInter(c,super,vbe,vfe,time=50)
fixed = ConditionalFilter(c, filldrops, c, "YDifferenceFromPrevious()", "lessthan", String(thresh))
return fixed
}
slightly modified, source: https://forum.doom9.org/showthread.php?p=17751849

to Vapoursynth, and got:

def filldrops(c, thresh=0.1)

def YDifferenceFromPrevious(n, f, clips):
if f.props['_SceneChangePrev']:
return clips[0]
else:
return clips[1]

super=core.mv.Super(clip=c,pel=2)
vfe=core.mv.Analyse(clip=super,truemotion=true,isb=false,delta =1)
vbe=core.mv.Analyse(clip=super,truemotion=true,isb=true,delta= 1)
filldrops = core.mv.FlowInter(clip=c,super,mvbw=vbe,mvfw=vfe,time=50)
#fixed = ConditionalFilter(c, filldrops, c, "YDifferenceFromPrevious()", "lessthan", String(thresh))
fixed = core.std.FrameEval(...)
return fixed

but I'm stuck at the ConditionalFilter-line. :/
-> can someone tell me how FrameEval(...) should look like to do what ConditionalFilter(...) does ?

Thanks!

Cu Selur

Myrsloik
11th July 2021, 15:45
def filldrops(c, thresh=0.1)
diffclip = core.std.PlaneStats(c, c[0] + c)
super=core.mv.Super(clip=c,pel=2)
vfe=core.mv.Analyse(clip=super,truemotion=true,isb=false,delta =1)
vbe=core.mv.Analyse(clip=super,truemotion=true,isb=true,delta= 1)
filldrops = core.mv.FlowInter(clip=c,super,mvbw=vbe,mvfw=vfe,time=50)
def selectFunc(n, f):
if f.props['PlaneStatsDiff'] < thresh:
return c
else:
return filldrops

fixed = core.std.FrameEval(c, selectFunc, prop_src=diffclip)
return fixed


Didn't test it but it should be 99% of the way there. Simple selection.

Selur
11th July 2021, 16:36
Thanks ! :)

JKyle
12th July 2021, 00:32
Thanks, @Selur and @Myrsloik.

I fixed some syntax errors and slightly modified the script to make it work in StaxRip.

Here (https://github.com/JJKylee/Filter-Scripts/blob/main/VapourSynth/filldrops.py)'s the source code.

Myrsloik
16th July 2021, 12:36
R54-RC1 (https://github.com/vapoursynth/vapoursynth/releases/tag/R54-RC1)

This release makes the handling of floating point masks consistent (now always 0-1 range, even for UV planes) and fixes some other minor bugs. Should be a very stable build overall.

r54:
updated visual studio 2019 runtime version
updated zimg to 3.0.2
cliptoprop now uses the length of the second clip instead of the first one
added sin and cos operator to the expr filter (AkarinVS)
made handling of floating point masks consistent (AkarinVS and more)
fixed memory leak on free in expr filter on linux (AkarinVS)

Selur
16th July 2021, 17:21
btw. is there a way to stop auto-loading so that only explicitly loaded filters are loaded nowadays?

@JKyle: Any plans to port Dejump to Vaporusynth?

Myrsloik
16th July 2021, 21:57
btw. is there a way to stop auto-loading so that only explicitly loaded filters are loaded nowadays?

@JKyle: Any plans to port Dejump to Vaporusynth?

An option to disable auto loading is probably coming soon. With more exciting things as well.

Selur
17th July 2021, 08:26
An option to disable auto loading is probably coming soon. With more exciting things as well.
Nice! Thanks for the info, looking forward to it. :)