Log in

View Full Version : Offloading to GPU


FranceBB
23rd January 2021, 14:17
Hi there, folks,
out of curiosity, this is one of the scripts I'm currently running automatically on several files on a farm with two servers which have an Intel Xeon 28c/56th and 64 GB of RAM each and I'm quite happy with the results I've got as output, however it's currently working at 0.6fps and encoding it's not the issue, Avisynth is. Is there anything (besides the Indexer) that I can offload to the GPU? I know about DGDecodeNV and I'm also a "customer" (Donald knows ;) ) but what about the other filters I'm using? As to encoding itself, I'm not really planning to use GPU encoding for the output due to quality concerns, so... is there anything inside Avisynth that I can offload to GPU?

(side note: Input is v210 lossless .avi 720x576 25i so nothing hard to index, you know...)


#Indexing
video=FFVideoSource("\\mibcssda001\Media Ingest\00_INGEST_MAM\A.R.C.A\00_FILE_DA_ENCODARE\file.avi")
ch1=FFAudioSource("\\mibcssda001\Media Ingest\00_INGEST_MAM\A.R.C.A\00_FILE_DA_ENCODARE\file.avi", track=1)
ch2=FFAudioSource("\\mibcssda001\Media Ingest\00_INGEST_MAM\A.R.C.A\00_FILE_DA_ENCODARE\file.avi", track=2)
ch3=FFAudioSource("\\mibcssda001\Media Ingest\00_INGEST_MAM\A.R.C.A\00_FILE_DA_ENCODARE\file.avi", track=3)
ch4=FFAudioSource("\\mibcssda001\Media Ingest\00_INGEST_MAM\A.R.C.A\00_FILE_DA_ENCODARE\file.avi", track=4)
audio=MergeChannels(ch1, ch2, ch3, ch4, ch1, ch2, ch3, ch4)
AudioDub(video, audio)

#Bob-deinterlacing
AssumeTFF()
QTGMC( Preset="Placebo")

#Bring everything to 16bit planar
HBD=ConvertBits(m_clip, bits=16)

#Convert to 4:2:2 planar 16bit
c=Converttoyuv422(HBD, matrix="Rec601")

#De-Sport 16bit planar
SpotLess(c)

#Degrain in 16bit planar
super = MSuper(pel=2, sharp=1)
bv1 = MAnalyse(super, isb = true, delta = 1, overlap=4)
fv1 = MAnalyse(super, isb = false, delta = 1, overlap=4)
bv2 = MAnalyse(super, isb = true, delta = 2, overlap=4)
fv2 = MAnalyse(super, isb = false, delta = 2, overlap=4)
degrain=MDegrain2(super,bv1,fv1,bv2,fv2,thSADC=1200, thSAD=1200)

#Spatial denoise 16bit planar
denoise=dfttest(degrain, sigma=64, tbsize=1, lsb_in=false, lsb=false, Y=true, U=true, V=true, dither=0)

#Adding borders for 1.33 PB 4:3 with 16bit planar precision
borders=AddBorders(denoise, 152, 0, 152, 0)

#Upscale to FULL HD with Spline64 + NNEDI and 16bit planar precision
resized=nnedi3_rpow2(borders, cshift="Spline64ResizeMT", rfactor=2, fwidth=1920, fheight=1080, nsize=4, nns=4, qual=1, etype=0, pscrn=2, threads=56, csresize=true, mpeg2=true, threads_rs=0, logicalCores_rs=true, MaxPhysCore_rs=true, SetAffinity_rs=false)

#From 16bit planar to 16bit interleaved
interleaved=ConvertToDoubleWidth(resized)

#Matrix Conversion from BT601 to BT709 with 16bit interleaved precision
color=Matrix(interleaved, from=601, to=709, rg=1.0, gg=1.0, bg=1.0, a=16, b=235, ao=16, bo=235, bitdepth=16)

#From 16bit interleaved to 16bit planar
planar=ConvertFromDoubleWidth(color)

#Dithering from 16bit planar to 8bit planar with the Floyd-Steinberg error diffusion
dithered=ConvertBits(planar, bits=8, dither=1)

#Limiter TV Range 0.0 - 0.7V
m_clip=Limiter(dithered, min_luma=16, max_luma=235, min_chroma=16, max_chroma=240)


Return m_clip

Atak_Snajpera
23rd January 2021, 15:32
By the way, no prefetch in script?

