Log in

View Full Version : How do I deal with this old anime DVD?


therobin
6th March 2019, 21:03
I got an anime dvd source I am trying to encode and it seems to have a weird interlacing/flickering issue throughout the video. I am not sure how to deal it or if there is a way to correct it since it occurs even after removing one of the fields.

Here is a sample: http://www.mediafire.com/file/uw6i2qy03t7bpd8/amisjourneyclip.mkv/file

If someone can tell me what is going on here I'd appreciate it.

ChaosKing
6th March 2019, 21:40
Wow what's a shitty dvd but seems to look with haf.QTGMC(clip, Preset='slow', TFF=True).std.SelectEvery( cycle=2, offsets=0) much better

import havsfunc as haf
clip = orig= core.ffms2.Source(source=r'D:\amisjourneyclip.mkv')

clip = haf.QTGMC(clip, Preset='slow', TFF=True).std.SelectEvery( cycle=2, offsets=0)
clip = haf.Stab(clip, dxmax=6, dymax=6, mirror=15)

mandarinka
7th March 2019, 16:32
Wow what's a shitty dvd but seems to look with haf.QTGMC(clip, Preset='slow', TFF=True).std.SelectEvery( cycle=2, offsets=0) much better

import havsfunc as haf
clip = orig= core.ffms2.Source(source=r'D:\amisjourneyclip.mkv')

clip = haf.QTGMC(clip, Preset='slow', TFF=True).std.SelectEvery( cycle=2, offsets=0)
clip = haf.Stab(clip, dxmax=6, dymax=6, mirror=15)

That sounds like utterly wrong. It's a cel anime, if you don't produce 23,976 fps, you screwed up.

I'll have a look later, I can't quickly tell if it is field blended because most of the shots are static, but I think you'll still want to do something close to IVTC instead of deinterlacing and ending up with 30 fps.

Give me a few hours.

ChaosKing
7th March 2019, 16:44
You can always put a decimate after qtgmc. Sometimes qtgmc is just easier or your only solution. But I would also like to know if there is another way to properly ivtc it.

poisondeathray
7th March 2019, 16:59
This doesn't get rid of the wobbling, but something to start with to help with the aliasing


import vapoursynth as vs
import havsfunc as haf
core = vs.get_core()
vid = ore.d2v.Source(r'PATH\amisjourneyclip_track1_[eng].d2v')
vid = core.vivtc.VFM(vid, order=1)
vid = core.vivtc.VDecimate(vid)
vid = haf.QTGMC(vid, InputType=1, Sharpness=0.2)
vid.set_output()



There is some chroma noise/ rainbows in some scenes too that you might want to filter

mandarinka
7th March 2019, 19:11
You can always put a decimate after qtgmc. Sometimes qtgmc is just easier or your only solution.

Not "can", you absolutely should.

I just tried running TFM and it cleanly IVTCes this to smooth 24000/1001 fps. It seems it is not field-blended, so technically you can IVTC this.

The problem lies elsewhere - the thing is heavilly aliased, so that is what you get after IVTC. Is this fully unprocessed source? If so, I am afraid it might really need qtgmc() - but with tdecimate at the end, not selectodd/even.

therobin
7th March 2019, 19:11
Previously, I was using Nedi3 with VFM and had some bad results but did restore the film rate. But QTGMC results are better so I just replaced Nedi3 with that and gives significantly better end picture.

To get rid of the rainbows I use:
clip = core.smoothuv.SmoothUV(clip, radius=3, threshold=200, interlaced=0)

But I am still having a problem with stab. It freaks out during some fades causing massive destabilization. Here is two more small clips. One is a fade and the other shows an image being scanned.

http://www.mediafire.com/file/y018ui2ntrm21rt/AmisJourneyClip_fade.mkv/file
http://www.mediafire.com/file/24t7p9ath7b7ffm/AmisJourneyClip_scan.mkv/file

therobin
7th March 2019, 19:23
Not "can", you absolutely should.

