pinterf / FFT3dGPU

FFT3dGPU
GNU General Public License v2.0
20 stars 1 forks source link

FR: Add VapourSynth interface #8

Open LigH-de opened 2 years ago

LigH-de commented 2 years ago

A comparable plugin for VapourSynth seems not to exist yet. So a dual interface DLL would surely be interesting for people comparing AviSynth with VapourSynth or writing applications which try to support both simultaneously (like Selur's Hybrid).

pinterf commented 2 years ago

Are you sure that this plugin is doing something differently/quicker than the fully rewritten Neo FFT3dFilter? (Yes, I'm trying to find reasons why not to do that :) )

LigH-de commented 2 years ago

Alright, Selur is discussing just that in the German Gleitz forum, I will tell him to tell his opinion here, he may agree to abandon this request...

pinterf commented 2 years ago

My opinion can be changed when later in this year I have more time than now and after doing my first VS conversion/addition it proves to be a quick and easy one. I think there was already another plugin I was requested to do this task but postponed for similar reasons.

Selur commented 2 years ago

I did some testing:

FFMS2 + NeoFFT3DFilter:

# Imports
import vapoursynth as vs
# getting Vapoursynth core
import ctypes
# Loading Support Files
Dllref = ctypes.windll.LoadLibrary("i:/Hybrid/64bit/vsfilters/Support/libfftw3f-3.dll")
core = vs.core

# Loading Plugins
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/DenoiseFilter/NEO_FFT3DFilter/neo-fft3d.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/SourceFilter/FFMS2/ffms2.dll")

# source: 'G:\TestClips&Co\files\MPEG-4 H.264\4k\4k_sample_4096x2160.mp4'
# current color space: YUV420P8, bit depth: 8, resolution: 4096x2160, fps: 25, color matrix: 2020ncl, yuv luminance scale: limited, scanorder: progressive
# Loading source using FFMS2
clip = core.ffms2.Source(source="G:/TestClips&Co/files/MPEG-4 H.264/4k/4k_sample_4096x2160.mp4",cachefile="E:/Temp/mp4_b30946f06bbf6d3e0309b51cccf4cf0c_853323747.ffindex",format=vs.YUV420P8,alpha=False)

# Setting color matrix to 2020ncl.
clip = core.std.SetFrameProps(clip, _Matrix=9)
clip = clip if not core.text.FrameProps(clip,'_Transfer') else core.std.SetFrameProps(clip, _Transfer=9)
clip = clip if not core.text.FrameProps(clip,'_Primaries') else core.std.SetFrameProps(clip, _Primaries=9)

# Setting color range to TV (limited) range.
clip = core.std.SetFrameProp(clip=clip, prop="_ColorRange", intval=1)

# making sure frame rate is set to 25
clip = core.std.AssumeFPS(clip=clip, fpsnum=25, fpsden=1)

# denoising using Neo-FFT3D
clip = core.neo_fft3d.FFT3D(clip=clip, bw=64, bh=64)

# set output frame rate to 25.000fps
clip = core.std.AssumeFPS(clip=clip, fpsnum=25, fpsden=1)

# Output
clip.set_output()

used 50-65% ​CPU, ~12GB RAM with VSPipe and gives

Output 6262 frames in 1796.79 seconds (3.49 fps)​

using FFMS2 without filtering, speed is way higher

Output 6262 frames in 42.96 seconds (145.75 fps)

usind FFMS2 + Avisynth with FFT3DGPU:

# Imports
import vapoursynth as vs
# getting Vapoursynth core
import ctypes
# Loading Support Files

Dllref = ctypes.windll.LoadLibrary("i:/Hybrid/64bit/vsfilters/Support/libfftw3f-3.dll")
Dllref = ctypes.windll.LoadLibrary("i:/Hybrid/64bit/Avisynth/avisynthPlugins/d3d9.dll")

# getting Vapoursynth core
core = vs.core
# Loading Plugins
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/SourceFilter/FFMS2/ffms2.dll")
core.std.LoadPlugin(path="I:/Hybrid/64bit/Vapoursynth/Vapoursynth64/coreplugins/AvsCompat.dll")
core.avs.LoadPlugin(path="i:/Hybrid/64bit/Avisynth/avisynthPlugins/FFT3dGPU.dll")

# source: 'G:\TestClips&Co\files\MPEG-4 H.264\4k\4k_sample_4096x2160.mp4'
# current color space: YUV420P8, bit depth: 8, resolution: 4096x2160, fps: 25, color matrix: 2020ncl, yuv luminance scale: limited, scanorder: progressive
# Loading source using FFMS2
clip = core.ffms2.Source(source="G:/TestClips&Co/files/MPEG-4 H.264/4k/4k_sample_4096x2160.mp4",cachefile="E:/Temp/mp4_b30946f06bbf6d3e0309b51cccf4cf0c_853323747.ffindex",format=vs.YUV420P8,alpha=False)
# Setting color matrix to 2020ncl.
clip = core.std.SetFrameProps(clip, _Matrix=9)
clip = clip if not core.text.FrameProps(clip,'_Transfer') else core.std.SetFrameProps(clip, _Transfer=9)
clip = clip if not core.text.FrameProps(clip,'_Primaries') else core.std.SetFrameProps(clip, _Primaries=9)
# Setting color range to TV (limited) range.
clip = core.std.SetFrameProp(clip=clip, prop="_ColorRange", intval=1)
# making sure frame rate is set to 25
clip = core.std.AssumeFPS(clip=clip, fpsnum=25, fpsden=1)

# Use FFT3DGPU
clip = core.avs.fft3dGPU(clip, bw=64, bh=64,precision=1)

# set output frame rate to 25.000fps
clip = core.std.AssumeFPS(clip=clip, fpsnum=25, fpsden=1)
# Output
clip.set_output()

I needed to use precision=1.

precision=0 produces artifacts, even when using 64bit Avisynth+ with FFT3DGPU and 4k input. (as as side note: using Avisynth+ with FFMS2 fft3dGPU(clip, bw=64, bh=64,precision=1) I get an the same speed fps) This gave me:

Output 6262 frames in 400.78 seconds (15.62 fps)

(precision=2 gives me 15.4fps, so roughly the same)

Since NeoFFT3DFilter also has mt an ncpu, I also tried mt=True and different ncpu values but I couldn't get it faster than 3.5fps

I also tried different source filters (LibavSMASHSource, LWLibavSource with and without hardware accelleration and DGDecNV), with FFT3DGPU and neo_fft3d.FFT3D. -> speed didn't change.

So yes, FFT3DGPU at least here is a lot faster than 'neo_fft3d.FFT3D(clip=clip, bw=64, bh=64)' and cpu usage is only ~3.5%.

My system is: Windows 11, 32GB RAM, Ryzen 9 3850X, Geforce GTX 1070ti, Vapoursynth R57. (so with newer gpus the speed of FFT3DGPU might even be higher)

pinterf commented 2 years ago

Yes, the difference is significant. (Myrsloik has another fft3dfilter version which - if I remember well - was comparable or better than neo's numbers.)

Selur commented 2 years ago

Tried that one too :) and it's basically the same speed as the neo version, also can't get it faster than 3.5fps.