#Indexing
video=FFVideoSource("\\mibcssda001\Media Ingest\00_INGEST_MAM\A.R.C.A\00_FILE_DA_ENCODARE\file.avi")
ch1=FFAudioSource("\\mibcssda001\Media Ingest\00_INGEST_MAM\A.R.C.A\00_FILE_DA_ENCODARE\file.avi", track=1)
ch2=FFAudioSource("\\mibcssda001\Media Ingest\00_INGEST_MAM\A.R.C.A\00_FILE_DA_ENCODARE\file.avi", track=2)
ch3=FFAudioSource("\\mibcssda001\Media Ingest\00_INGEST_MAM\A.R.C.A\00_FILE_DA_ENCODARE\file.avi", track=3)
ch4=FFAudioSource("\\mibcssda001\Media Ingest\00_INGEST_MAM\A.R.C.A\00_FILE_DA_ENCODARE\file.avi", track=4)
audio=MergeChannels(ch1, ch2, ch3, ch4, ch1, ch2, ch3, ch4)
AudioDub(video, audio)

#Bob-deinterlacing
AssumeTFF()
QTGMC( Preset="Placebo")

#Bring everything to 16bit planar
HBD=ConvertBits(m_clip, bits=16)

#Convert to 4:2:2 planar 16bit
c=Converttoyuv422(HBD, matrix="Rec601")

#De-Sport 16bit planar
SpotLess(c)

#Degrain in 16bit planar
super = MSuper(pel=2, sharp=1)
bv1 = MAnalyse(super, isb = true, delta = 1, overlap=4)
fv1 = MAnalyse(super, isb = false, delta = 1, overlap=4)
bv2 = MAnalyse(super, isb = true, delta = 2, overlap=4)
fv2 = MAnalyse(super, isb = false, delta = 2, overlap=4)
degrain=MDegrain2(super,bv1,fv1,bv2,fv2,thSADC=1200, thSAD=1200)

#Spatial denoise 16bit planar
denoise=dfttest(degrain, sigma=64, tbsize=1, lsb_in=false, lsb=false, Y=true, U=true, V=true, dither=0)

#Adding borders for 1.33 PB 4:3 with 16bit planar precision
borders=AddBorders(denoise, 152, 0, 152, 0)

#Upscale to FULL HD with Spline64 + NNEDI and 16bit planar precision
resized=nnedi3_rpow2(borders, cshift="Spline64ResizeMT", rfactor=2, fwidth=1920, fheight=1080, nsize=4, nns=4, qual=1, etype=0, pscrn=2, threads=56, csresize=true, mpeg2=true, threads_rs=0, logicalCores_rs=true, MaxPhysCore_rs=true, SetAffinity_rs=false)

#From 16bit planar to 16bit interleaved
interleaved=ConvertToDoubleWidth(resized)

#Matrix Conversion from BT601 to BT709 with 16bit interleaved precision
color=Matrix(interleaved, from=601, to=709, rg=1.0, gg=1.0, bg=1.0, a=16, b=235, ao=16, bo=235, bitdepth=16)

#From 16bit interleaved to 16bit planar
planar=ConvertFromDoubleWidth(color)

#Dithering from 16bit planar to 8bit planar with the Floyd-Steinberg error diffusion
dithered=ConvertBits(planar, bits=8, dither=1)

#Limiter TV Range 0.0 - 0.7V
m_clip=Limiter(dithered, min_luma=16, max_luma=235, min_chroma=16, max_chroma=240)

#Prefetch
m_clip=Prefetch(m_clip,28)

Return m_clip

Furthermore, Personally I wouldn't use such high values in MDegrain2 (thSADC=1200, thSAD=1200) because it is recipe for ugly ghosting artefacts.

real.finder
23rd January 2021, 16:14
there are https://github.com/nekopanda/AviSynthPlus/releases (I think avs+ can do same of it work after 3.6 update)

and there are some CUDA plugins here https://github.com/nekopanda/AviSynthCUDAFilters (don't know if they can work in avs+ 3.6)

and aside from all that, maybe we need someone backport opencl versions of plugins from VS like https://github.com/HomeOfVapourSynthEvolution/VapourSynth-NNEDI3CL (the SEt avs one is closed source and no one can update it since SEt is no longer active) and there are some plugins have both CL and CPU functions in the same plugin like https://github.com/HomeOfVapourSynthEvolution/VapourSynth-TCanny Asd already backport it to avs but only for the CPU function!

Frank62
23rd January 2021, 19:08
I wouldn't use QTGMC with "placebo". Seems the bottleneck to me. And often "slow" leaves more details. Try it.

FranceBB
24th January 2021, 10:47
The only reason why I didn't add Prefetch is that I know that some of the plugins create their own thread pool, like plugins_JPSDR which I'm using in my filterchain, so I don't know how it's gonna behave, but if you think it's gonna behave nicely, I'll add it.



Personally I wouldn't use such high values in MDegrain2 (thSADC=1200, thSAD=1200) because it is recipe for ugly ghosting artefacts.

