View Full Version : sRestore Vapoursynth vs Avisynth
Selur
23rd April 2023, 15:41
Using the following VapourSynth script:
# Imports
import vapoursynth as vs
import os
import ctypes
# Loading Support Files
Dllref = ctypes.windll.LoadLibrary("i:/Hybrid/64bit/vsfilters/Support/libfftw3f-3.dll")
import sys
# getting Vapoursynth core
core = vs.core
# Import scripts folder
scriptPath = 'i:/Hybrid/64bit/vsscripts'
sys.path.insert(0, os.path.abspath(scriptPath))
# Loading Plugins
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/GrainFilter/RemoveGrain/RemoveGrainVS.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/GrainFilter/AddGrain/AddGrain.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/DenoiseFilter/DFTTest/DFTTest.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/DenoiseFilter/FFT3DFilter/fft3dfilter.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/Support/EEDI3m.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/ResizeFilter/nnedi3/vsznedi3.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/Support/libmvtools.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/Support/scenechange.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/Support/fmtconv.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/MiscFilter/MiscFilters/MiscFilters.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/DeinterlaceFilter/Bwdif/Bwdif.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/SourceFilter/d2vSource/DGDecode.dll")
# Import scripts
import havsfunc
# source: 'G:\Output\Naruto DVD Folge 4_3 min.m2v'
# current color space: YUV420P8, bit depth: 8, resolution: 720x576, fps: 25, color matrix: 470bg, yuv luminance scale: limited, scanorder: top field first
# Loading G:\Output\Naruto DVD Folge 4_3 min.m2v using DGDecode
clip = core.dgdecode.MPEG2Source("J:/tmp/m2v_b7151a7e116c7001abddb45453f1386c_853323747.d2v",info=3)# 25 fps, scanorder: top field first
# Setting detected color matrix (470bg).
clip = core.std.SetFrameProps(clip, _Matrix=5)
# Setting color transfer info (470bg), when it is not set
clip = clip if not core.text.FrameProps(clip,'_Transfer') else core.std.SetFrameProps(clip, _Transfer=5)
# Setting color primaries info (BT.601 PAL), when it is not set
clip = clip if not core.text.FrameProps(clip,'_Primaries') else core.std.SetFrameProps(clip, _Primaries=5)
# 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)
clip = core.std.SetFrameProp(clip=clip, prop="_FieldBased", intval=2) # tff
# Deinterlacing using QTGMC
clip = havsfunc.QTGMC(Input=clip, Preset="Fast", TFF=True) # new fps: 50
# Making sure content is preceived as frame based
clip = core.std.SetFrameProp(clip=clip, prop="_FieldBased", intval=0) # progressive
# adjusting frame count and rate with sRestore
clip = havsfunc.srestore(source=clip, frate=23.9760, omode=6)
# set output frame rate to 23.976fps (progressive)
clip = core.std.AssumeFPS(clip=clip, fpsnum=24000, fpsden=1001)
# Output
clip.set_output()
and comparing it with the following AviSynth script:
ClearAutoloadDirs()
SetFilterMTMode("DEFAULT_MT_MODE", MT_MULTI_INSTANCE)
LoadPlugin("I:\Hybrid\64bit\Avisynth\avisynthPlugins\DGDecode.dll")
LoadPlugin("I:\Hybrid\64bit\Avisynth\avisynthPlugins\RgTools.dll")
LoadPlugin("I:\Hybrid\64bit\Avisynth\avisynthPlugins\masktools2.dll")
LoadPlugin("I:\Hybrid\64bit\Avisynth\avisynthPlugins\mvtools2.dll")
LoadPlugin("I:\Hybrid\64bit\Avisynth\avisynthPlugins\nnedi3.dll")
LoadPlugin("I:\Hybrid\64bit\Avisynth\avisynthPlugins\TIVTC.dll")
LoadPlugin("I:\Hybrid\64bit\Avisynth\avisynthPlugins\Average.dll")
LoadPlugin("I:\Hybrid\64bit\Avisynth\avisynthPlugins\grunt-x64.dll")
LoadPlugin("I:\Hybrid\64bit\Avisynth\avisynthPlugins\MedianBlur2.dll")
Import("I:\Hybrid\64bit\Avisynth\avisynthPlugins\mtmodes.avsi")
Import("I:\Hybrid\64bit\Avisynth\avisynthPlugins\QTGMC.avsi")
Import("I:\Hybrid\64bit\Avisynth\avisynthPlugins\Zs_RF_Shared.avsi")
Import("I:\Hybrid\64bit\Avisynth\avisynthPlugins\Srestore.avsi")
# loading source: G:\Output\Naruto DVD Folge 4_3 min.m2v
# color sampling YV12@8, matrix: bt470, scantyp: top field first, luminance scale: limited
MPEG2Source(d2v="J:\tmp\m2v_b7151a7e116c7001abddb45453f1386c_853323747.d2v",fieldop=0)
# current resolution: 720x576
# deinterlacing
AssumeTFF()
QTGMC(Preset="Fast", ediThreads=2)
# removing ghosting
srestore(frate=23.976,omode=6)
Preroll(Int(last.FrameRate()))
# filtering
# setting output fps to 23.976fps
AssumeFPS(24000,1001)
# output: color sampling YV12@8, matrix: bt470, scantyp: progressive, luminance scale: limited
return last
The AviSynth output has less blending:
https://i.ibb.co/9Yxjn8K/grafik.png (https://ibb.co/F7Qt6xZ)
https://imgsli.com/MTcyOTU2 (see left side of the image)
Any idea how to improve the blend removal in VapourSynth?
Is there a newer sRestore port for VapourSynth out there? (can someone make one?)
Cu Selur
Ps.: Used the clip from https://forum.videohelp.com/threads/409354-Delete-Scene-Blending-Frames-(or-the-effect-out-of-the-frame)-from-animes as source.
(uploaded the source an the reencodes to GoogleDrive (https://drive.google.com/drive/folders/1fzCwUi3D1wo_8zALwdmhY3VCrALcTVG8?usp=share_link).
poisondeathray
24th April 2023, 14:56
Similar poor results for vpy srestore here. The results are quite a bit worse on many frames compared to avs version
You reported the issue before - but on that sample it's very easy to see the problems, consider adding it as another example
https://github.com/HomeOfVapourSynthEvolution/havsfunc/issues/78
On the avs version, a few of the slightly blended frames are from QTGMC . If you replace with something like bwdif ,they are clean
Selur
24th April 2023, 15:11
You are right -> I added a link to this thread in the issue tracker.
Main question is: what is causing the differences and can it be fixed?
poisondeathray
24th April 2023, 15:56
The avs and vpy versions look quite different . Another difference is there is no masktools in vapoursynth. srestore is quite a complex script, way beyond my ability to "fix" it
poisondeathray
24th April 2023, 16:13
If I import an avs script using AVIsource with only bwdif, the vpy srestore works better too - about the same as the avs version. That sequence where girl is walking up is clean. But if I use vpy bwdif into srestore, it's blended.
In both cases, the output node of bwdif is about the same . Props isn't screwing it up - you can set them the same
In all cases, I go back a few seconds and test linearly , because you can get inconsistent results.
Could it be some threading issue ? AVISource is 1 frame in/out, and slower, so it "forces" linear processing in a way - so when I use MPEG2Source in the avs script only (just source filter) , and import using AVISource into the vpy script. Use vpy bwdif and srestore - it works now . So that's my working theory - some threading issue and mixing up frames
Is there a way to force linear/slow/threads=1 processing for source filter ? I used core.d2v.Source for vpy source loading
Selur
24th April 2023, 16:16
Yeah, so the whole GScriptClip-stuff in the AviSynth version makes it really difficult to read. :)
Additionally, the Vapoursynth version is based on sRestore 2.7e from 2009 and the current version probably changed quite a bit since then,..
poisondeathray
24th April 2023, 16:19
It cannot be a vpy srestore issue if it works with AVISource (mpeg2source in the avs script only)
core.num_threads = 1 , doesn't seem to help when everything is done in vapoursynth
poisondeathray
24th April 2023, 16:22
It works ok with DGSource. So it is a source filter issue
clip = core.dgdecodenv.DGSource(r'Naruto DVD Folge 4_3 min.dgi')
clip = core.bwdif.Bwdif(clip, field=3)
clip = haf.srestore(clip)
clip.set_output()
Selur
24th April 2023, 17:14
Doesn't work here,...
# Imports
import vapoursynth as vs
import os
import sys
# getting Vapoursynth core
core = vs.core
# Import scripts folder
scriptPath = 'i:/Hybrid/64bit/vsscripts'
sys.path.insert(0, os.path.abspath(scriptPath))
# Loading Plugins
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/DeinterlaceFilter/Bwdif/Bwdif.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/SourceFilter/DGDecNV/DGDecodeNV.dll")
# Import scripts
import havsfunc
# source: 'C:\Users\Selur\Desktop\Naruto DVD Folge 4_3 min.mkv'
# current color space: YUV420P8, bit depth: 8, resolution: 720x576, fps: 25, color matrix: 470bg, yuv luminance scale: limited, scanorder: top field first
# Loading C:\Users\Selur\Desktop\Naruto DVD Folge 4_3 min.mkv using DGSource
clip = core.dgdecodenv.DGSource("J:/tmp/mkv_2d1ce5e0c17bb199c7f9dc6f4331d407_853323747.dgi",fieldop=0)# 25 fps, scanorder: top field first
# Setting detected color matrix (470bg).
clip = core.std.SetFrameProps(clip, _Matrix=5)
# Setting color transfer info (470bg), when it is not set
clip = clip if not core.text.FrameProps(clip,'_Transfer') else core.std.SetFrameProps(clip, _Transfer=5)
# Setting color primaries info (BT.601 PAL), when it is not set
clip = clip if not core.text.FrameProps(clip,'_Primaries') else core.std.SetFrameProps(clip, _Primaries=5)
# 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)
clip = core.std.SetFrameProp(clip=clip, prop="_FieldBased", intval=2) # tff
# Deinterlace using Bwdif
clip = core.bwdif.Bwdif(clip=clip, field=3) # new fps: 50
# adjusting frame count and rate with sRestore
clip = havsfunc.srestore(source=clip, frate=23.9760, omode=6, speed=9, thresh=16, mode=2)
# set output frame rate to 23.976fps (progressive)
clip = core.std.AssumeFPS(clip=clip, fpsnum=24000, fpsden=1001)
# Output
clip.set_output()
https://i.ibb.co/3vGYHQx/grafik.png (https://ibb.co/nBZ8StX)
same when I simplify it to:
# Imports
import vapoursynth as vs
import os
import sys
# getting Vapoursynth core
core = vs.core
# Import scripts folder
scriptPath = 'i:/Hybrid/64bit/vsscripts'
sys.path.insert(0, os.path.abspath(scriptPath))
# Loading Plugins
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/DeinterlaceFilter/Bwdif/Bwdif.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/SourceFilter/DGDecNV/DGDecodeNV.dll")
# Import scripts
import havsfunc
# source: 'C:\Users\Selur\Desktop\Naruto DVD Folge 4_3 min.mkv'
# current color space: YUV420P8, bit depth: 8, resolution: 720x576, fps: 25, color matrix: 470bg, yuv luminance scale: limited, scanorder: top field first
# Loading C:\Users\Selur\Desktop\Naruto DVD Folge 4_3 min.mkv using DGSource
clip = core.dgdecodenv.DGSource("J:/tmp/mkv_2d1ce5e0c17bb199c7f9dc6f4331d407_853323747.dgi")# 25 fps, scanorder: top field first
# Deinterlace using Bwdif
clip = core.bwdif.Bwdif(clip=clip, field=3) # new fps: 50
# adjusting frame count and rate with sRestore
clip = havsfunc.srestore(source=clip)
# set output frame rate to 23.976fps (progressive)
clip = core.std.AssumeFPS(clip=clip, fpsnum=24000, fpsden=1001)
# Output
clip.set_output()
Selur
24th April 2023, 17:38
Using:
# Imports
import vapoursynth as vs
import os
import sys
# getting Vapoursynth core
core = vs.core
# Import scripts folder
scriptPath = 'i:/Hybrid/64bit/vsscripts'
sys.path.insert(0, os.path.abspath(scriptPath))
# Loading Plugins
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/ResizeFilter/nnedi3/NNEDI3CL.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/DeinterlaceFilter/TIVTC/libtivtc.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/SourceFilter/DGDecNV/DGDecodeNV.dll")
# Import scripts
import havsfunc
import TFMBob
# source: 'C:\Users\Selur\Desktop\Naruto DVD Folge 4_3 min.mkv'
# current color space: YUV420P8, bit depth: 8, resolution: 720x576, fps: 25, color matrix: 470bg, yuv luminance scale: limited, scanorder: top field first
# Loading C:\Users\Selur\Desktop\Naruto DVD Folge 4_3 min.mkv using DGSource
clip = core.dgdecodenv.DGSource("J:/tmp/mkv_2d1ce5e0c17bb199c7f9dc6f4331d407_853323747.dgi",fieldop=0)# 25 fps, scanorder: top field first
# Setting detected color matrix (470bg).
clip = core.std.SetFrameProps(clip, _Matrix=5)
# Setting color transfer info (470bg), when it is not set
clip = clip if not core.text.FrameProps(clip,'_Transfer') else core.std.SetFrameProps(clip, _Transfer=5)
# Setting color primaries info (BT.601 PAL), when it is not set
clip = clip if not core.text.FrameProps(clip,'_Primaries') else core.std.SetFrameProps(clip, _Primaries=5)
# 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)
clip = core.std.SetFrameProp(clip=clip, prop="_FieldBased", intval=2) # tff
clip = TFMBob.TFMBobN(clip=clip, cthresh=5, openCL=True) # see: https://github.com/Selur/VapoursynthScriptsInHybrid/blob/master/TFMBob.py
# adjusting frame count and rate with sRestore
clip = havsfunc.srestore(source=clip, frate=23.9760)
# set output frame rate to 23.976fps (progressive)
clip = core.std.AssumeFPS(clip=clip, fpsnum=24000, fpsden=1001)
# Output
clip.set_output()
seems to be result in less blends, but there are still more than in Avisynth. :(
Argh, scratch that,.. this causes some ugly artifacts in some scenes. :(
poisondeathray
24th April 2023, 18:53
DGSource,bwdif,srestore vpy works for me . Similar results to avs srestore
This is what I'm getting
https://www.mediafire.com/file/rbsx5expprcp543/dgsource,bwdif,srestore_vpy.mp4/file
Selur
24th April 2023, 19:04
Strange, when I use:
# Imports
import vapoursynth as vs
import os
import sys
# getting Vapoursynth core
core = vs.core
# Import scripts folder
scriptPath = 'i:/Hybrid/64bit/vsscripts'
sys.path.insert(0, os.path.abspath(scriptPath))
# Loading Plugins
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/DeinterlaceFilter/Bwdif/Bwdif.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/SourceFilter/DGDecNV/DGDecodeNV.dll")
# Import scripts
import havsfunc
# source: 'C:\Users\Selur\Desktop\Naruto DVD Folge 4_3 min.mkv'
# current color space: YUV420P8, bit depth: 8, resolution: 720x576, fps: 25, color matrix: 470bg, yuv luminance scale: limited, scanorder: top field first
# Loading C:\Users\Selur\Desktop\Naruto DVD Folge 4_3 min.mkv using DGSource
clip = core.dgdecodenv.DGSource("J:/tmp/mkv_2d1ce5e0c17bb199c7f9dc6f4331d407_853323747.dgi",fieldop=0)# 25 fps, scanorder: top field first
# Setting detected color matrix (470bg).
clip = core.std.SetFrameProps(clip, _Matrix=5)
# Setting color transfer info (470bg), when it is not set
clip = clip if not core.text.FrameProps(clip,'_Transfer') else core.std.SetFrameProps(clip, _Transfer=5)
# Setting color primaries info (BT.601 PAL), when it is not set
clip = clip if not core.text.FrameProps(clip,'_Primaries') else core.std.SetFrameProps(clip, _Primaries=5)
# 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)
clip = core.std.SetFrameProp(clip=clip, prop="_FieldBased", intval=2) # tff
# Deinterlace using Bwdif
clip = core.bwdif.Bwdif(clip=clip, field=3) # new fps: 50
# Making sure content is preceived as frame based
clip = core.std.SetFrameProp(clip=clip, prop="_FieldBased", intval=0) # progressive
# adjusting frame count and rate with sRestore
clip = havsfunc.srestore(source=clip, frate=23.9760)
# adjusting output color from: YUV420P8 to YUV420P10 for NVEncModel
clip = core.resize.Bicubic(clip=clip, format=vs.YUV420P10, range_s="limited")
# set output frame rate to 23.976fps (progressive)
clip = core.std.AssumeFPS(clip=clip, fpsnum=24000, fpsden=1001)
# Output
clip.set_output()
I get: Naruto DVD Folge 4_3 min_VS_DGSource_BWDIF_sRestore (https://drive.google.com/file/d/1c4Hk4lAm8wHMZhfG_yGGvW0OIRElYjjt/view?usp=share_link) which isn't better than the qtgmc version. :(
No clue what I do differently than you. :(
-> can you open my script (with adjusted paths) and check whether it looks fine for you? Maybe something in my script is causing the issue.
Cu Selur
poisondeathray
24th April 2023, 19:13
My script was in post #8 . I got similar problems earlier, and it was definitely from source filter d2vsource
I don't see anything in your script that would cause that problem
Maybe version and dependency differences. I used an old vapoursynth version, old plugins, old scripts, old havsfunc. I'll check with a newer version and see if problem pops up . (vapoursynth /python dependencies are 10x worse than "avs .dll hell" )
EDIT-
That was an R54 setup.
Yes, I got blends on R61 setup, and R57 setup. Something maybe with dependencies/scripts/plugins differences between those. It's going to take some work to figure out what's causing it... :(
Selur
24th April 2023, 19:24
Thanks for looking into it a bit further.
I'll send you links, to all the stuff I use in my Hybrid version.
Would be nice to know that causes the issue. :)
poisondeathray
24th April 2023, 20:06
DGDecodeNV.dll was the same for my versions
Bwdif.dll was different, but using old version in R57 didn't make a difference
Does not appear to be srestore version issue either; using older srestore (or copying over old havsfunc) in R57 still gets blends . Using newer srestore in older R54 still ok.
Not sure why the difference, maybe some other dependency (or unlikely, core difference causing problem. Or maybe it is some API <4 vs. >=4 issue ?)
HolyWu
25th April 2023, 13:52
The culprit is that std.Cache filter becomes no-op in API4 (https://github.com/vapoursynth/vapoursynth/blob/5032849b537719ec460d0c7534ca1f03b4a2fb90/src/core/simplefilters.cpp#L140). Specifically, srestore requires the make_linear functionality from std.Cache in API3 (https://web.archive.org/web/20210506085526/https://www.vapoursynth.com/doc/functions/cache.html) to work as expected because it calculates some global statistics and those statistics get updated every frame inside FrameEval. Without make_linear, some calls inside FrameEval get skipped and the statistics calculated are incorrect. But it seems impossible to achieve the same result by using std.SetVideoCache in API4 (http://www.vapoursynth.com/doc/functions/video/setvideocache.html).
poisondeathray
25th April 2023, 14:22
The culprit is that std.Cache filter becomes no-op in API4 (https://github.com/vapoursynth/vapoursynth/blob/5032849b537719ec460d0c7534ca1f03b4a2fb90/src/core/simplefilters.cpp#L140). Specifically, srestore requires the make_linear functionality from std.Cache in API3 (https://web.archive.org/web/20210506085526/https://www.vapoursynth.com/doc/functions/cache.html) to work as expected because it calculates some global statistics and those statistics get updated every frame inside FrameEval. Without make_linear, some calls inside FrameEval get skipped and the statistics calculated are incorrect. But it seems impossible to achieve the same result by using std.SetVideoCache in API4 (http://www.vapoursynth.com/doc/functions/video/setvideocache.html).
Thanks
Do you have any suggestions how to address that in API4 ?
Maybe have 2 types of Cache ? Perhaps Myrsloik can look at it ?
BTW - Nice to see you back here :)
Selur
25th April 2023, 16:27
Interesting, didn't know about std.SetVideoCache. :)
(as a side note: this would also explain why muvsfunc.Cdeblend doesn't work as expected)
Myrsloik
25th April 2023, 22:10
The culprit is that std.Cache filter becomes no-op in API4 (https://github.com/vapoursynth/vapoursynth/blob/5032849b537719ec460d0c7534ca1f03b4a2fb90/src/core/simplefilters.cpp#L140). Specifically, srestore requires the make_linear functionality from std.Cache in API3 (https://web.archive.org/web/20210506085526/https://www.vapoursynth.com/doc/functions/cache.html) to work as expected because it calculates some global statistics and those statistics get updated every frame inside FrameEval. Without make_linear, some calls inside FrameEval get skipped and the statistics calculated are incorrect. But it seems impossible to achieve the same result by using std.SetVideoCache in API4 (http://www.vapoursynth.com/doc/functions/video/setvideocache.html).
I'm happy that it worked for you but unfortunately make_linear=True never was a guarantee of frames actually being requested linearly. Maybe it worked well enough for some of you sometimes. I'd honestly suggest turning srestore into a proper plugin.
As a really stupid plan b create a dummy passthrough filter (like the filter skeleton example), use Unordered as the mode and call setLinearFilter(). Replace the Cache() with this filter instead. Maybe it'll whack things into order enough.
HolyWu
26th April 2023, 14:45
I think this is what really make a difference for srestore because it can no longer get statistics from the skipped frames.
from functools import partial
import vapoursynth as vs
def print_num(n, clip):
print(f"frame number: {n}")
return clip
clip = vs.core.std.BlankClip(length=20)
clip = clip.std.FrameEval(partial(print_num, clip=clip))
#clip = clip.std.Cache(make_linear=True)
clip = clip.std.SelectEvery(2, 0)
clip.set_output()
Test the script using R55-API3 (https://github.com/vapoursynth/vapoursynth/releases/tag/R55-API3).
Without Cache(make_linear=True), it outputs:
frame number: 0
frame number: 2
frame number: 4
frame number: 6
frame number: 8
frame number: 10
frame number: 12
frame number: 14
frame number: 16
frame number: 18
With Cache(make_linear=True), now it outputs:
frame number: 0
frame number: 1
frame number: 2
frame number: 3
frame number: 4
frame number: 5
frame number: 6
frame number: 7
frame number: 8
frame number: 9
frame number: 10
frame number: 11
frame number: 12
frame number: 13
frame number: 14
frame number: 15
frame number: 16
frame number: 17
frame number: 18
Setsugen no ao
26th April 2023, 15:52
Even though everything in this snippet is bad practice, it can be monkey patched by just forcing the requests
last0 = source.std.FrameEval(eval=srestore_inside, prop_src=[bclpYStats, dclpYStats, dclipYStats])
def _force_eval(n):
for nn in range(max(n-5, 0), min(last0.num_frames, n + 1)):
last0.get_frame(nn)
return last0
last = last0.std.FrameEval(_force_eval)
Myrsloik
26th April 2023, 19:29
I think this is what really make a difference for srestore because it can no longer get statistics from the skipped frames.
from functools import partial
import vapoursynth as vs
def print_num(n, clip):
print(f"frame number: {n}")
return clip
clip = vs.core.std.BlankClip(length=20)
clip = clip.std.FrameEval(partial(print_num, clip=clip))
#clip = clip.std.Cache(make_linear=True)
clip = clip.std.SelectEvery(2, 0)
clip.set_output()
Test the script using R55-API3 (https://github.com/vapoursynth/vapoursynth/releases/tag/R55-API3).
...
You may get away with something like PlaneStats(clip[1:], clip, prop='junk') instead of Cache to fill in the gap caused by selectevery. Or Stack*+Crop* or whatever to trigger requesting multiple frames to compensate
Selur
27th April 2023, 15:54
As a side note, I just stumbled over a workaround:
Using:
# clip is 50fps progressive due to QTGMC
clip = sRestore.srestore(clip, frate=29.94)
clip = core.std.AssumeFPS(clip=clip, fpsnum=30000, fpsden=1001)
clip = sRestore.srestore(clip, frate=23.976)
clip = core.std.AssumeFPS(clip=clip, fpsnum=24000, fpsden=1001)
instead of the normal:
clip = sRestore.srestore(clip, frate=23.976)
clip = core.std.AssumeFPS(clip=clip, fpsnum=24000, fpsden=1001)
seems to work fine, still a modified stestore script would be preferable.
I'd honestly suggest turning srestore into a proper plugin.
that would be cool
Cu Selur
Ps.: calling sRestore two times helps, but doesn't fix it (still some blends left, that could be removed and get removed in Avisynth)
Selur
29th April 2023, 06:36
Okay, since cddeblend and srestore don't properly work (may have never worked as good as the Avisynth alternatives) I was wondering what filters do folks use to remove (random) blends ?
I mean, especially folks filtering animes must deal with blends quite often.
Maybe:
1. creating a Vapoursynth script which loads the source and applies some filtering.
2. load that Vapoursynth script as source (using VapourSource) in an Avisynth script, which applies sRestore.
3. loading that AvisynthScript with vsavsreader and apply the rest of the filtering.
could work,.... (assuming VapourSource and vsavsreader still work at least on Windows, I have no hope for Linux&Mac)
Cu Selur
ChaosKing
17th September 2023, 23:46
Can you test again with:
core = vs.core
core.num_threads=1
Selur
19th September 2023, 17:21
using (with R63):
# Imports
import vapoursynth as vs
import os
import ctypes
# Loading Support Files
Dllref = ctypes.windll.LoadLibrary("F:/Hybrid/64bit/vsfilters/Support/libfftw3f-3.dll")
import sys
# getting Vapoursynth core
core = vs.core
# Limit thread count to 1
core.num_threads = 1
# Import scripts folder
scriptPath = 'F:/Hybrid/64bit/vsscripts'
sys.path.insert(0, os.path.abspath(scriptPath))
# Loading Plugins
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/GrainFilter/RemoveGrain/RemoveGrainVS.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/GrainFilter/AddGrain/AddGrain.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DenoiseFilter/DFTTest/DFTTest.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DenoiseFilter/NEO_FFT3DFilter/neo-fft3d.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/Support/EEDI3m_opencl.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/ResizeFilter/nnedi3/NNEDI3CL.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/Support/libmvtools.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/Support/scenechange.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/Support/fmtconv.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/MiscFilter/MiscFilters/MiscFilters.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DeinterlaceFilter/Bwdif/Bwdif.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/SourceFilter/DGDecNV/DGDecodeNV.dll")
# Import scripts
import havsfunc
# source: 'C:\Users\Selur\Desktop\Naruto DVD Folge 4_3 min.m2v'
# current color space: YUV420P8, bit depth: 8, resolution: 720x576, fps: 25, color matrix: 470bg, yuv luminance scale: limited, scanorder: top field first
# Loading C:\Users\Selur\Desktop\Naruto DVD Folge 4_3 min.m2v using DGSource
clip = core.dgdecodenv.DGSource("J:/tmp/m2v_89c111c29e9cbbcf0ca7e1f8c9f8aa6b_853323747.dgi",fieldop=0)# 25 fps, scanorder: top field first
# Setting detected color matrix (470bg).
clip = core.std.SetFrameProps(clip, _Matrix=5)
# Setting color transfer info (470bg), when it is not set
clip = clip if not core.text.FrameProps(clip,'_Transfer') else core.std.SetFrameProps(clip, _Transfer=5)
# Setting color primaries info (BT.601 PAL), when it is not set
clip = clip if not core.text.FrameProps(clip,'_Primaries') else core.std.SetFrameProps(clip, _Primaries=5)
# 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)
clip = core.std.SetFrameProp(clip=clip, prop="_FieldBased", intval=2) # tff
# Deinterlacing using QTGMC
clip = havsfunc.QTGMC(Input=clip, Preset="Fast", TFF=True, opencl=True) # new fps: 50
# Making sure content is preceived as frame based
clip = core.std.SetFrameProp(clip=clip, prop="_FieldBased", intval=0) # progressive
# adjusting frame count and rate with sRestore
clip = havsfunc.srestore(source=clip, frate=23.9760)
# adjusting output color from: YUV420P8 to YUV420P10 for QSVEncModel
clip = core.resize.Bicubic(clip=clip, format=vs.YUV420P10, range_s="limited")
# set output frame rate to 23.976fps (progressive)
clip = core.std.AssumeFPS(clip=clip, fpsnum=24000, fpsden=1001)
# Output
clip.set_output()
doesn't really help.
Cu Selur
Myrsloik
23rd September 2023, 18:05
using (with R63):
...
doesn't really help.
Cu Selur
Exactly how are you outputting it for comparison? Single threaded mode should work identically to the avisynth version.
Selur
23rd September 2023, 18:08
I used vsViewer (= older Vapoursynth Editor), will do a reencode and compare the results.
=> You are right seems to be an issue with the preview, so disabling MultiThreading helps.
(Added the file to my Google Drive (https://drive.google.com/file/d/1c4Hk4lAm8wHMZhfG_yGGvW0OIRElYjjt/view?usp=share_link) next to the others.)
Is there a way to just disable multithreading for sRestore/cdeblend/...?
Cu Selur
ChaosKing
24th September 2023, 10:09
preview in vsedit is kinda "broken" for cdeblend, but seems to work then using the encode function. Tested with VapourSynth-Editor-r19-mod-5-x86_64
Try
Cdeblend(clip, omode=4) # 4=stats
this is always show 0.0 in vsedit.
This editor shows it correct: https://github.com/Irrational-Encoding-Wizardry/vs-preview
Selur
27th October 2023, 17:33
Has anyone tested srestore from https://github.com/WolframRhodium/muvsfunc/blob/master/muvsfunc.py ?
"srestore with serialized execution by explicit node processing dependency" sounds promising.
Okay, did a quick test. Decimation works wonderful, but the serialization basically means if you jump to frame X, all frames before X have to be processed first. ;)
So still hoping for someone to implement this in a filter or that the muvsfunc.srestore will be tweaked,...
Cu Selur
WolframRhodium
31st October 2023, 10:40
..., but the serialization basically means if you jump to frame X, all frames before X have to be processed first. ;)
So still hoping for someone to implement this in a filter or that the muvsfunc.srestore will be tweaked,...
This is a basic design of srestore for deterministic result, so the encoding output is the same as previewing.
Another problem of this approach is that, after jumping to frame X, previewing any frame long before X is time consuming. In this case, re-processing is currently out of my control (from a script writer perspective) because that is related to vapoursynth's caching of frames. And I think it can't be perfect here because for immediate jumping one will need to cache all frames in memory.
An improvement could be like, allowing the user to specify what frames should be cached. This can be implemented as a standalone caching plugin, but I'm not sure whether that is useful.
Selur
1st November 2023, 06:11
Do you think it would make much of a difference if the caching would be restricted to 100frames?
WolframRhodium
1st November 2023, 11:29
I have no clear thoughts in favor or against this approach. From a user perspective, similar to your approach, I would expect the program provide an option to specify what frames need to be cached (although not all of them may be processed before previewing). Initial thought on implementation of this kind of program is they seem too restrictive and each sequential filter (Cdeblend, srestore) would require a new plugin.
Selur
9th November 2024, 11:22
Trying to adjust srestore (https://github.com/Selur/VapoursynthScriptsInHybrid/blob/fe3d6370deb912ddc91903641c3c9653861dbac0/havsfunc.py#L2656) like cdeblend (https://github.com/WolframRhodium/muvsfunc/commit/698dae325241c9278c6da0d52282f3a0eb8cddee) was adjusted.
(Having no clue) I thought it would be basically replacing:
###### evaluation call & output calculation ######
bclpYStats = bclp.std.PlaneStats()
dclpYStats = dclp.std.PlaneStats()
dclipYStats = core.std.PlaneStats(dclip, dclip.std.Trim(first=2))
last = source.std.FrameEval(eval=srestore_inside, prop_src=[bclpYStats, dclpYStats, dclipYStats])
###### final decimation ######
return ChangeFPS(last.std.Cache(make_linear=True), source.fps_num * numr, source.fps_den * denm)
with:
###### evaluation call & output calculation ######
bclpYStats = bclp.std.PlaneStats()
dclpYStats = dclp.std.PlaneStats()
dclipYStats = core.std.PlaneStats(dclip, dclip.std.Trim(first=2))
prop_src = []
for i in range(preroll, 0, -1):
prop_src.extend([bclpYStats[0] *i + bclpYStats, dclpYStats[0]*i+dclpYStats, dclipYStats[0]*i+dclipYStats])
prop_src.extend([bclpYStats, dclpYStats, dclipYStats])
last = source.std.FrameEval(functools.partial(srestore_inside), prop_src=prop_src)
###### final decimation ######
return ChangeFPS(last, source.fps_num * numr, source.fps_den * denm)
but with that, it does not seem that sRestore has any effect aside from the ChangeFPS.
Standalone version of the current script: https://pastebin.com/ycrgv45t
=> does someone know how to fix this?
Cu Selur
Dust Signs
2nd December 2024, 11:54
Are there any updates or workarounds for using srestore in Vapoursynth like in AviSynth?
The bug report here (https://github.com/HomeOfVapourSynthEvolution/havsfunc/issues/78) resulted (as far as I can tell) in the removal of srestore altogether (affecting newer versions of VapourSynth).
Is there any workaround or combination of filters around it or does this mean that there is currently no way to use srestore in VapourSynth (and to fall back to AviSynth instead)?
Selur
2nd December 2024, 15:11
No update.
a. you could use sRestore which forces linear processing in muvsfunc.py (https://github.com/WolframRhodium/muvsfunc/blob/master/muvsfunc.py#L8318) (this is what Hybrid does atm.)
b. write a mod of havsfunc sRestore (https://github.com/Selur/VapoursynthScriptsInHybrid/blob/007d4107f9d0452dd9c45bdb66e08338db3fc6b9/havsfunc.py#L2663) which adds a preroll to it, like Myrsloik did for cdeblend (https://github.com/WolframRhodium/muvsfunc/issues/48). If you get this working, please share. :)
Cu Selur
vBulletin® v3.8.11, Copyright ©2000-2025, vBulletin Solutions Inc.