I just tried running TFM and it cleanly IVTCes this to smooth 24000/1001 fps. It seems it is not field-blended, so technically you can IVTC this.

The problem lies elsewhere - the thing is heavilly aliased, so that is what you get after IVTC. Is this fully unprocessed source? If so, I am afraid it might really need qtgmc() - but with tdecimate at the end, not selectodd/even.

Source is from the DVD which I used makemkv to get an mkv to work with. The LD of this movie has the exact same issue. A friend sent me a DVD recording of his LD version and it produce the same problems (He doesn't have a direct capture device). This production is part of a TV series of which this particular piece was produce as a movie and shown in theaters. The other episodes did not have this problem (which were only available by VHS or LD from what I know). I have no idea how it could have ended up like this.

mandarinka
7th March 2019, 19:54
I came up with this.

I don't like stab, because it forces you to crop more and it might kill some detail too, I prefer to not filter for that purpose. The shaking isn't very bad anyway.


setmemorymax(1000)
ffvideosource("n:\amisjourneyclip.mkv")

qtgmc(preset="very slow", MatchPreset="Slower", edimode="nnedi3", MatchPreset2="Slower", lossless=0,sourcematch=3)
requestlinear() #it gets very slow without this
#now to decimate it to 24 fps
TDecimate(mode=1, cycleR =6, cycle = 10)

#now my favourite derainbowing
prerb = last
derbmask = last.tedgemask(threshY=7).mt_deflate()
prefiltered = last.FFT3Dfilter(sigma=1.5,bw=16,bh=16,bt=3,ow=8,oh=8,plane=0)
derbsuperfilt = MSuper(prefiltered) # all levels for MAnalyse
derbsuper = MSuper(levels=1) # one level is enough for MCompensate
derbbackward_vec2 = MAnalyse(derbsuperfilt, isb = true, delta = 2, overlap=4, truemotion = true, chroma=true,search=5, searchparam=4)
derbbackward_vec1 = MAnalyse(derbsuperfilt, isb = true, delta = 1, overlap=4, truemotion = true, chroma=true,search=5, searchparam=4)
derbforward_vec1 = MAnalyse(derbsuperfilt, isb = false, delta = 1, overlap=4, truemotion = true, chroma=true,search=5, searchparam=4)
derbforward_vec2 = MAnalyse(derbsuperfilt, isb = false, delta = 2, overlap=4, truemotion = true, chroma=true,search=5, searchparam=4)
# use not-prefiltered (super) clip for motion compensation
derbforward_compensation1 = MCompensate(derbsuper, derbforward_vec1,thSCD2=160,thSCD1=600)
derbforward_compensation2 = MCompensate(derbsuper, derbforward_vec2,thSCD2=160,thSCD1=600)
derbbackward_compensation1 = MCompensate(derbsuper, derbbackward_vec1,thSCD2=160,thSCD1=600)
derbbackward_compensation2 = MCompensate(derbsuper, derbbackward_vec2,thSCD2=160,thSCD1=600)
# create interleaved 5 frames sequences
interleave(derbforward_compensation2, derbforward_compensation1, last, derbbackward_compensation1, derbbackward_compensation2)
DFMDeRainbow5(8)
#dfttest(Y = false) # you could uncomment this if you wanted to filter more strongly - but it leads to more discoloration
selectevery(5,2) # return filtered central (not-compensated) frames only
mt_merge(prerb,last, derbmask,luma=true)

#to calm the shimmering edges more, let's use mdegrain2 on edges
requestlinear() # again, I get shit speed without this, multiple mvtools2 is not easy on avisynth
source = last
prefilt = last.removegrain(6).FFT3Dfilter(sigma=1.5,bw=16,bh=16,bt=3,ow=8,oh=8,plane=4)
superfilt = prefilt.MSuper(pel=2, sharp=1)
super = MSuper(pel=2, sharp=1)
backward_vec2 = MAnalyse(superfilt, isb = true, delta = 2, overlap=4)
backward_vec1 = MAnalyse(superfilt, isb = true, delta = 1, overlap=4)
forward_vec1 = MAnalyse(superfilt, isb = false, delta = 1, overlap=4)
forward_vec2 = MAnalyse(superfilt, isb = false, delta = 2, overlap=4)
degrainedge = source.MDegrain2(super, backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=230)
edgemask = removegrainhd(rank=25,radius=6).tedgemask(threshY=8)
mt_merge(source,degrainedge,edgemask,luma=true)


Derainbower from here (https://forum.doom9.org/showthread.php?t=171715)
The source has already been derianbowed and only the worst crap remains muted there, so I am afraid it might be hard to fix it completely. Perhaps also try bifrost() before qtgmc.

Perhaps you need to comment out the RequestLinear() when previewing/testing in virtualdub, I don't recall how it works now. For encoding you definitely want them there.
BTW if you get insanely low speeds, it might help to first encode just the qtgmc to a separate lossless file and then do the other steps on that. You will also have it ready for more experiments or redoing the filtering with different setup/ideas.

The QTGMC line might not be best, I reused it from one old anime rip I did many years ago. Perhaps somebody else could provide something saner/better for this case. Note that I have quite old plugins now because I have not been keeping up to date. So some QTGMC parameters might not work on current version.

I got 2.1 fps on Ryzen 3 2200G.

Note that you don't have any global motion like pans or other high-motion scene in the sample, so I can only hope it won't screw up on those.

Edit: here is a the result I got - I encoded it at double resolution accidentaly, sorry. uloz.to (https://uloz.to/!WUKWIlkwVHqU/ami-try-mkv)

Edit2:
Hmm, I got linked to this topic but didn't realize I'm in vapoursynth section. Sorry for giving avisynth code. I don't know how to do this all in vs, sorry. (Is using avisynth to filter this one source a problem? I think somebody got the derainbower working in VS, at least, and rest should be available too.)
---------------------------------

P.S. For people that will google up this stuff when looking for general old anime advice.
Don't use qtgmc, that is only for this particular (and not typical) case.
Perhaps look at this https://pastebin.com/2JPC88Lc

ChaosKing
7th March 2019, 20:03
You can try the "old" stab() https://github.com/theChaosCoder/lostfunc/blob/master/lostfunc.py
You need the DePan.dll for that which supports the range parameter. (You can find DePan.dll here https://forum.doom9.org/showthread.php?t=175529)

ChaosKing
7th March 2019, 20:57
The VFM + qtgmc combo by poisondeathray looks best to me.

My test script + encode https://www.dropbox.com/s/ibofdl29hrx5pfw/ami.mkv?dl=1
Denoising, sharpening, dehalo etc. needs tweaking. Nothing is final or really tested.
clip = orig= core.ffms2.Source(source=r'D:\Download\amisjourneyclip.mkv')

clip = core.vivtc.VFM(clip, order=1)
clip = core.vivtc.VDecimate(clip)
clip = haf.QTGMC(clip, InputType=1, Sharpness=0, Preset='very slow', TFF=True, MatchPreset="Slower", EdiMode="nnedi3", MatchPreset2="Slower", Lossless=0, SourceMatch=3)

c = clip
clip = los.Stab(clip, range=30, dxmax=4, dymax=4, mirror=15)

clip = haf.MCTemporalDenoise(clip, settings="medium")

clip = haf.ContraSharpening(clip, c, radius=2)
clip = haf.FineDehalo(clip, rx=2.0)
return core.std.CropRel(clip, left=16, top=4, right=4, bottom=0)

@mandarinka Are you using avisynth+? There is also a Tedgemask replacement https://github.com/chikuzen/TEMmod. replace tedgemask() with TEMmod()

mandarinka
7th March 2019, 21:51
I would not run denoise on this. QTGMC already does some of it. And if you smooth this, the look would be really bland. Generally I think cel anime looks bad if you smooth it out.

Unless you mask it to edges only. Then a degrained could calm the shimmering (which is why I used mdegrain2).

ad TEMmod - nope, I used normal 2.6. Does TEMmod improve the line detection (I don't really need YV24 support and stuff like that).

therobin
8th March 2019, 07:20
So after testing out those QTGMC, that last one seems to remove most of the shimmering issues from the video. So this is what I got so far based on my previous script and what was posted here:
import vapoursynth as vs
import havsfunc as haf
import lostfunc as los

core = vs.get_core()
clip = core.ffms2.Source('amisjourneyclip.mkv')

clip = core.vivtc.VFM(clip, order=1, chroma=0, mchroma=0)
clip = core.vivtc.VDecimate(clip)
clip = haf.QTGMC(clip, InputType=1, Sharpness=0, Preset='very slow', TFF=True, MatchPreset="Slower", EdiMode="nnedi3", MatchPreset2="Slower", Lossless=0, SourceMatch=3)

#clip = haf.Stab(clip, dxmax=6, dymax=6, mirror=0)
clip = los.Stab(clip, range=30, dxmax=6, dymax=6, mirror=0)
clip = core.smoothuv.SmoothUV(clip, radius=5, threshold=100, interlaced=0)
clip = haf.FineDehalo(clip, rx=2.0)
clip = core.std.Crop(clip, 20, 8, 4, 2)
#clip = core.fft3dfilter.FFT3DFilter(clip, sigma=2.5, bt=5, bw=32, bh=32, ow=16, oh=16, sharpen=0.7)
#clip = core.bilateral.Bilateral(clip, sigmaS=1, sigmaR=0.01, PBFICnum=16, algorithm=2)
#clip = core.hqdn3d.Hqdn3d(clip)
clip = core.resize.Spline36(clip, width=640, height=480)

clip.set_output()

I might drop stab due to its issues. I just tried los.Stab and it has even worse freakout. (See here (http://www.mediafire.com/file/w58lop56z7ompc7/amisjourneyclip_test.mkv/file) for the above script and here (http://www.mediafire.com/file/6z4ekqdjk740aha/amisjourneyclip_test_noStab.mkv/file) for the same without any stab). Not sure why it happens on mine and not yours. For denoiser, I haven't decided on that yet. I am mostly concerned with removing the shimmering interlacing artifacts first and QTGMC seems to take care of that.

mandarinka, that sample has seems to take care of the shimmering which is great. But has a strange framerate (due to lack of IVTC?). I also noticed there is still a lot of rainbowing. That script is too complicated for me, but I am assuming it is a conservative configuration to prevent derainbowing side-effects? SmoothUV does a good job of removing the remaining rainbows for me. The last part about using mdegrain2 might be of interest to me but it is too complicated for me to translate into vs. Can you make a sample with and without it so I can see what it is doing? Not sure I want to install avisynth just to experiment with it.

ChaosKing
8th March 2019, 09:36
It looks like you have seeking issues (not frame accurate). Try a newer ffms2 version or use lsmash or d2vsource.
There are several derainbow filters ported to VS like ASTDR, DFMDerainbow, Bifrost ... see http://vsdb.top/

mandarinka
8th March 2019, 14:04
mandarinka, that sample has seems to take care of the shimmering which is great. But has a strange framerate (due to lack of IVTC?). I also noticed there is still a lot of rainbowing. That script is too complicated for me, but I am assuming it is a conservative configuration to prevent derainbowing side-effects? SmoothUV does a good job of removing the remaining rainbows for me.

The framerate should be correct (24000/1001 aka 23,976 - that is as it should be). When I try to play the encoded sample, the zoom at 0:09 is perfectly smooth so it should be correct.

Installing avisynth isn't anything complicated. But I think you hsould be able to find a mdegrain2 teplate for vsynth too and just copy the values.


The last part about using mdegrain2 might be of interest to me but it is too complicated for me to translate into vs. Can you make a sample with and without it so I can see what it is doing? Not sure I want to install avisynth just to experiment with it.
It's a temporal thing, it likely won't show in screenshots that much. It should somewhat calm the jagged diagonal lines. http://screenshotcomparison.com/comparison/131723

ChaosKing
8th March 2019, 15:34
Here's a quick comparison between DFMDerainbow() and ASTDRmc() https://www.dropbox.com/s/13b7sfujmxxghhl/deraincomp.mkv?dl=1
astdr looks best to me
import dfmderainbow as df
df = df.DFMDerainbow(clip, maskthresh=7)
import ASTDR as ast
ast = ast.ASTDRmc(clip)

therobin
8th March 2019, 23:04
Ok problem with stab is solved by using d2v source. Latest ffms2 test8 did not change anything even after rebuilding the index. It looks like los.Stab does not have the issues from the haf.Stab version, so I guess I can keep that now.

I did try to test haf.MCTemporalDenoise but my vapoursynth would crash with an error in DFTTest.dll. Not sure what is happening there.

Here is another sample (http://www.mediafire.com/file/idqo65j6hj2c9jv/AmisJourneyClip_train.mkv/file) which QTGMC seems to struggle with when using progressive input. If I set InputType=0, it fixes it up nicely, but then I have to decimate half the frames. Not sure of the pros and cons of either method though.

therobin
10th March 2019, 23:56
mandarinka, I am trying to duplicate that mdegrain2 script in vapoursynth. But removegrainhd is not available in vapoursynth, some of the lines do not have clips specified and TEdge in vapoursynth does not take threshY. So this is what I came up with.

This in avisynth:
#to calm the shimmering edges more, let's use mdegrain2 on edges
requestlinear() # again, I get shit speed without this, multiple mvtools2 is not easy on avisynth
source = last
prefilt = last.removegrain(6).FFT3Dfilter(sigma=1.5,bw=16,bh=16,bt=3,ow=8,oh=8,plane=4)
superfilt = prefilt.MSuper(pel=2, sharp=1)
super = MSuper(pel=2, sharp=1)
backward_vec2 = MAnalyse(superfilt, isb = true, delta = 2, overlap=4)
backward_vec1 = MAnalyse(superfilt, isb = true, delta = 1, overlap=4)
forward_vec1 = MAnalyse(superfilt, isb = false, delta = 1, overlap=4)
forward_vec2 = MAnalyse(superfilt, isb = false, delta = 2, overlap=4)
degrainedge = source.MDegrain2(super, backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=230)
edgemask = removegrainhd(rank=25,radius=6).tedgemask(threshY=8)
mt_merge(source,degrainedge,edgemask,luma=true)
I converted to this in vapoursynth:
prefilt = core.rgvs.RemoveGrain(clip, 6)
prefilt = core.fft3dfilter.FFT3DFilter(prefilt, sigma=1.5, bw=16, bh=16, bt=3, ow=8, oh=8, planes=[0,1,2])
superfilt = core.mv.Super(prefilt, pel=2, sharp=1)
super = core.mv.Super(clip, pel=2, sharp=1) Since no input is specified above, I assumed input for MSuper is effectively the source
backward_vec2 = core.mv.Analyse(superfilt, isb=1, delta=2, overlap=4)
backward_vec1 = core.mv.Analyse(superfilt, isb=1, delta=1, overlap=4)
forward_vec1 = core.mv.Analyse(superfilt, isb=0, delta=1, overlap=4)
forward_vec2 = core.mv.Analyse(superfilt, isb=0, delta=2, overlap=4)
degrainedge = core.mv.Degrain2(clip, super, backward_vec1, forward_vec1, backward_vec2, forward_vec2, thsad=230)
#edgemask = mvf.TEdge(clip) Does not take threshY. Sobel looked much cleaner in defaults.
edgemask = core.std.Sobel(clip)
clip = core.std.MaskedMerge(clip, degrainedge, edgemask, planes=[0,1,2])
Does it look correct to you? It is functioning and calms those jaggies a bit. Just want to verify it is correctly translated.

ChaosKing
12th March 2019, 09:12
You could use https://github.com/sekrit-twc/avsproxy to run the 32bit removegrainhd() filter "inside" VS.

avsproxy can load external avisynth dlls, so you don't even need to install avisynth. (I think you need to copy devil.dll and one other dll next to avisynth.dll so it can find it)

therobin
13th March 2019, 02:17
Thanks for that. That will be useful in the future. Turns out mvf.TEdge() edgemask is very differeny from TEdgeMask() in avisynth.

Here is a comparison of std.Sobel(), mvf.TEdge() and the intended one from the avs script posted: https://imgur.com/a/iA6T5er

So the converted script looks like this now:
prefilt = core.rgvs.RemoveGrain(clip, 6)
prefilt = core.fft3dfilter.FFT3DFilter(prefilt, sigma=1.5, bw=16, bh=16, bt=3, ow=8, oh=8, planes=[0,1,2])
superfilt = core.mv.Super(prefilt, pel=2, sharp=1)
super = core.mv.Super(clip, pel=2, sharp=1)
backward_vec2 = core.mv.Analyse(superfilt, isb=1, delta=2, overlap=4)
backward_vec1 = core.mv.Analyse(superfilt, isb=1, delta=1, overlap=4)
forward_vec1 = core.mv.Analyse(superfilt, isb=0, delta=1, overlap=4)
forward_vec2 = core.mv.Analyse(superfilt, isb=0, delta=2, overlap=4)
degrainedge = core.mv.Degrain2(clip, super, backward_vec1, forward_vec1, backward_vec2, forward_vec2, thsad=230)
edgemask = core.avsw.Eval(r'AddAutoloadDir("c:\Users\ROBN\AppData\Roaming\VapourSynth\avsproxy\plugins") clip.removegrainhd(rank=25,radius=6).tedgemask(threshY=8)', clips=clip, clip_names='clip', avisynth=r'c:\Users\ROBN\AppData\Roaming\VapourSynth\avsproxy\avisynth.dll', slave_log=r"c:\Users\ROBN\AppData\Roaming\VapourSynth\avsproxy\log.txt",)
clip = core.std.MaskedMerge(clip, degrainedge, edgemask, planes=[0,1,2])

I'll do some testing to compare the output vs sobel.

ChaosKing
13th March 2019, 02:40
You could also test tcanny (it has multiple edge detection modes)

ChaosKing
13th March 2019, 17:28
jackoneill heard your prayers https://forum.doom9.org/showthread.php?p=1868700

therobin
15th March 2019, 05:46
jackoneill heard your prayers https://forum.doom9.org/showthread.php?p=1868700

OK just installed it and ran some quick tests. The parameters for this TEdgeMask is still different from the one posted (I guess that is because it is based on the TEMod() version). The outputs are the same in defaults and when setting threshold/threshY=8. Below that, the makediff starts to show.

So that considered, it is effectively identical for the purpose of this script.

Now I have examined Sobel, Prewitt, TCanny, AVS TEdgeMask, mvf.TEdge and this TEdgeMask via MakeDiff when used in this script. I didn't save any screens, but the conclusion is pretty simple. Sobel and AVS TEdgeMask produce pretty much the same results. Prewitt shows slightly less effectiveness than Sobel according to the less edges shown in the MakeDiff. mvf.TEdge is no good here since it is so sensitivity it picks up noise in the edgemask (it would need massive pre-filtering). TCanny produced a very different (thinner) edgemask that did not play well in this script (little effectiveness) unless configured to Sobel's operator (so might as well use Sobel).

So this script's edge mask can be done like this:
edgemask = core.avsw.Eval(r'AddAutoloadDir("<Plugins>") clip.removegrainhd(rank=25,radius=6)', clips=clip, clip_names='clip', avisynth=r'<avisynth.dll>', slave_log=r"<log.txt>",)
edgemask = core.tedgemask.TEdgeMask(clip, threshold=8)

Or just:
edgemask = core.std.Sobel(clip)

Going back to QTGMC, I found there is a trade off with using InputType=1 (Progressive) and InputType=0 (Interlace) with this source. In progressive, it cleans up the shimmering better than interlace, but leaves more interlacing behind. In interlace, it cleans more interlacing, but leaves behind more shimmering. So, I combined them. I used GTQMC with InputType=1 followed by QTGMC again with InputType=0. The results produced a cleaner overall image. I created a set of screenshots (https://imgur.com/a/kGun73Y) to demonstrate difference in the aliasing. Here is a sample video (http://www.mediafire.com/file/f41d4pv02je16tw/AmiJourney_Sample_QTGMC_Compare.mkv) to show the shimmering difference. So am I crazy for doing this?

Finally, I tested several derainbowers and denoisers. I ended up liking a tweaked SmoothUV and HQDN3D best.

So my script currently looks like this:
import vapoursynth as vs
import lostfunc as los
import havsfunc as haf

core = vs.get_core()
clip = core.d2v.Source(r'..\WIP\Amis Journey DGindex.d2v')

clip = core.vivtc.VFM(clip, order=1, chroma=0, mchroma=0)
clip = core.vivtc.VDecimate(clip)

clip = haf.QTGMC(clip, InputType=1, Sharpness=0, Preset='very slow', TFF=True, MatchPreset='very slow', EdiMode='EEDI3', EdiQual=2, EdiMaxD=32, MatchPreset2='very slow', TR0=2, TR1=2, TR2=1, Rep0=1, Rep1=1, Rep2=1, Lossless=0, SourceMatch=3)
clip = haf.QTGMC(clip, InputType=0, Sharpness=0, Preset='very slow', TFF=True, EdiMode='EEDI3', EdiQual=2, EdiMaxD=32, TR0=2, TR1=2, TR2=1, Rep0=1, Rep1=1, Rep2=1, Lossless=2, SourceMatch=3, FPSDivisor=2)
clip = core.std.SetFieldBased(clip, 0)

prefilt = core.rgvs.RemoveGrain(clip, 6)
prefilt = core.fft3dfilter.FFT3DFilter(prefilt, sigma=1.5, bw=16, bh=16, bt=3, ow=8, oh=8, planes=[0,1,2])
superfilt = core.mv.Super(prefilt, pel=2, sharp=1)
super = core.mv.Super(clip, pel=2, sharp=1)
backward_vec2 = core.mv.Analyse(superfilt, isb=1, delta=2, overlap=4)
backward_vec1 = core.mv.Analyse(superfilt, isb=1, delta=1, overlap=4)
forward_vec1 = core.mv.Analyse(superfilt, isb=0, delta=1, overlap=4)
forward_vec2 = core.mv.Analyse(superfilt, isb=0, delta=2, overlap=4)
degrainedge = core.mv.Degrain2(clip, super, backward_vec1, forward_vec1, backward_vec2, forward_vec2, thsad=230)
edgemask = core.avsw.Eval(r'AddAutoloadDir("c:\Users\ROBN\AppData\Roaming\VapourSynth\avsproxy\plugins") clip.removegrainhd(rank=25,radius=6)', clips=clip, clip_names='clip', avisynth=r'c:\Users\ROBN\AppData\Roaming\VapourSynth\avsproxy\avisynth.dll', slave_log=r"c:\Users\ROBN\AppData\Roaming\VapourSynth\avsproxy\log.txt")
edgemask = core.tedgemask.TEdgeMask(clip, threshold=8)
clip = core.std.MaskedMerge(clip, degrainedge, edgemask, planes=[0,1,2])

clip = los.Stab(clip, range=30, dxmax=4, dymax=4, mirror=0)
clip = core.smoothuv.SmoothUV(clip, radius=5, threshold=40, interlaced=0)
clip = core.std.Crop(clip, 20, 8, 4, 2)
c = clip
clip = core.hqdn3d.Hqdn3d(clip, lum_spac=2, lum_tmp=6)
clip = haf.ContraSharpening(clip, c, radius=2)
clip = haf.FineDehalo(clip, rx=2.0)
clip = core.resize.Spline36(clip, width=640, height=480)

clip.set_output()