True, however there's so much noise and grain on those tapes that I don't have much choice. Those are 25i truly interlaced recordings of live feeds from RAI from the 70s on U-Matic and believe me, they have no details whatsoever, tons of grain and far too much noise (due to the transmission methods employed at the time).

https://cdn.thegreatbear.net/wp-content/uploads/2013/05/ampex-umatic-tapes-dehydrating1.jpg

https://static.tvtropes.org/pmwiki/pub/images/umatictapes.png

Note: not my pictures

We've also noticed a deterioration of the binders in a magnetic tape which hold the iron oxide magnetic coating to its plastic carrier. Some people suggested dehydrating them in a carefully controlled manner, but we don't have the tools to do that, anyway for now it seems they're playing someway, somehow, so it might as well be the last time they play. They're in horrible conditions and a very strong denoise and degrain is needed (oh and I checked, I don't get ghosting, except when the ball is sometimes removed in tennis matches, but I encode them with different parameters to solve the problem, so it's not a big deal. ;) )

I wouldn't use QTGMC with "placebo". Seems the bottleneck to me. And often "slow" leaves more details. Try it.

Not that there are many details in those contents, but I'll give it a shot.

Frank62
24th January 2021, 13:50
Ok... with so much grain it really will make no difference. Then better try "fast"... ;)
For electronical grain like this we still use NeatVideo, since many years. But also quite slow.

FranceBB
24th January 2021, 14:01
For electronical grain like this we still use NeatVideo, since many years. But also quite slow.

Yeah, Jean Philippe also suggested it to me two years ago (although it's a paid solution). :)

Frank62
24th January 2021, 18:54
Just if you are interested:
We use NeatVideo as best solution for this kind of noise, but I forgot: VERY carefully...
In amost all cases we turn it to only 5% spatial heights (mids and lows zero!), and temporally 2 or 3 frames. So it provides the best temporal noise remover I know up to now.
In many cases we also mix back some of the original noise (overlay, transparency ~0.3) to avoid wax-effect.

Atak_Snajpera
24th January 2021, 19:06
Yeah, forget about QTGMC placebo and just use medium. Anything above that is a waste of time and electricity. Regarding prefetch ,i recommend using number of physical cores first instead of going straight to number of total supported threads. You may also reduce number of threads in nnedi to 2 or even 1.

FranceBB
28th January 2021, 11:17
Ok, I tried with Prefetch and I gotta say, I'm not impressed at all...
If anything, I'm surprised 'cause it's even slower than without it...
I tried limiting NNEDI to 1 thread and also removing it completely from the filter chain, but nothing, in all my tests, I dropped from 0.3-0.5fps without Prefetch to 0.1fps with Prefetch at 28...

EDIT: Lowering Prefetch down to 8 or 6 allows me to get the very same speed I usually get without Prefetch, so 0.3fps... It's not really worth it... I'm not gonna be using Prefetch! (Keep in mind that it's a 28c/56th Xeon, so I expected much better from it...)

pinterf
28th January 2021, 12:10
Ok, I tried with Prefetch and I gotta say, I'm not impressed at all...
If anything, I'm surprised 'cause it's even slower than without it...
I tried limiting NNEDI to 1 thread and also removing it completely from the filter chain, but nothing, in all my tests, I dropped from 0.3-0.5fps without Prefetch to 0.1fps with Prefetch at 28...

EDIT: Lowering Prefetch down to 8 or 6 allows me to get the very same speed I usually get without Prefetch, so 0.3fps... It's not really worth it... I'm not gonna be using Prefetch! (Keep in mind that it's a 28c/56th Xeon, so I expected much better from it...)

Have you adjusted SetMemoryMax? Large thread count needs more memory. Low memory kills the caches and the speed. Put it to a huge value, then check the actual memory consumption with Avsmeter.

FranceBB
28th January 2021, 13:53
Setting SetMemoryMax(128000) so 128 GB, which is the maximum available RAM on the other server and Prefetch to 28, it goes all the way up to 21 GB of RAM, then it goes down to 14 GB, then it goes up to 21 GB, then it drops to 14 GB in a loop.
The speed however is the same: 0.1fps.
With Prefetch 2 the RAM is steady and way lower and the speed is 0.3fps, so about the same as I get without Prefetch.
This is definitely weird...

pinterf
28th January 2021, 15:53
The bottleneck is TemporalMedian in Spotless.
TemporalMedian works internally by histograms, bit depth heavily affects the speed. Checking only 256 levels is much quicker than doing it with a histogram array size of 65536.

First I have modded the plugin to use SSE2 for 16 bit videos.
Presently only 8 bit videos have SSE2 in TemporalMedian, 10+ bit depths are using plain C. (Untested, did not put it in live code)
It got quicker but not that much.

Then I tried feeding MedianBlur with only a 10 bit clip. I recommend you trying this option.

EDIT:
specify directly threads=1 for dfttest when using Prefetch. Its default value is 0, which means that it is using num_processors internal threads. When thread count is not 1, this filter has MT_SERIALIZED behaviour instead of MT_MULTI_INSTANCE.

FranceBB
30th January 2021, 14:19
specify directly threads=1 for dfttest when using Prefetch. Its default value is 0, which means that it is using num_processors internal threads. When thread count is not 1, this filter has MT_SERIALIZED behaviour instead of MT_MULTI_INSTANCE.

Ok, I'll try with threads=1 on dfttest as well, but question: I just noticed that it can't handle more than 16 threads if I use it normally without Prefetch.


if (threads < 0 || threads > 16)
env->ThrowError("dfttest: threads must be between 0 and 16 (inclusive)!");


line 1345-1346 of dfttest.cpp. Why is that?

pinterf
30th January 2021, 14:42
I don't know.
Back to Spotless: the way TemporalMedian is used (radius=0, temporal radius=1) is highly unoptimal in present plugin, I'm considering optimizing this special case.
You could also try z_ConvertFormat instead of Matrix, it can combine the colorspace the bit depth conversion and dithering.

FranceBB
30th January 2021, 14:58
I don't know.
Back to Spotless: the way TemporalMedian is used (radius=0, temporal radius=1) is highly unoptimal in present plugin, I'm considering optimizing this special case.
You could also try z_ConvertFormat instead of Matrix, it can combine the colorspace the bit depth conversion and dithering.

Gotcha.
I'll try to replace it with z_ConvertFormat so that I don't have to go to 16bit interleaved and come back. That should speed things up even further.

pinterf
30th January 2021, 16:45
I've just tried the above mentioned special use case (radius=0, temporal radius=1) with an optimized TemporalMedian version.
Breaking the script after Spotless:
With the original DLL version the script run at 0.37fps.
Then I developed AVX2 into TemporalMedian (still the generic approach) and it reached 0.57fps. Good.
But this special case separation resulted in a huge speed gain, now I'm getting 3.08fps. A significant change.
AAA+ Green Label :)
I'm doing some more checks then I release it in some days.

pinterf
30th January 2021, 21:25
Please test with this one: MedianBlur2 new version.
https://github.com/pinterf/MedianBlur2/releases/tag/1.1
- 1.1 (20210130) - pinterf
- Speed: SSE2 and AVX2 for 10+ bits (generic case, MedianBlur)
- Speed: SSE2 and AVX2 for TemporalMedianBlur
- Speed: Much-much quicker: TemporalMedianBlur special case: temporal radius=1 or 2, spatial radius=0 (C, SSE4.1, AVX2)
- Pass frame properties when Avisynth interface>=8
- Debug helper parameter 'opt': integer default -1
<0: autodetect CPU
0: C only (disable SSE2 and AVX2)
1: SSE2 (disable SSE4.1 and AVX2)
2: SSE4 (disable AVX2)
3: AVX2

FranceBB
30th January 2021, 21:26
I've just tried the above mentioned special use case (radius=0, temporal radius=1) with an optimized TemporalMedian version.
Breaking the script after Spotless:
With the original DLL version the script run at 0.37fps.
Then I developed AVX2 into TemporalMedian (still the generic approach) and it reached 0.57fps. Good.
But this special case separation resulted in a huge speed gain, now I'm getting 3.08fps. A significant change.
AAA+ Green Label :)
I'm doing some more checks then I release it in some days.

Wow! 3FPS? That would be a dream!! *_*
It would speed things up a lot considering that this filterchain is here to stay in the foreseeable future in our server! Thanks!! :D
I really look forward to try it and put it in production!

Frank62
30th January 2021, 23:15
Thanks from me, too! Will save a lot of time in the future!

Atak_Snajpera
30th January 2021, 23:54
3 FPS is still a pathetic speed for SD content on 28 core CPU. If I were you would first optimize your script for usage with prefetch function. Do you really , really, really need that spotless and dfftest? Why not use knlmeanscl as extra denoiser after MDegrain? IT looks like you are just throwing filters (in random order) just to kill performance. I do not understand why you resize after adding borders? Furthermore, For optimal performance upscaling should be done somewhere at the end of script. Addborders should be the last. In general your script reminds of german Tiger tank from WWII... ...Crazy overengineered beast.

ChaosKing
31st January 2021, 00:16
Idk if anyone saw this, but the wiki says http://avisynth.nl/index.php/MedianBlur2
Same as Clense() but much slower:
MedianBlurTemporal(radiusy=0, radiusu=0, radiusv=0, temporalradius=1)

Maybe slower in 1879... but today with a 1080p clip (Ryzen 2600) clense() = 80fps & MedianBlurTemporal(radiusY=0,radiusU=0,radiusV=0,temporalradius=1) = 10 fps :sly:

Output looks the same to me.

Surprise: temporalradius = 1 is the default in spotless

StainlessS
31st January 2021, 03:01
Chaos, nice observation, take 10 points.
[EDIT: My old science teacher used to give 10 points for bringing her bike upstairs, one with most points got to go home 30 mins early on Friday.]

OK, Here some numbers.
Probably not best clip to try, was JohnMeyer Parade clip, 488x360, bout 7300 frames, cropped mod 4 and cleaned up a bit, saved lossless UT_Video.
Machine W7, Core Duo quad, Q9550. Sata 3 drive but only Sata2 interface.
EDIT: 8 bit only.

SpotLess Numbers

MediumBlur2 v1.0 RADT=1=23.82 FPS : RADT=3=20.58 FPS
MediumBlur2 v1.1 RADT=1=30.28 FPS : RADT=3=24.13 FPS
MediumBlur2 v1.1_Clense RADT=1=30.50 FPS : RADT=3=24.11 FPS


Maybe disappointing, but somebody post some numbers on lossy clip with SATA3, I gotta get back to W10 setup stuff.
tryin' to find W10 x86 drivers for a tablet laptop thingy, that maker seems to have abandoned [Baytrail].


Function SpotLess(clip c,int "RadT",int "ThSAD",int "ThSAD2",int "pel",bool "chroma", int "BlkSz",Int "Olap",bool "tm",Bool "glob",Float "bBlur") {
myName = "SpotLess: "
RadT = Default(RadT,1) # Temporal radius. (MCompensate arg)
ThSAD = Default(ThSAD,10000) # SAD threshold at radius 1 (Default Nearly OFF).
ThSAD2 = Default(ThSAD2,ThSAD) # SAD threshold at radius RadT.
Pel = Default(pel,2) # Default 2. 1, 2, or 4. Maybe set 1 for HD+. (1=precision to pixel, 2=precision to half pixel, 4=quarter pixel)
Chroma = Default(chroma,True) # MAnalyse chroma arg. If set to true, use chroma in block matching.
BlkSz = Default(BlkSz,8) # Default 8. MAnalyse BlkSize. Bigger blksz quicker and perhaps better, esp for HD clips. Maybe also better where BIG noise.
OLap = Default(OLap, BlkSz/2) # Default half of BlkSz.
Tm = Default(tm,True) # TrueMotion, Some folk swear MAnalyse(truemotion=false) is better.
Glob = Default(glob,True) # Default True, Allow set MAnalyse(global) independently of TrueMotion.
Bblur = Default(bblur,0.0) # Default OFF
Assert(1 <= RadT,myName + " 1 <= RadT")
Assert(0.0 <= bblur <= 1.58, myName + "0.0 <= bblur <= 1.58")
Assert(pel==1 || pel==2 || pel==4, myName + "pel==1 || pel==2 || pel==4")
pad = max(BlkSz,8)
sup = (bBlur<=0.0 ? c : c.blur(bblur)).MSuper(hpad=pad,vpad=pad,pel=pel,sharp=2)
sup_rend = (bBlur<=0.0) ? sup : c.MSuper(hpad=pad,vpad=pad,pel=pel,sharp=2,levels=1) # Only 1 Level required where not MAnalyse-ing.
MultiVec = sup.MAnalyse(multi=true, delta=RadT,blksize=BlkSz,overlap=OLap,chroma=Chroma,truemotion=Tm,global=Glob)
c.MCompensate(sup_rend, MultiVec, tr=RadT, thSad=ThSAD, thSad2=ThSAD2)
(RadT==1)
\ ? Eval("try { clense } catch(err_msg) { MedianBlurTemporal(radiusY=0,radiusU=0,radiusV=0,temporalradius=RadT) } ")
\ : MedianBlurTemporal(radiusY=0,radiusU=0,radiusV=0,temporalradius=RadT)
SelectEvery(RadT*2+1,RadT) # Return middle frame
}

AviSource("D:\Parade.avi")
SpotLess(RadT=1)
Prefetch(4)
Return last


EDIT: BOTH MedianBlur2's were x86 XP version. Clense() from RGTools [dont know which version, if there is a choice].
Will use Clense() if available [and RadT==1) else MedianBlurTemporal().
Not a lot in it for clense(), but lets see some other numbers [and for non XP version].
EDIT: It might be true that new MedianBlurTemporal is especially optimized for RadT=1 already (3 frames, prev curr and next, quick order sort).

EDIT: Redone, RadT=1, better CPU usage for v1.1 and Clense.

MediumBlur2 v1.0
Frames processed: 7373 (0 - 7372)
FPS (min | max | average): 7.330 | 394290 | 26.03
Process memory usage (max): 85 MiB
Thread count: 13
CPU usage (average): 41.1%
Time (elapsed): 00:04:43.242

MediumBlur2 v1.1
Frames processed: 7373 (0 - 7372)
FPS (min | max | average): 6.444 | 184002 | 32.88
Process memory usage (max): 82 MiB
Thread count: 13
CPU usage (average): 28.1%
Time (elapsed): 00:03:44.208

RGTools_Clense:
Frames processed: 7373 (0 - 7372)
FPS (min | max | average): 9.959 | 197145 | 32.65
Process memory usage (max): 80 MiB
Thread count: 13
CPU usage (average): 28.3%
Time (elapsed): 00:03:45.816

EDIT: Above, redone again.

ChaosKing
31st January 2021, 09:23
"old" spotless gives me ~6.2 fps, with clense() its 9.3 fps

EDIT test was wrong

Re-tested:
spotless + clense and MediumBlur2 v1.1 have almost the same speed ~12.2fps, but clense seems a tiny bit faster.
spotless + MediumBlur2 v1.0 ~5.X fps

FranceBB
31st January 2021, 10:31
I do not understand why you resize after adding borders?

Input is 720x576, so it's either 16:9 or 4:3.
If it's 4:3, I first add borders to get 1.77 then I upscale to FULL HD 1920x1080 'cause it's easier to make the calculations.
As to the upscale itself, it's better to upscale with NNEDI3 than to let the Omneon playout port upscale it for me on playback with a FastBicubic() ;)

3 FPS is still a pathetic speed for SD content on 28 core CPU.

Considering the kind of filters and the kind of high bit depth processing that the server is doing, it's really not that pathetic.

Do you really , really, really need that spotless and dfftest?


Well, there are spots and scratches, so yeah. I used to use KillerSpot() before StainlessS made SpotLess() and I was very reluctant at first last summer. I could go back to KillerSpot() but I don't see how that it's gonna help. As to DFTTest, you should know me by now, I'm very bonded to my habits. DFTTest has been my de facto denoiser for a very long time (literally several years in many different cases), so it's hard for me to change it in favor of another denoiser, but if you say it would help performances and achieve a very similar output, then why not...


Why not use knlmeanscl as extra denoiser after MDegrain?


I might give KNLMeans a shot, but again I'm very reluctant in changing my preferred filters.

tormento
31st January 2021, 11:51
Well, there are spots and scratches, so yeah.
Ever tried to give a light pass with SMDegrain prefilter 4 with multiple frames and low thsad?

Atak_Snajpera
31st January 2021, 12:05
If source Has already terrible quality (requires ultra heavy denoising) like you said earlier then why do you even bother working in 16 bits? I also doubt that nnedi can improve anything over simpler resizer. Like I said. Your script is over-enginereed and hence your problems with slow performance.

ChaosKing
31st January 2021, 12:55
Input is 720x576, so it's either 16:9 or 4:3.
DFTTest has been my de facto denoiser for a very long time (literally several years in many different cases), so it's hard for me to change it in favor of another denoiser, but if you say it would help performances and achieve a very similar output, then why not...

Different sources require different solutions. Sticking always only to one filter could also mean less quality and/or waste of cpu time.
You could als try BM3D for ultra denoising. It can give very good results, but is also veryslow. Available only in Vapoursynth.

Atak_Snajpera
31st January 2021, 13:05
You should start with something like this...


#Deinterlace
video=AssumeTFF(video).QTGMC(Preset="Medium",FPSDivisor=2)

#CPU_Denoise
super=MSuper(video,pel=2)
fv1=MAnalyse(super,isb=false,delta=1,overlap=4)
bv1=MAnalyse(super,isb=true,delta=1,overlap=4)
fv2=MAnalyse(super,isb=false,delta=2,overlap=4)
bv2=MAnalyse(super,isb=true,delta=2,overlap=4)
fv3=MAnalyse(super,isb=false,delta=3,overlap=4)
bv3=MAnalyse(super,isb=true,delta=3,overlap=4)
video=MDegrain3(video,super,bv1,fv1,bv2,fv2,bv3,fv3,thSAD=400)

#Prefetch
video=Prefetch(video,8)

#GPU_Denoise
video=KNLMeansCL(video,d=1, a=2, s=4, h=4, device_type="GPU", device_id=0)

#Upscale
video=Spline36ResizeMT(video,1440,1080)

#Borders
Import("C:\Users\Dave\Documents\Delphi_Projects\RipBot264\_Compiled\Tools\AviSynth plugins\Scripts\AutoBorders.avs")
video=AutoBorders(video,16.0/9.0)


AvsMeter running on Xeon E5-2690 (8C/16T) with RX570 4GiB (5 TFLOPS of FP32 performance)
AVSMeter 3.0.6.0 (x64), (c) Groucho2004, 2012-2020
AviSynth+ 3.4 (r2925, master, x86_64) (3.4.0.0)

Number of frames: 43500
Length (hh:mm:ss.ms): 00:24:11.450
Frame width: 1920
Frame height: 1080
Framerate: 29.970 (30000/1001)
Colorspace: YV12

Frame (current | last): 2174 | 43499
FPS (cur | min | max | avg): 16.74 | 3.754 | 58.93 | 34.57
Process memory usage: 886 MiB
Thread count: 81
CPU usage (current | average): 61.4% | 57.0%

Time (elapsed | estimated): 00:01:02.624 | 00:20:58.265

Now you see why your speed is pathetic on that 28 core beast?

Some examples
https://i.postimg.cc/Bv1YD8p8/0.png
https://i.postimg.cc/nzbd1HS3/1.png
https://i.postimg.cc/0QYVWLLP/2.png

StainlessS
31st January 2021, 16:42
Re-tested:
spotless + clense and MediumBlur2 v1.1 have almost the same speed ~12.2fps, but clense seems a tiny bit faster.
spotless + MediumBlur2 v1.0 ~5.X fps

Did you note CPU usage at all ? [EDIT: With/without clense]

FranceBB
31st January 2021, 16:50
Changing from DFTTest to KNLMeansCL and leaving the script as it was brought an additional 0.8fps speed improvement, although the NVIDIA Quadro P4000 was just sitting there all the time as it wasn't being used much (i.e the bottleneck wasn't DFTTest).
On the other hand, when I looked at the background among other things I noticed that KNLMeansCL(degrain, d=1, a=2, s=4, h=4, device_type="GPU", device_id=0) left more details but at the same time failed to remove some of the very heavy noise.
Since it's copyrighted material, I had to discuss with my boss and pick a very short part of a recording of a studio which doesn't exist anymore and I've now prepared a very short sample of one of our best looking tape from the 80s which is a common use case scenario for this kind of filter chain.
In the sample (which has been corrected by an hardware Time Base Corrector before being captured in lossless), we can see how there's a bit of everything: noise, raimbowning, etc, but all of that has been taken care of by the filters.

Sample Download: https://we.tl/t-XHsQ8bpop0


Source:

https://i.imgur.com/r4wRr8e.png

DFTTest:

https://i.imgur.com/xKFp0az.png

KNLMeansCL:

https://i.imgur.com/iAprgYy.png

Source 2:

https://i.imgur.com/GOFICJy.png

DFTTest 2:

https://i.imgur.com/j0It2tp.png

KNLMeansCL 2:

https://i.imgur.com/z8yeHz9.png




A few side note:

1) in this shot there are no spots or scratches as it's incredibly well preserved, however in many others there are plenty of them, especially during the olympics game.

2) I've seen the benefit of NNEDI3 over Spline in terms of ringing artifacts on many other occasions

3) 16bit precision might be an overkill but the last thing I want is to introduce banding while denoising... you know... as if those tapes didn't have enough problems already...


What's in the Download Package:

in the download package there's the lossless sample from the Blackmagic Decklink card after the hardware Sony TBC and after it has been trimmed by Virtual Dub in lossless. You'll also find a file named "DFTTest" which is what the current playout port is gonna play (i.e the result of my current filterchain) and one called KNLMeansCL which is the very same filterchain but with KNLMeansCL instead of DFTTest.
Feel free to play with it and remember that it's one of the very best sources.


Note: just to let you know, I've been working on those contents ever since this summer and this is what we've achieved for one of the very latest documentaries by manually working with luma and chroma after the filterchain cleaned our tapes:

https://i.imgur.com/nfUiMw5.jpg
https://i.imgur.com/xEKvZLo.jpg
https://i.imgur.com/FJT687P.jpg
https://i.imgur.com/zwEGsKN.jpg
https://i.imgur.com/A9WMuoB.jpg
https://i.imgur.com/mDcv9Qy.jpg
https://i.imgur.com/peYAMzu.jpg

so now perhaps you know why waiting while it's encoding at 0.5fps doesn't really bother if speeding things up means lowering the quality. And yes, in the cleaned results there are some ghosting artifacts which can be spotted by trained people like us, but home users? They're not gonna see them, and I would rather have them than the ugly horrible mess I have at the source.

real.finder
31st January 2021, 17:31
I have mcKNLMeansCL, which should give better output and better denoise, it's in dfttestMC_and_MC_things.avsi you can try it


Since it's copyrighted material, I had to discuss with my boss and pick a very short part of a recording of a studio which doesn't exist anymore and I've now prepared a very short sample of one of our best looking tape from the 80s which is a common use case scenario for this kind of filter chain.
In the sample (which has been corrected by an hardware Time Base Corrector before being captured in lossless), we can see how there's a bit of everything: noise, raimbowning, etc, but all of that has been taken care of by the filters.

Sample Download: https://we.tl/t-XHsQ8bpop0


Source:

https://i.imgur.com/r4wRr8e.png


why it's in RGB format?!

pinterf
31st January 2021, 17:43
Changing from DFTTest to KNLMeansCL and leaving the script as it was brought an additional 0.8fps speed improvement, although the NVIDIA Quadro P4000 was just sitting there all the time as it wasn't being used much (i.e the bottleneck wasn't DFTTest).

Was this test with the old MedianBlur2 or with the new 1.1?

Atak_Snajpera
31st January 2021, 17:52
LOL.I was expecting a lot worse quality than that source footage you have uploaded ;) You definitely do not need that dfftest and 16 bit at all. Your script is an overkill.

Changing from DFTTest to KNLMeansCL and leaving the script as it was brought an additional 0.8fps speed improvement, although the NVIDIA Quadro P4000 was just sitting there all the time as it wasn't being used much (i.e the bottleneck wasn't DFTTest).
You do realize that you should not put GPU filter before Prefetch function? You will get better performance if you put KNLMeansCL after prefetch.

FranceBB
31st January 2021, 18:24
LOL.I was expecting a lot worse quality than that source footage you have uploaded ;)


I know, some of them are really bad but they're from events like football games or the olympics etc and I can't upload them. All those from the studio are "recent" (70s-80s) and they're not so bad, but they're the only ones I can upload, 'cause...

Me: "Can I upload a sample from the 1940 Winter Olympics on Doom9?"

Boss: And what is that?

Me: "The international encoding forum in which expert developers can help me tweak filters and speed up workflows"

Boss: So they're gonna be public?

Me: "Yes, but only for a limited time and just a few-"

Boss: No!

Me: "But-"

Boss: No!


xD



You definitely do not need that dfftest and 16 bit at all. Your script is an overkill.


So I'm gonna be fine with 8bit post-processing?

Was this test with the old MedianBlur2 or with the new 1.1?

New one, much faster than the old one! Going from 0.x to 3.x - 5.x was a huge speed boost! :D
What I meant with 0.8fps speed increase is that on top of the 3-5fps increase by MedianBlur2, I get another fps (0.8 actually) by KNLMeansCL if I swap DFTTest for it. ;)

Frank62
31st January 2021, 19:00
LOL.I was expecting a lot worse quality than that source footage you have uploaded ;) You definitely do not need that dfftest and 16 bit at all. Your script is an overkill.

I totally agree. The filtered end product looks absolutely over-filtered. Even the better above samples are too much filtered, and you will see it, when watching, although the stills look "better".

This is why I said: Use NeatVideo with 5(!)% and also re-mix some original noise. You don't seem to have much experience with older sources, but I suppose you have again only one shot?
Less is more.

poisondeathray
31st January 2021, 19:34
I agree, overfiltered

As RF pointed out, the newsclip is uncompressed RGB. You probably forget to use direct stream copy in vdub. (Tip - When uploading uncompressed material, zip it up e.g. 7-zip)

Don't forget to use border=true for QTGMC. Watch the bottom edge of the news clip with border=true vs. without. It flickers and flashes without border=true , and you're going to trigger epileptic seizure in someone...

tormento
31st January 2021, 19:54
I know, some of them are really bad but they're from events like football games or the olympics etc and I can't upload them.
Apart from renewing my invite to give a shot to SMDegrain, whenever you can use the deinterlace within DGSource. Nvidia did a good job and being SD source to be filtered, nobody will notice any difference with QTGMC. Remember that DGSource has a NLMeans noise filter in CUDA itself too.

ChaosKing
31st January 2021, 20:17
Yeah it is overfiltered.
You don't even see the pattern on the suit anymore... a simple smdegrain with low tr=3, thSAD=100 looks 10x better to me (maybe add some Finedehalo too)
I would really like to test bm3d on one of the black/white videos :D

In the black/white image (guy with 4 on his back) you can see banding like effects in the sky, which most likely comes from dfttest. I remember that it happily produces banding...

https://i.imgur.com/MtEQ4nw.jpg

DJATOM
31st January 2021, 20:23
bm3d
Brace for slow speed :D