View Full Version : MVTools-pfmod


pinterf
31st March 2016, 17:57
Get latest version from here:
MvTools2 with depans, release pages (https://github.com/pinterf/mvtools/releases)

Historical part here:
----

I'd like to announce my first published plugin mod.

mvtools-pfmod 2.7.0.1 (https://github.com/pinterf/mvtools/releases/download/r2.7.0.1/mvtools-2.7.0.1-pfmod.7z)

- based on mvtools 2.6.0.5
- Sorry, no new colorspaces, just v2.6 API
- access violation fixes
- Intel C++ 16 build with Visual Studio 2015
- 32 and 64 bit versions
- works like a charm with latest AVS+ r1828-MT :) (though I didn't have problems with 2.6.0.5)

Background (chain reaction):
- Once I tried to use DepanStabilize on vapoursynth. The reason was that vapoursynth offers 16 bit color depth natively, and I have modified DepanStabilize for using stacked input.
- One day I changed my vapoursynth to 64bit only.
- I realized that DepanStabilize is 32bit only, so I compiled it to 64 bit.
- But VapourSynth did not allow to use old 2.5 AVS API for x64. So I modified DepanStabilize for v2.6 API.
- At that time I had no confidence porting DepanEstimate to x64 (input for DepanStabilize), tried to use MDepan from the native vapoursynth mvtools. But this function was not ported yet.
- Had to go back to use the 64 bit 2.6.0.5 mvtools on VapourSynth, but it was v2.5 API => ported it
- mvtools MDepan did not work, I had freezes. Learned debugging dlls in visual studio. Caught a famous 0xc0000005 in it and happily fixed it. And myrsloik was kind enough to integrate a hack into vs's avscompat module just because of 64-bit avs mdepan.
- Meanwhile my DepanStabilize-mod got YV24 support, and with stacked high bit depth logic, and I was able to stabilize my 10 bit Prores 444 test files! I reached my goal: my 8mm film restoration project is not starting anymore with dropping to 8bit YV12 right in the very first step.
- The mvtools project stalled - I was busy with fixing avs+ mt slowdown - until recently stax76 had problems under Win10 and the existing x64 mvtools2. After some busy nights another access violation was fixed in the x64 part.
- Thus I had a working mvtools2 version, and didn't want to keep it in secret.
- Finally along with my avs+ branch I had to learn how to create git repos, branch, push, as all these git things are new to me.

So please use this mod with fun.

Fizick
31st March 2016, 23:26
Hi, pinterf!

From your readme.md:
Current build as of March 31, 2016:
2.7.0.1 (skipped 2.6.x.x to leave numbering space to the previous authors)
It is a bug :)
I have small update to original MVTools . And versioning is confusing now. 2.6.x.x is not appropriate for me (it is without Firesledge's additions). May be will use 2.5.11.10,...

P.S. I also have bad 8mm films for restoration.

Motenai Yoda
1st April 2016, 22:17
as I remember with overlap = blksize/4 the last rows or coloumns are unfiltered , at least, by mdegrainX
are you planning to fix this?

ps I have 2.6.0.5 version

pinterf
1st April 2016, 23:11
I have small update to original MVTools . And versioning is confusing now. 2.6.x.x is not appropriate for me (it is without Firesledge's additions). May be will use 2.5.11.10,...

P.S. I also have bad 8mm films for restoration.
Restoration project never ends, mine is not even started, always waiting to the best workflow, testing new scripts, re-scan some originals in every two years hoping for the better, ehh, too much time.
But you are back here. Good. :)

Anyway, that's what I don't like, billions of versions doing almost the same, one fixing this, other's version fixes that, my version fixed some other things. And now it seems that I missed some other (quality) fixes, as Motenai Yoda noticed?

Overdrive80
2nd April 2016, 13:45
as I remember with overlap = blksize/4 the last rows or coloumns are unfiltered , at least, by mdegrainX
are you planning to fix this?

ps I have 2.6.0.5 version

For this, didnt it use int "hpad", int "vpad" of Msuper? I dont remember very fine.

Motenai Yoda
2nd April 2016, 16:24
For this, didnt it use int "hpad", int "vpad" of Msuper? I dont remember very fine.

I didn't investigate too much, as I tried with 16/4 or 32/8 it needs mod64 res...
but I see the same even with overlap=blksize/2, just difference in how many rows or coloumns are unfiltered.

Maybe it's some rounding stuff

pinterf
29th April 2016, 13:53
New mvtools2 version on the horizon.
Update: merged with Fizick's 2.5.11.22 version.
More info in the first post.

Download mvtools2 2.7.0.22 for 32 and 64 bit (https://github.com/pinterf/mvtools/releases/download/r2.7.0.22/mvtools2-2.7.0.22.7z)

jpsdr
30th April 2016, 07:38
Out of curiosity i take a qucik look at the asm code, and i've noticed a possible issue in this :

%macro RB2CubicHorizontalInplaceLine_SSE_macro 3 ; weight1, weight2, shift
[endprolog]
xchg rdx, rcx ; pSrc, nWidthMMX
; mov rdx, pSrc
; mov rcx, nWidthMMX
; prepare constants
pcmpeqw mm7, mm7 ; = FFFFFFFFFFFFFFFF
pxor mm6, mm6 ; =0
psubw mm6, mm7 ; =1
psllw mm6, %3-1; 4 ; *16 = 16

pxor mm7, mm7 ; =0

pcmpeqw mm5, mm5 ; = FFFFFFFFFFFFFFFF
psrlw mm5, 8 ; /256 = 00FF00FF00FF00FF
mov eax, %1; 05
movd mm4, eax
pshufw mm4, mm4, 0

mov eax, %2; 10
movd mm3, eax
pshufw mm3, mm3, 0


mov eax, 1 ; very first (left) is skipped

.loopw:
cmp eax, ecx
jge .finish

movq mm0, [rdx+rax*2-2]


In your code, you allways use only eax, never fully clear rax, put 1 in eax and not rax, and suddenly use rax. Is it safe ? Can't something be left in the up 32 part when you suddenly use rax ? Personnaly, i should have put "mov rax,1" instead.
Didn't look all the code, so don't know if there is "issues" like this elsewhere.

pinterf
30th April 2016, 07:53
Possibly not if the prolog really dont nullify it. Already fixed one or two such cases where I had to deal with the code but haven't checked all asm codes.

bcn_246
11th May 2016, 23:46
After Fizick updated mvtools to 2.5.11.22 and fixed some issues (e.g. green artifacts in MFlowInter), I made a new merge with 2.6.0.5 that still works in both 32 and 64 bit.

Download mvtools2 2.7.0.22 for 32 and 64 bit (20160429) (https://github.com/pinterf/mvtools/releases/download/r2.7.0.22/mvtools2-2.7.0.22.7z)

After it survived a full night QTGMC("Slow") 100-thread stress test under Avisynth+ 64bit (r1849), I decided to publish it.
Please give it a try.

----
I'd like to announce my first published plugin mod.

mvtools-pfmod 2.7.0.1 (https://github.com/pinterf/mvtools/releases/download/r2.7.0.1/mvtools-2.7.0.1-pfmod.7z)

- based on mvtools 2.6.0.5
- Sorry, no new colorspaces, just v2.6 API
- access violation fixes
- Intel C++ 16 build with Visual Studio 2015
- 32 and 64 bit versions
- works like a charm with latest AVS+ r1828-MT :) (though I didn't have problems with 2.6.0.5)

Background (chain reaction):
- Once I tried to use DepanStabilize on vapoursynth. The reason was that vapoursynth offers 16 bit color depth natively, and I have modified DepanStabilize for using stacked input.
- One day I changed my vapoursynth to 64bit only.
- I realized that DepanStabilize is 32bit only, so I compiled it to 64 bit.
- But VapourSynth did not allow to use old 2.5 AVS API for x64. So I modified DepanStabilize for v2.6 API.
- At that time I had no confidence porting DepanEstimate to x64 (input for DepanStabilize), tried to use MDepan from the native vapoursynth mvtools. But this function was not ported yet.
- Had to go back to use the 64 bit 2.6.0.5 mvtools on VapourSynth, but it was v2.5 API => ported it
- mvtools MDepan did not work, I had freezes. Learned debugging dlls in visual studio. Caught a famous 0xc0000005 in it and happily fixed it. And myrsloik was kind enough to integrate a hack into vs's avscompat module just because of 64-bit avs mdepan.
- Meanwhile my DepanStabilize-mod got YV24 support, and with stacked high bit depth logic, and I was able to stabilize my 10 bit Prores 444 test files! I reached my goal: my 8mm film restoration project is not starting anymore with dropping to 8bit YV12 right in the very first step.
- The mvtools project stalled - I was busy with fixing avs+ mt slowdown - until recently stax76 had problems under Win10 and the existing x64 mvtools2. After some busy nights another access violation was fixed in the x64 part.
- Thus I had a working mvtools2 version, and didn't want to keep it in secret.
- Finally along with my avs+ branch I had to learn how to create git repos, branch, push, as all these git things are new to me.

So please use this mod with fun.
Thanks, can also confirm this works with the Dither package.

GMJCZP
12th May 2016, 16:36
Thanks for the contribution, but not working in WXP SP3. Again, VS2015 is the guilty.

pinterf
14th May 2016, 07:22
First post links to the package containing an additional XP-win32 build.

Due to problems of Intel compiler with xp toolsets, XP builds temporarily need VS2015, so I cannot provide x64 build for XP now.

GMJCZP
14th May 2016, 14:34
It works, thanks!
Without AvsMeter, I noted that this build is more slow that Fizick and cretindesalpes versions. It's weird.

pinterf
14th May 2016, 15:40
Yes, weird. What is your processor?
I compiled the XP version with the simplest /arch:SSE.
And I suppose the built-in asms are working the same way.

I checked the x86 versions with avsmeter on my standard qtgmc(fast) script.
2.6.0.5 (cretindesalpes): 101 fps
2.7.0.22: 104-105 fps (practically head by head the non-XP: Intel 2017beta, and XP:VS2015 builds)
Fizick's one did not run as Mdegrain1 does not have a named argument "lsb".

GMJCZP
14th May 2016, 15:54
I have C2D E4400 and I use AVisynth sET MT. For accident the tests have been with MT mode deactivated.

BakaProxy
17th May 2016, 14:34
Idk if this has already been asked and/or answered but is it possible to use mvtools in mt? Uhh more like whenever I use mdegrain (and the vectors that come allong) cpu utilization is rather low, some scenarios even only 20%. I've tried every mt mode with mvtools but it either completely freezes the encode or it doesn't change anything performance wise. Prefetch amounts don't change anything as well, it just takes longer to start with large amounts.

Verstuurd vanaf mijn SM-A500FU met Tapatalk

pinterf
17th May 2016, 15:03
I don't know if it helps, but you could try avstp (http://forum.doom9.org/showthread.php?t=164407). In the original 2.6.0.5 it worked and hopefully I did not ruin it.

bilditup1
23rd May 2016, 06:22
I don't know if it helps, but you could try avstp (http://forum.doom9.org/showthread.php?t=164407). In the original 2.6.0.5 it worked and hopefully I did not ruin it.

I have successfully used your build with avstp 1.0.3 and AviSynth 2.6.1 alpha. This appears to provide a speed bump of 25% (6fps --> 7.44fps) when used with a 4770K@4.5Ghz on an MPEG2 1080i30 source run through QTGMC with Fast preset and divisor = 2 followed by a Spline36Resize to SD (640x360). Not sure whether this is good or bad performance for QTGMC with your MvTools and avstp. Usage does not get higher than 33%...but at least it's stable and unfinicky, unlike AVS MT.

Groucho2004
16th June 2016, 10:05
@pinterf
mvtools2 and some other of Fizick's plugins insists on (delay-) loading "fftw3.dll". The FFTW distributables however are named "libfftw3f-3.dll". In order to avoid renaming and user confusion I suggest adding the code in blue:
hinstLib = LoadLibrary("fftw3.dll"); // delayed loading
if (hinstLib == NULL)
hinstLib = LoadLibrary("libfftw3f-3.dll");

pinterf
16th June 2016, 13:14
Thank you, done.
I've already done it in DepanEstimate (work still in progress)

yup
17th June 2016, 10:44
pinterf!
I am testing Your MVTools under Avisynth+ 64 bit and find strange behaviour during using QTGMC, when try dct=5 I see wrong motion estimation, other dct 1,2,3, 4 work normally.
yup.

GMJCZP
17th June 2016, 13:17
Without AvsMeter, I noted that this build is more slow that Fizick and cretindesalpes versions. It's weird.

What happened with that?

pinterf
17th June 2016, 13:55
What happened with that?
Could not reproduce, for me, it was faster in a qtgmc process. But I don't know what kind of script you are using.
What numbers (fps) did you see without and with avsmeter on the different mvtools versions?

pinterf
17th June 2016, 14:13
pinterf!
I am testing Your MVTools under Avisynth+ 64 bit and find strange behaviour during using QTGMC, when try dct=5 I see wrong motion estimation, other dct 1,2,3, 4 work normally.
yup.
Is it only the x64 version or 32 bit, too?
If both versions share the problem, unfortunately it must be in the deepness of the original code, would be very hard for me to dig into it.
And if it is reproducible also with Fizick's version, we should ask him.
Nevertheless, I will try it when I have time; bwt, is it hard to recognize, or I will see an obvious garbage?

GMJCZP
17th June 2016, 14:52
Test results only with AvsMeter:

Log file created with: AVSMeter 2.2.8 (x86)

[Clip info]
File.avi
Number of frames: 2447
Length (hh:mm:ss.ms): 00:01:21.656
Frame width: 512
Frame height: 384
Framerate: 29.967 (100000/3337)
Colorspace: YV12
Active MT Mode: 0
Audio channels: n/a
Audio bits/sample: n/a
Audio sample rate: n/a
Audio samples: n/a

[Script]
function PreF_MDeGrain(clip src, int "radius", int "P_thSAD")
{

radius = default(radius, 2)
P_thSAD = default(P_thSAD, 400)

preNR = src.frfun3b(s=8,T=2,tuv=7)

preNR_super = preNR.MSuper(pel=2, sharp=1)
src_super = src.MSuper(pel=2, sharp=1, levels=1)

backward_vec3 = MAnalyse(preNR_super, isb = true, delta = 3, overlap=4)
backward_vec2 = MAnalyse(preNR_super, isb = true, delta = 2, overlap=4)
backward_vec1 = MAnalyse(preNR_super, isb = true, delta = 1, overlap=4)
forward_vec1 = MAnalyse(preNR_super, isb = false, delta = 1, overlap=4)
forward_vec2 = MAnalyse(preNR_super, isb = false, delta = 2, overlap=4)
forward_vec3 = MAnalyse(preNR_super, isb = false, delta = 3, overlap=4)

radius >= 3 ? src.MDegrain3(src_super, backward_vec1, forward_vec1, backward_vec2, forward_vec2, backward_vec3, forward_vec3, thSAD=P_thSAD) : \
radius == 2 ? src.MDegrain2(src_super, backward_vec1, forward_vec1, backward_vec2, forward_vec2, thSAD=P_thSAD) : \
src.MDegrain1(src_super, backward_vec1, forward_vec1, thSAD=P_thSAD)
}

[Results]

MVTools 2.7.0.22 XP (pinterf):

[Runtime info]
Frames processed: 2447 (0 - 2446)
FPS (min | max | average): 4.663 | 10.79 | 5.337
Memory usage (phys | virt): 368 | 364 MiB
Thread count: 1
CPU usage (average): 50%
Time (elapsed): 00:07:38.488

MVTools 2.6.0.5 (cretindesalpes):

[Runtime info]
Frames processed: 2447 (0 - 2446)
FPS (min | max | average): 4.372 | 12.48 | 6.170
Memory usage (phys | virt): 367 | 364 MiB
Thread count: 1
CPU usage (average): 50%
Time (elapsed): 00:06:36.585

MVTools 2.5.11.22 (Fizick):

[Runtime info]
Frames processed: 2447 (0 - 2446)
FPS (min | max | average): 5.836 | 14.11 | 6.548
Memory usage (phys | virt): 364 | 362 MiB
Thread count: 1
CPU usage (average): 50%
Time (elapsed): 00:06:13.685

Groucho2004
17th June 2016, 16:21
@GMJCZP
The script is incomplete. It seems you cut arbitrary parts out of the log file.
If you want us to try and reproduce it you'll have to post the entire script.

GMJCZP
17th June 2016, 17:59
@GMJCZP
The script is incomplete. It seems you cut arbitrary parts out of the log file.
If you want us to try and reproduce it you'll have to post the entire script.

Do you mean include performance data?

Groucho2004
17th June 2016, 18:12
Do you mean include performance data?
No, the full script.

GMJCZP
17th June 2016, 18:27
Here:

[Script]

# PLUGINS
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\avstimerf.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\dgdecode.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\Decomb521VFR1.3_PPro-P3.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\mt_masktools-26.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\TIVTC.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\masktools.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\dither.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\Deen_beta.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\EEDI2_imp.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\deblock.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\Tnlmeans.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\dfttest.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\nnedi3.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\RemoveGrain.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\RemoveGrainTSSE3.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\KNLMeansCL.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\yadifmod2.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\nnedi2.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\RemoveDirtSSE2.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\WarpSharp.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\aWarpSharp2.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\nnedi.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\nnedi2.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\asharp.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\awarpsharp.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\Average.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\TcannyMod.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\DeFlicker.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\ChromaShift.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\gradfun2db.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\cnr2.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\mvtools2.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\unfilter.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\ColorMatrix.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\frfun3b.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\fft3dfilter.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\ReduceFlickerSSE3.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\Toon-v1.1.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\DctFilter.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\Repair.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\RepairTSSE2.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\tdeint.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\TBilateral.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\tmm.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\sangnom.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\undot.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\vinverse.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\VagueDenoiser.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\SSIQ.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\MVTools.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\DeGrainMedian.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\FillMargins.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\MSharpen.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\mipsmooth.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\VSFilter.dll")
#LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\DeDup.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\autoadjust.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\VerticalCleanerSSE3.dll")
LoadPlugin("C:\ARCHIV~1\GORDIA~1\AviSynthPlugins\Convolution3DYV12.dll")



import("D:\Tipos de archivo de audio y video\Avi\Herramientas Avi\AviSynth\Scripts\Sharpening\SeeSaw\SeeSaw.avs"
import("D:\Tipos de archivo de audio y video\Avi\Herramientas Avi\AviSynth\Scripts\Sharpening\FastLineDarken\FastLineDarkenMod.avsi")
import("D:\Tipos de archivo de audio y video\Avi\Herramientas Avi\AviSynth\Scripts\Correccion color\YLevels\YLevels_mt.avsi")
import("D:\Tipos de archivo de audio y video\Avi\Herramientas Avi\AviSynth\Scripts\Fix Chroma\ChromaShift_SP\ChromaShift_SP.avs")
import("D:\Tipos de archivo de audio y video\Avi\Herramientas Avi\AviSynth\Scripts\DeBanding\Dither\dither.avsi")
import("D:\Tipos de archivo de audio y video\Avi\Herramientas Avi\AviSynth\Scripts\DeBanding\Dither\mt_xxpand_multi.avsi")
import("D:\Tipos de archivo de audio y video\Avi\Herramientas Avi\AviSynth\Scripts\Compresion de videos\SPresso.avsi")
import("D:\Tipos de archivo de audio y video\Avi\Herramientas Avi\AviSynth\Scripts\Restauracion de frames\Imagenes en Avisynth\RescueFrame.avsi")
import("D:\Tipos de archivo de audio y video\Avi\Herramientas Avi\AviSynth\Scripts\John Meyer MVDeGrain\PreF_MDeGrain.avsi")


avisource("File.avi",audio=false)

PreF_MDeGrain()

pinterf
17th June 2016, 19:23
That is quite a big difference, worth the inspection

Groucho2004
17th June 2016, 21:16
That is quite a big difference, worth the inspection
I'm getting very similar results, different source but the trend is the same:
MVTools 2.7.0.22 XP (pinterf):

[Runtime info]
Frames processed: 200 (0 - 199)
FPS (min | max | average): 3.139 | 4.879 | 3.190
Memory usage (phys | virt): 360 | 357 MiB
Thread count: 2
CPU usage (average): 25%
Time (elapsed): 00:01:02.687

MVTools 2.6.0.5 (cretindesalpes):

[Runtime info]
Frames processed: 200 (0 - 199)
FPS (min | max | average): 3.625 | 5.432 | 3.688
Memory usage (phys | virt): 353 | 350 MiB
Thread count: 2
CPU usage (average): 25%
Time (elapsed): 00:00:54.227

MVTools 2.5.11.22 (Fizick):

[Runtime info]
Frames processed: 200 (0 - 199)
FPS (min | max | average): 3.494 | 5.718 | 3.938
Memory usage (phys | virt): 380 | 378 MiB
Thread count: 2
CPU usage (average): 25%
Time (elapsed): 00:00:50.791

pinterf
17th June 2016, 21:56
I wonder if its only the xp build that is slow?

yup
19th June 2016, 18:51
pinterf
Is it only the x64 version or 32 bit, too?
If both versions share the problem, unfortunately it must be in the deepness of the original code, would be very hard for me to dig into it.
And if it is reproducible also with Fizick's version, we should ask him.
Nevertheless, I will try it when I have time; bwt, is it hard to recognize, or I will see an obvious garbage?
Avisynt+ 32 bit ant Your version MVTools work without problem.
Testing script
SetMemoryMax(1536)
SetFilterMTMode("DEFAULT_MT_MODE",2)
SetFilterMTMode("AviSource",3)
AVISource("samplevhs.avi")
AssumeTFF()
QTGMC(dct=5)
Prefetch(8)
sample video https://www.dropbox.com/s/5exreq9j9e0r0hs/test.avi?dl=0
yup.

pinterf
20th June 2016, 17:09
SetMemoryMax(1536)
SetFilterMTMode("DEFAULT_MT_MODE",2)
SetFilterMTMode("AviSource",3)
AVISource("samplevhs.avi")
AssumeTFF()
QTGMC(dct=5)

sample video https://www.dropbox.com/s/5exreq9j9e0r0hs/test.avi?dl=0
yup.
Nasty bug. But reproducible. So far that's all.
Something within MVAnalyze is broken on x64.
This modification works:
QTGMC(/*Preset="Slower",*/dct=5, ChromaMotion=false)

yup
21st June 2016, 09:40
pinterf!
Yes, it is work
chromamotion=false
I am using this option for my VHS capture video.
yup.

pinterf
4th August 2016, 10:56
Dear users, 2016 is a lucky year, MvTools2 finally got YUV 4:2:2 and 4:4:4 support (YV16 and YV24).

See source and binaries here:
MVTools2 2.7.0.22c (https://github.com/pinterf/mvtools/releases/tag/r2.7.0.22c)

Please try this *test* build, which works for me with my usual scripts and YV16 gives identical output as with the former YUY2 format.

No need hacking YUY2 sources any more to special planar format and back, convert your source once to YV16 and process it.

P.S.
Could not try it with SMDegrain.avsi, because the script internally assumes YV12 for planar YUV format. BTW the script is full with YUY2 conversion, maybe it can be lighter, too.

yup
4th August 2016, 11:00
pinterf!
:thanks:
Work with QTGM without problems, practically at same speed like YV12.
yup.

Reel.Deel
4th August 2016, 13:27
Very nice. Thank you pinterf! :)


No need hacking YUY2 sources any more to special planar format and back, convert your source once to YV16 and process it.

P.S.
Could not try it with SMDegrain.avsi, because the script internally assumes YV12 for planar YUV format. BTW the script is full with YUY2 conversion, maybe it can be lighter, too.

Yes, both QTGMC and SMDegrain are quite bloated due to the planar YUY2 hack. A while back I started modding QTGMC to remove the hack, I never finished but MVTools supporting YV16 makes it a lot easier.

GMJCZP
5th August 2016, 03:57
Hi pinterf, and Windows XP problem?
Anyway thank you for your effort.

pinterf
5th August 2016, 07:13
Did you try it?

feisty2
5th August 2016, 07:15
Hi pinterf, and Windows XP problem?
Anyway thank you for your effort.

just drop xp already, turn to Linux if you dislike windows10 or windows7

tormento
5th August 2016, 20:17
Very nice. Thank you pinterf! :)



Yes, both QTGMC and SMDegrain are quite bloated due to the planar YUY2 hack. A while back I started modding QTGMC to remove the hack, I never finished but MVTools supporting YV16 makes it a lot easier.

Please make the SMDegrain mod available when finished :)

Motenai Yoda
5th August 2016, 21:34
It's an hard work to add y8 and 16bit support too?

feisty2
6th August 2016, 04:01
Kind of, some components like SATD were coded in asm and incompatible with high bitdepth, gotta rewrite them completely
And 16bits support is sort of practical still
Floating point support is much harder, not sure if it's possible to implement floating point support and integer support both within a single plugin
vectors are like, int vx, int vy, int sad for both uint8_t and uint16_t
And SAD(sum of absolute differences) for floating point inputs are also floating points obviously, gotta do some reinterpret_cast tricks here

pinterf
6th August 2016, 07:46
It's an hard work to add y8 and 16bit support too?

y8 is possibly easy, possibly working with three planes is hardcoded now.

16 bit/float support is hard (=takes time), but even this modding to YV24 took days and was a nightmare.

I have already put high bit depth supporting code here and there and my last internal version has a working MSuper in 16 bits as a first step.

And I think I will not cut the possibility of the float version, just for my curiosity (inspired by feisty2)

pinterf
6th August 2016, 07:57
Since 2.7.0.22c I have found 3-4 other use of harcoded div 2 for horizontal subsampling (affects only YV24), but will make a fix only if I have time.
Till then you are still encouraged to test it, of course.

feisty2
6th August 2016, 08:04
you're gonna get into the floating point SAD trouble if you do plan to mess with fp support,
I did a nasty reinterpret_cast trick to stuff fp SAD in vectors

static inline auto _fakeint(float a) {
return reinterpret_cast<int32_t &>(a);
}

static inline auto _back2flt(int32_t a) {
return reinterpret_cast<float &>(a);
}

maybe there's a better way to do this, but...

Motenai Yoda
6th August 2016, 11:26
Kind of, some components like SATD were coded in asm and incompatible with high bitdepth, gotta rewrite them completely

IIRC both x264 and x265 should yet sports high bitdepth SATD in asm.

amayra
6th August 2016, 11:50
can you do something about SVPflow i try to updated but i failed

Reel.Deel
6th August 2016, 13:33
Please make the SMDegrain mod available when finished :)

I never said that I was modding SMDegrain. Ask Dogway if he's interested, I'm sure he can do more efficiently since it's his script. A while back I gave him a few suggestions (post 87-89 (http://forum.videohelp.com/threads/369142-Simple-MDegrain-Mod-v3-1-2d-A-Quality-Denoising-Solution?p=2409148&viewfull=1#post2409148)) but nothing came of it.

can you do something about SVPflow i try to updated but i failed

Please do not cross-post. SVPflow has nothing to do with this thread.

tormento
6th August 2016, 20:47
I never said that I was modding SMDegrain
Oh... I am so sorry.

I confused you with real.finder.

GMJCZP
6th August 2016, 22:49
The version 2.7.0.22c not working in XP 32 bits. Access violation.

pinterf
7th August 2016, 06:21
Sad. I was compiling them with xp in mind.
One week holday begins, I'll disappear.

real.finder
15th August 2016, 01:28
P.S.
Could not try it with SMDegrain.avsi, because the script internally assumes YV12 for planar YUV format.

it didn't

planar = IsYUY2(input) ? true : false

planar in SMDegrain mean YUY2, I was surprised too

so it should work like qtgmc in yv16 and yv24, especially with http://pastebin.com/JtWFN124

pinterf
15th August 2016, 12:51
it didn't

planar = IsYUY2(input) ? true : false

planar in SMDegrain mean YUY2, I was surprised too

so it should work like qtgmc in yv16 and yv24, especially with http://pastebin.com/JtWFN124

This modified smdegrain.avsi works!
The old version gave "image heights don't match" when using lsb=true because it assumed the dimensions of YV12 subsampling.

pinterf
16th August 2016, 20:44
After-before holiday release for early adopters :)

general: supporting Y8, YV16, YV24 format besides YV12 and YUY2
Some additional fixes for YV24
Allow greyscale input (Y8) - I hope
dct modes >= 5 now use SATD again (so far it was in dead code, contrary to 2.5.13.1 remarks)
fftw 3.3.5 support (changed function names, 3.3.4 still OK), see http://www.fftw.org/download.html
XP support again
compiled to SSE2 with optional SSE4.2 paths

Download: 2.7.0.22d for 32 and 64 bit (20160816) (https://github.com/pinterf/mvtools/releases/tag/r2.7.0.22d)

Sparktank
16th August 2016, 21:08
fftw 3.3.5 support

Oh cool, didn't even notice an update for FFTW.
Looking at the Release Notes (http://www.fftw.org/release-notes.html), it's not critical to little old me.

pinterf
16th August 2016, 21:25
Oh cool, didn't even notice an update for FFTW.
There are other (http://forum.doom9.org/showthread.php?p=1777186#post1777186) nice topics on doom9 :)

Sparktank
16th August 2016, 23:42
There are other (http://forum.doom9.org/showthread.php?p=1777186#post1777186) nice topics on doom9 :)

I'm too far behind to pick up on VS scripting to make regular use of VS.

But, it's good to know that the update is making rounds.
For future reference, I'll make note of it.

yup
17th August 2016, 07:53
pinterf!
:thanks:
I see some slowdown for dct=5, approx. 10%.
FFTW updated.
yup.

pinterf
17th August 2016, 08:45
pinterf!
:thanks:
I see some slowdown for dct=5, approx. 10%.
FFTW updated.
yup.
Yes, slowdown, because the old one did virtually nothing.

real.finder
5th September 2016, 03:59
hi pinterf, since you work on mvtools, dogway said that denoising chroma with luma only vectors is bugged

pinterf
5th September 2016, 05:21
Is this bug a new one with yv24? Anyway, some more hint, format, script and parameters would be welcome. Freeze or just garbaged output? I am thankful for each minute I can spare instead of blind guessing.

real.finder
5th September 2016, 07:19
Is this bug a new one with yv24? Anyway, some more hint, format, script and parameters would be welcome. Freeze or just garbaged output? I am thankful for each minute I can spare instead of blind guessing.
it's old, dogway write this in SMDegrain

!chroma ? Assert(plane==0, "Denoising chroma with luma only vectors is bugged in mvtools and thus unsupported") : nop()

and here http://forum.doom9.org/showthread.php?p=1551305#post1551305

pinterf
5th September 2016, 08:49
Thanks, I will look into it.

pinterf
26th September 2016, 21:32
I have run the script you linked
chroma=false
plane=4

super_search=MSuper(chroma=chroma?true:(plane==0?false:true))
bv2=super_search.MAnalyse(isb = true, delta = 2,chroma=chroma)
bv1=super_search.MAnalyse(isb = true, delta = 1,chroma=chroma)
fv1=super_search.MAnalyse(isb = false, delta = 1,chroma=chroma)
fv2=super_search.MAnalyse(isb = false, delta = 2,chroma=chroma)
MDegrain2(super_search, bv1, fv1, bv2, fv2, thSAD=200,plane=plane)

but found nothing.

Since I had to deal with the code, did it seriously and unified the MDegrain1/2/3 code for better understanding. It became much more general and a bit faster (at least for MSVC).

As a result of generality: now we have a new MDegrain4 and MDegrain5.

Note that MDegrainN still exists but if there are no special extra SAD parameters, it calls MDegrain1/2/3. No change, it did call them before - but now calls MDegrain4 and MDegrain5 for tr=4 or 5. (Reason by the docs: because they are faster).

Then I became curious whether I can make mvtools co-operate with the latest avs+ dev build, so went on. I had already made MSuper work for 16 bit in the past. The analyzation parts (b and f vectors) still work at 8 bits (haven't ported yet MAnalyze), but MDegrain1/5 can use a 16 bit input and 16 bit super clip and the output is also native 16 bits

a=Avisource("Hi8.avi").assumefps(25,1).trim(0, 499)
a=a.ConvertToYUV444()
sup = a.MSuper(pel=1) #pel=2
fv1 = sup.MAnalyse(isb=false, delta=1, overlap=4)
bv1 = sup.MAnalyse(isb=true, delta=1, overlap=4)
fv2 = sup.MAnalyse(isb=false, delta=2, overlap=4)
bv2 = sup.MAnalyse(isb=true, delta=2, overlap=4)
fv3 = sup.MAnalyse(isb=false, delta=3, overlap=4)
bv3 = sup.MAnalyse(isb=true, delta=3, overlap=4)
fv4 = sup.MAnalyse(isb=false, delta=4, overlap=4)
bv4 = sup.MAnalyse(isb=true, delta=4, overlap=4)
fv5 = sup.MAnalyse(isb=false, delta=5, overlap=4)
bv5 = sup.MAnalyse(isb=true, delta=5, overlap=4)
sup16=a.ConvertBits(16).MSuper(pel=1)
a.ConvertBits(16).MDegrain5(Sup16, bv1, fv1, bv2, fv2, bv3, fv3, bv4, fv4, bv5, fv5, thSAD=10000). Info()
ConvertBits(8, dither=0)


Btw, I managed to replace/rewrite the remaining inline asm codes (integer DCT, Resizers, YUY2 converters etc.) for SIMD intrinsics, and now it compiles x64 version in plain VS2015 (+yasm of course)!

And the last info:
Earlier last week I have found some more YV12/YUY specific codes (x/2) in MFlow/MFlowFPS, which may have issues at YV24 in 2.7.0.22d. I hope these occurences were the last ones of this type.

PS: no release, just status report

tormento
30th September 2016, 18:35
As a result of generality: now we have a new MDegrain4 and MDegrain5.
We need MDegrain6 too ;)

pinterf
30th September 2016, 19:23
Haha, I was just practicing. And you will get a special MDegrain2.718281, too

tormento
1st October 2016, 19:32
Haha, I was just practicing. And you will get a special MDegrain2.718281, too

MDegrainE :D

real.finder
19th October 2016, 00:47
I have run the script you linked
chroma=false
plane=4

super_search=MSuper(chroma=chroma?true:(plane==0?false:true))
bv2=super_search.MAnalyse(isb = true, delta = 2,chroma=chroma)
bv1=super_search.MAnalyse(isb = true, delta = 1,chroma=chroma)
fv1=super_search.MAnalyse(isb = false, delta = 1,chroma=chroma)
fv2=super_search.MAnalyse(isb = false, delta = 2,chroma=chroma)
MDegrain2(super_search, bv1, fv1, bv2, fv2, thSAD=200,plane=plane)

but found nothing.



since dogway didn't come I find sample that has the bug

first, I edit the SMDegrain to accept this case (http://forum.videohelp.com/threads/369142-Simple-MDegrain-Mod-v3-1-2d-A-Quality-Denoising-Solution?p=2413356&viewfull=1#post2413356)

the sample http://rgho.st/private/64kh5qQPS/203861da41c6be0a9bc92d8518f840c5

here frame 55 without filter http://i.imgur.com/24VWm23.png

and here with SMDegrain(chroma=false) http://i.imgur.com/fIkzlH1.png

pinterf
19th October 2016, 16:57
Ok, here is my script

FFMS2("chroma.mp4")
#ConvertToYUV444()
chroma=false
plane=4 # 0:Luma 1:U 2:V 3:UV 4:All
#ConvertBits(12) #10-16
#super_search=MSuper(chroma=chroma?true:(plane==0?false:true))
super_search=MSuper(chroma=true)

bv1=super_search.MAnalyse(isb = true, delta = 1,chroma=chroma)
fv1=super_search.MAnalyse(isb = false, delta = 1,chroma=chroma)
a=MDegrain1(super_search, bv1, fv1, thSAD=0,plane=plane)
b=MDegrain1(super_search, bv1, fv1, thSAD=200,plane=plane)
c=MDegrain1(super_search, bv1, fv1, thSAD=2000,plane=plane)
Stackvertical(a,b,c)#.GreyScale() # bigger thSAD: more "false" blocks but not in greyscale
#MShow(super_search, bv1) #uncomment to see vectors
#super_search #uncomment to see super clip
#ConvertBits(8)


I cannot see bugs here. The big static uniform colored areas make the motion estimation very hard.
Uncomment the MShow line above the see those vectors.

What I also recognized that the blotchy artifacts occur when the luma-only sad is minimal.
Check frame 49, lower right corner. MDegrain is in work, it blends frame #50 into that.
You can check it best at the thSAD=2000 clip. (3rd one if using the above stacked script)
When you uncomment grayscale conversion, it seem to be ok.
I think this kind of clip needs fine-tuning.

real.finder
20th October 2016, 03:45
Ok, here is my script

FFMS2("chroma.mp4")
#ConvertToYUV444()
chroma=false
plane=4 # 0:Luma 1:U 2:V 3:UV 4:All
#ConvertBits(12) #10-16
#super_search=MSuper(chroma=chroma?true:(plane==0?false:true))
super_search=MSuper(chroma=true)

bv1=super_search.MAnalyse(isb = true, delta = 1,chroma=chroma)
fv1=super_search.MAnalyse(isb = false, delta = 1,chroma=chroma)
a=MDegrain1(super_search, bv1, fv1, thSAD=0,plane=plane)
b=MDegrain1(super_search, bv1, fv1, thSAD=200,plane=plane)
c=MDegrain1(super_search, bv1, fv1, thSAD=2000,plane=plane)
Stackvertical(a,b,c)#.GreyScale() # bigger thSAD: more "false" blocks but not in greyscale
#MShow(super_search, bv1) #uncomment to see vectors
#super_search #uncomment to see super clip
#ConvertBits(8)


I cannot see bugs here. The big static uniform colored areas make the motion estimation very hard.
Uncomment the MShow line above the see those vectors.

What I also recognized that the blotchy artifacts occur when the luma-only sad is minimal.
Check frame 49, lower right corner. MDegrain is in work, it blends frame #50 into that.
You can check it best at the thSAD=2000 clip. (3rd one if using the above stacked script)
When you uncomment grayscale conversion, it seem to be ok.
I think this kind of clip needs fine-tuning.

yes, you right, but the problem is why with chroma=true at the thSAD=200 clip chroma will be good but with chroma=false will be that bad?

pinterf
20th October 2016, 14:52
yes, you right, but the problem is why with chroma=true at the thSAD=200 clip chroma will be good but with chroma=false will be that bad?
When you ignore chroma in MAnalyze, the computed SAD (sum of absolute pixel differences between frame blocks (e.g. current, current-1)) will only be computed on luma. If SAD is zero, the blocks are 100% similar.

MDegrain makes its decision on comparing this precomputed sad value (per block) with the given thSAD parameter.

The position of the artifacts is seen exactly at those places where the luma value (check the greyscale clip) is very similar between the compared - e.g. current - next_by_1 - frames.
I think that in this case the SAD of the block (based on luma data only) is well below the given thSAD threshold,thus the blocks are getting blended together. If the difference (SAD) is minimal, then the similar blocks are practically averaged (more or less).

So based only by the luma, it happens that two completely differently colored blocks are merged. Although they differ on the chroma very much, but we asked MAnalyze to ignore it with chroma=false. And we can see the result: one block of the current frame is orange, the next frame contains a blueish grey block at the same place, their luma is similar; the resulting block will look nice in greyscale, but the chroma - and our visual feelings - will be somewhat mixed.

At least this is what I have learned from the code itself and the usage experiences so far.

real.finder
20th October 2016, 16:09
When you ignore chroma in MAnalyze, the computed SAD (sum of absolute pixel differences between frame blocks (e.g. current, current-1)) will only be computed on luma. If SAD is zero, the blocks are 100% similar.

MDegrain makes its decision on comparing this precomputed sad value (per block) with the given thSAD parameter.

The position of the artifacts is seen exactly at those places where the luma value (check the greyscale clip) is very similar between the compared - e.g. current - next_by_1 - frames.
I think that in this case the SAD of the block (based on luma data only) is well below the given thSAD threshold,thus the blocks are getting blended together. If the difference (SAD) is minimal, then the similar blocks are practically averaged (more or less).

So based only by the luma, it happens that two completely differently colored blocks are merged. Although they differ on the chroma very much, but we asked MAnalyze to ignore it with chroma=false. And we can see the result: one block of the current frame is orange, the next frame contains a blueish grey block at the same place, their luma is similar; the resulting block will look nice in greyscale, but the chroma - and our visual feelings - will be somewhat mixed.

At least this is what I have learned from the code itself and the usage experiences so far.

I see, so chroma=false without plane=0 is bad idea especially in Anime

maybe with good chosen of Search parameter in MAnalyze will make it better

pinterf
20th October 2016, 19:42
After having released the first real test build of high bit depth Avisynth+, here is another release:
MvTools2 2.7.1.22 (https://github.com/pinterf/mvtools/releases/tag/r2.7.1.22)

Important note:
Built with VS2015, this build is 3-8% slower than previous ICC build. Don't use it if you stuck at YV12 or YUY2 clips and this speed loss makes you unhappy.

Changes:

Experimental native 10-16 bit support (MSuper, MAnalyze, MDegrain1-5, MDegrainN)
Some additional fixes for YV24
New: MDegrain4, MDegrain5
16 bit SATD (slow C) for dct>=5 modes and SSE2 optimized regular SAD for 10-16 bits
for 10+ bits you need at least Avisynth+ r2290 but works with classic avs on 8 bits
Inline assembly rewritten to intrinsics -> 64 bit build is possible in VS2015
(External assembly untouched)
Experimental AVX/AVX2 code paths (maybe insignificant, at least I had a test how to mix them together with a non-avx core


Demo script (avs+):
SetMemoryMax(6000)
FFMS2("prores_yuv422p10le_hq_apch_yuv422p10.mov").RemoveAlphaPlane() #if YUVA original
ConvertBits(14)
ConvertToYUV444()
sup = MSuper(pel=1) #pel=2
fv1 = sup.MAnalyse(isb=false, delta=1, overlap=4)
bv1 = sup.MAnalyse(isb=true, delta=1, overlap=4)
fv2 = sup.MAnalyse(isb=false, delta=2, overlap=4)
bv2 = sup.MAnalyse(isb=true, delta=2, overlap=4)
fv3 = sup.MAnalyse(isb=false, delta=3, overlap=4)
bv3 = sup.MAnalyse(isb=true, delta=3, overlap=4)
fv4 = sup.MAnalyse(isb=false, delta=4, overlap=4)
bv4 = sup.MAnalyse(isb=true, delta=4, overlap=4)
fv5 = sup.MAnalyse(isb=false, delta=5, overlap=4)
bv5 = sup.MAnalyse(isb=true, delta=5, overlap=4)
MDegrain5(Sup, bv1, fv1, bv2, fv2, bv3, fv3, bv4, fv4, bv5, fv5, thSAD=10000). Info()
ConvertBits(8,dither=0)

Motenai Yoda
22nd October 2016, 01:17
sure this is right? with ConvertBits(16)
sup = MSuper(pel=1) #pel=2
fv1 = sup.MAnalyse(isb=false, delta=1, overlap=4)
bv1 = sup.MAnalyse(isb=true, delta=1, overlap=4)
fv2 = sup.MAnalyse(isb=false, delta=2, overlap=4)
bv2 = sup.MAnalyse(isb=true, delta=2, overlap=4)
MDegrain2(Sup, bv1, fv1, bv2, fv2, thSAD=200)
converttostacked()
b=last

d=Dither_convert_8_to_16()
sup2 = MSuper(pel=1) #pel=2
fv12 = sup2.MAnalyse(isb=false, delta=1, overlap=4)
bv12 = sup2.MAnalyse(isb=true, delta=1, overlap=4)
fv22 = sup2.MAnalyse(isb=false, delta=2, overlap=4)
bv22 = sup2.MAnalyse(isb=true, delta=2, overlap=4)

m=d.dither_get_msb()
supM = m.Msuper(pel=1)

l=d.dither_get_lsb()
supL = l.Msuper(pel=1)

msb=m.MDegrain2(SupM, bv12, fv12, bv22, fv22, thSAD=200,lsb=true)
lsb= l.MDegrain2(SupL, bv12, fv12, bv22, fv22, thSAD=200)

nullclip = l.mt_lut(y=0,u=0,v=0)
diff1=stackvertical(nullclip,lsb)
msb.dither_add16(diff1)
c=last

mt_makediff(b,c,u=3,v=3)
levels(100,1,155,0,255,true)

I get the same lsb part but different msb one, like is applied dithering on msb.
also seems to be slower

pinterf
23rd October 2016, 21:48
sure this is right? with ConvertBits(16)
sup = MSuper(pel=1) #pel=2
fv1 = sup.MAnalyse(isb=false, delta=1, overlap=4)
bv1 = sup.MAnalyse(isb=true, delta=1, overlap=4)
fv2 = sup.MAnalyse(isb=false, delta=2, overlap=4)
bv2 = sup.MAnalyse(isb=true, delta=2, overlap=4)
MDegrain2(Sup, bv1, fv1, bv2, fv2, thSAD=200)
converttostacked()
b=last

d=Dither_convert_8_to_16()
sup2 = MSuper(pel=1) #pel=2
fv12 = sup2.MAnalyse(isb=false, delta=1, overlap=4)
bv12 = sup2.MAnalyse(isb=true, delta=1, overlap=4)
fv22 = sup2.MAnalyse(isb=false, delta=2, overlap=4)
bv22 = sup2.MAnalyse(isb=true, delta=2, overlap=4)

m=d.dither_get_msb()
supM = m.Msuper(pel=1)

l=d.dither_get_lsb()
supL = l.Msuper(pel=1)

msb=m.MDegrain2(SupM, bv12, fv12, bv22, fv22, thSAD=200,lsb=true)
lsb= l.MDegrain2(SupL, bv12, fv12, bv22, fv22, thSAD=200)

nullclip = l.mt_lut(y=0,u=0,v=0)
diff1=stackvertical(nullclip,lsb)
msb.dither_add16(diff1)
c=last

mt_makediff(b,c,u=3,v=3)
levels(100,1,155,0,255,true)

I get the same lsb part but different msb one, like is applied dithering on msb.
also seems to be slower
1.) Is it intentional that the input of the 2nd pass is the stacked 8 bit output of the first 16 bit degrain phase?
2.) Then I don't understand the second part.
You make a d=Dither_convert_8_to_16() from an already stacked clip, and take its lsb that is always zero and filter it, why?
l=d.dither_get_lsb()
supL = l.Msuper(pel=1)
lsb= l.MDegrain2(SupL, bv12, fv12, bv22, fv22, thSAD=200)


My comparison script:

FFMS2("chroma.mp4")#.trim(0, 499)
orig8=last
ConvertBits(16)
sup = MSuper(pel=1) #pel=2
fv1 = sup.MAnalyse(isb=false, delta=1, overlap=4)
bv1 = sup.MAnalyse(isb=true, delta=1, overlap=4)
fv2 = sup.MAnalyse(isb=false, delta=2, overlap=4)
bv2 = sup.MAnalyse(isb=true, delta=2, overlap=4)
MDegrain2(Sup, bv1, fv1, bv2, fv2, thSAD=200)
converttostacked()
stackedresult1 =last

orig8
sup2 = MSuper(pel=1) #pel=2
fv12 = sup2.MAnalyse(isb=false, delta=1, overlap=4)
bv12 = sup2.MAnalyse(isb=true, delta=1, overlap=4)
fv22 = sup2.MAnalyse(isb=false, delta=2, overlap=4)
bv22 = sup2.MAnalyse(isb=true, delta=2, overlap=4)
stackedResult2 = orig8.MDegrain2(Sup2, bv12, fv12, bv22, fv22, thSAD=200,lsb=true)

mt_makediff(stackedresult1,stackedresult2,u=3,v=3)
levels(100,1,155,0,255,true)

Motenai Yoda
24th October 2016, 01:28
1.) Is it intentional that the input of the 2nd pass is the stacked 8 bit output of the first 16 bit degrain phase?
2.) Then I don't understand the second part.
You make a d=Dither_convert_8_to_16() from an already stacked clip, and take its lsb that is always zero and filter it, why?
1- no it wasn't lol
2- that is the way I use mdegrain on stacked clip, indeed lsb filtered part is all 0 if the input clip's lsb is all 0

btw I found a lot of differences even with your method, in the msb part too...

pinterf
24th October 2016, 07:58
1- no it wasn't lol
2- that is the way I use mdegrain on stacked clip, indeed lsb filtered part is all 0 if the input clip's lsb is all 0

btw I found a lot of differences even with your method, in the msb part too...
There's no reason to get identical results.
For 16 bit input, even if the original clip is 8 bits and its straight 16 bit conversion has zero lsb, the lower resolution subclips in Super are already interpolated and have meaningful lsb parts.
So the vectors after MAnalyze are possibly different than it would be estimated from a single 8 bit source.
Then the weighting and blending inside MDegrain works with higher precision than for a 8 bit input. That is a difference, too.

real.finder
25th October 2016, 08:59
speaking of MAnalyze, I have an idea in my mind but I don't know if it good or not, or even if I can do it

it's for 8 bit clip, it's by doing convert to yv24 (if it not yv24) then merge Y, U and V in one 16 bit plane (Y16) then use it in MAnalyze to get more accurate motion vectors

and then use the vectors for both luma and chroma

real.finder
1st November 2016, 22:19
@pinterf

can you add rgb24 support in MSuper and MAnalyse and MRecalculate?

making the support work as if it one colour not treats it as R G B separately

:thanks:

feisty2
1st November 2016, 23:39
RGB sucks
I added RGB support in my branch of mvtools and it didn't work out so well

StainlessS
1st November 2016, 23:43
@pinterf

can you add rgb24 support in MSuper and MAnalyse and MRecalculate?

making the support work as if it one colour not treats it as R G B separately

:thanks:

How exactly would one measure differences if implemented as above ?

Would diff in blue count a teeny weeny bit, in green somewhat more, and in red a helluva lot ?

real.finder
2nd November 2016, 00:16
How exactly would one measure differences if implemented as above ?

Would diff in blue count a teeny weeny bit, in green somewhat more, and in red a helluva lot ?

I didn't get what you mean well but what about convert rgb24 to hex (http://forum.doom9.org/showpost.php?p=1784059&postcount=2499) internally in MAnalyse and MRecalculate?

StainlessS
2nd November 2016, 00:26
One would have to have some difference measure, eg convert rgb to luma-y, and measure dif in that.
Or rgb color cube distance.
I don't get what you are saying about convert to hex.
Perhaps you should elaborate a little on what you want.

real.finder
2nd November 2016, 00:31
One would have to have some difference measure, eg convert rgb to luma-y, and measure dif in that.
Or rgb color cube distance.
I don't get what you are saying about convert to hex.
Perhaps you should elaborate a little on what you want.

https://en.wikipedia.org/wiki/Web_colors#Converting_RGB_to_hexadecimal

pinterf
2nd November 2016, 00:45
Mixing color component together does not help. The base of the whole motion analysis is SAD, pixel values of two frames get subtracted, then we get the absolute value and finally sum them up for 8x8, 16x16, up to 128x128 (vapoursynth mvtools2 port) pixel blocks.
Creating a compound representation of rgb value result us that the component at the lsb side will affect the result for 1/65536 of weight than the component at the msb side 0xff0000 mask (for 8 bits)

StainlessS
14th November 2016, 02:22
See here Bug in v2.5.11.2 and v2.5.11.20, and v2.5.11.22. Fixed in v2.7.1.22:- http://forum.doom9.org/showthread.php?t=174025

Also, MvTools2 v2.7.1.22 MBlockFps(Blend=False) and MFlowFps(Blend=False) are broken, creates mangled frames at scene change.

pinterf
14th November 2016, 08:55
Hi,

could you please try this test build (overlap fix only), and report back, though the scenechange problem is not intended to be fixed.

http://www.mediafire.com/file/u8pp73pjrcp4v2p/2.7.1.22postForStainless.7z
(test only, not for public)

Edit: what do you mean under "mangled", can you provide a test script and a hint where to look at that behaviour, and also, whether older 2.5.xx or 2.6.0.5 versions behave similarly?

StainlessS
14th November 2016, 10:25
Overlap fix seems to work ok.

By Mangled I meant that bad frame was produced, did not seem to be blend or correct behavior when Blend=False, ie duplicate previous frame
(that is End Of Scene Frame) at scene change.

Script testing v2.6.0.5 (frames are so different that synthesized frames should be same as frame prior to them [EDIT: when Blend=false).
EDIT: Result Frames 0, 2 and 4 are the original frames with a scene change between each, frames 1 and 3 are synthesized frames at scene change.

Function DoubleRate(clip c,Bool "Blend",Bool "Flow") {
# Works OK with MvTools2 v2.6.0.5
c
Blend=Default(Blend,False) # Avoid blends at scene change (copy previous frame)
Flow=Default(Flow,False) # If True, Use MFlowFps instead of MBlockFps
super = MSuper(pel=2, hpad=16, vpad=16,rfilter=4)
bw_1 = MAnalyse(super, chroma = false, isb = true, blksize = 16, OverLap=2, searchparam = 3, plevel = 0, search = 3, badrange = (-24))
fw_1 = MAnalyse(super, chroma = false, isb = false, blksize = 16, OverLap=2, searchparam = 3, plevel = 0, search = 3, badrange = (-24))
bw_2 = MRecalculate(super, chroma = false, bw_1, blksize = 8, searchparam = 1, search = 3) # No Overlap (currently broken for final vectors)
fw_2 = MRecalculate(super, chroma = false, fw_1, blksize = 8, searchparam = 1, search = 3) # No Overlap
Return (!Flow)
\ ? MBlockFps(super, bw_2, fw_2, num=FramerateNumerator(c) * 2, den=FramerateDenominator(c), mode=0, Blend=Blend)
\ : MFlowFps(super, bw_2, fw_2, num=FramerateNumerator(c) * 2, den=FramerateDenominator(c), Blend=Blend)
}

BLEND=False
FLOW=False
A=Colorbars.Killaudio.ConvertToYV12.Trim(0,-1)
B=A.FlipHorizontal
(A++B++A).ShowFrameNumber
DoubleRate(Blend=BLEND,Flow=FLOW)
BilinearResize(320,240)
I=Last.Blankclip(Height=4)
StackVertical(Trim(0,-1),I,Trim(1,-1),I,Trim(2,-1),I,Trim(3,-1),I,Trim(4,-1))

result
https://s20.postimg.cc/8g734a3y5/Mvt1_zpsnlgewgiq.png (https://postimg.cc/image/drlzozq0p/)

Script testing v2.7.1.22 and working for OverLap and without the previous script MRecalculate to step over the Overlap bug (In actual fact v2.6.0.5 puts
up error OverLap Must be 0, if function creating MBlockFps used vectors, use Overlap>0).


Function DoubleRate(clip c,Bool "Blend",Bool "Flow") {
# for MvTools2 v2.7.1.22 testing
c
Blend=Default(Blend,False) # Avoid blends at scene change (copy previous frame)
Flow=Default(Flow,False) # If True, Use MFlowFps instead of MBlockFps
super = MSuper(pel=2, hpad=16, vpad=16,rfilter=4)
bw_1 = MAnalyse(super, chroma = false, isb = true, blksize = 16, OverLap=2, searchparam = 3, plevel = 0, search = 3, badrange = (-24))
fw_1 = MAnalyse(super, chroma = false, isb = false, blksize = 16, OverLap=2, searchparam = 3, plevel = 0, search = 3, badrange = (-24))
Return (!Flow)
\ ? MBlockFps(super, bw_1, fw_1, num=FramerateNumerator(c) * 2, den=FramerateDenominator(c), mode=0, Blend=Blend)
\ : MFlowFps(super, bw_1, fw_1, num=FramerateNumerator(c) * 2, den=FramerateDenominator(c), Blend=Blend)
}

BLEND=False
FLOW=False
A=Colorbars.Killaudio.ConvertToYV12.Trim(0,-1)
B=A.FlipHorizontal
(A++B++A).ShowFrameNumber
DoubleRate(Blend=BLEND,Flow=FLOW)
BilinearResize(320,240)
I=Last.Blankclip(Height=4)
StackVertical(Trim(0,-1),I,Trim(1,-1),I,Trim(2,-1),I,Trim(3,-1),I,Trim(4,-1))


Result (showing 'Mangled frames')
https://s20.postimg.cc/6po22smf1/Mvt2_zpsjhtxm4sh.png (https://postimg.cc/image/o2ychnhq1/)

You can check the behaviour using 2nd script DoubleRate() and look at any scene change, with Blend=True, should create blend at scene change, if false, then should use copy of End of Scene frame for synthesized frame [EDIT: As in first above result].

Thanks pinterf, looking good. :)

EDIT: I dont know if you saw a previous edit from the Interframe thread, here tis:-

EDIT: The problem seems to occur if OverLap used in creating final BackWards and Forwards vectors supplied to MBlockFps,
ie MAnalyse(Overlap=whatever) if MRecalculate not used, and in final MRecalculate(Overlap=whatever) if used.

This works ok without Overlap in final vectors

Function foo2(clip source, int "multi") {
last = source
multi = default(multi, 2)
prefilt = DeGrainMedian() # some smoothing
superfilt = MSuper(prefilt, hpad=16, vpad=16) # all levels for MAnalyse
super = MSuper(source, pel = 2, hpad = 16, vpad = 16, rfilter = 4) # one level is enough for MRecalculate
bw_1 = MAnalyse(superfilt, chroma = false, isb = true, blksize = 16, OverLap=8, searchparam = 3, plevel = 0, search = 3, badrange = (-24))
fw_1 = MAnalyse(superfilt, chroma = false, isb = false, blksize = 16, OverLap=8, searchparam = 3, plevel = 0, search = 3, badrange = (-24))
bw_2 = MRecalculate(super, chroma = false, bw_1, blksize = 8, OverLap=4, searchparam = 1, search = 3)
fw_2 = MRecalculate(super, chroma = false, fw_1, blksize = 8, OverLap=4,searchparam = 1, search = 3)
bw_3 = MRecalculate(super, chroma = false, bw_2, blksize = 4, searchparam = 0, search = 3) # No Overlap
fw_3 = MRecalculate(super, chroma = false, fw_2, blksize = 4, searchparam = 0, search = 3) # No Overlap
MBlockFps(source, super, bw_3, fw_3, FramerateNumerator(Source) * multi, FramerateDenominator(Source), mode = 0, Blend=False)
return last
}


But think I'll be using this until fixed at least.

Function DoubleRate(clip c,Bool "Blend") {
c
Blend=Default(Blend,False) # Avoid blends at scene change (copy previous frame)
prefilt = DeGrainMedian() # some smoothing
superfilt = MSuper(prefilt, hpad=16, vpad=16, rfilter = 4) # all levels for MAnalyse
super = MSuper(pel=2, hpad=16, vpad=16,rfilter=4,levels=1) # one level is enough for MRecalculate
bw_1 = MAnalyse(superfilt, chroma = false, isb = true, blksize = 16, OverLap=2, searchparam = 3, plevel = 0, search = 3, badrange = (-24))
fw_1 = MAnalyse(superfilt, chroma = false, isb = false, blksize = 16, OverLap=2, searchparam = 3, plevel = 0, search = 3, badrange = (-24))
bw_2 = MRecalculate(super, chroma = false, bw_1, blksize = 8, searchparam = 1, search = 3) # No Overlap (currently broken for final vectors)
fw_2 = MRecalculate(super, chroma = false, fw_1, blksize = 8, searchparam = 1, search = 3) # No Overlap
MBlockFps(super, bw_2, fw_2, num=FramerateNumerator(c) * 2, den=FramerateDenominator(c), mode=0, Blend=Blend)
Return Last
}


EDIT: Ive Added BLEND arg to above two scripts, Default False, here are both results in order with BLEND=True

script 1
https://s20.postimg.cc/rnytembnh/Mvt1_T_zpsem2whf25.png (https://postimg.cc/image/4mi88vbzt/)

script 2 (showing 'Mangled frames')
https://s20.postimg.cc/i5z2ekpz1/Mvt2_T_zpsut3baxg8.png (https://postimg.cc/image/x1xlm61dl/)

EDIT: I've added FLOW=False default to both scripts, so you can also test MFlowFps if set true.

EDIT: I spoke too soon, there seems to be a problem at right and bottom edges on real video, also can be seen on frames 1 and 3
of 2nd results.

Script producing

Function DoubleRate(clip c,Bool "Blend",Bool "Flow") {
# for MvTools2 v2.7.1.22 testing
c
Blend=Default(Blend,False) # Avoid blends at scene change (copy previous frame)
Flow=Default(Flow,False) # If True, Use MFlowFps instead of MBlockFps
super = MSuper(pel=2, hpad=16, vpad=16,rfilter=4)
bw_1 = MAnalyse(super, chroma = false, isb = true, blksize = 16, OverLap=2, searchparam = 3, plevel = 0, search = 3, badrange = (-24))
fw_1 = MAnalyse(super, chroma = false, isb = false, blksize = 16, OverLap=2, searchparam = 3, plevel = 0, search = 3, badrange = (-24))
Return (!Flow)
\ ? MBlockFps(super, bw_1, fw_1, num=FramerateNumerator(c) * 2, den=FramerateDenominator(c), mode=0, Blend=Blend)
\ : MFlowFps(super, bw_1, fw_1, num=FramerateNumerator(c) * 2, den=FramerateDenominator(c), Blend=Blend)
}


AvisourcE("F:\v\StarWars.avi")

DoubleRate
Trim(12744,12746)
LanczosResize(400,224)
StackVertical(Trim(0,-1),Trim(1,-1),Trim(2,-1))


https://s20.postimg.cc/g2on6wq65/tinman_zpszva3otnp.png (https://postimg.cc/image/3o1v6kynt/)

EDIT: Still occurs if adding Crop(4,4,-4,-4) before call to DoubleRate (get rid of any crud, for padding).
EDIT: Still occurs if changing hpad and vpad to 0.
EDIT: And a live video scene change (Blend=false)
https://s20.postimg.cc/h68rivat9/Luke_zpsgeuc6dpt.png (https://postimg.cc/image/5tw613249/)

EDIT: What above looks like using v2.6.0.5 and same script but with script1 DoubeRate(Blend=True), Blend=False (as above)
should produce 2nd frame same as the 1st frame.
https://s20.postimg.cc/w3h8jvo1p/Luke_Blend_zpsqjrprzvo.png (https://postimg.cc/image/oaqkrwi2h/)

pinterf
14th November 2016, 16:35
Thanks, don't spend any more time on it, fabuolus error report. Now it's my turn.

pinterf
16th November 2016, 00:43
Hi StainlessS!

Try this test build please.
http://www.mediafire.com/file/aako4wx66anwoak/2.7.2.22ForStainlessS.zip

About the bug. er...
Guess what: A /256 was somehow changed into /(8*8) for better readability :). No, it wasn't really me, but the monkeys.

As a side-effect I think I have ported MFlowFPS to native 10-16 bits that can be used with Avisynth+.

StainlessS
16th November 2016, 03:42
MBlockFPS, have fixed side green border, but bottom green border remains in synthesized frames where not at scene change,
ie at scene change, synthesized frame is duplicate of previous frame (blend=false), or simple 50.0/50.0 blend (Blend=True),
so just a problem in synthesized frames that are not at scene change.
The Mangled frames at scene change have gone.

MFlowFPS, dont see any problems.

Unfortunately, I made a bob-boo earlier in other 'Compiler Error ???' thread, I said problem was gone (MSCDetection floating point -1.#IND000),
unfortunately, I dont seem to have checked for more than the disappearance of the floating point error, seems that the MSCDetection return clip
never spots a scene change, all frames identical Green, which is I think all YUV channels 0. (Both End of Scene and Start of Scene clips fail).

Below, code snippet to do detections easily yourself, requires no external plugins (EXCEPT of course MVTools2, which I know you have :) ).


FN="F:\v\StarWars.avi"

BLEND= false
FLOW = false

#######################
Avisource(FN)

#Trim(10000,0)

DORG=SelectEvery(1,0,0) # Original Each frame twice
DBL =DoubleRate(Blend=BLEND,Flow=FLOW)

DORG_S = DORG.Sub("Original, Each frame twice",0)
DBL_S = DBL.Sub("Double Rate : Blend="+String(Blend)+" Flow="+String(Flow),1)

Return StackVertical(DORG_S,DBL_S)
#######################

Function DoubleRate(clip c,Bool "Blend",Bool "Flow") {
# for MvTools2 v2.7.1.22 testing
c
Blend=Default(Blend,False) # Avoid blends at scene change (copy previous frame)
Flow=Default(Flow,False) # If True, Use MFlowFps instead of MBlockFps
super = MSuper(pel=2, hpad=16, vpad=16,rfilter=4)
bw_1 = MAnalyse(super, chroma = false, isb = true, blksize = 16, OverLap=2, searchparam = 3, plevel = 0, search = 3, badrange = (-24))
fw_1 = MAnalyse(super, chroma = false, isb = false, blksize = 16, OverLap=2, searchparam = 3, plevel = 0, search = 3, badrange = (-24))
Return (!Flow)
\ ? MBlockFps(super, bw_1, fw_1, num=FramerateNumerator(c) * 2, den=FramerateDenominator(c), Blend=Blend, mode=0)
\ : MFlowFps(super, bw_1, fw_1, num=FramerateNumerator(c) * 2, den=FramerateDenominator(c), Blend=Blend)
}

Function Sub(clip c,string tit,int Md) {
Function SubStrLo(int n,string tit,Int Md) {Return string(n)+"] "+tit+(n%2==0?"":Md==0?" (Duplicate)":" (Synthesized)")}
S = "SubTitle(SubStrLo(current_frame,"+Chr(34)+tit+Chr(34)+","+String(Md)+"))"
StackVertical(c.BlankClip(height=20).ScriptClip(S),c)
}


Produces something like below (at scene change, Blend=true [no green bottom border in synth frame at scene change])
https://s20.postimg.cc/jq4ecyyd9/Moons_zpspa6uhpct.png (https://postimg.cc/image/f48a4mcu1/)

EDIT: Above script, you can scrub through whole movie in eg VDubMod and check-out scene changes, and mod BLEND and FLOW
to check other modes.

EDIT: Oops, sorry, above script requires Grunt plugin.

EDIT: Got rid of Grunt() requirement, script updated.

pinterf
16th November 2016, 15:22
Hi! Found something, another try

http://www.mediafire.com/file/60o8c43r2cbyi3d/2.7.2.22StainLessS2.zip
Test build, not a release.

The bottom line bug was fixed.

The fixes/additions since 2.7.1.22:
- new: MBlockFPS 10-16 bit
- nSCD2 regression fix
- nSCD1 (thCSD1) scale for 10+ bits
- MBlockFPS: overlaps working buffers were not copied to the output.
- MBlockFPS: overlaps: Right columns were ok for the luma only.
- MBlockFPS: overlaps: Blend of bottom rows were operating on somewhere the top rows instead of the last row.

There are still visible differences on the edges, because right and bottom lines are simply blended when we use overlaps, but this is the way it works.

StainlessS
17th November 2016, 14:09
There are still visible differences on the edges, because right and bottom lines are simply blended when we use overlaps, but this is the way it works.

Oh dear, wish you had not told me that, I'll be forever looking for it now :)

https://s20.postimg.cc/mlhhju2d9/Olap8_zpsbrsjy3u5.png (https://postimg.cc/image/6n8rtp855/)

Script, no requirements.

FN="F:\v\StarWars.avi"

BLEND= false
FLOW = false

#######################
Avisource(FN)

DORG = SelectEvery(1,0,0) # Original Each frame twice
DBLA = DoubleRateA(Blend=BLEND,Flow=FLOW)
DBLB = DoubleRateB(Blend=BLEND,Flow=FLOW)
DBLC = DoubleRateC(Blend=BLEND,Flow=FLOW)

DORG_S = DORG.Sub("Original, Each frame twice",0)
DBLA_S = DBLA.Sub("DoubleRate_A(OLap=0) : Blend="+String(Blend)+" Flow="+String(Flow),1)
DBLB_S = DBLB.Sub("DoubleRate_B(NEW, Olap=8) : Blend="+String(Blend)+" Flow="+String(Flow),1)
DBLC_S = DBLC.Sub("DoubleRate_C(MRecalc, Olap=8): Blend="+String(Blend)+" Flow="+String(Flow),1)

H = DORG_S.Blankclip(Height=4,color=$FFFFFF)
LFT = StackVertical(DORG_S,H,DBLB_S)
RGT = StackVertical(DBLA_S,H,DBLC_S)
V = LFT.Blankclip(Width=4,color=$FFFFFF)

Return StackHorizontal(LFT,V,RGT) #.trim(48115,0)
#######################

Function DoubleRateA(clip c,Bool "Blend",Bool "Flow") {
# Overlap = 0
c
Blend=Default(Blend,False) # Avoid blends at scene change (copy previous frame)
Flow=Default(Flow,False) # If True, Use MFlowFps instead of MBlockFps
super = MSuper(pel=2, hpad=16, vpad=16,rfilter=4)
bw_1 = MAnalyse(super, chroma = false, isb = true, blksize = 16, OverLap=0, searchparam = 3, plevel = 0, search = 3, badrange = (-24))
fw_1 = MAnalyse(super, chroma = false, isb = false, blksize = 16, OverLap=0, searchparam = 3, plevel = 0, search = 3, badrange = (-24))
Return (!Flow)
\ ? MBlockFps(super, bw_1, fw_1, num=FramerateNumerator(c) * 2, den=FramerateDenominator(c), Blend=Blend, mode=0)
\ : MFlowFps(super, bw_1, fw_1, num=FramerateNumerator(c) * 2, den=FramerateDenominator(c), Blend=Blend)
}


Function DoubleRateB(clip c,Bool "Blend",Bool "Flow") {
# for MvTools2 v2.7.1.22 testing
c
Blend=Default(Blend,False) # Avoid blends at scene change (copy previous frame)
Flow=Default(Flow,False) # If True, Use MFlowFps instead of MBlockFps
super = MSuper(pel=2, hpad=16, vpad=16,rfilter=4)
bw_1 = MAnalyse(super, chroma = false, isb = true, blksize = 16, OverLap=8, searchparam = 3, plevel = 0, search = 3, badrange = (-24))
fw_1 = MAnalyse(super, chroma = false, isb = false, blksize = 16, OverLap=8, searchparam = 3, plevel = 0, search = 3, badrange = (-24))
Return (!Flow)
\ ? MBlockFps(super, bw_1, fw_1, num=FramerateNumerator(c) * 2, den=FramerateDenominator(c), Blend=Blend, mode=0)
\ : MFlowFps(super, bw_1, fw_1, num=FramerateNumerator(c) * 2, den=FramerateDenominator(c), Blend=Blend)
}

Function DoubleRateC(clip c,Bool "Blend",Bool "Flow") {
# Works OK with MvTools2 v2.6.0.5
c
Blend=Default(Blend,False) # Avoid blends at scene change (copy previous frame)
Flow=Default(Flow,False) # If True, Use MFlowFps instead of MBlockFps
super = MSuper(pel=2, hpad=16, vpad=16,rfilter=4)
bw_1 = MAnalyse(super, chroma = false, isb = true, blksize = 16, OverLap=8, searchparam = 3, plevel = 0, search = 3, badrange = (-24))
fw_1 = MAnalyse(super, chroma = false, isb = false, blksize = 16, OverLap=8, searchparam = 3, plevel = 0, search = 3, badrange = (-24))
bw_2 = MRecalculate(super, chroma = false, bw_1, blksize = 8, searchparam = 1, search = 3) # No Overlap (currently broken for final vectors)
fw_2 = MRecalculate(super, chroma = false, fw_1, blksize = 8, searchparam = 1, search = 3) # No Overlap
Return (!Flow)
\ ? MBlockFps(super,bw_2, fw_2, num=FramerateNumerator(c) * 2, den=FramerateDenominator(c), Blend=Blend, mode=0)
\ : MFlowFps(super, bw_2, fw_2, num=FramerateNumerator(c) * 2, den=FramerateDenominator(c), Blend=Blend)
}

Function Sub(clip c,string tit,int Md) {
Function SubStrLo(int n,string tit,Int Md) {Return string(n)+"] "+tit+(n%2==0?"":Md==0?" (Duplicate)":" (Synthesized)")}
S = "SubTitle(SubStrLo(current_frame,"+Chr(34)+tit+Chr(34)+","+String(Md)+"))"
StackVertical(c.BlankClip(height=20).ScriptClip(S),c)
}

Shows Synthesized frame, not at scene change, motion coming in from RHS.
TopLeft, original frames, every other one a duplicate,
Top Right, Overlap=0,
Bot Left, New version MvTools, Overlap=8
Bot Right, Old, Overlap=8, with MRecalculate.

All seems to be working OK, for block/Flow/FPS.

Script to show problem in MSCDetection, no requrements.


FN="LowBitrateAnime.AVI"
Avisource(FN)

Function EndOfSceneClip(clip c,Int "thSCD1",Int "thSCD2") { # All Luma Samples set 255 at EOS
thSCD1=Default(thSCD1,400) thSCD2=Default(thSCD2,130)
sup=c.MSuper(pel=1,sharp=0,rfilter=2,hpad=16, vpad=16)
bv=sup.MAnalyse(isb=true, delta=1,blksize=16,overlap=8)
Return c.MSCDetection(bv,thSCD1=thSCD1,thSCD2=thSCD2)
}

Function StartOfSceneClip(clip c,Int "thSCD1",Int "thSCD2") { # All Luma Samples set 255 at SOS
thSCD1=Default(thSCD1,400) thSCD2=Default(thSCD2,130)
sup=c.MSuper(pel=1,sharp=0,rfilter=2,hpad=16, vpad=16)
fv=sup.MAnalyse(isb=false,delta=1,blksize=16,overlap=8)
Return c.MSCDetection(fv,thSCD1=thSCD1,thSCD2=thSCD2)
}

EOS = EndOfSceneClip
SOS = StartOfSceneClip
#return EOS
SSS="""
e = EOS.AverageLuma
s = SOS.AverageLuma
Subtitle(String(current_frame)+String(e,"] EOS=%.1f")+String(s," : SOS=%.1f"))
(e!=0.0)
\ ? Subtitle("End Of Scene",Size=48,Text_Color=$FF0000,Y=Height/2-24,Align=5)
\ : (s!=0.0) ? Subtitle("Start Of Scene",Size=48,Text_Color=$0000FF,Y=Height/2+24,Align=5)
\ : NOP
return last
"""

Scriptclip(SSS)


We are nearly there :)

EDIT: Oh damn, meant to put the MBlockFPS example up on PhotoBucket instead of MFlowFPS, arh well done now.

EDIT: MBlockFPS version
http://i1136.photobucket.com/albums/n494/StainlessStephen/BlkOlap8_zpsa5wve3uc.png
EDIT: Above image lost due to Photobucket problem.

EDIT: The Blending mentioned in the quote at top of post is shown on Right Hand Edge of lower two (Overlap) images in
both image sets (dark edge, sourced from next image coming from rhs).

pinterf
17th November 2016, 19:40
I'm not saying I'm ready, this is just a new test build inspired by StainlessS :)

http://www.mediafire.com/file/k78dcmzft746kv1/2.7.3.22StainlessS4.zip

There were side effects again, ported some more mvtools2 filters to native 10-16 bits and fixed some bugs.

Recent change log

20161117: MFlow, MFlowInter, MFlowBlur: native 10-16 bits
20161117: MSCDetection: fix scene change filler pixel default value
20161117: MFlowFPS: native 10-16 bit
20161117: MCompensate: native 10-16 bit + possible bugfix bottom padding UV
20161117: Fix SAD for 10-16 bit depths for horizontal block sizes >= 16
20161116: MBlockFPS: Additional overlap fixes (bottom lines)
20161116: MBlockFPS: native 10-16 bit with Avisynth plus
20161116: MBlockFPS: additional overlap fix (Right)
20161115: Fix nSCD2 (Scene change threshold block count %) (2.7.1.22 regression)
20161114: MBlockFPS overlap fix test build (copy buffer to output)


Short status report on the 8+ bit transition:
MShow, MDepan are not yet ported to 10-16 bits. You can try the others, e.g. MDegrains for 10+ bits with Avisynth plus.

EDIT: MFlow, MFlowInter, MFlowBlur ported, removed from the non-16 bit list.

And of course you can freely use 4:2:2 and 4:4:4 formats.
(like YV16 and YV24)

StainlessS
18th November 2016, 12:25
Thanks pinterf, everything seems hunky dory,
I'll continue to use this version and report if I find any anomalies, again thanx.

EDIT: I'll probably be using something like below

Function ChangeFrameRate(clip c,Bool "Blend",Bool "Flow",Int "Num",Int "Den",Int "BlkSize",Int "OverLap") {
# Req MvTools2 v2.7.1.22+ for Overlap>0
Blend=Default(Blend,False) # Avoid blends at scene change (copy previous frame)
Flow=Default(Flow,False) # If True, Use MFlowFps instead of MBlockFps
BlkSize=Default(BlkSize,16) Overlap=Default(Overlap,BlkSize/2)
n=Default(num,0) d=default(den,0) valid=(n>0 && d>0) n=(!valid)?c.FramerateNumerator*2:n d=(!valid)?c.FramerateDenominator:d # Default = doublerate
super = c.MSuper(pel=2, hpad=BlkSize, vpad=BlkSize,rfilter=4)
bv = MAnalyse(super, chroma=false, isb=true, blksize=BlkSize, OverLap=OverLap, searchparam=3, plevel=0, search=3, badrange=(-24))
fv = MAnalyse(super, chroma=false, isb=false, blksize=BlkSize, OverLap=OverLap, searchparam=3, plevel=0, search=3, badrange=(-24))
Return (!Flow)
\ ? c.MBlockFps(super, bv, fv, num=n, den=d, Blend=Blend, mode=0)
\ : c.MFlowFps(super, bv, fv, num=n, den=d, Blend=Blend)
}

Function DoubleRate(clip c,Bool "Blend",Bool "Flow") {Return c.ChangeFrameRate(Blend,Flow,c.FramerateNumerator*2,c.FramerateDenominator)}

pinterf
18th November 2016, 23:18
Thanks, StainlessS, you were excellent, first class tester. You really deserve a new mvtools3 that can realtime interpolate the two suns of tatooine on a ZX81.
But until then I will just bump the version numbers and make a release soon.

Good news for me that finally I have finished porting the last two filters, MDepan and MShow for high bit depth, and also finished the two other DLLs for video stabilizing with Depan (DepanEstimate) and DepanStabilize.

pinterf
19th November 2016, 19:46
New release:


MvTools2 2.7.5.22 (20161119)
General support of 10-16 bit formats with Avisynth Plus (r2294 or newer recommended)
with new MDegrain4 and MDegrain5 filters.
Depan: 2.13.1 (20161119)
DepanEstimate: 2.10 (20161119)
General support of 10-16 bit formats with Avisynth Plus
Compiled for 64 bit for the first time
Supporting YV16 and YV24 for 8 bit and their 10+ bits equivalents
Requires 2.6 interface


Download:
MvTools 2.7.5.22 + Depan + DepanEstimate for 32 and 64 bits (https://github.com/pinterf/mvtools/releases/tag/r2.7.5.22)

For general info see readme or the first page of the thread.
Have fun.

Todo:

greyscale support (not tested)
Port remaining inline assembly to SIMD intrinsics
satd 16 bit to SIMD
fix reported bugs

Sparktank
19th November 2016, 19:56
Great work, guys! :goodpost:

tormento
20th November 2016, 12:01
Now we need a revised masktools :)

real.finder
20th November 2016, 12:16
New release:


MvTools2 2.7.5.22 (20161119)
General support of 10-16 bit formats with Avisynth Plus (r2294 or newer recommended)
with new MDegrain4 and MDegrain5 filters.
Depan: 2.13.1 (20161119)
DepanEstimate: 2.10 (20161119)
General support of 10-16 bit formats with Avisynth Plus
Compiled for 64 bit for the first time
Supporting YV16 and YV24 for 8 bit and their 10+ bits equivalents
Requires 2.6 interface


Download:
MvTools 2.7.5.22 + Depan + DepanEstimate for 32 and 64 bits (https://github.com/pinterf/mvtools/releases/tag/r2.7.5.22)

For general info see readme or the first page of the thread.
Have fun.

Todo:

greyscale support (not tested)
Port remaining inline assembly to SIMD intrinsics
satd 16 bit to SIMD
fix reported bugs


:thanks: Energetic as always :D

has the Depan fix this bug (http://forum.videohelp.com/threads/371336-Stabilization-Tools-Pack-v2-1?p=2386111&viewfull=1#post2386111) (turns the video green)?

Reel.Deel
20th November 2016, 14:47
New release:


MvTools2 2.7.5.22 (20161119)
General support of 10-16 bit formats with Avisynth Plus (r2294 or newer recommended)
with new MDegrain4 and MDegrain5 filters.
Depan: 2.13.1 (20161119)
DepanEstimate: 2.10 (20161119)
General support of 10-16 bit formats with Avisynth Plus
Compiled for 64 bit for the first time
Supporting YV16 and YV24 for 8 bit and their 10+ bits equivalents
Requires 2.6 interface


Download:
MvTools 2.7.5.22 + Depan + DepanEstimate for 32 and 64 bits (https://github.com/pinterf/mvtools/releases/tag/r2.7.5.22)

For general info see readme or the first page of the thread.
Have fun.

Todo:

greyscale support (not tested)
Port remaining inline assembly to SIMD intrinsics
satd 16 bit to SIMD
fix reported bugs


Awesome work as always, thanks pinterf! :thanks:


has the Depan fix this bug (http://forum.videohelp.com/threads/371336-Stabilization-Tools-Pack-v2-1?p=2386111&viewfull=1#post2386111) (turns the video green)?

I think Fizick fixed it in the latest release, see here: http://forum.doom9.org/showthread.php?p=1763563#post1763563

Now we need a revised masktools :)

A while back tp7 started working on a 16-bit MaskTools, unfortunately it was not finished. See here: https://github.com/tp7/masktools/commits/16bit

Maybe someone will come along and finish it. Another route is porting VS' Expr and co.

feisty2
20th November 2016, 15:38
Someday, maybe there will be a complete version of mvtools that could merge all mvtools variations into one
One binary serves as both a vaporsynth plugin and an avisynth plugin, supporting bitdepths from 8 to 32 and arbitrary temporal radius..

real.finder
20th November 2016, 16:43
I think Fizick fixed it in the latest release, see here: http://forum.doom9.org/showthread.php?p=1763563#post1763563



I missed this update...

real.finder
30th November 2016, 14:39
MvTools2 2.7.5.22d is slower than mvtools2 2.7.0.22d

~1.7 fps vs ~1.5 fps with same complex script

is this because it built without ICC?

Groucho2004
30th November 2016, 15:04
MvTools2 2.7.5.22d is slower than mvtools2 2.7.0.22d

~1.7 fps vs ~1.5 fps with same complex script

is this because it built without ICC?
No. It's because ill-tempered fairies have invaded your computer and are eating CPU cycles. :sly:

If you post the script that causes this behaviour and possibly mention what CPU you have you'll probably get a better answer.

pinterf
30th November 2016, 17:14
MvTools2 2.7.5.22d is slower than mvtools2 2.7.0.22d

~1.7 fps vs ~1.5 fps with same complex script

is this because it built without ICC?
Yes.
Since then I found some bottlenecking places when using __forceinline helped poor vs2015.

Testing on a typical MDegrain3 script:
2.7.5.22: 4.13 fps (VS2015)
2.7.0.22d: 4.69 fps
2.7.futu.re: 4.62 fps (VS2015)

Promising.

Groucho2004
30th November 2016, 17:26
Testing on a typical MDegrain3 script:
2.7.5.22: 4.13 fps (VS2015)
2.7.0.22d: 4.69 fps

What CPU do you use for these tests? Also, what switches for ICC?

pinterf
30th November 2016, 17:39
i7 ivy bridge.
Icc build was for sse2 with optional sse4.1 code paths

real.finder
30th November 2016, 17:51
Yes.
Since then I found some bottlenecking places when using __forceinline helped poor vs2015.

Testing on a typical MDegrain3 script:
2.7.5.22: 4.13 fps (VS2015)
2.7.0.22d: 4.69 fps
2.7.futu.re: 4.62 fps (VS2015)

Promising.

why stop using ICL in last ver.? for amd users?

Groucho2004
30th November 2016, 18:06
Icc build was for sse2 with optional sse4.1 code pathsWell, that's just one switch (QaxNNN). From my experience with Intel compilers, there are at least 5-7 other switches that can affect performance. Just a little selection:
/O3 optimize for maximum speed and enable more aggressive optimizations

/Qipo[n] enable multi-file IP optimization between files

/Qunroll-aggressive

/Qopt-ra-region-strategy[:<keyword>]
select the method that the register allocator uses to partition each
routine into regions
routine - one region per routine
block - one region per block
trace - one region per trace
loop - one region per loop
default - compiler selects best option

/Qprof profiling

pinterf
30th November 2016, 18:08
Will check it later now i'm from mobile.

Groucho2004
30th November 2016, 18:23
Icc build was for sse2 with optional sse4.1 code paths
One more thing about the automatic CPU dispatcher (enabled with QaX...) in the Intel compiler - This could actually have an impact on AMD CPUs since I suspect that even with the latest incarnation of the compiler it may chose sub-optimal optimizations for those.
If I build for specific instruction sets, I always "hard-code" them by using "Qx..." instead of "QaX...". This way all CPUs use the same code path. That of course means building binaries for each instruction set.
I also recommend testing if the SSE4.x or even AVX options really make a difference. More often than not, they don't. As usual, it all depends on the code.

jpsdr
1st December 2016, 11:57
If I build for specific instruction sets, I always "hard-code" them by using "Qx..." instead of "QaX...". This way all CPUs use the same code path. That of course means building binaries for each instruction set.
Oh... You too.

Didn't know some of the options :

/Qunroll-aggressive
/Qopt-ra-region-strategy[:<keyword>]

I'll have to check themn even if... "aggressive". Just seeing the word make me a little suspicious.

Groucho2004
1st December 2016, 12:15
Oh... You too.

Didn't know some of the options :

/Qunroll-aggressive
/Qopt-ra-region-strategy[:<keyword>]

I'll have to check themn even if... "aggressive". Just seeing the word make me a little suspicious.
Don't worry. :)

I suppose my way of building binaries differs a lot from what everyone else does. I don't use the IDE, I create makefiles for my projects and build from the command line with batch files. The makefiles have easily accessible compiler and linker options so I can quickly change them, rebuild and test.

As for all compiler options - run "icl -help" and pipe into a text file. And there are of course the Intel docs that come with the compiler which have lots of stuff about optimization (which almost nobody reads, I guess).

pinterf
1st December 2016, 14:44
One more thing about the automatic CPU dispatcher (enabled with QaX...) in the Intel compiler - This could actually have an impact on AMD CPUs since I suspect that even with the latest incarnation of the compiler it may chose sub-optimal optimizations for those.
If I build for specific instruction sets, I always "hard-code" them by using "Qx..." instead of "QaX...". This way all CPUs use the same code path. That of course means building binaries for each instruction set.
I also recommend testing if the SSE4.x or even AVX options really make a difference. More often than not, they don't. As usual, it all depends on the code.

Not to mention the aligment hints, hints for typical loop size, etc.

Finally I couldn't find my old ICC settings. Sure, loop unrolling was at default, so it was not fine-tuned, but I've seen unrolled loops in the asm output (sometimes I check the asm code that compilers generate). Global optimization was on, and the maximum optimization, too.

When I have successfully gained back a lot of speed, I used VS2015's performance profiler that showed me the parts where the code spends most of the time. Then I forced these functions to be inline.

There were other optimizations I have made, so perhaps the ICC version could also be faster, from the current codebase.

Interesting article on the optimizer changes came with VS2015 update 3:
https://blogs.msdn.microsoft.com/vcblog/2016/05/04/new-code-optimizer/

Groucho2004
1st December 2016, 17:42
There are also oddball cases where the compiler options for max. speed have the opposite effect. I have a couple of programs where turning off automatic inlining or even using "O1" instead of "O2/O3" results in faster binaries. Always test, if possible on Intel and AMD CPUs.

jpsdr
4th December 2016, 11:06
And there are of course the Intel docs that come with the compiler which have lots of stuff about optimization (which almost nobody reads, I guess).
Yes, i've read it... a long time ago.;)

pinterf
4th December 2016, 21:01
New version. 2.7.6.22
Depan and DepanEstimate are unchanged.

https://github.com/pinterf/mvtools/releases/tag/2.7.6.22

Change log
2.7.6.22 (20161204) - fixes and speedup


fix: sumLumaChange underflow (used for dct=2,6,9) (regression during 16 bit support)
fix: MeanLumaChange scale for 10-16 bits (used for dct=2,6,9)
fix: Mask fix: 8 bit mask resizer bug in SIMD intrinsics - Thx real.finder
(regression on inline asm -> SIMD transition)
Fix: dctmode=1,2: pixel distance was not corrected for 16 bit pixel sizes
speed: Let's help VS2015 with some __forceinline directives to recognize the truth.
speed: Misc optimizations throughout the code (bit shifts instead of div or mul)
speed: FFTW DCT: C code replaced with SIMD SSE2/SSE4 (FloatToBytes, BytesToFloat)
speed: 16 bit SAD: a few optimizations in SSE2, AVX-coded SSE2 and AVX2 codepath
VS2015 compiler: /MT -> /MD (from static to dynamic dlls - now it really needs VS2015 redistributables)

Motenai Yoda
6th December 2016, 01:05
depanestimate (or depan) parameters have been changed? coz scene change detection looks broken to me

tormento
6th December 2016, 05:36
Strange enough, now MDegrain5 is more effective than MDegrain6 in SMDegrain and almost comparable with MDegrain4.

Perhaps MDegrain6 (and MDegrainN) is needed or simply wrong script implementation?

pinterf
6th December 2016, 10:33
Strange enough, now MDegrain5 is more effective than MDegrain6 in SMDegrain and almost comparable with MDegrain4.

Perhaps MDegrain6 (and MDegrainN) is needed or simply wrong script implementation?
I don't understand exactly but when MDegrainN is called, if thSAD2 = thSAD and thSADC = thSADC2 then MDegrainN will call the original MDegrain1..5 because it is said to be faster.
MDegrain6 does not exist, it always uses MDegrainN.

pinterf
6th December 2016, 10:34
depanestimate (or depan) parameters have been changed? coz scene change detection looks broken to me
Dunno, this one needs investigating.

tormento
6th December 2016, 11:44
I don't understand exactly but when MDegrainN is called, if thSAD2 = thSAD and thSADC = thSADC2 then MDegrainN will call the original MDegrain1..5 because it is said to be faster.
MDegrain6 does not exist, it always uses MDegrainN.

I meant SMDegrain with tr=5 or tr=6. According to my experience, 6 was more effective in noise reduction than 5.

Can't trace back when things went wrong, as I always used 4 or 6.

real.finder
6th December 2016, 20:35
ok, I did another change, http://forum.videohelp.com/threads/369142-Simple-MDegrain-Mod-v3-1-2d-A-Quality-Denoising-Solution?p=2413356&viewfull=1#post2413356

try with always_mdegrainn=true

tormento
7th December 2016, 14:49
try with always_mdegrainn=true

Files:

pee.264 (http://www53.zippyshare.com/v/c6vwyvYM/file.html)
pee.dgi (http://www53.zippyshare.com/v/mGjFageP/file.html)

SMDegrain.avsi (http://forum.videohelp.com/threads/369142-Simple-MDegrain-Mod-v3-1-2d-A-Quality-Denoising-Solution?p=2413356&viewfull=1#post2413356) + this (http://forum.doom9.org/showthread.php?p=1787600#post1787600) variation to use KNLMeansCL 1.0

Basic script and variations:

SetMemoryMax(8000)
SetFilterMTMode("DEFAULT_MT_MODE", 2)
SetFilterMTMode("ChangeFPS", 3)

SetFilterMTMode("DGSource", 3)
LoadPlugin("D:\eseguibili\media\DGDecNV\x64\DGDecodeNV.dll")
DGSource("E:\in\Pee Wee's big adventure\pee.dgi")

ChangeFPS(last,last,true)

SMDegrain (tr=4,PreFilter=4,thSAD=400,contrasharp=false,refinemotion=false,truemotion=true,plane=4,chroma=true,lsb=true,mode=6,TV_range=false)

Prefetch(7)

encoded 2162 frames, 7.81 fps, 4015.53 kb/s, duration 0:04:36.77
av2y [info]: E:\in\Pee Wee's big adventure\pee_44.avs: 1920x1080, 2997/125 fps, 2162 frames
Final file size is 43.2 MB bytes.

SMDegrain (tr=4,PreFilter=4,thSAD=400,contrasharp=false,refinemotion=false,truemotion=true,plane=4,chroma=true,lsb=true,mode=6,TV_range=false,always_MDegrainN=true)

encoded 2162 frames, 7.72 fps, 4245.76 kb/s, duration 0:04:40.05
av2y [info]: E:\in\Pee Wee's big adventure\pee_44a.avs: 1920x1080, 2997/125 fps, 2162 frames
Final file size is 45.7 MB bytes.

SMDegrain (tr=5,PreFilter=4,thSAD=400,contrasharp=false,refinemotion=false,truemotion=true,plane=4,chroma=true,lsb=true,mode=6,TV_range=false)

encoded 2162 frames, 7.00 fps, 3771.63 kb/s, duration 0:05:08.76
av2y [info]: E:\in\Pee Wee's big adventure\pee_54.avs: 1920x1080, 2997/125 fps, 2162 frames
Final file size is 40.6 MB bytes.

SMDegrain (tr=5,PreFilter=4,thSAD=400,contrasharp=false,refinemotion=false,truemotion=true,plane=4,chroma=true,lsb=true,mode=6,TV_range=false,always_MDegrainN=true)

encoded 2162 frames, 6.81 fps, 3991.23 kb/s, duration 0:05:17.41
av2y [info]: E:\in\Pee Wee's big adventure\pee_54a.avs: 1920x1080, 2997/125 fps, 2162 frames
Final file size is 42.9 MB bytes.

SMDegrain (tr=6,PreFilter=4,thSAD=400,contrasharp=false,refinemotion=false,truemotion=true,plane=4,chroma=true,lsb=true,mode=6,TV_range=false)

encoded 2162 frames, 6.16 fps, 3806.16 kb/s, duration 0:05:51.22
av2y [info]: E:\in\Pee Wee's big adventure\pee_64.avs: 1920x1080, 2997/125 fps, 2162 frames
Final file size is 40.9 MB bytes.

SMDegrain (tr=6,PreFilter=4,thSAD=400,contrasharp=false,refinemotion=false,truemotion=true,plane=4,chroma=true,lsb=true,mode=6,TV_range=false,always_MDegrainN=true)

encoded 2162 frames, 6.12 fps, 3806.16 kb/s, duration 0:05:53.37
av2y [info]: E:\in\Pee Wee's big adventure\pee_64a.avs: 1920x1080, 2997/125 fps, 2162 frames
Final file size is 40.9 MB bytes.

Something is going wrong, I think, in script or in latest MVTools iteration. How is possible that a 6 frame noise reduction is less effective than a 5 frame and almost equivalent to a 4?

real.finder
7th December 2016, 18:19
Files:

pee.264 (http://www53.zippyshare.com/v/c6vwyvYM/file.html)
pee.dgi (http://www53.zippyshare.com/v/mGjFageP/file.html)

SMDegrain.avsi (http://forum.videohelp.com/threads/369142-Simple-MDegrain-Mod-v3-1-2d-A-Quality-Denoising-Solution?p=2413356&viewfull=1#post2413356) + this (http://forum.doom9.org/showthread.php?p=1787600#post1787600) variation to use KNLMeansCL 1.0

Basic script and variations:

SetMemoryMax(8000)
SetFilterMTMode("DEFAULT_MT_MODE", 2)
SetFilterMTMode("ChangeFPS", 3)

SetFilterMTMode("DGSource", 3)
LoadPlugin("D:\eseguibili\media\DGDecNV\x64\DGDecodeNV.dll")
DGSource("E:\in\Pee Wee's big adventure\pee.dgi")

ChangeFPS(last,last,true)

SMDegrain (tr=4,PreFilter=4,thSAD=400,contrasharp=false,refinemotion=false,truemotion=true,plane=4,chroma=true,lsb=true,mode=6,TV_range=false)

Prefetch(7)

encoded 2162 frames, 7.81 fps, 4015.53 kb/s, duration 0:04:36.77
av2y [info]: E:\in\Pee Wee's big adventure\pee_44.avs: 1920x1080, 2997/125 fps, 2162 frames
Final file size is 43.2 MB bytes.

SMDegrain (tr=4,PreFilter=4,thSAD=400,contrasharp=false,refinemotion=false,truemotion=true,plane=4,chroma=true,lsb=true,mode=6,TV_range=false,always_MDegrainN=true)

encoded 2162 frames, 7.72 fps, 4245.76 kb/s, duration 0:04:40.05
av2y [info]: E:\in\Pee Wee's big adventure\pee_44a.avs: 1920x1080, 2997/125 fps, 2162 frames
Final file size is 45.7 MB bytes.

SMDegrain (tr=5,PreFilter=4,thSAD=400,contrasharp=false,refinemotion=false,truemotion=true,plane=4,chroma=true,lsb=true,mode=6,TV_range=false)

encoded 2162 frames, 7.00 fps, 3771.63 kb/s, duration 0:05:08.76
av2y [info]: E:\in\Pee Wee's big adventure\pee_54.avs: 1920x1080, 2997/125 fps, 2162 frames
Final file size is 40.6 MB bytes.

SMDegrain (tr=5,PreFilter=4,thSAD=400,contrasharp=false,refinemotion=false,truemotion=true,plane=4,chroma=true,lsb=true,mode=6,TV_range=false,always_MDegrainN=true)

encoded 2162 frames, 6.81 fps, 3991.23 kb/s, duration 0:05:17.41
av2y [info]: E:\in\Pee Wee's big adventure\pee_54a.avs: 1920x1080, 2997/125 fps, 2162 frames
Final file size is 42.9 MB bytes.

SMDegrain (tr=6,PreFilter=4,thSAD=400,contrasharp=false,refinemotion=false,truemotion=true,plane=4,chroma=true,lsb=true,mode=6,TV_range=false)

encoded 2162 frames, 6.16 fps, 3806.16 kb/s, duration 0:05:51.22
av2y [info]: E:\in\Pee Wee's big adventure\pee_64.avs: 1920x1080, 2997/125 fps, 2162 frames
Final file size is 40.9 MB bytes.

SMDegrain (tr=6,PreFilter=4,thSAD=400,contrasharp=false,refinemotion=false,truemotion=true,plane=4,chroma=true,lsb=true,mode=6,TV_range=false,always_MDegrainN=true)

encoded 2162 frames, 6.12 fps, 3806.16 kb/s, duration 0:05:53.37
av2y [info]: E:\in\Pee Wee's big adventure\pee_64a.avs: 1920x1080, 2997/125 fps, 2162 frames
Final file size is 40.9 MB bytes.

Something is going wrong, I think, in script or in latest MVTools iteration. How is possible that a 6 frame noise reduction is less effective than a 5 frame and almost equivalent to a 4?

I think that MDegrainN with thSAD2 (it's thSAD/2 in SMDegrain) will did it in another way, like what MRecalculate do, so now you have new option to do your denoise :)

tormento
7th December 2016, 18:45
I think that MDegrainN with thSAD2 (it's thSAD/2 in SMDegrain) will did it in another way, like what MRecalculate do, so now you have new option to do your denoise :)

I really can't understand you... :(

real.finder
7th December 2016, 18:52
I really can't understand you... :(

I mean always_mdegrainn=true, you can use it even with tr=1

it will make the denoise more friendly with the details (it will look like refinemotion=true)

tormento
7th December 2016, 20:55
I mean always_mdegrainn=true, you can use it even with tr=1

it will make the denoise more friendly with the details (it will look like refinemotion=true)

Ok but I can't really understand why now tr=6 gives so bad results...

Motenai Yoda
9th December 2016, 00:08
@real.finder IIRC there was a bug in smdegrain when chroma = something and plane = something (maybe about prefilter???) I sent an mp about the fix to dogway some time ago but IIRC he didn't applied it

real.finder
9th December 2016, 00:18
@real.finder IIRC there was a bug in smdegrain when chroma = something and plane = something (maybe about prefilter???) I sent an mp about the fix to dogway some time ago but IIRC he didn't applied it

I think you mean this http://forum.doom9.org/showthread.php?p=1779900#post1779900

Motenai Yoda
9th December 2016, 16:35
IIRC was something of smdegrain itself,

what about using a prefilter clip and chroma=false?
087
Chr2 = chroma ? 3 : IsClip(prefilter) ? 1 : (prefilter == 3 ? 2 : 1)

... looks like was fixed in the end.

Groucho2004
13th December 2016, 12:22
pinterf, you mentioned that your version was forked from 2.6.0.5 and that you did not touch the code that interfaced with avstp.dll. I ran a test to see how it affects the speed.

The simple script:
colorbars(width = 1024, height = 512, pixel_type = "yv12").killaudio().assumefps(25, 1).trim(0, 199)
addgrain(var = 100)
super = MSuper(pel = 2, sharp = 1)
backward_vec2 = MAnalyse(super, isb = true, delta = 2, overlap = 4)
backward_vec1 = MAnalyse(super, isb = true, delta = 1, overlap = 4)
forward_vec1 = MAnalyse(super, isb = false, delta = 1, overlap = 4)
forward_vec2 = MAnalyse(super, isb = false, delta = 2, overlap = 4)
MDegrain2(super, backward_vec1, forward_vec1, backward_vec2, forward_vec2, thSAD = 400)


The first run is with a slightly older version of Fizick's mvtools2.dll (2.5.11.3), built by me with VC10:
Frames processed: 200 (0 - 199)
FPS (min | max | average): 7.003 | 13.65 | 7.148
Memory usage (phys | virt): 150 | 149 MiB
Thread count: 1
CPU usage (average): 25%
Efficiency index: 0.2859


Next is with your latest (2.7.6.22):
Frames processed: 200 (0 - 199)
FPS (min | max | average): 5.805 | 11.34 | 5.878
Memory usage (phys | virt): 149 | 148 MiB
Thread count: 1
CPU usage (average): 25%
Efficiency index: 0.2351


And here is yours with avstp.dll present in the auto-load directory:
Frames processed: 200 (0 - 199)
FPS (min | max | average): 8.886 | 28.06 | 14.87
Memory usage (phys | virt): 151 | 149 MiB
Thread count: 4
CPU usage (average): 71%
Efficiency index: 0.2095


I enabled the efficiency index feature in AVSMeter to see how well the plugins use CPU cycles. Your version clearly makes use of avstp but it is rather inefficient. Removing avstp will run the code single-threaded but it's quite a bit slower and less efficient than Fizick's DLL. So, my point is - Perhaps the code that interfaces with avstp causes an overhead and explains the slower operation, even when avstp is not present. Just some food for thought.

tormento
13th December 2016, 13:32
Perhaps the code that interfaces with avstp causes an overhead and explains the slower operation, even when avstp is not present. Just some food for thought.
I completely removed avstp and use AviSynth+ MT with way better results. IMHO avstp is almost useless.

pinterf
13th December 2016, 17:12
When I will have time, I should check the SAD function selection.
avstp surely has no that much overhead.

pinterf
14th December 2016, 19:49
New release. I was trying to give a speed boost for my mod.
MvTools2 2.7.7.22 and Depans (https://github.com/pinterf/mvtools/releases/)


change some 8 bit SAD functions for the better
separating bottleneck 8 bit/16 bit code paths in order not to use slower int64 calculations for 8 bit, where there are no integer overflow problems
more __forceinlines for helping the compiler
general speed gain of 5-15% compared to 2.7.6.22, much reduced speed gap compared to the "classic" YV12 8 bit mvtools2 versions


Groucho2004, thank you for the inspiring speed test, I was using that test script with 8 and 16 block sizes, avsmeters were burning hard :)

StainlessS
14th December 2016, 20:36
You be a star Pinterf, Thanx :)

Groucho2004
14th December 2016, 21:55
New release. I was trying to give a speed boost for my mod.
MvTools2 2.7.7.22 and Depans (https://github.com/pinterf/mvtools/releases/)
It's a bit faster, ~6.5 fps with the same test as above.

real.finder
14th December 2016, 22:47
Fizick MVTools v2.5.11.22 -> ~5.0 fps

pinterf MvTools2 2.7.6.22 -> ~4.3 fps

Firesledge MvTools 2.6.0.5 -> ~4.85 fps

pinterf MvTools2 2.7.7.22 -> ~4.79 fps

pinterf mvtools2 2.7.0.22d -> ~4.31 fps

pinterf MvTools2 2.7.5.22d -> ~3.9 fps

real.finder
18th December 2016, 06:30
MSuper is broken after mvtools2_2.7.0.22d (mvtools2_2.7.0.22d was fine)

ex:-


ColorBars(width=640, height=480, pixel_type="YUY2")
MSuper(sharp=1)


will gave access violation reading 0x176A9000

pinterf
18th December 2016, 11:26
Thank you for the report

New release:
MvTools2 2.7.8.22 + Depan + DepanEstimate (https://github.com/pinterf/mvtools/releases/tag/2.7.8.22)


fix: YUY2 input (MvTools, DepanStabilize) - regression after 2.7.0.22d
fix: YUY2 freeze at script exit.
MDegrain YUY2 plane deallocation fix. This bug is present in MDegrain3 in the original 2.5.11.22.
Helper YUY2 planes were freed up even if not allocated.

Reel.Deel
19th December 2016, 15:14
Pinterf, regarding speed have you included the changes from SVP's MVTools? IIRC correctly, jackoneil included this change in his VS version.

A while back I did some speed test with different versions of MVTools. Results were similar to Keiyakusha's; MVTools from SVP (http://svp-team.com/wiki/Plugins:_MVTools2) is faster than the rest. On their website they claim MAnalyze to be faster. Maybe jackoneill can include this difference?



MAnalyse
Can be faster than original version (with chroma=true) by 20-40%, look at PlaneOfBlocks.h for changes.

A DL link in longer on their website so here it is: mvtools-2.5.11.9-svp.zip (https://web-beta.archive.org/web/20150829061844/http://www.svp-team.com/files/gpl/mvtools-2.5.11.9-svp.zip)

pinterf
19th December 2016, 15:26
Pinterf, regarding speed have you included the changes from SVP's MVTools? IIRC correctly, jackoneil included this change in his VS version.



A DL link in longer on their website so here it is: mvtools-2.5.11.9-svp.zip (https://web-beta.archive.org/web/20150829061844/http://www.svp-team.com/files/gpl/mvtools-2.5.11.9-svp.zip)
Yes, it smartly shortcuts the limit check. Here cost is sum of MotionDistortion, luma SAD and chroma SAD. The fast version is checking a limit after each component, and not after summing up all the three. E.g. if cost is already over the limit after having luma SAD, it does not call SAD for chroma.

pinterf
19th December 2016, 15:38
I mean yes, I have checked now.
But no, I have not integrated. But I will, thanks

pinterf
20th December 2016, 13:16
New build
MvTools2 2.7.9.22 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.9.22)
New: much faster analysis when choma is involved.
The speed up idea was applied from the 2.5.11.9-svp branch

StainlessS
21st December 2016, 01:49
New build

You guys, all of you, thanx so very much. (Pinterf, RD, SVP team, the whole lot of you + some that went un-mentioned) :)

Sparktank
21st December 2016, 02:02
You guys, all of you, thanx so very much. (Pinterf, RD, SVP team, the whole lot of you + some that went un-mentioned) :)

^ This!

I cannot imagine a world without this to help interpolating movies. :)

FranceBB
23rd December 2016, 02:09
New build
MvTools2 2.7.9.22 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.9.22)
New: much faster analysis when choma is involved.
The speed up idea was applied from the 2.5.11.9-svp branch

Thank you! :D

ajp_anton
27th December 2016, 00:07
I don't know if this is the right topic, but since you're releasing the DePan plugins in the same package, I'll ask here...

I'm using MDepan and DePanEstimate to stabilize a video, however it puts random scene changes during a vertical pan that makes for a really jerky clip. I've tried to set every threshold through the roof to really make sure to disable all possible scene changes (the clips I'm stabilizing don't have any scene changes), I've increased the maximum corrections and played with dampening, but nothing helps. They always happen on the same frames.
MDepan's info=true doesn't seem to indicate a scene change, so I guess it happens in DePanEstimate.
Is there any other setting I could try? I can post (send via PM) a short video tomorrow if that helps.

real.finder
27th December 2016, 07:32
depanestimate (or depan) parameters have been changed? coz scene change detection looks broken to me

I don't know if this is the right topic, but since you're releasing the DePan plugins in the same package, I'll ask here...

I'm using MDepan and DePanEstimate to stabilize a video, however it puts random scene changes during a vertical pan that makes for a really jerky clip. I've tried to set every threshold through the roof to really make sure to disable all possible scene changes (the clips I'm stabilizing don't have any scene changes), I've increased the maximum corrections and played with dampening, but nothing helps. They always happen on the same frames.
MDepan's info=true doesn't seem to indicate a scene change, so I guess it happens in DePanEstimate.
Is there any other setting I could try? I can post (send via PM) a short video tomorrow if that helps.

I think this is because the original depan, from original site (http://web.archive.org/web/20161210165507/http://avisynth.org.ru/depan/depan.html)


DePan Version 1.12, January 31, 2016 - stabilize second frame after scenechange, other small fixes.
DePan Version 1.13, February 18, 2016 - Experimental method=2 (unlimited stabilize) and method=-1 (tracking) of DepanStabilize.
DePanEstimate v1.10, February 22, 2016 - DePanEstimate: added wleft, wtop, removed improve. Fixed doc about default values range, stab (thanks HolyWu).
DePan Version 1.13.1, April 6, 2016 - Fixed old bug (chroma tint) for subpixel=2 without rotation and zoom (Depan, DepanStabilize).


and here is the .dll of them http://rgho.st/private/7QWLfLWz8/d8466a216c2dd8feeb7dd6cec4d01b9d

ajp_anton
27th December 2016, 14:44
Thank you, those old versions work. Too bad they don't have x64 binaries or support 16-bit video, but for now my project is saved.

real.finder
27th December 2016, 15:20
Thank you, those old versions work. Too bad they don't have x64 binaries or support 16-bit video, but for now my project is saved.

it's better to upload sample so pinterf will fix the bug

pinterf
27th December 2016, 16:54
Yes, upload a sample please, I have put in some safety because my sample went chaotic and stabilization caused finally access viola (too big resulting shift) maybe I have put too much in.

ajp_anton
28th December 2016, 00:04
Found another less personal clip that I can post here publicly.

http://ajpanton.se/avsbug/source.mkv (~4.2 MB)

Script:
ffms2("source.mkv")

vectors = msuper().manalyse(isb = false)
mdata = mdepan(vectors, zoom=true, rot=true)
depanstabilize(data=mdata, dxmax=100, dymax=100, rotmax=2.0, mirror=15)

Frame 62 is always detected as scene change in the new version, old version works fine.

There's another problem though, that might be related to Avisynth itself. I'll post that in the Avs+ thread, and I don't know if these issues are related.

pinterf
28th December 2016, 12:54
You are right. The safety check I have issued on the motion data, was too strict.

tormento
5th January 2017, 10:24
@pinterf

Before having optimized 4 and 5 frame, I used 6 when grain was really horrible. Is it feasible to have it too?

pinterf
5th January 2017, 12:05
No problem, I have included 4 and 5 only for curiousity when I had moved 1-3 into a common codebase, extenting it to 6 is not much work. But why, is MDegrainN that much different?

tormento
5th January 2017, 15:00
No problem, I have included 4 and 5 only for curiousity when I had moved 1-3 into a common codebase, extenting it to 6 is not much work. But why, is MDegrainN that much different?

Tried with SMDegrain script. Worst results than with 5.

Just for my information, how is MDegrainN different from native 4 or 5 one?

pinterf
16th January 2017, 16:51
New build.
MvTools2 2.7.11.22 + Depan + DepanEstimate (https://github.com/pinterf/mvtools/releases/tag/2.7.11.22)

MvTools2 2.7.11.22 (20170116)
New: MDegrain6
Mod: MDegrain1-6 SSE4 for 10-16 bit (was: C. 3-5% gain, wasn't bottleneck)

MvTools2 2.7.10.22 (20161228)
fix: YV12 debug info display wrong text placement on chroma planes
(also depans)

This pack has fix for DepanStabilize: removed too sctrict checking for large motion vectors received from depan (false scene change detection)

tormento
17th January 2017, 11:03
new: Mdegrain6

thank you!!!

FranceBB
17th January 2017, 19:15
Thank you!! (Especially for supporting XP! ;) )

pinterf
20th January 2017, 11:16
New build
MvTools2 2.7.12.22 with Depan and DepanEstimate (https://github.com/pinterf/mvtools/releases/tag/2.7.12.22)

MvTools2 2.7.12.22 (20170120)

New: Faster SATD (dct=5..10) 8 bit: updated x264 function selectors, SSE2/4/AVX/AVX2
+10% speed for a whole typical MDegrain3 process on my i7-3770
New: Much faster SATD (dct=5..10) 10-16 bit: SSE2/SSE4 instead of C
+50% speed for a whole typical MDegrain3 process (which is approx half speed of 8 bit)

yup
23rd January 2017, 10:42
pinterf!
:thanks:
I confirm speed up 10% QTGMC script with dct=5.
yup.

DJATOM
31st January 2017, 17:14
Hi, pinterf!
Guess I found a bug. Look at this comparisons
http://diff.pics/sozv19EkovWc/1
http://diff.pics/SjvcumOUdmgo/1
Example script below
LWLibavVideoSource(source="E:\12.mkv").ConvertFromDoubleWidth(bits=10).ConvertBits(16,true)
sup = msuper()
fa = manalyse(sup,isb=false,delta=1,overlap=4,truemotion=false)
fb = manalyse(sup,isb=true,delta=1,overlap=4,truemotion=false)
mdegrain1(sup,fb,fa,thsad=64,thsadc=96)
#ConvertBits(16,true) # ConvertToStacked requires 16 bit
ConvertToStacked()
Those glitches usually appears while some details moving and on the scenecuts.
Also my comrade complained about slightly different colours after Mdeg1 if lsb=true. But It happens not on every source...
I can ask for reproducing example with source if needed.

pinterf
31st January 2017, 17:26
Hi, pinterf!
Guess I found a bug. Look at this comparisons
http://diff.pics/sozv19EkovWc/1
http://diff.pics/SjvcumOUdmgo/1
Example script below

Those glitches usually appears while some details moving and on the scenecuts.
Also my comrade complained about slightly different colours after Mdeg1 if lsb=true. But It happens not on every source...
I can ask for reproducing example with source if needed.
For different colors: as I remember, for lsb=true there is no rounding after summing up the blocks.
(btw: ConvertBits(16) is enough, no need for ",true")
edit:
How did you generate those PNG's? Running the script and viewing the output with ConvertBits(10), ConvertBits(12), ConvertBits(14) and ConvertBits(16) at the beginning?

DJATOM
31st January 2017, 17:46
For different colors: as I remember, for lsb=true there is no rounding after summing up the blocks.
(btw: ConvertBits(16) is enough, no need for ",true")
edit:
How did you generate those PNG's? Running the script and viewing the output with ConvertBits(10), ConvertBits(12), ConvertBits(14) and ConvertBits(16) at the beginning?
Running in Avspmod and previewing the output while changing ConvertBits() params at the beginning.

pinterf
31st January 2017, 17:54
Ok, could you upload a plus minus 5 frames sample around the problematic frame? Thanks

DJATOM
31st January 2017, 18:09
Sent.

kgrabs
1st February 2017, 10:20
It seems like 16 bit output is nerfed for me with block size 4. It just looks like the lsb is a green copy of the msb.
Image: blksize=4 (https://my.mixtape.moe/zvqhlx.png)
Image: blksize=8 (https://my.mixtape.moe/tiujny.png)
It seems to start at version 2.7.7.22, and I'm not really sure what to make of it. It's the 32 bit version btw

pinterf
1st February 2017, 12:22
New build:
MvTools2 2.7.13.22 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.13.22)

2.7.13.22 (20170201)

Fix: MDegrain1-6,N 10-16 bit thSCD scaling
Fix: MVShow: tolerance scaling for 10-16 bits


Thanks for DJATOM for the report. I hope, this addresses your problems.

DJATOM
1st February 2017, 14:46
New build:
MvTools2 2.7.13.22 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.13.22)

2.7.13.22 (20170201)

Fix: MDegrain1-6,N 10-16 bit thSCD scaling
Fix: MVShow: tolerance scaling for 10-16 bits


Thanks for DJATOM for the report. I hope, this addresses your problems.
Yes, It seems you did well. At least no glitches on the video. I'll do "production" encode later and compare it with the source.

edcrfv94
4th February 2017, 17:38
I update 2.7.13.22 from 2.7.0.22d, then AvsPmod show up a Error Window.

super = last.MSuper( levels=1, pel=1, sharp=0)
forward_vectors = MAnalyse(super, blksize=4, levels=1, search=3, searchparam=5, isb=true)
last.MFlow(super,forward_vectors)

AvsPmod Error Window

Traceback (most recent call last):
File "avsp.pyo", line 10451, in OnSliderChanged
File "avsp.pyo", line 13917, in SetVideoStatusText
File "avsp.pyo", line 14066, in GetVideoInfoDict
File "avsp.pyo", line 17256, in FormatTime
TypeError: %d format: a number is required, not float



Also MCaWarpSharp3 "MFlow(super2,forward_vectors)" will make the AvsPmod crash,
###
###
### MCaWarpSharp3()
### :fix halo, chroma bleeding & blurry edges (Sharpener/line enhacer)
###
### (24-11-2011)
###
### By z. ndmn.(zee944) with Did嶪 guidance.
### Optimized by Dogway
### http://forum.doom9.org/showthread.php?t=159248
###
### line enhacer: define (sharpen) blurry edges, or remove ringing.
###
### dependencies: MVTools2, masktools, aWarpSharp[20090619]
###
###
### supsamp [default: 4]
### -------------------
### Interpolation strength. Recommended 4 for
### encoding, 2 for testing. 1 disables it [1...4]
###
###
### post [default: 4]
### -------------------
### Post processing of the sharpened areas for better blending/integration [1...4]
### 1 = no post
### 2 = a little blurring on the sharp new edges...
### 3 = ...or sharpening everywhere else to make the image consistent.
### 4 = or a mix of both
###
###
### PPstr [default: 1.0]
### -------------------
### Strength of the postprocessing
###
###
### fast [default: true]
### -------------------
### Independent to supsamp, this can give a small speed boost to the function.
###
###
### w,h [default: input size]
### -------------------
### Target resize. Internally a clip super sampling is performed. Due to the function being naturally
### slow, if you had plans to resize afterwards it would be a good idea to do it now in this step.
###
###
### Usage:
###
### MCaWarpSharp3(4,4)
###
###
########################################################################


function MCaWarpSharp3(clip source, int "supsamp",int "post", float "PPstr", bool "fast", int "w", int "h"){

w1=source.width()
h1=source.height()

supsamp = default(supsamp, 4) # supsamp=2 recommended for testing, supsamp=4 for encoding.
post = default(post, 4) # mix the warpsharped edges with original footage thru blur and sharpen post processing
str = default(PPstr,1.0) # post processing strength of whatever option you chose
fast = default(fast,true) # enables fast mode, which gives some boost.
w = default(w,w1) # I exposed the size parameters because internally a resize is performed, \
h = default(h,h1) # so if you had a plan on resizing, this is a good chance to do.


# if no supersampling (supsamp=1) -> (thresh=255,blur=3,type=1,depth=8,chroma=4)
# if 4x supersampling (supsamp=4) -> (thresh=192,blur=36,type=1,depth=96,chroma=4)


var=32*pow(supsamp,-2)
w1=w1*supsamp
h1=h1*supsamp

source
sourceSup=LanczosResize(w1,h1,taps=fast?3:4)

WarpedEdges=sourceSup.aWarpSharp2(
\ thresh = int(pow(supsamp,-0.207)*255),
\ blur = 3* int(pow(supsamp,1.7925)),
\ type = 1,depth=8*int(pow(supsamp,1.7925)),chroma=4)

# Getting back to the original shapes with motion compensation to have good and undeformed edges, although still cartoonish look
Interleave(sourceSup,WarpedEdges)

blurredclip=GaussResize(w1*2,h1*2,p=var).GaussResize(w1,h1,p=var)

super = MSuper (blurredclip, levels=1, pel=fast?1:2, sharp=fast?0:2)
super2 = MSuper ( levels=1, pel=fast?1:2, sharp=fast?0:2)
forward_vectors = MAnalyse(super, blksize=4, levels=1, search=3, searchparam=5, isb=true)
MFlow(super2,forward_vectors)

SelectEvery(2,0)
LanczosResize(w,h,taps=fast?3:4)

# Replacing 'bad' edges with 'good' edges on the original image
source = post==1 && (Defined(w) || Defined(h)) ? source.LanczosResize(w,h,taps=fast?3:4) : source
edgemask = source.mt_edge("min/max",U=-128,V=-128).blur(1.0)

Assert ((post >= 1 && post <= 4 ) ? true : false, chr(10) + "'post' have not a correct value! [1,2,3,4]" + chr(10))
post = (post==1) ? mt_merge(source,last,edgemask,luma=true)
\ : (post==2) ? mt_merge(Blur(min(str*0.5,1.58)),edgemask,luma=true)
\ : (post==3) ? mt_merge(LSFmod(defaults=fast?"fast":"slow",strength=int(str*20),edgemode=0,soothe=true,ss_x=1.0,ss_y=1.0),last,edgemask,luma=true)
\ : (post==4) ? mt_merge(LSFmod(defaults=fast?"fast":"slow",strength=int(str*20),edgemode=0,soothe=true,ss_x=1.0,ss_y=1.0),Blur(min(str*0.5,1.58)),edgemask,luma=true)
\ : blankclip(source, width=width, height=120).SubTitle("post = " + string(post),text_color=$FFFFFF,font="COURIER NEW",size=12,x=320,y=90)

return post}

pinterf
4th February 2017, 18:29
Is it only MFlow that is problematic for you?
Which Avisynth version are you using?
Does the problem occur when you directly encode e.g. for x264, or run the script with AvsMeter?

edcrfv94
4th February 2017, 19:42
Is it only MFlow that is problematic for you?
Which Avisynth version are you using?
Does the problem occur when you directly encode e.g. for x264, or run the script with AvsMeter?

AVSMeter248:
colorbars(width = 1920, height = 1080, pixel_type = "yv12").killaudio().assumefps(25, 1)
MCaWarpSharp3()

Avisynth 2.6.0 ST 32-bit

AviSynth 2.60, build:Mar 32 2015 [16:38:54] (2.6.0.6)

Exceotion 0xC0000005 [STATUS_ACCESS_VIOLATION]
Module: C:\Program Files (x86)\AviSynth+\plugins\mvtools2.dll
Address: 0x60CF8248


avsplus-r1858-pfmod 32bit

AviSynth+ 0.1 (r1858, MT-pfmod, i386) (0.1.0.0)

Exception 0xC0000005 [STATUS_ACCESS_VIOLATION]
Module: C:\Program Files (x86)\AviSynth+\plugins+\mvtools2.dll
Address: 0x5E8B8248

avsplus-r1858-pfmod 64bit

AviSynth+ 0.1 (r1858, MT-pfmod, x86_64) (0.1.0.0)

Exception 0xC0000005 [STATUS_ACCESS_VIOLATION]
Module: C:\Program Files (x86)\AviSynth+\plugins64+\mvtools2.dll
Address: 0x000007FEE4196547

If only MFlow.
AvsPmod64 avsplus-r1858-pfmod 64bit error.
AVSMeter248 no error.

colorbars(width = 1920, height = 1080, pixel_type = "yv12").killaudio().assumefps(25, 1)
super = last.MSuper( levels=1, pel=1, sharp=0)
forward_vectors = MAnalyse(super, blksize=4, levels=1, search=3, searchparam=5, isb=true)
last.MFlow(super,forward_vectors)

Groucho2004
4th February 2017, 19:48
Exceotion 0xC0000005 [STATUS_ACCESS_VIOLATION]
Module: C:\Program Files (x86)\AviSynth+\plugins64+\mvtools2.dll
Address: 0x000007FEE4196547
I'm just curious how you got that typo in there. Did you type the error message?

edcrfv94
4th February 2017, 19:58
I'm just curious how you got that typo in there. Did you type the error message?

Ye, because I can not find the log file.
"AVSMeter.exe" "test.avs" -log

Groucho2004
4th February 2017, 20:01
Ye, because I can not find the log file.Should be in the same directory as the script unless you specified a different directory in the INI file.

pinterf
4th February 2017, 20:16
Could not reproduce. First I thought that it is a VS2015 redistributable problem?
AvsMeter -avsinfo can tell it (or avsmeter64)
One note: plugins64+ is for avs+ only filters (basically that ship with avisynth+), plugins64 is for the generic 64 bit filters.
And as a second note, you could refresh your avisynth+ version, there were huge changes since 1858, now we are at v2420, check https://github.com/pinterf/AviSynthPlus/releases

real.finder
5th February 2017, 01:45
colorbars(width = 1920, height = 1080, pixel_type = "yv12").killaudio().assumefps(25, 1)
MCaWarpSharp3()


with 2015.02.20 avs mt by SEt I can reproduce


Traceback (most recent call last):
File "avsp.pyo", line 9061, in OnMenuVideoToggle
File "avsp.pyo", line 13855, in ShowVideoFrame
File "avisynth.pyo", line 462, in GetFrame
WindowsError: exception: access violation reading 0x12F85000


but this work fine


colorbars(width = 1920, height = 1080, pixel_type = "yv12").killaudio().assumefps(25, 1)
super = last.MSuper( levels=1, pel=1, sharp=0)
forward_vectors = MAnalyse(super, blksize=4, levels=1, search=3, searchparam=5, isb=true)
last.MFlow(super,forward_vectors)

pinterf
5th February 2017, 16:26
Thanks, reproduced. Now it's my turn.

Edit:
I've got it.
Occurs when vectors are resized with a big ratio, e.g. 4x size.
The bug is also present in the original 2.5.11.22.
If no problem was experienced, it was only pure luck.
Memory access happens beyond the allocated memory area of vectors.
Fix in progress.

Reel.Deel
5th February 2017, 18:10
I think I found another bug? Don't know if it's related to the problem above but with the following script I get:

Avisynth read error:
MVTools: vector clip is too small (corrupted?)

Tested with the latest 32/64-bit AVS+, MVTools, and VirtualDubFilterMod. Here's the sample clip: https://www.dropbox.com/s/a51vkbw4vklz3d1/Sample_SD.avi?dl=1
The script is a broken down YFRC (http://avisynth.nl/index.php/YFRC). IIRC this script use to work correctly with v2.6.0.5.

FFVideoSource("Sample_SD.avi") #720x480, 18FPS

clp_Super = MSuper(last.blur(1), chroma=true, pel=2)
fps_num = FrameRateNumerator(last)*2
fps_den = FrameRateDenominator(last)

bw1_vec116 = clp_Super.MAnalyse(blksize=16, blksizeV=16, isb=true , chroma=false, search=1, searchparam=1, truemotion=true, lambda=2000, global=true, dct=0, divide=2)
fw1_vec116 = clp_Super.MAnalyse(blksize=16, blksizeV=16, isb=false, chroma=false, search=1, searchparam=1, truemotion=true, lambda=2000, global=true, dct=0, divide=2)

FPSconverted16 = last.MFlowFps(last.MSuper(levels=1), bw1_vec116, fw1_vec116, num=fps_num, den=fps_den, blend=false, mask=0)

FPSconverted16

pinterf
5th February 2017, 18:44
I think I found another bug? Don't know if it's related to the problem above but with the following script I get:
IIRC this script use to work correctly with v2.6.0.5.
[/CODE]
Tried all variants, 2.6.0.5 reports this error too. But it seems that the 2.5 versions are silent.
edit:
silent, because an internal return value is not checked for anything

Present (2.6/2.7 line)
const int hs_i32 = header_size / sizeof(int);
pMv += hs_i32; // go to data - v1.8.1
data_size -= hs_i32;
const bool ok_flag = FakeGroupOfPlanes::Update(pMv, data_size); // fixed a bug with lost frames
if (! ok_flag)
{
env->ThrowError("MVTools: vector clip is too small (corrupted?)");
}


2.5.11.22:
pMv += _headerSize/sizeof(int); // go to data - v1.8.1
// FakeGroupOfPlanes::Update(reinterpret_cast<const int*>(fn->GetReadPtr()));// fixed a bug with lost frames
FakeGroupOfPlanes::Update(pMv);// fixed a bug with lost frames

pinterf
6th February 2017, 16:57
New build:
MvTools2 2.7.14.22 (20170206) with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.14.22)


Fix: MAnalyze divide=2 showed "vector clip is too small", inherited from 2.6.0.5, sanity check was done but length to check was not filled for divideextra data
Fix: MFlow access violation in internal mv resizer when resizing factor was big (MCaWarpSharp3 4x supersampling case), bug introduced in upstream 2.5.11.22

Thanks for edcrfv94 and Reel.Deel for the reports.

edcrfv94
6th February 2017, 22:58
AvsPmod 64bit There is an error message, but can still be used no crash.
Traceback (most recent call last):
File "avsp.pyo", line 11690, in OnFocusVideoWindow
File "avsp.pyo", line 13917, in SetVideoStatusText
File "avsp.pyo", line 14066, in GetVideoInfoDict
File "avsp.pyo", line 17256, in FormatTime
TypeError: %d format: a number is required, not float


Thank

Reel.Deel
7th February 2017, 14:33
New build:
MvTools2 2.7.14.22 (20170206) with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.14.22)
[LIST]


Thanks for the quick fix!

Selur
11th February 2017, 19:41
@pinterf: using 'MvTools2 2.7.14.22 (20170206)' on a Xeon E5640 I get:
Couldn't import -1 (1): le to load "C:\PROGRA~1\Hybrid\AVISYN~1\mvtools2.dll", error=0xc1 (using 32bit Avisynth MT 2.6)
Works fine on my i7-4770k system (both Win10 pro 64bit).
-> some assembler error?

script I used:
SetMemoryMax(768)
SetMTMode(2,16) # change MT mode
LoadPlugin("C:\PROGRA~1\Hybrid\AVISYN~1\LoadDll.dll")
LoadPlugin("C:\PROGRA~1\Hybrid\AVISYN~1\DGDecode.dll")
LoadPlugin("C:\PROGRA~1\Hybrid\AVISYN~1\AddGrainC.dll")
LoadPlugin("C:\PROGRA~1\Hybrid\AVISYN~1\dfttest.dll")
LoadPlugin("C:\PROGRA~1\Hybrid\AVISYN~1\EEDI2.dll")
LoadPlugin("C:\PROGRA~1\Hybrid\AVISYN~1\eedi3.dll")
LoadPlugin("C:\PROGRA~1\Hybrid\AVISYN~1\FFT3DFilter.dll")
LoadPlugin("C:\PROGRA~1\Hybrid\AVISYN~1\mt_masktools-26.dll")
LoadPlugin("C:\PROGRA~1\Hybrid\AVISYN~1\mvtools2.dll")
LoadPlugin("C:\PROGRA~1\Hybrid\AVISYN~1\nnedi.dll")
LoadPlugin("C:\PROGRA~1\Hybrid\AVISYN~1\nnedi2.dll")
LoadPlugin("C:\PROGRA~1\Hybrid\AVISYN~1\SSE2Tools.dll")
LoadPlugin("C:\PROGRA~1\Hybrid\AVISYN~1\TDeint.dll")
LoadPlugin("C:\PROGRA~1\Hybrid\AVISYN~1\VerticalCleanerSSE2.dll")
LoadPlugin("C:\PROGRA~1\Hybrid\AVISYN~1\nnedi3.dll")
LoadPlugin("C:\PROGRA~1\Hybrid\AVISYN~1\RgTools.dll")
LoadCPlugin("C:\PROGRA~1\Hybrid\AVISYN~1\yadif.dll")
LoadDll("C:\PROGRA~1\Hybrid\AVISYN~1\fftw3.dll")
LoadDll("C:\PROGRA~1\Hybrid\AVISYN~1\LIBFFT~1.DLL")
Import("C:\Program Files\Hybrid\avisynthPlugins\QTGMC.avsi")
Import("C:\Program Files\Hybrid\avisynthPlugins\SMDegrain v.3.1.2d.avsi")
# input luminance scale tv
MPEG2Source(d2v="mpg_5cb0dee9abb9613ab109ab931493183c_28745.d2v")
# deinterlacing
AssumeBFF()
QTGMC(Preset="Fast", ediThreads=2)
SelectEven()
# filtering
return last

DJATOM
11th February 2017, 20:12
0xc1

I suppose your server has outdated vs2015 runtime or it does not installed at all. Please check that first.

Groucho2004
11th February 2017, 21:51
Couldn't import -1 (1): le to load "C:\PROGRA~1\Hybrid\AVISYN~1\mvtools2.dll", error=0xc1Probably what DJATOM suspects, you can also try to check with Dependency Walker and/or AVSMeter ("-avsinfo").

Selur
11th February 2017, 22:44
@Groucho2004: 'AVSMeter -avsinfo' only reports:
AVSMeter 2.4.9 (x86) - Copyright (c) 2012-2017, Groucho2004

VersionString: AviSynth 2.60, build:Feb 20 2015 [03:16:45]
VersionNumber: 2.60
File version: 2.6.0.5
Interface Version: 6
Multi-threading support: Yes
Linker/compiler version: 12.0
Avisynth.dll location: C:\Program Files\Hybrid\avisynthPlugins\avisynth.dll
Avisynth.dll time stamp: 2015-02-20, 00:18:42 (UTC)
but I'm probably missing vs2015 runtime

Selur
11th February 2017, 22:52
-> Thanks that worked. :) (adding dlls from latest 2015 runteim)

StainlessS
12th February 2017, 23:02
Current MvTool problem.


Function Test(clip c, float "bblur", float "csharp",Bool "ShowBlur") {
bblur=default(bblur, 0.6) csharp = default(csharp, 0.6) ShowBlur=Default(ShowBlur,False)
bs=16 hpad=bs vpad=bs
c2=c.blur(bblur)
softsup = c2.MSuper(hpad=hpad,vpad=vpad)
sharpsup= c.sharpen(csharp).MSuper(hpad=hpad,vpad=vpad,levels=1)
bv = MAnalyse(softsup,isb=true ,delta=1,blksize=BS,overlap=BS/2)
fv = MAnalyse(softsup,isb=false,delta=1,blksize=BS,overlap=BS/2)
BlurC=(ShowBlur)?c2.BlankClip(color=$FF0000):c2
BlurC.MDegrain1(sharpsup, bv,fv,thSAD=400)
return(last)
}

FN="F:\V\Cabaret.avi"
AviSource(FN)
return Test(ShowBlur=True)


Above intent to show areas in Bright Red where bv and fv do not coincide.
Exhibiting similar problems to those displayed earlier in thread for MFlowFPS/MBlockFPS, here:- https://forum.doom9.org/showthread.php?p=1785795#post1785795

And result here (Displaying red line down RHS and Bottom border):
https://s20.postimg.cc/5xle3li7x/Red_zpsakt6koqv.png (https://postimg.cc/image/fuwewnptl/)

EDIT: Hpad and VPad set to 0, make no difference.

pinterf
12th February 2017, 23:21
Is clip width and height divisible by 16?

StainlessS
12th February 2017, 23:28
Well, em, no!

Added this

FN="F:\V\Cabaret.avi"
AviSource(FN)
W=Width/16*16
H=Height/16*16
Crop(0,0,W,h)
return Test(ShowBlur=True)


Problem gone.
Guess I should have checked before squealing. (busy doing something when it bit me, so threw together quick test).
EDIT: Still, twould be nice if it did not do that.

StainlessS
14th February 2017, 11:45
Hi Pinterf,
It probably dont matter too much but you are using [EDIT: code from] old version Info.h, was refactored by IanB a few years back.
Old version was very slow (also suffered from a couple of bugs, one for RGB [which is not implemented in MVTools] and
one where characters above 127 were not printed correctly [out of array bounds, did not check if this is the case with your implementation]). [EDIT: + print out of frame crashing bug.]

Here link to IanB refactor:- http://avisynth2.cvs.sourceforge.net/viewvc/avisynth2/avisynth/src/core/info.h?revision=1.7&view=markup

And thread that prompted refactor:- https://forum.doom9.org/showthread.php?t=156888&highlight=DDigit

EDIT: And here a companion to refactored Info.h, InfoF.h

/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software

Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
// ------------------------------------------------------------------
// @ http://forum.doom9.org/showthread.php?t=156888
// ------------------------------------------------------------------
// InfoF.h, by StainlessS @ Doom9.org, 1st June 2011.
//
// A companion to Info.h, provides formatted printing via embedded control codes.
// For use with the April 17 2011 (and above) edition of Info.h by IanB.
// Obtainable here (look for 'Info.h'):-
//
// http://avisynth2.cvs.sourceforge.net/viewvc/avisynth2/avisynth/src/core/
//
// ------------------------------------------------------------------
// Formatting control codes:-
// '\n', Newline, positioning cursor 1 line down and at left edge of screen.
// '\r', Newline Special, moves 1 line down and positions cursor at on-entry X position.
// '\b', Backspace, obvious, not sure how useful this will be.
// '\f', Forward Space, again obvious, re-uses formfeed code for this. Again, maybe not so useful.
// '\t', Tab, @ character positions, every 4 characters.(relative screen LHS).
// ------------------------------------------------------------------
// SJ, 3 June 2011, minor mod, reduced pointer swaps by using se in outer loop.
// ------------------------------------------------------------------

void __stdcall DrawFStringPlanar(PVideoFrame &dst,int x,int y,const char *s,bool pix = true)
{ // Draw formatted string at pixel or character coords, pix == false = character coords
if(pix == false) {x *= 10; y *= 20;} // To Chars
int in_x = x; // REM x for '\r'
const unsigned char *se=(unsigned char*)s; // unsigned
while(*se) { // while, some to do
int n;
for(s=(char*)se; n = *se, n>=' ' && n <= 223; ++se); // Find end+1 of printable
int len = (char*)se - s; // Len of printable
if (len) { // Some to print
DrawStringPlanar(dst,x,y,s,len); // do the biz
x += len * 10; // update x coord
} else { // Ctrl code OR nonsense;
if(n == '\n') {
x = 0; y+=20; // Newline, down 1, LHS
} else if (n == '\r') {
x = in_x; y +=20; // Newline Special, Down 1, orig x coord
} else if(n == '\b') {
x -= 10; // Backward Space
} else if (n == '\f') {
x += 10; // Forward Space
} else if (n == '\t') {
x+= ((4*10)-(x%(4*10))); // H-Tab (step 4)
}
++se; // skip ctrl code (and unknowns, outer loop detects nul sentinel)
}
}
}

void __stdcall DrawFStrPlanar(PVideoFrame &dst,int x,int y,const char *s)
{ // Formatted Print @ character coords
DrawFStringPlanar(dst,x,y,s,false);
}

void __stdcall DrawFStringYUY2(PVideoFrame &dst,int x,int y,const char *s,bool pix = true)
{ // Draw formatted string at pixel or character coords, pix == false = character coords
if(pix == false) {x *= 10; y *= 20;} // To Chars
int in_x = x; // REM x for '\r'
const unsigned char *se=(unsigned char*)s; // unsigned
while(*se) { // while, some to do
int n;
for(s=(char*)se; n = *se, n>=' ' && n <= 223; ++se); // Find end+1 of printable
int len = (char*)se - s; // Len of printable
if (len) { // Some to print
DrawStringYUY2(dst,x,y,s,len); // do the biz
x += len * 10; // update x coord
} else { // Ctrl code OR nonsense;
if(n == '\n') {
x = 0; y+=20; // Newline, down 1, LHS
} else if (n == '\r') {
x = in_x; y +=20; // Newline Special, Down 1, orig x coord
} else if(n == '\b') {
x -= 10; // Backward Space
} else if (n == '\f') {
x += 10; // Forward Space
} else if (n == '\t') {
x+= ((4*10)-(x%(4*10))); // H-Tab (step 4)
}
++se; // skip ctrl code (and unknowns, outer loop detects nul sentinel)
}
}
}

void __stdcall DrawFStrYUY2(PVideoFrame &dst,int x,int y,const char *s)
{ // Formatted Print @ character coords
DrawFStringYUY2(dst,x,y,s,false);
}

void __stdcall DrawFStringRGB32(PVideoFrame &dst,int x,int y,const char *s,bool pix = true)
{ // Draw formatted string at pixel or character coords, pix == false = character coords
if(pix == false) {x *= 10; y *= 20;} // To Chars
int in_x = x; // REM x for '\r'
const unsigned char *se=(unsigned char*)s; // unsigned
while(*se) { // while, some to do
int n;
for(s=(char*)se; n = *se, n>=' ' && n <= 223; ++se); // Find end+1 of printable
int len = (char*)se - s; // Len of printable
if (len) { // Some to print
DrawStringRGB32(dst,x,y,s,len); // do the biz
x += len * 10; // update x coord
} else { // Ctrl code OR nonsense;
if(n == '\n') {
x = 0; y+=20; // Newline, down 1, LHS
} else if (n == '\r') {
x = in_x; y +=20; // Newline Special, Down 1, orig x coord
} else if(n == '\b') {
x -= 10; // Backward Space
} else if (n == '\f') {
x += 10; // Forward Space
} else if (n == '\t') {
x+= ((4*10)-(x%(4*10))); // H-Tab (step 4)
}
++se; // skip ctrl code (and unknowns, outer loop detects nul sentinel)
}
}
}

void __stdcall DrawFStrRGB32(PVideoFrame &dst,int x,int y,const char *s)
{ // Formatted Print @ character coords
DrawFStringRGB32(dst,x,y,s,false);
}

void __stdcall DrawFStringRGB24(PVideoFrame &dst,int x,int y,const char *s,bool pix = true)
{ // Draw formatted string at pixel or character coords, pix == false = character coords
if(pix == false) {x *= 10; y *= 20;} // To Chars
int in_x = x; // REM x for '\r'
const unsigned char *se=(unsigned char*)s; // unsigned
while(*se) { // while, some to do
int n;
for(s=(char*)se; n = *se, n>=' ' && n <= 223; ++se); // Find end+1 of printable
int len = (char*)se - s; // Len of printable
if (len) { // Some to print
DrawStringRGB24(dst,x,y,s,len); // do the biz
x += len * 10; // update x coord
} else { // Ctrl code OR nonsense;
if(n == '\n') {
x = 0; y+=20; // Newline, down 1, LHS
} else if (n == '\r') {
x = in_x; y +=20; // Newline Special, Down 1, orig x coord
} else if(n == '\b') {
x -= 10; // Backward Space
} else if (n == '\f') {
x += 10; // Forward Space
} else if (n == '\t') {
x+= ((4*10)-(x%(4*10))); // H-Tab (step 4)
}
++se; // skip ctrl code (and unknowns, outer loop detects nul sentinel)
}
}
}

void __stdcall DrawFStrRGB24(PVideoFrame &dst,int x,int y,const char *s)
{ // Formatted Print @ character coords
DrawFStringRGB24(dst,x,y,s,false);
}

EDIT: Above could probably do with a guard to prevent multiple #include's.

CPP Snippet client for formatted print, from this thread:- https://forum.doom9.org/showthread.php?t=163082

void __stdcall INTERNALNAME::DrawFStr(PVideoFrame &dst,int x,int y,const char *format, ...)
{
// This member function added in v0.2, adds BOTH string and screen/layout formatting,
// eg '%f' for string and '\n' for screen/layout.

// Firstly, string formatting, into the buffer implemented in the class instance, formatted_buf[FMT_BUFSZ].
va_list args;
va_start(args, format);
_vsnprintf(formatted_buf,FMT_BUFSZ-1, format, args);
va_end(args);
// The above allows you to use this member function in the same way as eg printf("test=%d",i) ie DrawFStr(dst,x,y,"test=%d",i)

// The DrawFStrXXX fn's are implemented in the InfoF.h file and provide screen/layout formatting, eg '\'n and '\t'.
// As string formatting has already been done above (eg floats etc turned to character strings), and the below
// DrawFStrXXX functions provide screen/layout formatting, so full formatting is achieved on the video frame.
//
// Formatting control codes (as provided by InfoF.h):-
// '\n', Newline, positioning cursor 1 line down and at left edge of screen.
// '\r', Newline Special, moves 1 line down and positions cursor at on-entry X position.
// '\b', Backspace, obvious, not sure how useful this will be.
// '\f', Forward Space, again obvious, re-uses formfeed code for this. Again, maybe not so useful.
// '\t', Tab, @ character positions, every 4 characters.(relative screen LHS).
//
if(vi.IsPlanar()) DrawFStrPlanar(dst,x,y,formatted_buf);
else if(vi.IsYUY2()) DrawFStrYUY2(dst,x,y,formatted_buf);
else if(vi.IsRGB32()) DrawFStrRGB32(dst,x,y,formatted_buf);
else if(vi.IsRGB24()) DrawFStrRGB24(dst,x,y,formatted_buf);
}


EDIT: Looks to me like your implementation of Info.h also has old bug where printing off bottom of frame will result in crash (if small frame).

Also looks like it suffers from the characters above 127 not printing properly bug (signed char to int, -ve font array index).

fix internally in draw character funcs (will correct any errors with -ve index by client caller)

// Client caller
int num = s[si]; // or *s;
num -= ' '; // Conv font ix, eg chr(137) [Copyright] could be -ve if s is pointer to signed char.

// draw func
num &= 0xFF; // Ensure +ve char (Fix EXT ASCII bug), assumes twos compliment arithmetic (possible problem if compiled on non PC m/c).
if(num >= 192)
num = 0; // SPACE index (invalid character index, was out of font array)

pinterf
15th February 2017, 07:43
Thanks, I'll check it. All I did with debug display was to make it work for high bit depth. And perhaps writing not only on Y. If I remember correctly.

StainlessS
17th February 2017, 01:46
Hi Pinterf,

Excuse a dumb question, but do you have any recommendation as to which MMask (or whatever) to use to measure 'Goodness' of produced
vectors ? I've started a script to test and log results by throwing all variations of args at MSuper/MAnalyse, and for delta 1 to 3 (maybe more).
Just wanted to see if I could find good general settings by measurement. figured I'de find some good measure at some point but not sure that
I can, so I'm currently stuck not knowing what direction to take.
I thought maybe occlusion mask might be a start but we wild mask frames on black frame sequence, so seems not.
Is there any way of combining masks to estimate goodness of vectors, via AverageLuma or whatever, any response would be appreciated.

feisty2
17th February 2017, 05:24
SAD mask (kind=1)

StainlessS
17th February 2017, 05:37
Thanks Feisty, you are a sweetie :)

pinterf
17th February 2017, 09:48
I like when the questions get answered without me. btw masks, I think I still have some work on the mask side for 10+ bits. Are masks 8 bit in the vapoursynth mvtools version?

feisty2
17th February 2017, 10:33
there's still no high bit depth support for MMask in jackoneill's branch, but I got my 32bits floating point version of MMask in my branch.
https://github.com/IFeelBloated/vapoursynth-mvtools-sf/blob/master/src/MVMask.cpp

real.finder
10th March 2017, 00:45
I think there are something related to mvtools here https://forum.doom9.org/showpost.php?p=1800104&postcount=2286

cuz QTGMC(SLMode=0,tv_range=false,tr1=0,tr2=0)

will be ok in all bit depth

pinterf
10th March 2017, 10:34
I think there are something related to mvtools here https://forum.doom9.org/showpost.php?p=1800104&postcount=2286

cuz QTGMC(SLMode=0,tv_range=false,tr1=0,tr2=0)

will be ok in all bit depth
What difference should I recognize? Yes, there are minor differences, but only when I'm looking at the same frames with the alt-tab method and pixel-peeping. I'm testing with a Hi8 DV-AVI source.

real.finder
10th March 2017, 19:46
What difference should I recognize? Yes, there are minor differences, but only when I'm looking at the same frames with the alt-tab method and pixel-peeping. I'm testing with a Hi8 DV-AVI source.

it look sharp and somehow with some artefact

real.finder
11th March 2017, 07:28
even in SMDegrain, so I think there are something in MDegrainX

and something else, can you add error message for not use lsb with native high bits?

pinterf
12th March 2017, 18:54
Can you send me a short clip sample where the differences are well visible? It would save me time to have a good test case, thank you in advance

real.finder
12th March 2017, 23:23
Can you send me a short clip sample where the differences are well visible? It would save me time to have a good test case, thank you in advance

done in pm :)

pinterf
17th March 2017, 09:09
New release with an important fix for 10+ bits
MvTools2 2.7.15.22 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.15.22)

MvTools2 2.7.15.22 (20170316)
Fix: 16 bit SAD for non-AVX code path
Misc: MDegrain1-6: add error on lsb_flag=true for non-8 bit sources

MysteryX
28th March 2017, 16:50
Here's a bug with MVTools2 with YV24.

Here's what it looks like on a still video, but I don't think it matters which source you use.
https://s1.postimg.org/fffg0qn0b/mvtools2bug.png (https://postimg.org/image/fffg0qn0b/)


AviSource("Preview.avi")
ConvertToYV24()
jm_fps(60)


function jm_fps(clip source, float "fps")
{
fps = default(fps, 25.000)
fps_num = int(fps * 1000)
fps_den = 1000

prefiltered = RemoveGrain(source, 22)
super = MSuper(source, hpad = 16, vpad = 16, levels = 1) # one level is enough for MRecalculate
superfilt = MSuper(prefiltered, hpad = 16, vpad = 16) # all levels for MAnalyse
backward = MAnalyse(superfilt, isb = true, blksize = 16, overlap = 4, search = 3, dct = 0)
forward = MAnalyse(superfilt, isb = false, blksize = 16, overlap = 4, search = 3, dct = 0)
forward_re = MRecalculate(super, forward, blksize = 8, overlap = 2, thSAD = 100)
backward_re = MRecalculate(super, backward, blksize = 8, overlap = 2, thSAD = 100)
out = MFlowFps(source, super, backward_re, forward_re, num = fps_num, den = fps_den, blend = false, ml = 200, mask = 2)

return out
}

pinterf
29th March 2017, 08:07
Thanks, reproduced. YV16 and YV24 both have artifacts
EDIT:
Could you send me a link to your source?
Because your script produces the same artifacts for all colorspaces YV12, YUY2, YV24 for me.
Checked YV12 and YUY2 with older mvtools versions 2.5.11.3, 2.5.11.22, 2.6.0.5 and they are also ugly.

MysteryX
29th March 2017, 18:07
I often use this source for testing; with LSMASHSource
https://www.spiritualselftransformation.com/files/media-encoder-old.mpg

pinterf
30th March 2017, 08:12
I often use this source for testing; with LSMASHSource
https://www.spiritualselftransformation.com/files/media-encoder-old.mpg
Thanks. Still I can see no differences between YV12/YV24 or even YUV444P16.
Are you using 2.7.15.22?
If so, what processor capabilities do you have? (Different code paths?)

MysteryX
1st April 2017, 04:16
Thanks. Still I can see no differences between YV12/YV24 or even YUV444P16.
Are you using 2.7.15.22?
If so, what processor capabilities do you have? (Different code paths?)
I'll be traveling until the 12th. I can do some more testing later if you haven't figured it out yet.

Motenai Yoda
9th April 2017, 23:03
depanestimate (or depan) parameters have been changed? coz scene change detection looks broken to me

It isn't fixed yet?

real.finder
9th April 2017, 23:34
It isn't fixed yet?

it is


Depan 2.13.1.2 (20161228)
Fix: DepanStabilize: removed too strict checking for large motion vectors received from depan
that resulted in like scene change

Motenai Yoda
10th April 2017, 00:50
it is

I got it,
but what I was/am experiencing is a lot of scene-changes not detected...

VS_Fan
10th April 2017, 07:29
I got it,
but what I was/am experiencing is a lot of scene-changes not detected...Have you tried using lower values for the thSDC2 parameter?
This is what I usually do: The default for thSCD2 is 130 equivalent to the 51% of blocks changed. Try lower values in steps of 8, which corresponds approximately to steps of 3%: to 128, 120, 112, etc.

You can use showSAD parameter of the mShow function to estimate both thSCD1 & thSCD2 values:
return mshow(super, vectors, showsad=True, thSCD1=400, thSCD2=112, sil=1)
After determining the appropriate values of thSCDx paramenters, you can use the info=True parameter of the mDepan Function, to refine them more precisely:
globalmotion = mDepan(pf, vectors, zoom=True, pixaspect=1.0, thSCD1=400, thSCD2=112, info=True, error=60.0, wrong=40.0)
return globalmotion
BTW: error and wrong parameters of mDepan can be raised a bit from the defaults to make it more tolerant to big movements that could otherwise reset the motion compensation as if it were due to Scene Change

Finally, you can use the info=True parameter in the DePanStabilize function to verify the results.

And don't forget to comment out the whole mShow function and set to False the showsad and info parameters

Motenai Yoda
10th April 2017, 20:55
I'm not using mdepan but depanestimate

s = 8
stab_reference = removegrain(4,-1,-1).mt_edge(mode="min/max",U=-128,V=-128)
data = depanestimate(stab_reference,trust=2.0,dxmax=s,dymax=s,stab=12,zoommax=1.0)
DePanStabilize(cutoff=1.0,data=data,dxmax=s,dymax=s,zoommax=1.0,rotmax=0.0,mirror=15,blur=30,method=1,subpixel=2)

pinterf
11th April 2017, 05:57
Ok, I'll make a comparison with this script

MysteryX
15th April 2017, 02:37
Thanks. Still I can see no differences between YV12/YV24 or even YUV444P16.
Are you using 2.7.15.22?
Yes


If so, what processor capabilities do you have? (Different code paths?)
MMX2 SSE2Fast SSSE3 SSE4.2 AVX

This is the script I use. I am unable to see artifacts in YV12 and am unable to get good results in YV24. Also, single-threaded gives only slight artifacts while Prefetch(4) gives much stronger artifacts, so there is some multi-threading memory issue.

LWLibavVideoSource("Input.mpg", cache=False, threads=1)
ConvertToYV24()
jm_fps(60)
Prefetch(4)

pinterf
15th April 2017, 08:34
Same processor features for me, but to be sure I have run the script on AVX2 simulator, and w/o AVX and there was no issue at all.

Still something is different.

Script (with the current variant of jm_fps)
LWLibavVideoSource("media-encoder-old.mpg", cache=False, threads=1)
ConvertToYV24()
jm_fps(60)
Prefetch(4)
function jm_fps(clip source, float "fps")
{
fps = default(fps, 25.000)
fps_num = int(fps * 1000)
fps_den = 1000

prefiltered = source.IsYUY2 ? RemoveGrain(source.ConvertToYV16(), 22).ConvertToYUY2() : RemoveGrain(source, 22)
super = MSuper(source, hpad = 16, vpad = 16, levels = 1) # one level is enough for MRecalculate
superfilt = MSuper(prefiltered, hpad = 16, vpad = 16) # all levels for MAnalyse
backward = MAnalyse(superfilt, isb = true, blksize = 16, overlap = 4, search = 3, dct = 0)
forward = MAnalyse(superfilt, isb = false, blksize = 16, overlap = 4, search = 3, dct = 0)

forward_re = MRecalculate(super, forward, blksize = 8, overlap = 2, thSAD = 100)
backward_re = MRecalculate(super, backward, blksize = 8, overlap = 2, thSAD = 100)
out = MFlowFps(source, super, backward_re, forward_re, num = fps_num, den = fps_den, blend = false, ml = 200, mask = 2)
return out
}
Clip: the one you have provided (352x288)
Win7 Prof
MvTools2 2.7.15.22
RgTools 0.95
Avs+ r2455 (checked both x86 and x64)
libfftw3f-3.dll: 3.3.5

Could you please start minimizing this script until the issue is still there? Or modify parameters (e.g. other dct setting, eliminate RemoveGrain, and changing blocksize from 16/8 to 32/16) or change LibAvVideoSource to ffms2? Thanks in advance.

MysteryX
15th April 2017, 16:53
Interesting. It is RemoveGrain.dll that fails. If I remove it, then it works.

pinterf
15th April 2017, 20:31
Good. Time to kill those plugins that have already replacement. Then I'm not debugging any further.

MysteryX
19th April 2017, 19:45
Good. Time to kill those plugins that have already replacement. Then I'm not debugging any further.
What could RemoveGrain be replaced with to work in YV24?

Reel.Deel
19th April 2017, 19:47
What could RemoveGrain be replaced with to work in YV24?

RgTools (https://github.com/pinterf/RgTools/releases)

MysteryX
20th April 2017, 23:44
MvTools.MMask doesn't work in 16-bit

Here's what I get
https://s10.postimg.org/uew8whaud/MMask_Bug.png (https://postimg.org/image/uew8whaud/)

You can use the FrameRateConverter (https://forum.doom9.org/showthread.php?p=1804492#post1804492) code to test.

MysteryX
21st April 2017, 22:27
Also, MMask leaves junk data in unused planes. It might be good to avoid that.

pinterf
22nd April 2017, 08:26
Yes, it is a mask, not something for watching

MysteryX
22nd April 2017, 15:35
Sometimes it's good to preview the mask visually. Why doesn't it just use a Y8 clip? Are the other planes really unused, or are they applied on the chroma planes? Just want to be sure the random data isn't affecting my code.

pinterf
22nd April 2017, 16:55
Y8 exists since avs 2.6 and mvtools was a 2.5 plugin

pinterf
23rd April 2017, 09:39
New release
MvTools2 2.7.16.22 (https://github.com/pinterf/mvtools/releases/tag/2.7.16.22)

Change log
- 2.7.16.22 (20170423)
Fix: MMask 10-16 bits
Fix: MRecalculate 14-16 bits passed nSCD1=999999 internally which caused overflow (scene change problems later)
Fix is done by clamping SCD1 to 8*8*(255-0) (maximum value of sum of SADs on a 8x8 block)
Misc: MDegrainX 8 bits: internal 16 bit buffer to 8 bits: SSE2

MysteryX
23rd April 2017, 14:17
Thanks! There were quite a lot of bugs with 16-bit here and in masktools2

MysteryX
23rd April 2017, 17:52
Y8 exists since avs 2.6 and mvtools was a 2.5 plugin

Can you confirm whether the other planes are unused?

Can I convert the mask to Y8 and get the same result, but with lower mask processing cost? I tried and the mask didn't seem to get applied. This could be supported without breaking old code.

MysteryX
23rd April 2017, 19:18
Why is there such a difference between the masks generated in YV12 and YV24?


EM = MaskSAD > 0 ? C.MMask(bak, ml=MaskSAD, kind=1) : BlankClip(C) # kind=SAD
EMfwd = MaskSAD > 0 ? C.MMask(fwd, ml=MaskSAD, kind=1) : EM # kind=temporal blending
EMfwd = FrameDouble ? EMfwd.DeleteFrame(0) : EMfwd
EM = MaskSAD > 0 ? EM.Overlay(EMfwd, opacity=0.5, mode="lighten") : EM
SkipEM = EM
return ScriptClip(SkipEM, "Subtitle(String(AverageLuma))").ConvertToY8()


YV12
https://s15.postimg.org/l28nzz3yf/Mask_YV12.png (https://postimg.org/image/l28nzz3yf/)

YV24
https://s15.postimg.org/42zpkpsqv/Mask_YV24.png (https://postimg.org/image/42zpkpsqv/)

pinterf
23rd April 2017, 19:26
Perhaps the scaling does not normalize on a larger chroma part in SAD. What does it look like if you use YUY2? It should be between yv12 and yv24.

MysteryX
23rd April 2017, 19:47
Perhaps the scaling does not normalize on a larger chroma part in SAD. What does it look like if you use YUY2? It should be between yv12 and yv24.
Yes, it is between YV12 and YV24.

How can I normalize the output?

raffriff42
23rd April 2017, 20:28
Fantastic to see high bit depth suddenly becoming a real thing, supported by all the best filters. Pinterf, I know you're probably standing on some tall shoulders, but your recent productivity has been amazing. You're a closer (https://www.google.com/search?q=ALWAYS+BE+CLOSING)!

StainlessS
23rd April 2017, 20:38
your recent productivity has been amazing.

Yes, Pinterf is the Dogs Bollocks, no exception !

MysteryX
23rd April 2017, 21:14
Fantastic to see high bit depth suddenly becoming a real thing, supported by all the best filters
While others have been talking about it for what... 10 or 15 years?

"Just do it" is a better philosophy than "let's talk about it"

MysteryX
23rd April 2017, 21:25
SMDegrain was written before 16-bit support was added to MaskTools2 and MVTools2. Now that they both support 16-bit, SMDegrain should be adapted for it.

Edit: Actually, if SMDegrain uses libraries that support 16-bit, it should work with native 16-bit out-of-the-box when supplied a 16-bit clip -- will have to test.

pinterf
24th April 2017, 10:51
Yes, it is between YV12 and YV24.

How can I normalize the output?
From the original MMask documentation (kind=1)

"kind=1 (SAD)
Allows to build a mask of the SAD (sum of absolute differences) values instead of the vectors' length. It can be useful to find problem areas with bad motion estimation. Internal factor blksize*blksizeV/4 is used for normalization of scale ml."

So it does not take into account the larger SAD values by design, normalization only handles the different block sizes.

Less subsampling means that there is more chroma SAD.
There is another thing to mention: when you omit chroma, then SAD will contain only luma SAD, regardless of the subsampling.

MysteryX
24th April 2017, 16:47
I think that behavior should be changed -- but it needs to stay compatible with previous behaviors, so it might need an extra parameter to normalize.

pinterf
25th April 2017, 09:58
I dont know whether this behavior was intentional in the yv12/yuy2 age

MysteryX
25th April 2017, 17:30
I see no reason or purpose for such behavior -- yet nobody complained so far

Morku
26th April 2017, 10:56
Version 2.7.16.22 brings me artefefacts in image on the right side, when I use QTGMC, most noticable as a popping green line:

http://imgur.com/ZQUg5RH

It's more heavily when using a slow preset like slow, slower, placebo... it is kind of gone when I use "ultra fast".

I revert back to 2.7.15.22 and everything is back fine.

Thats the script I am using:


AVISource("x.avi", audio=true).AssumeFPS(25,1)

QTGMC(Denoiser="dfttest", Preset="Slower", EdiMode="NNEDI3", EdiThreads=8, Sharpness=1.0)

Thats the state of my program version:
Avisynth+(x86) r2455 MT
masktools2 2.2.7
nnedi3 0.9.4.40
rgtools 0.95
QTGMC 3.357s
dfftest 1.94 ICL10

I hope I could help somehow.

Groucho2004
26th April 2017, 11:17
What are the image dimensions? Try to crop 2 pixels from the right (or left).

Morku
26th April 2017, 11:22
It's 720x576 (PAL).
To add crop(0, 0, -2, 0) does not solve the problem.

EDIT:
To add crop before QTGMC removes the green line, it's now grey.

Groucho2004
26th April 2017, 11:23
It's 720x576 (PAL).
To add crop(0, 0, -2, 0) does not solve the problem.Hm, don't know. Better post in the new QTGMC() thread.

EDIT:
To add crop before QTGMC removes the green line, it's now grey.
Well, cropping before the filters was implied. Anyway, pinterf is probably on the right track.

pinterf
26th April 2017, 11:36
It's 720x576 (PAL).
To add crop(0, 0, -2, 0) does not solve the problem.

EDIT:
To add crop before QTGMC removes the green line, it's now grey.
Could you resize it in 704x576?
Chroma width is 360 at YV12 which is not divisible by 16.
EDIT: found it, fix is coming soon

Morku
26th April 2017, 13:49
EDIT: found it, fix is coming soon

Thanks a lot :)

pinterf
26th April 2017, 14:11
New release with an important fix (regression in previous 2.7.16.22), big thanks to Morku for the early report.

The SAD mask scaling issue (different magnitude for YV12 and YV24) was noticed by MysteryX. @MysteryX: please have a look at it.

MvTools2 2.7.17.22 (https://github.com/pinterf/mvtools/releases/tag/2.7.17.22)

Change log
- 2.7.17.22 (20170426)
Fix: Regression in 2.7.16.22: MDegrain right pixel artifacts on non-modulo 16 widths
Misc: MMask, mode SADMask output is normalized further by video subsampling (YV16/YV24 has larger SAD value due to bigger chroma part that classic YV12)

MysteryX
26th April 2017, 17:41
YV24 masks are now weaker than YV12 masks.

YV12 / YV24
https://s12.postimg.org/3tq0khpa1/Mask_YV12.png (https://postimg.org/image/3tq0khpa1/) https://s12.postimg.org/e52dd5gzd/Mask_YV24.png (https://postimg.org/image/e52dd5gzd/)

It seems you're over-compensating.

Taurus
26th April 2017, 17:59
Thanks pinterf!
The same thing Morku was explaining happened to me yesterday.
I hope the new build will fix this.
It happened on a cropped and resized video to 960x720.
Straight 1920x1080 and 1280x720 do not show this artifact.
Will test the new build in a few minutes...
Hmmh, at first glance everything is allright now.
Green line and grey line after cropping are gone on my side.
Maybe Morku can comment on this.

QTGMC 3.357s
masktools2 2.2.7
nnedi3 0.9.4.40
rgtools 0.95
dfftest 1.94 ICL10
mvtools2 2.7.17.22

pinterf
26th April 2017, 18:04
YV24 masks are now weaker than YV12 masks.[/img][/url]

It seems you're over-compensating.
Or the theory fails.
SAD comes from luma and chroma
On YV12 Y:U:V has 1:0.25:0.25 ratio
On YV24 the ratio is 1:1:1.
I think the masks should look the same when you convert the clips to greyscale before analysis (or chroma=false)? Just an idea.

pinterf
26th April 2017, 18:06
Thanks pinterf!
The same thing Morku was explaining happened to me yesterday.

Uh, I'm really sorry for the inconvenience.

Morku
26th April 2017, 18:22
Green line and grey line after cropping are gone on my side.
Maybe Morku can comment on this.


My example also looks fine now without cropping and resizing.
Thank you for the fast fix.

Taurus
26th April 2017, 19:20
Uh, I'm really sorry for the inconvenience.

No problem.
I deeply appreciate your work on modernising and fixing Avisynth flaws:thanks:.

MysteryX
26th April 2017, 21:23
I think the masks should look the same when you convert the clips to greyscale before analysis (or chroma=false)? Just an idea.
Just to clarify, the screenshots call ConvertToY8 on the masks.

pinterf
27th April 2017, 10:07
Just to clarify, the screenshots call ConvertToY8 on the masks.
That's ok, I wondered that what happens when the clip to analyze is GreyScale()'d before that. Thus the chroma SAD difference is zero for both YV12 and YV24 and does not affect the SAD weighting.

I'm thinking that there should be an option to be able to give weight the chroma part of the SAD. The internal contribution of SAD elements (Luma:Chroma) in YV12 is 1:0.5, while for YV24 the ratio is 1:2, which drives the whole thing a bit off.

MysteryX
27th April 2017, 22:42
Here's our famous moose in Y8 / Y12 / Y16 / Y24
https://s12.postimg.org/8azyfqv89/Mask_Y8.png (https://postimg.org/image/8azyfqv89/) https://s12.postimg.org/x5jg9tg2h/Mask_Y12.png (https://postimg.org/image/x5jg9tg2h/) https://s12.postimg.org/lhpef9qxl/Mask_Y16.png (https://postimg.org/image/lhpef9qxl/) https://s12.postimg.org/jr6dds9eh/Mask_Y24.png (https://postimg.org/image/jr6dds9eh/)

MysteryX
28th April 2017, 21:23
Question about MMask. According to doc

Creates mask clip from source clip with motion vectors data. Mask is defined by blocks data, but is interpolated to fit full frame size. The mask is created both on the luma and on chroma planes. Mask values may be from 0 (min) to 255 (max).


In practice, I found chroma to contain rubbish and I'm only using the Luma plane. Yet the docs seem to say otherwise.

MysteryX
29th April 2017, 00:05
Pinterf, are you going to do additional modification to MMask?

From my tests, with your latest version, YV24 is about 1.25x stronger than YV12. If I want to adjust manually, however, that adjustment would need to be done before applying gamma, which means I couldn't use the Gamma argument and would instead have to use Levels after.

MysteryX
29th April 2017, 02:16
I realized mask strength is also different between BlkSize=8 (weaker), 16, and 32 (stronger).

I'm just curious as to what causes such mask strength variation. It's hard to work with the masks if their levels vary based on various factors.

MysteryX
2nd May 2017, 16:28
MvTools only supports block size 4, 8, 16 and 32, while SVP supports 10, 12, 14, etc. Would it be difficult to give more flexibility for block size?

pinterf
3rd May 2017, 19:34
MvTools only supports block size 4, 8, 16 and 32, while SVP supports 10, 12, 14, etc. Would it be difficult to give more flexibility for block size?
Yes, a bit difficult, it would need additional SAD asm functions, supporting half (YV12 chroma) and semi-half (YV16 chroma) sizes, MDegrain, etc...

I think making SAD chroma part to have the same well-behaving Luma:Chroma 4:2 ratio is more important. It should give similar results for both for YV12 (as now) and for YV24. Because now YV24 has Luma:Chroma 4:8 ratio inside the block SADs which may over-empasise chroma SAD and may not be desirable. Perhaps an extra chroma SAD scaling factor would enable us to achieve 4:4 or 4:8 luma:chroma SAD ratios.

MysteryX
3rd May 2017, 22:04
Yes, that's important. Keep us posted.

I'm also curious as to how other scripts were affected by this mask irregularity. SMDegrain script must be affected by this as well.

pinterf
12th May 2017, 21:08
New release.
MvTools2 2.7.18.22 (https://github.com/pinterf/mvtools/releases/tag/2.7.18.22)

This release took quite a lot of time, feedback welcomed.

Change log

- 2.7.18.22 (20170512)
Fix: 10-16 bit: DCT buffer possible overflow

Fix: DCT is fast again for non 8x8 blocksizes. Regression since 2.7.5.22.

New: Chroma SAD is now always half of luma SAD, regardless of video format
Without this: YV24's luma:chroma SAD ratio is 4:8 instead of 4:2 (of YV12)

New: MAnalyze, MRecalculate new parameter: "scaleCSAD" integer, default 0
Fine tune chroma SAD weight relative to luma SAD.
ScaleCSAD values for luma:chroma SAD ratio
-2: 4:0.5
-1: 4:1
0: 4:2 (default, same as the native ratio for YV12)
1: 4:4
2: 4:8

New: Block sizes 64, 48, 24, 12, 6
MAnalyze/MRecalculate new block sizes (SATD support mod4 sizes)
List of available block sizes
64x64, 64x48, 64x32, 64x16
48x64, 48x48, 48x24, 48x12
32x64, 32x32, 32x24, 32x16, 32x8
24x48, 24x24, 24x32, 24x12, 24x6
16x64, 16x32, 16x16, 16x12, 16x8, 16x4, 16x2
12x48, 12x24, 12x16, 12x12, 12x6
8x32, 8x16, 8x8, 8x4, 8x2, 8x1
6x24, 6x12, 6x6, 6x3
4x8, 4x4, 4x2
3x6, 3x3
2x4, 2x2

Note: some smaller block sizes can only be available in 4:4:4 formats, due to block size division (chroma subsampling)

New: All block sizes are supported in MDegrain1-6, MDegrainN, and MScaleVect

New: Changed to 2017 version of asm files for 8 bit SAD/SATD functions from x265 project.
Added not implemented asm code for 12, 24, 48 sizes
For some block sizes AVX2 and SSE4 is supported (AVX2 if reported under AviSynth+)
e.g. BlkSize 32 is faster now.

New: MMask SAD Mask to give identical weights for other-than-YV12 formats, e.g. for YV24

Motenai Yoda
12th May 2017, 22:16
did you got time to check depan/depanestimate?

StainlessS
13th May 2017, 00:33
:thanks: for the update, you are a one man tsunami !
And thank you for being Pinterf :)

pinterf
13th May 2017, 15:10
did you got time to check depan/depanestimate?
No, but now i'm investigating. Are you using 32 or 64 bit version?

MysteryX
13th May 2017, 19:50
MRecalculate with blksize=3


MVTools: no BLITCHROMA function for block size 1x1

pinterf
13th May 2017, 20:31
Int(3/2)=1

pinterf
13th May 2017, 20:54
Int(3/2)=1
Edit: try yv24. That's why I've noted above that specific block sizes are unavailable in color spaces with chroma subsampling. 6x6 needs also 3x3 in yv12 and 3x6 in yv16. 3x3 has no further division.

MysteryX
13th May 2017, 21:04
I note that masks are still slightly stronger with larger block sizes than with smaller block sizes. Why is that?

pinterf
13th May 2017, 21:43
Masks are calculated for blocks. Less blocks, more blocky enlargement. Since they are resized to the original size of the clip. Could a denser overlap help probably?

MysteryX
13th May 2017, 22:02
The output isn't necessarily worse; in fact the result can often be better. It's just that the mask is stronger too so I have no way of knowing which is better through code.

Here's an example.

Frame in 16 / 32
https://s29.postimg.org/gho8f26fn/Flow16.png (https://postimg.org/image/gho8f26fn/) https://s29.postimg.org/k2k3yaaz7/Flow32.png (https://postimg.org/image/k2k3yaaz7/)

Mask in 16 / 32
https://s29.postimg.org/ajaf4tngz/Mask16.png (https://postimg.org/image/ajaf4tngz/) https://s29.postimg.org/cp4pzbqxf/Mask32.png (https://postimg.org/image/cp4pzbqxf/)

Although the image looks better in 32, the mask is also considerably stronger in 32.

Masks vary between frames, but it has a strong tendency for the mask to be stronger with larger block size, without regards to the actual output quality.

real.finder
13th May 2017, 22:48
I wonder if mvtools need scaleparams Parameter since the output is different for every bit depth (like what tormento note in encode size (https://forum.doom9.org/showthread.php?t=169832&page=11))

pinterf
14th May 2017, 06:01
What parameter? Sad is already normalized to 8x8 8 bit, taking into account subsampling, block size and bit depth. Scene change value perhaps in MSCDetection?

real.finder
14th May 2017, 07:17
What parameter? Sad is already normalized to 8x8 8 bit, taking into account subsampling, block size and bit depth. Scene change value perhaps in MSCDetection?

Ysc? now it be the max value by default, right? I didn't note any script that use some other value, so if it use max value by default then I see no problem

I was wonder about something else that may used in SMDegrain and QTGMC

pinterf
14th May 2017, 07:36
And that parameter is scaled, anyway, when given

pinterf
25th May 2017, 18:13
New release, mask fixes after a painful debug session.
Important fix for DepanEstimate (thanks to Motenai Yoda)
And some new features again.

MvTools2 2.7.19.22 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.19.22)

- 2.7.19.22 (20170525)
New: [MMask] Support any 8-16 bits greyscale and planar input video formats (Y8..Y16, Planar RGB)
Input clip can even be of different bit depth or format from vector's original format
For kind==5 where U and V is filled, the greyscale option is not allowed
Mod: [MMask] Faster: request source frame only for kind=5.
Fix: [MxxxxFPS,MMask]: MakeVectorOcclusionMaskTime garbage in bottom blocks (30 hrs of debugging)
Fix: [MMask] bottom padding garbage for padded frame dimension
Fix: [MMask] proper 10+ bits scene change values (for default: 1023, 4095, 16383, 65535. Was: 65535)
Parameter is still in 8-bit range
Fix: [MRecalculate] prevent overflow during thSAD scaling in 16 bits or large block sizes (32, 48...)
Fix: [DepanEstimate] Sometimes giving wrong motion instead of scene change detection
Fix: [MAnalyze] Possible overflow in MAnalyze 8 bit, block size 48x48 and above.
Overflow-safe predictor recalc for big block sizes
New: [General] Add block size 12x3 for SAD, allow 6x24
List of available block sizes
64x64, 64x48, 64x32, 64x16
48x64, 48x48, 48x24, 48x12
32x64, 32x32, 32x24, 32x16, 32x8
24x48, 24x24, 24x32, 24x12, 24x6
16x64, 16x32, 16x16, 16x12, 16x8, 16x4, 16x2
12x48, 12x24, 12x16, 12x12, 12x6, 12x3
8x32, 8x16, 8x8, 8x4, 8x2, 8x1
6x24, 6x12, 6x6, 6x3
4x8, 4x4, 4x2
3x6, 3x3
2x4, 2x2
Mod: [Internal] Reorganized 10-16 bit SAD simd intrinsics, faster 8-12% for BlkSize 12-32


Fixed an old bug in a mask helper function.

The bug which happened to emerge _somewhere_ in the flow of the frame rate converter script by MysteryX et al., only in multithreading, only with special frame size and block and overlaps dimensions, and can could only be recognized by running the same encoding six times and check the one or two different sized result mkv frame by frame.

Finally replacing the pitch variable (https://github.com/pinterf/mvtools/commit/ad11ad0878e4a49acfc0fa065e20a7fca853eae9) solved the mistery (uninitialized mask block buffer part which contained some garbage from other thread's frame buffer). Never again this madness, I'm getting tired.

Then fixed another bottom part padding garbage issue which worked when Avisynth+ used asm bitBlt instead of memcpy BitBlt. The old code relied on Avisynth doing BitBlt copy from bottom to top vs top to bottom.

burfadel
25th May 2017, 23:13
I just tried 2.7.19.22 which results in an instant crash (x64 version). Version 2.7.17.22 works fine. I notice Version 2.7.19.22 files are very much noticeably bigger than 2.7.17.22.

MysteryX
26th May 2017, 00:11
Never again this madness, I'm getting tired.
MaskFun.cpp, you might want to rename that

pinterf
26th May 2017, 05:27
I just tried 2.7.19.22 which results in an instant crash (x64 version). Version 2.7.17.22 works fine. I notice Version 2.7.19.22 files are very much noticeably bigger than 2.7.17.22.
Bad news. Which filters/script were you using? I probably need your processor family as well, thanks.
Bigger file sizes are normal and come from the huge increase in block sizes.

burfadel
26th May 2017, 10:11
Bad news. Which filters/script were you using? I probably need your processor family as well, thanks.
Bigger file sizes are normal and come from the huge increase in block sizes.

MysteryX's Framerateconverter, the 24 May 2017 version. This is on a Ryzen R7-1700X CPU.

Not sure what part of the code, some basic scripts like filldrops3 works, as does jm_fps for which frameconverter is based upon. If I set output="none" in framerateconverter it still crashes.

BTW the x64 dll for 2.7.17.22 is 1.28 MB, and for 2.7.19.22 it is 3.04 MB, so almost 238 percent larger. Does that sound right?

jackoneill
26th May 2017, 10:21
Fixed an old bug in a mask helper function.

The bug which happened to emerge _somewhere_ in the flow of the frame rate converter script by MysteryX et al., only in multithreading, only with special frame size and block and overlaps dimensions, and can could only be recognized by running the same encoding six times and check the one or two different sized result mkv frame by frame.

Finally replacing the pitch variable (https://github.com/pinterf/mvtools/commit/ad11ad0878e4a49acfc0fa065e20a7fca853eae9) solved the mistery (uninitialized mask block buffer part which contained some garbage from other thread's frame buffer). Never again this madness, I'm getting tired.


The extra funny thing is that I fixed this very bug in the VapourSynth port over a year ago (https://github.com/dubhater/vapoursynth-mvtools/commit/6e78a6e74a31b867348b0046613f41df78a4d692). I remember telling Firesledge about it, but I guess he fixed it after you forked.

pinterf
26th May 2017, 10:45
The extra funny thing is that I fixed this very bug in the VapourSynth port over a year ago (https://github.com/dubhater/vapoursynth-mvtools/commit/6e78a6e74a31b867348b0046613f41df78a4d692). I remember telling Firesledge about it, but I guess he fixed it after you forked.
Omg, sometimes I go over your commit list, but I missed this one. (There was no update after 2.6.0.5 which was my initial source)

And there were other obstacles detecting this bug, such as at the very beginning I put MFlowFPS in Serialized MT mode for avs+ and was trying to debug in this setup. Which was not a good idea as this mode is not working properly, I have just written in avs+ topic.

burfadel
26th May 2017, 10:54
Pinterf, not sure what causes that instant crash bug. Like I said, other simpler scripts work, so I believe it must be a change related to the more complex functions of the script.

pinterf
26th May 2017, 12:13
Pinterf, not sure what causes that instant crash bug. Like I said, other simpler scripts work, so I believe it must be a change related to the more complex functions of the script.
Thanks, it happens when exiting from the DLL, MMask+greyscale input clip. Filter wants to release things related to chroma, which wasn't allocated.
Now I have another AV but it may be related to the current Framerateconverter.dll, but I have to make sure.
EDIT: recompiled Framerateconverter with VS2015 solved the problem, maybe I had no VS 2017 redist installed (? I have VS2017 on my machine)
EDIT2: there are still occasional crashes when running this converter script, but it does not seem to be mvtools2 related.

pinterf
26th May 2017, 17:00
Hotfix (MMask causing crash when DLL exits), thanks burfadel for the report!

Download: MvTools2 2.7.20.22 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.20.22)
As usual, please report any issue, for there were big internal changes since 2.7.17.22, so there can be bugs. Thanks.

And here is a note: MMask earlier somehow accepted Y8 input, but still processed all three planes with the internal resizing. But since the pitch is zero, it happened to spoil only the top line of the already filled Y plane (for YV12: half of it), to tell the truth, I don't know why it did not crash, but anyway, template clip format is free now (8-16, 4:2:0, 4:4:4, planar RGB, Y-only). And for greyscale the filter don't spend time with preparing and copying masks for non-existant U and V planes. (The reason of the hotfix was that although a resizer object was not created for U/V planes but it still got freed up)

Change log
- 2.7.20.22 (20170526) - hotfix
Fix: [MMask] greyscale input resulted in AV when filter exiting

- 2.7.19.22 (20170525)
New: [MMask] Support any planar input video formats e.g. greyscale, Planar RGB.
Input clip can even be of different bit depth or format from vector's original format
For kind==5 where U and V is filled, the greyscale option is not allowed
Mod: [MMask] Faster: request source frame only for kind=5.
Fix: [MxxxxFPS,MMask]: MakeVectorOcclusionMaskTime garbage in bottom blocks (30 hrs of debugging)
Fix: [MMask] bottom padding garbage for padded frame dimension
Fix: [MMask] proper 10+ bits scene change values (for default: 1023, 4095, 16383, 65535. Was: 65535)
Parameter is still in 8-bit range
Fix: [MRecalculate] prevent overflow during thSAD scaling in 16 bits or large block sizes (32, 48...)
Fix: [DepanEstimate] Sometimes giving wrong motion instead of scene change detection
Fix: [MAnalyze] Possible overflow in MAnalyze 8 bit, block size 48x48 and above.
Overflow-safe predictor recalc for big block sizes
New: [General] Add block size 12x3 for SAD, allow 6x24
List of available block sizes
64x64, 64x48, 64x32, 64x16
48x64, 48x48, 48x24, 48x12
32x64, 32x32, 32x24, 32x16, 32x8
24x48, 24x24, 24x32, 24x12, 24x6
16x64, 16x32, 16x16, 16x12, 16x8, 16x4, 16x2
12x48, 12x24, 12x16, 12x12, 12x6, 12x3
8x32, 8x16, 8x8, 8x4, 8x2, 8x1
6x24, 6x12, 6x6, 6x3
4x8, 4x4, 4x2
3x6, 3x3
2x4, 2x2
Mod: [Internal] Reorganized 10-16 bit SAD simd intrinsics, faster 8-12% for BlkSize 12-32

burfadel
26th May 2017, 17:18
Thanks! Works well now :).

hello_hello
3rd June 2017, 05:36
pinterf,
In case you'd care to take a look at it, there appears to be a problem with your flavour of MaskTools2 and the SeeSaw sharpening script.
https://forum.doom9.org/showthread.php?p=1808548#post1808548

Thanks.

Hi, I have tried the new version of masktools and there is a problem

Evaluate: Unhandled C++ exception!

(SeeSaw.avs, line 128)

(SeeSaw.avs, line 80)

burfadel
3rd June 2017, 06:17
pinterf,
In case you'd care to take a look at it, there appears to be a problem with your flavour of MaskTools2 and the SeeSaw sharpening script.
https://forum.doom9.org/showthread.php?p=1808548#post1808548

Thanks.

Try combining it with lsfmod (for example) to initiate a crash.

hello_hello
3rd June 2017, 07:04
Try combining it with lsfmod (for example) to initiate a crash.

No problems with LSFMod here (default settings). I use LSFMod quite regularly.

Although if you mean like this it's still the same error:

a = last
b = a.LSFMod()
SeeSaw(a, b)

I just realised I posted in the wrong thread (MVTools2 rather than MaskTools2) so I'll copy my post above to that thread.
https://forum.doom9.org/showthread.php?p=1808558#post1808558

burfadel
3rd June 2017, 08:33
No problems with LSFMod here (default settings). I use LSFMod quite regularly.

Although if you mean like this it's still the same error:

a = last
b = a.LSFMod()
SeeSaw(a, b)

I just realised I posted in the wrong thread (MVTools2 rather than MaskTools2) so I'll copy my post above to that thread.
https://forum.doom9.org/showthread.php?p=1808558#post1808558

What I meant was, seesaw() for me works by itself, but when there are certain other filters somewhere else in the script it fails. It's possibly a multi-instance issue calling on the same filters.

Does it work by itself with nothing else in the script? If so, try enabling the filters until it fails. If my above assumption is correct (because it is for me), it will fail when you use another script/plugin that uses masktools.

hello_hello
24th June 2017, 00:34
pinterf,
due to a discussion in this thread (https://forum.doom9.org/showthread.php?p=1810228#post1810228) regarding possible plugin differences, I tested a few versions of MVTools2 (Avisynth 2.6 on XP) and thought I'd ask about the result.

I was using Avisynth's Compare() as per the following pic (QTGMC deinterlacing), because when viewing the raw Avisynth output it looks visually identical to me, but there must be enough differences when different versions of MVTools2 are used to cause the video to be encoded slightly differently, as after it's encoded I can see it's not the same. Not necessarily better or worse, but there's definitely encoding differences.

How much of it is by accident or design or by bug fix, I don't know.

QTGMC 3.33, MVTools2 version 2.7.20.22 vs 2.5.11.22
http://image.ibb.co/eFJPA5/compare2.jpg

With the following script for testing (although I think it'd apply to any script using MVTools2)

DGDecode_mpeg2source("D:\video.d2v")
fields=AssumeTFF().SeparateFields()
super = MSuper(fields)
backward_vec2 = MAnalyse(super, isb = true, delta = 2, overlap=2)
forward_vec2 = MAnalyse(super, isb = false, delta = 2, overlap=2)
MDegrain1(fields, super, backward_vec2,forward_vec2,thSAD=400)
Weave()

MVTools2 version 2.6.0.5 (cretindesalpes) has a different output to version 2.5.11.22 (Fizick)
Version 2.7.0.1 (1st Pinterf) has identical output to version 2.6.0.5 (cretindesalpes)
Version 2.7.20.22 (latest Pinterf) has a different output to version 2.7.0.1 (1st Pinterf)

By accident, I discovered the following script produces green frames with version 2.7.20.22, but versions 2.7.0.1 and 2.7.0.22d are okay. Anything newer results in green frames.

tr = 6 # Temporal radius
super = MSuper ()
multi_vec = MAnalyse (super, multi=true, delta=tr)
MDegrainN (super, multi_vec, tr, thSAD=400, thSAD2=150)

Version 2.7.0.22d:

http://image.ibb.co/dMMb8Q/2_7_0_22d.jpg

Version 2.7.1.22:

http://image.ibb.co/dOtChk/2_7_1_22.jpg

Version 2.7.20.22:

http://image.ibb.co/cDfEv5/2_7_20_22.jpg

Cheers.

hello_hello
24th June 2017, 03:03
While I'm asking, I assume this means there's a reasonable difference between the old ff3dfilter and the new? Is it something to care about?

Cheers.

fft3dfilter 2.3 vs fft3dfilter 2.4

http://image.ibb.co/mGjk2k/fft3dfilter1.jpg

fft3dfilter 2.3 vs fft3dfilter 2.1.1

http://image.ibb.co/cGOdNk/fft3dfilter2.jpg

pinterf
26th June 2017, 10:38
I'll check it later this week
EDIT: Found. Seems that since MDegrain4-6 functions exist, no one uses MDegrainN?

hello_hello
26th June 2017, 23:55
I think I copied that script from the MVTools2 documentation for testing. If I did it was really just by chance I picked that one.

If the difference in QTGMC output is being caused by MVTools2 it'd be something other than MDegrainN. I'm not sure what it uses or when, but I found mention of MDegrain1, MDegrain2, MDegrain3, MDegrain4 & MDegrain5 in the script, plus these days it gets the SMDegrain script involved too.
(QTGMC 3.357s)

For the above comparison I used QTGMC's default settings. ie QTGMC()
I can try investigating further if you like.

Thanks.

hello_hello
27th June 2017, 00:33
It could be that I'm losing my mind, or maybe it's related to the previous MDegrainN bug, but I've been using the following for light denoising now and then:

tr = 1 # Temporal radius
mt = true # Internal multithreading
lsb = false # 16-bit
thSAD = 200 # denoising strength
blksize = 16 # block size
overlap = 4 # block overlap
super = MSuper (mt=mt)
multi_vec = MAnalyse (super, mt=mt, multi=true, blksize=blksize, overlap=overlap, delta=tr)
MDegrainN (super, multi_vec, tr, mt=mt, lsb=lsb, thSAD=thSAD, thSAD2=150)

That works fine, but if I make the three changes highlighted blue below, it results in an error message "Invalid arguments to function MDegrainN". Am I missing the obvious?

#tr = 1 # Temporal radius
mt = true # Internal multithreading
lsb = false # 16-bit
thSAD = 200 # denoising strength
blksize = 16 # block size
overlap = 4 # block overlap
super = MSuper (mt=mt)
multi_vec = MAnalyse (super, mt=mt, multi=true, blksize=blksize, overlap=overlap, delta=1)
MDegrainN (super, multi_vec, tr=1, mt=mt, lsb=lsb, thSAD=thSAD, thSAD2=150)

Thanks.

MysteryX
27th June 2017, 00:39
MDegrainN (super, multi_vec, tr=1, mt=mt, lsb=lsb, thSAD=thSAD, thSAD2=150)
tr is the name of the variable, not the name of the parameter.

Try this

MDegrainN (super, multi_vec, 1, mt=mt, lsb=lsb, thSAD=thSAD, thSAD2=150)

hello_hello
27th June 2017, 02:05
MysteryX,
If it's a named argument, shouldn't tr=1 work, or am I being dumb?

Your suggestion does work, by the way.

MDegrainN (super, multi_vec, 1, mt=mt, lsb=lsb, thSAD=thSAD, thSAD2=150)

But to me it should work like this. All these MAnalyse configurations seem to be fine:

tr = 1 # Temporal radius
mt = true # Internal multithreading
lsb = false # 16-bit
thSAD = 200 # denoising strength
blksize = 16 # block size
overlap = 4 # block overlap
super = MSuper (mt=mt)
multi_vec = MAnalyse (super, mt=mt, multi=true, blksize=blksize, overlap=overlap, delta=tr)
MDegrainN (super, multi_vec, tr, mt=mt, lsb=lsb, thSAD=thSAD, thSAD2=150)

or

multi_vec = MAnalyse (super, blksize=16, mt=mt, multi=true, overlap=overlap, delta=tr)

or

multi_vec = MAnalyse (super, 16, mt=mt, multi=true, overlap=overlap, delta=tr)

I'm not understanding why the same doesn't apply to "tr", or even supplying the input clips for MDegrainN as named arguments. That doesn't seem to work either. Should it, or am I being silly?

MysteryX
27th June 2017, 03:06
I'm not understanding why the same doesn't apply to "tr", or even supplying the input clips for MDegrainN as named arguments. That doesn't seem to work either. Should it, or am I being silly?
Because the argument's name is not "tr". We'd have to check in the doc to know the argument's name.

hello_hello
27th June 2017, 03:23
I did. :)

tr
Temporal radius, > 0. Must match the mvmulti content, i.e. the delta parameter in MAnalyse.

MDeGrainN (
clip,
clip super,
clip mvmulti,
int tr,
int thSAD (400),
int thSADC (thSAD),
int plane (4),
int limit (255),
int limitC (limit),
int thSCD1,
int thSCD2,
bool isse,
bool planar,
bool lsb (false),
int thSAD2 (thSAD),
int thSADC2 (thSADC),
bool mt (true)
)

pinterf
27th June 2017, 11:56
While I'm asking, I assume this means there's a reasonable difference between the old ff3dfilter and the new? Is it something to care about?

Cheers.

fft3dfilter 2.3 vs fft3dfilter 2.4

http://image.ibb.co/mGjk2k/fft3dfilter1.jpg

fft3dfilter 2.3 vs fft3dfilter 2.1.1

http://image.ibb.co/cGOdNk/fft3dfilter2.jpg
Maybe different compiler, 80 bit x87 arithmetic vs 64 bit IEEE double/float, or rounding, etc...
I have found a build of 2.1.1 version from 2011 which is giving identical results to the current 2.2.4 but is different from the original 2007 version.
Nevertheless, the differences are very minor.
Even the existing C and SSE results are different within the same plugin, so I don't think we should put more time into investigating bit-identical outputs in this case.

pinterf
27th June 2017, 12:01
I did. :)

tr
Temporal radius, > 0. Must match the mvmulti content, i.e. the delta parameter in MAnalyse.

MDeGrainN (
clip,
clip super,
clip mvmulti,
int tr,
int thSAD (400),
int thSADC (thSAD),
int plane (4),
int limit (255),
int limitC (limit),
int thSCD1,
int thSCD2,
bool isse,
bool planar,
bool lsb (false),
int thSAD2 (thSAD),
int thSADC2 (thSADC),
bool mt (true)
)

MDegrainN's signature:
ccci[thSAD]i[thSADC]i[plane]i[limit]i[limitC]i[thSCD1]i[thSCD2]i[isse]b[planar]b[lsb]b[thsad2]i[thsadc2]i[mt]b

Even super and mvmulti are named in the documentation but cannot be specified with their names.

hello_hello
27th June 2017, 16:14
pinterf,

Thanks for your efforts. The "tr" thing seems odd, but at least now I know why.

Cheers.

pinterf
29th June 2017, 13:51
New mvtools2 release, fixed broken MDegrainN chroma.
Thanks hello_hello for the report.

Download mvtools2 2.7.21.22 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.21.22)

- 2.7.21.22 (20170629)
Fix: [MDegrainN] fix chroma plane processing

MysteryX
1st July 2017, 20:03
I'm trying to build MvTools2 to run it into a profiler to see if anything comes up while running with MT.

How do I get it to build? It needs YASM.

I downloaded the x64 version of YASM. Extracted to this folder and removed the "vs" in front of each file so it's called "yasm"
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\VCTargets\BuildCustomizations\

Then I copied vsyasm.exe to
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\bin\

I changed the project to use VS 2017 and WinSdk10.

I get this error
The command ""C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\bin\"vsyasm.exe -Xvc -f Win32 -g cv8 -i "asm/include" -o "Win32\Debug\mvtools\\" -rnasm -pnasm -DPREFIX asm\Bilinear.asm asm\fdct_mmx.asm" exited with code 1.

What's missing?

StainlessS
2nd July 2017, 16:31
MysteryX, could these be related.

https://forum.doom9.org/showthread.php?p=1742975#post1742975

https://forum.doom9.org/showthread.php?p=1780581#post1780581

feisty2
3rd July 2017, 16:32
any particular reason you cant just get rid of all that asm shit and use intrinsics instead?

StainlessS
3rd July 2017, 18:55
any particular reason you cant just get rid of all that asm shit and use intrinsics instead?

I'm sure that Pinterf would appreciate all assistance that you care to offer in doing that, would likely be lots of hard work and a whole bevy of new bugs to iron out, but would give you much satisfaction when you've finally done it successfully.

Looking forward to it. :thanks:

MysteryX
3rd July 2017, 20:04
Here are benchmark tests of jm_fps script (simplified version)

function jm_fps(clip C, int Dct) {
Blksize=16
BlkSizeV=16
Dct = Default(Dct, 0)
NewNum=60
NewDen=1
Recalculate = false
Prefilter = C.RemoveGrain(22)
superfilt = MSuper(prefilter, hpad=16, vpad=16) # all levels for MAnalyse
super = MSuper(C, hpad=16, vpad=16, levels=1)
bak = MAnalyse(superfilt, isb=true, blksize=BlkSize, blksizev=BlkSizeV, overlap = BlkSize>4?(BlkSize/4+1)/2*2:0, overlapv = BlkSizeV>4?(BlkSizeV/4+1)/2*2:0, search=3, dct=Dct)
fwd = MAnalyse(superfilt, isb=false, blksize=BlkSize, blksizev=BlkSizeV, overlap = BlkSize>4?(BlkSize/4+1)/2*2:0, search=3, dct=Dct)
fwd = Recalculate ? MRecalculate(super, fwd, blksize=BlkSize/2, blksizev=BlkSizeV/2, overlap = BlkSize/2>4?(BlkSize/8+1)/2*2:0, overlapv = BlkSizeV/2>4?(BlkSizeV/8+1)/2*2:0, thSAD=100) : fwd
bak = Recalculate ? MRecalculate(super, bak, blksize=BlkSize/2, blksizev=BlkSizeV/2, overlap = BlkSize/2>4?(BlkSize/8+1)/2*2:0, overlapv = BlkSizeV/2>4?(BlkSizeV/8+1)/2*2:0, thSAD=100) : bak
Flow = MFlowFps(C, super, bak, fwd, num=NewNum, den=NewDen, blend=false, ml=200, mask=2, thSCD2=255)
return Flow
}

DCT=0, single-thread

FPS (min | max | average): 3.189 | 14.91 | 5.136
Memory usage (phys | virt): 289 | 296 MiB
Thread count: 21
CPU usage (average): 12%

DCT=0, Prefetch(8)

FPS (min | max | average): 2.933 | 77949 | 15.08
Memory usage (phys | virt): 1401 | 1422 MiB
Thread count: 29
CPU usage (average): 68%

DCT=1, single-threaded

FPS (min | max | average): 0.160 | 16.01 | 0.448
Memory usage (phys | virt): 314 | 319 MiB
Thread count: 21
CPU usage (average): 11%


DCT=1, Prefetch(8)

FPS (min | max | average): 0.109 | 66813 | 1.119
Memory usage (phys | virt): 1096 | 1105 MiB
Thread count: 26
CPU usage (average): 37%

DCT=0 is "fine" with 68% CPU usage. DCT=1 is what gives problems with multi-threading with 37% CPU usage, choppy playback, and occasional freezes -- but DCT=1 is definitely better than before the recent Pinterf fix!

Groucho2004
3rd July 2017, 21:07
any particular reason you cant just get rid of all that asm shit and use intrinsics instead?The asm shit tends to be pretty fast if done properly.

feisty2
4th July 2017, 00:37
The asm shit tends to be pretty fast if done properly.

-> any particular reason you cant just get rid of all that asm shit and use intrinsics instead?
no comment

Groucho2004
4th July 2017, 01:00
any particular reason you cant just get rid of all that asm shit and use intrinsics instead?Define "use intrinsics". There is no automatic ASMShitToIntrinsics converter of which I'm aware. There are ~10,000 lines of asm in mvtools2.

feisty2
4th July 2017, 01:05
Define "use intrinsics". There is no automatic ASMShitToIntrinsics converter of which I'm aware. There are ~10,000 lines of asm in mvtools2.

https://software.intel.com/sites/landingpage/IntrinsicsGuide/#

Groucho2004
4th July 2017, 01:11
https://software.intel.com/sites/landingpage/IntrinsicsGuide/#Very good, you posted the Intel intrinsics reference. I still don't see the magic that converts 10000 lines of ASM shit to intrinsics.

Groucho2004
4th July 2017, 01:18
any particular reason you cant just get rid of all that asm shit and use intrinsics instead?By the way, what did you do with the asm shit in your VS single precision mvtools?

feisty2
4th July 2017, 01:21
Your original post was "asm shit is fast", and I been saying, intrinsics are equally fast, without having to use an assembler
Obviously you realized that, then you changed your point to, "you can't automatically convert raw asm to intrinsics"
Get a room with Katie already, troll

Groucho2004
4th July 2017, 01:45
Your original post was "asm shit is fast", and I been saying, intrinsics are equally fast, without having to use an assembler
Obviously you realized that, then you changed your point to, "you can't automatically convert raw asm to intrinsics"
Get a room with Katie already, trollI didn't change my point, you missed it. Also, you didn't write "intrinsics are equally fast, without having to use an assembler", you wrote "use intrinsics instead" which is very vague and implies that this could be done instantly.

What's wrong with using an assembler? Do you realize that for example the speed of libx264 is based on its highly efficient asm code?

My point is that there is perfectly good and fast asm code in mvtools2 (32 and 64 bit). Having this converted to intrinsics would be good but it's a lot of work.

tebasuna51
4th July 2017, 13:04
...
Get a room with Katie already, troll

Please guys stop that way.

The question is clear, stop the discussion.

Groucho2004
4th July 2017, 17:08
Please guys stop that way.

The question is clear, stop the discussion.
I'm not sure to which question you're referring, Mystery's or feisty's. Either way, nothing wrong with having a discussion. I still don't quite understand feisty's troll accusation but I suppose there was some kind of misinterpretation of something I posted...

TheFluff
4th July 2017, 17:42
The main benefit of intrinsics over handwritten assembly is that it's easier to write and maintain, as well as easier to integrate into your C++ stuff (such as templates - a lot of the VS multi-bitdepth stuff uses templated intrinsics). A minor bonus is that you don't need a separate assembler in addition to your regular compiler. However, if you already have a bunch of well tested and functioning .asm (in separate files, not some inline monstrosity pain in the rear) and that you have no intention of changing, then porting to intrinsics is just a lot of busy-work that's probably going to introduce a lot of new and exciting bugs. Not even the VS port of MVTools has gotten rid of all the .asm files, because there was simply no need. New code has been ported to intrinsics though.

Groucho2004
4th July 2017, 19:12
However, if you already have a bunch of well tested and functioning .asm (in separate files, not some inline monstrosity pain in the rear) and that you have no intention of changing, then porting to intrinsics is just a lot of busy-work that's probably going to introduce a lot of new and exciting bugs. Not even the VS port of MVTools has gotten rid of all the .asm files, because there was simply no need.
That was exactly my point. I think pinterf replaced most (if not all) inline asm with intrinsics so the remaining problem seems to be that some people have trouble producing a few .obj files using yasm/nasm. It's just bizarre.

yup
10th July 2017, 08:40
pinterf :thanks: for update.
Now some my scripts work stable.
But I see strange behaviour when open scripts in VirtualDubMod, I do not see error message if I writen script with error related to MVTools functions, during this VirtatualDub hung and not response.
I can not close video in Vitualdub, only close Vitualdub.
Job control also do not work.
Please advice.

yup.

pinterf
11th July 2017, 09:45
any particular reason you cant just get rid of all that asm shit and use intrinsics instead?
Because the porting is done in my free time which is limited.

Asm vs intrinsics.

SAD and SATD code (which are the most important routines regarding mvtools2 speed) written in intrinsics is _much_ slower than using existing asm, I'm talking about VS2015/2017 code generator.

I have experienced the opposite case as well when the generated code from intrinsics is faster than the original asm (experienced in FFT3DFilter and TIVTC) perhaps because of smarter instruction ordering. Even a C version can be faster than the old asm (TIVTC).

I usually have a look at the generated assembler code of the intrinsics.

There are cases when the optimizer uses too many xmm registers, so the prolog/epilog register save/restore (which we cannot control) takes significant time relative to the actual task, as experienced in 16 bit SAD intrinsics routines. I had to play with less-than-optimal loop unrolling until I found out the fastest result for a particular SAD blocksize.

pinterf
11th July 2017, 10:11
DCT=0 is "fine" with 68% CPU usage. DCT=1 is what gives problems with multi-threading with 37% CPU usage, choppy playback, and occasional freezes -- but DCT=1 is definitely better than before the recent Pinterf fix!
DCT=1 is using integer arithmetic for 8 bit video and 8x8 block sizes.
In all other cases (such as for block size 16x16) the routines from the FFTW3 library are used.
I don't know which fftw3 version are you using (i can see 3.3.6 as the latest one in http://www.fftw.org/ ), perhaps you could try comparing different versions.

MysteryX
12th July 2017, 05:21
I don't know which fftw3 version are you using (i can see 3.3.6 as the latest one in http://www.fftw.org/ ), perhaps you could try comparing different versions.
I don't know which version but it is from March 2014 :D I'll try the latest and see how it behaves.

Still the same problem. Stuck at 37% CPU usage.

It is the libfftw3f-3.dll file in C:\Windows\SysWOW64, correct?

If I use BlkSize=8, I get 47% CPU usage.

shae
13th July 2017, 14:04
What's supposed to happen if FFTW is missing?

QTGMC seems to work without it. Is it because MvTools2 doesn't always need it or something else?

And can it load libfftw3f-3.dll from the same directory as mvtools2.dll instead of the system dir?
AvsMeter says the FFTW DLL cannot be loaded, but maybe it only looks for it in the system directory.

real.finder
13th July 2017, 14:45
What's supposed to happen if FFTW is missing?

QTGMC seems to work without it. Is it because MvTools2 doesn't always need it or something else?

And can it load libfftw3f-3.dll from the same directory as mvtools2.dll instead of the system dir?
AvsMeter says the FFTW DLL cannot be loaded, but maybe it only looks for it in the system directory.

yes, MvTools2 doesn't always need it

you can load FFTW DLL by using this (https://forum.doom9.org/showthread.php?t=119200), x64 here (https://forum.doom9.org/showthread.php?p=1777483#post1777483)

shae
13th July 2017, 23:09
I think I'll just go by "it's probably fine if it the script loads, doesn't crash, and the beginning of the video look okay". :)

GMJCZP
20th July 2017, 03:28
When I use this hello_hello script (# 301) in 16 bits:
tr = 1 # Temporal radius
mt = true # Internal multithreading
lsb = false # 16-bit
thSAD = 200 # denoising strength
blksize = 16 # block size
overlap = 4 # block overlap
super = MSuper (mt=mt)
multi_vec = MAnalyse (super, mt=mt, multi=true, blksize=blksize, overlap=overlap, delta=tr)
MDegrainN (super, multi_vec, tr, mt=mt, lsb=lsb, thSAD=thSAD, thSAD2=150)

By putting lsb = true, delta =1 and tr> 1 I get artifacts.

hello_hello
20th July 2017, 04:50
GMJCZP,
Delta and TR have to be the same. From the help file:

MDeGrainN has a temporal radius given by the tr parameter, and uses a special motion vector clip.
tr
Temporal radius, > 0. Must match the mvmulti content, i.e. the delta parameter in MAnalyse.

GMJCZP
20th July 2017, 13:27
:thanks:

Problem solved.

GMJCZP
20th July 2017, 16:04
Now I have another problem, I do not present the image correctly if I do not use f3kdb and DitherPost together, I'm still a rookie at this 16-bit:

Dither_convert_8_to_16()
Temporalsoften(2,1,2,mode=2,scenechange=10)
dither_resize16(720,480,kernel="spline16",invks=true,invkstaps=3,src_left=0.0,u=3,v=3)
MDegrainLight(2,lsb=true,thSAD=200)
f3kdb(range=15, grainY=0, grainC=0, keep_tv_range=True, input_depth=16, output_depth=8)
DitherPost()

# MDegrainLight
# https://forum.doom9.org/showthread.php?p=1810543#post1810543
# Original idea by hello_hello

function MDegrainLight(clip input, int "tr", bool "mt", bool "lsb", int "thSAD", int "thSAD2", int "blksize", int "overlap")
{
tr = Default(tr, 1) # Temporal radius
mt = Default(mt, true) # Internal multithreading
lsb = Default(lsb, false) # 16-bit
thSAD = Default(thSAD, 200) # Denoising strength
thSAD2 = Default(thSAD2, 150)
blksize = Default(blksize, 16) # Block size
overlap = Default(overlap, 4) # Block overlap

super = input.MSuper (mt=mt)
multi_vec = MAnalyse (super, mt=mt, multi=true, blksize=blksize, overlap=overlap, delta=tr)
input.MDegrainN (super, multi_vec, tr, mt=mt, lsb=lsb, thSAD=thSAD, thSAD2=thSAD2)
return last
}


In truck, if I use dfttest(sigma=2, tbsize=1, lsb_in=true, lsb=true, Y=true, U=true, V=true, opt=3, dither=0), instead of MDegrain, DitherPost is no longer necessary.
Can anyone please explain to me if I am redundant with DitherPost, or if my script is correct?

Or is there a way to use only, or f3kdb or DitherPost?

blaze077
20th July 2017, 19:04
1. Afaik, TemporalSoften does not support 16 bit stacked input, so you should apply it before the dither_convert_8_to_16 call.

2. I don't think MDegrainN takes in 16 bit stacked input. It can only output it using lsb=true. (No lsb_in parameter)

3. Ditherpost simply turns a 16 bit clip into an 8 bit clip. In your f3kdb call, you already output 8 bit video so you don't need ditherpost.

Alternatively, you could change f3kdb's output_depth to 16, and then ditherpost would work as expected.

GMJCZP
20th July 2017, 21:07
1. Temporal soften does not have anything to do with the problem.
2. The script works perfectly as it is, the problem is if I use f3kdb and DitherPost together, I said it before.
3. I repeat it again, if I do not use DitherPost the video is poorly displayed.

Anyway thanks for the reply.

I repeat my doubt, Is my script okay and I'm not messing with DitherPost?, Because I can not get an f3kdb command that correctly displays the image.

EDIT: I solved the problem, the MVTools documentation says:

lsb

Generates 16-bit data when set to true. The picture made of the most siginificant bytes (MSB) is stacked on the top of the least significant byte (LSB) block. Hence a twice taller resulting picture. You can extract the MSB or the LSB with a simple Crop() call. This mode helps recovering the full bitdepth of temporally dithered data.

Then the definitive script looks like this:

Dither_convert_8_to_16()
Temporalsoften(2,1,2,mode=2,scenechange=10)
dither_resize16(720,480,kernel="spline16",invks=true,invkstaps=3,src_left=0.0,u=3,v=3)
MDegrainLight(2,lsb=true,thSAD=200).Crop(0,0,0,960)
f3kdb(range=15, grainY=0, grainC=0, keep_tv_range=True, input_depth=16, output_depth=8)

# MDegrainLight
# https://forum.doom9.org/showthread.php?p=1810543#post1810543
# Original idea by hello_hello

function MDegrainLight(clip input, int "tr", bool "mt", bool "lsb", int "thSAD", int "thSAD2", int "blksize", int "overlap")
{
tr = Default(tr, 1) # Temporal radius
mt = Default(mt, true) # Internal multithreading
lsb = Default(lsb, false) # 16-bit
thSAD = Default(thSAD, 200) # Denoising strength
thSAD2 = Default(thSAD2, 150)
blksize = Default(blksize, 16) # Block size
overlap = Default(overlap, 4) # Block overlap

super = input.MSuper (mt=mt)
multi_vec = MAnalyse (super, mt=mt, multi=true, blksize=blksize, overlap=overlap, delta=tr)
input.MDegrainN (super, multi_vec, tr, mt=mt, lsb=lsb, thSAD=thSAD, thSAD2=thSAD2)
return last
}

In short, DitherPost was not necessary.

blaze077
20th July 2017, 21:26
I just tried to run your script and the cause is indeed your MDegrainLight function.
As you know, 16 bit stacked is double the height of the normal video (MSB and LSB).
You pass a 16 bit stacked clip to MDegrainN, but MDegrain does not have any way of knowing that you passed a 16 bit stacked clip to it. It just assumes that you gave it an 8 bit clip and processes it accordingly.
Since you pass lsb=true to MDegrainN, it tries to convert the already 16 bit stacked clip to 16 bit stacked again.
The result is that your video is now 4 times it's normal height!
With the f3kdb call, the video is back to double height and with the ditherpost call, it is back to normal height.

A solution can be to call ditherpost() before all the MVTools calls (MSuper, analyze and degrainN) inside your MDegrainLight function.

GMJCZP
20th July 2017, 21:35
Thank you. Now I face this:

What if I use lsb = false? Is the cleaning quality maintained? This would no longer require Crop.

Edit: or just try your alternative.

GMJCZP
20th July 2017, 22:15
Subjectively speaking, as to the quality of the image, you're right, it's best to call DitherPost first.

Everything looks like this:

Dither_convert_8_to_16()
Temporalsoften(2,1,2,mode=2,scenechange=10)
dither_resize16(720,480,kernel="spline16",invks=true,invkstaps=3,src_left=0.0,u=3,v=3)
MDegrainLight(2,lsb=true,thSAD=200)
f3kdb(range=15, grainY=0, grainC=0, keep_tv_range=True, input_depth=16, output_depth=8)

# MDegrainLight
# https://forum.doom9.org/showthread.php?p=1810543#post1810543
# Original idea by hello_hello

function MDegrainLight(clip input, int "tr", bool "mt", bool "lsb", int "thSAD", int "thSAD2", int "blksize", int "overlap")
{
tr = Default(tr, 1) # Temporal radius
mt = Default(mt, true) # Internal multithreading
lsb = Default(lsb, false) # 16-bit
thSAD = Default(thSAD, 200) # Denoising strength
thSAD2 = Default(thSAD2, 150)
blksize = Default(blksize, 16) # Block size
overlap = Default(overlap, 4) # Block overlap

input = (lsb == true ) ? input.DitherPost() : input

super = input.MSuper (mt=mt)
multi_vec = MAnalyse (super, mt=mt, multi=true, blksize=blksize, overlap=overlap, delta=tr)
input.MDegrainN (super, multi_vec, tr, mt=mt, lsb=lsb, thSAD=thSAD, thSAD2=thSAD2)
return last
}

I wonder if it is not better to use DitherPost (mode = - 1), since f3kdb, so I understand, is already doing Dithering.

However, if there is something better it would be good to know.

Edit: I tried DitherPost (mode = -1) and it looks microscopically better, this makes me think that it is better to put DitherPost (mode = -1) .MDeGrainLight (). F3kdb. If there is no f3kdb then maybe it would be nice to put DitherPost (mode = 0) .MDeGrainLight ().
In any case it would be better not to put it inside the DitherPost function, unless within the function define a new variable that takes this into account.

blaze077
21st July 2017, 03:18
There is another method which would avoid any sort of dithering down. While MVTools does not support stacked input, it does support native high bit depth.
You could convert the stacked format to native bit depth (no data loss), degrain the native 16 bit video using MDegrainN and then convert the native 16 bit video back to 16 bit stacked.
This might be slower but it would be much better.

Like so:
function MDegrainLight(clip input, int "tr", bool "mt", bool "lsb", int "thSAD", int "thSAD2", int "blksize", int "overlap")
{
tr = Default(tr, 1) # Temporal radius
mt = Default(mt, true) # Internal multithreading
lsb = Default(lsb, false) # 16-bit
thSAD = Default(thSAD, 200) # Denoising strength
thSAD2 = Default(thSAD2, 150)
blksize = Default(blksize, 16) # Block size
overlap = Default(overlap, 4) # Block overlap

input = lsb ? input.ConvertFromStacked() : input

super = input.MSuper(mt=mt)
multi_vec = MAnalyse(super, mt=mt, multi=true, blksize=blksize, overlap=overlap, delta=tr)
input.MDegrainN(super, multi_vec, tr, mt=mt, thSAD=thSAD, thSAD2=thSAD2)
return lsb ? ConvertToStacked() : last
}

Note: You will need Avisynth+ (any release with working HBD support).

GMJCZP
21st July 2017, 05:05
Thanks again.
For now I do not use AVS+, but in the future I will take it into account. I think it is best to use DitherPost, either mode = -1 or mode = 0, outside of the function due to the presence of f3kbd, so IMO I have more flexibility.

Edit: Dithering Down (I'm no expert in understanding the term, sorry) would be mitigated with DitherPost (mode = -1) but the difference seems minimal with respect to DitherPost (mode = 0).

GMJCZP
21st July 2017, 16:27
Is it possible to use MCompensate together with MdegrainN? I can not do it.

BakaProxy
21st July 2017, 16:36
Is it possible to use MCompensate together with MdegrainN? I can not do it.Technically yes, but I don't think there's much use to it since mdegrain is already kind of motion compensating.

Verstuurd vanaf mijn SM-A500FU met Tapatalk

StainlessS
21st July 2017, 16:42
Is it possible to use MCompensate together with MdegrainN? I can not do it.

Not sure what you want here but I think that in using MDegrainN, you have already used MCompensate (in a round about way, ie prior to the degrain of MDegrainN, frames are MC compensated to predicted positions, and then degrained).
Not sure that repeating the experience will improve anything much.

EDIT: Beaten by BakaProxy. :)

GMJCZP
21st July 2017, 17:18
Thanks to both.
I suppose Mrecalculate can, right?

Edit: I could do it, lol.

StainlessS
21st July 2017, 17:56
Thanks to both.
I suppose Mrecalculate can, right?

Edit: I could do it, lol.

Not sure that you could, at least without another MAnalyse on the output of the degraining. You could perhaps do Mrecalculate if you broke it up into MAnalyse type funcs, and then Mrecalculate on each result, and then MDegrainX type func on result of all of that lot.

EDIT:
MDegrainN (which I have never knowingly used) is just a bunch of MAnalyse funcs, followed by a bunch of MDegrainX funcs,
to use MRecalculate, you would need to use that func (MreCalc) between MAnalyse and MDegrainX.

EDIT:
is just a bunch of MAnalyse funcs
Well sort of, equiv to lots of MAnalyse with lots of Delta offsets.

EDIT: Who said life was supposed to be easy ? :)

GMJCZP
21st July 2017, 18:16
Life is simpler than you think, TinMan:

# MDegrainLight
# https://forum.doom9.org/showthread.php?p=1813061#post1813061
# Original idea by detmek, hello_hello
# Adapted by GMJCZP
# Requirements: MVTools, Dither Tools (optional for lsb=true)

function MDegrainLight(clip input, int "tr", bool "mt", bool "lsb", int "thSAD", int "thSAD2", int "blksize", int "overlap")
{
tr = Default(tr, 1) # Temporal radius
mt = Default(mt, true) # Internal multithreading
lsb = Default(lsb, false) # 16-bit
thSAD = Default(thSAD, 200) # Denoising strength
thSAD2 = Default(thSAD2, 150)
blksize = Default(blksize, 16) # Block size
overlap = Default(overlap, 4) # Block overlap

# <Options for lsb=true>
#input = lsb ? input.DitherPost(mode=-1) : input # For AVS, AVS+ users
#input = lsb ? input.ConvertFromStacked() : input # For AVS+ only, more slow, suggestion of blaze077

super = input.MSuper (mt=mt)
multi_vec = MAnalyse (super, mt=mt, multi=true, blksize=blksize, overlap=overlap, delta=tr)
multi_vec_re = MRecalculate(super,multi_vec, tr=tr,blksize=4)
input.MDegrainN (super, multi_vec_re, tr, mt=mt, lsb=lsb, thSAD=thSAD, thSAD2=thSAD2)
# return lsb ? ConvertToStacked() : last # For AVS+ only, more slow, suggestion of blaze077
return last
}

:)

StainlessS
21st July 2017, 18:21
GMJCZP,

Well that Fizick, or whoever designed this stuff is well more clever than I gave credit for, thank you for the education, we need as much of that as we can get. :)

GMJCZP
21st July 2017, 18:44
I give you the whole reason, Fizick, cretindesalpes, pinterf are geniuses.

GMJCZP
22nd July 2017, 01:20
@ pinterf:

I noticed that the parameter search = 5 (Umh) produces identical results as search = 4 (Hex). In x264 the results are different.

burfadel
22nd July 2017, 09:47
Life is simpler than you think, TinMan:

# MDegrainLight
# https://forum.doom9.org/showthread.php?p=1813061#post1813061
# Original idea by hello_hello
# Adapted by GMJCZP
# Requirements: MVTools, Dither Tools (optional for lsb=true)

function MDegrainLight(clip input, int "tr", bool "mt", bool "lsb", int "thSAD", int "thSAD2", int "blksize", int "overlap")
{
tr = Default(tr, 1) # Temporal radius
mt = Default(mt, true) # Internal multithreading
lsb = Default(lsb, false) # 16-bit
thSAD = Default(thSAD, 200) # Denoising strength
thSAD2 = Default(thSAD2, 150)
blksize = Default(blksize, 16) # Block size
overlap = Default(overlap, 4) # Block overlap

# <Options for lsb=true>
#input = lsb ? input.DitherPost() : input # For AVS, AVS+ users
#input = lsb ? input.ConvertFromStacked() : input # For AVS+ only, more slow, suggestion of blaze077

super = input.MSuper (mt=mt)
multi_vec = MAnalyse (super, mt=mt, multi=true, blksize=blksize, overlap=overlap, delta=tr)
multi_vec_re = MRecalculate(super,multi_vec, tr=tr,blksize=4)
input.MDegrainN (super, multi_vec_re, tr, mt=mt, lsb=lsb, thSAD=thSAD, thSAD2=thSAD2)
# return lsb ? ConvertToStacked() : last # For AVS+ only, more slow, suggestion of blaze077
return last
}

:)

I have found that processing chroma and luma separately produces nicer results in regards to mdegrain. I came up with the following script based on existing Mdegrain concept, in conjuction with a luma mask I borrowed from the linked post. The luma mask is beneficial in reducing motion artifacts.

In this script luma is handed by MVtools and chroma is handled by FFT3DFilter. FFT3DFilter seems more appropriate for chroma, and MVTools seems more appropriate for luma according to the results that each achieves. On a clip I tried it also was worked as a de-rainbow filter, although the effect is likely quite weak.

# MClean basic script
# Mask from bennynihon https://forum.doom9.org/showthread.php?p=1689444#post1689444
# Remaining script by burfadel altered from generic information
# Basics for this script is to remove grain whilst retaining as much information as possible
# The script should also be relatively fast, even without Masktools2 multithreading (disabled due to possible MT bug)
# Chroma is processed via a different method to luma for optimal results
# Requires RGTools, Modplus (Veed, for part of chroma filter), MVTools2, Masktools2, FFT3DFilter


function MClean(clip c, int "thSAD", int "blksize", int "blksizeV", int "overlap", int "cblksize", int "cblksizeV", int "cpu")
{
thSAD = Default(thSAD, 350) # Denoising threshold
blksize = Default(blksize, 16) # Horizontal block size for luma
blksizeV = Default(blksizeV, blksize) # Vertical block size for luma, default same as horizontal
overlap = Default(overlap, 8) # Block overlap
cblksize = Default(cblksize, 32) # Horizontal block size for chroma
cblksizeV = Default(cblksizeV, cblksize) # Vertical block size for chroma, default same as horizontal
cpu = Default(cpu, 4) # Threads for FFT3DFilter

coverlapH = (cblksize/2) # Overlap for horizontal chroma blocks, half blksize
coverlapV = (cblksizeV/2) # Overlap for vertical chroma blocks, half blksizeV


# Masks
LumaMask=mt_binarize(c, threshold=64, upper=true).greyscale().BilinearResize((c.width/16)*2, (c.height/16)*2).BilinearResize(c.width,c.height).mt_binarize(threshold=254)
EdgeMask=mt_edge(c, mode="prewitt",thy1=0,thy2=16).greyscale().mt_binarize(threshold=16, upper=true).BilinearResize((c.width/16)*2, (c.height/16)*2).BilinearResize(c.width,c.height).mt_binarize(threshold=254)
GrainMask=mt_logic(LumaMask,EdgeMask,mode="and")
DegrainMask=GrainMask.mt_invert()

# Chroma filter
filt_chroma=fft3dfilter(veed(c), plane=3, bw=cblksize, bh=cblksizeV, ow=coverlapH, oh=coverlapV, bt=5, sharpen=0.6, ncpu=cpu, dehalo=0.2, sigma=2.35)

# Luma Filter
super = c.MSuper(rfilter=4, chroma=false,hpad=16, vpad=16)
bvec2 = MAnalyse(super, chroma=false, isb = true, delta = 2, blksize=blksize, blksizeV=blksizeV, overlap=overlap, search=5, searchparam=5)
bvec1 = MAnalyse(super, chroma=false, isb = true, delta = 1, blksize=blksize, blksizeV=blksizeV, overlap=overlap, search=5, searchparam=3)
fvec1 = MAnalyse(super, chroma=false, isb = false, delta = 1, blksize=blksize, blksizeV=blksizeV, overlap=overlap, search=5, searchparam=3)
fvec2 = MAnalyse(super, chroma=false, isb = false, delta = 2, blksize=blksize, blksizeV=blksizeV, overlap=overlap, search=5, searchparam=5)
Clean = c.MDegrain2(super, bvec1, fvec1, bvec2, fvec2, thSAD=thSAD, plane = 0)

#Luma mask merge
filt_luma = c.mt_merge(Clean, DegrainMask, U=1, V=1)

# Combining result of luma and chroma cleaning
output = mergechroma(filt_luma, filt_chroma)

return output
}

Yes, no doubt it could be improved, but it produces pretty good results. I guess from that you could add dither.

MysteryX
1st August 2017, 06:03
Hey, quick question. MvTools2 has performance and stability issues with MT, especially when using DCT=1. Does the VapourSynth version also have such issues or does it work smoothly there?

blaze077
1st August 2017, 07:06
It works perfectly even with DCT=1 for me. I've never encountered a problem with it (because of Vapoursynth's stable MT).

hello_hello
1st August 2017, 13:19
GMJCZP,
Thanks for the credit in your script, but I must confess the idea was not mine.
Im pretty sure I stole it from this post.
https://forum.doom9.org/showthread.php?p=1583955#post1583955

GMJCZP
1st August 2017, 16:06
GMJCZP,
Thanks for the credit in your script, but I must confess the idea was not mine.
Im pretty sure I stole it from this post.
https://forum.doom9.org/showthread.php?p=1583955#post1583955

Thank you for your honesty. You have not stolen anything, just the circumstances. ;)

I updated the script just to reflect this.

MysteryX
2nd August 2017, 04:10
Does DCT=1 have the same issues with BlkSize=8 that doesn't use FFTW?


ColorBarsHD()
ConvertToYV12()
jm_fps()
Prefetch(8)

function jm_fps(clip source, float "fps")
{
fps = default(fps, 60)
fps_num = int(fps * 1000)
fps_den = 1000

prefiltered = RemoveGrain(source, 22)
super = MSuper(source, hpad = 16, vpad = 16, levels = 1) # one level is enough for MRecalculate
superfilt = MSuper(prefiltered, hpad = 16, vpad = 16) # all levels for MAnalyse
backward = MAnalyse(superfilt, isb = true, blksize = 8, overlap = 4, search = 3, dct = 1)
forward = MAnalyse(superfilt, isb = false, blksize = 8, overlap = 4, search = 3, dct = 1)
forward_re = MRecalculate(super, forward, blksize = 4, overlap = 2, thSAD = 100)
backward_re = MRecalculate(super, backward, blksize = 4, overlap = 2, thSAD = 100)
out = MFlowFps(source, super, backward_re, forward_re, num = fps_num, den = fps_den, blend = false, ml = 200, mask = 2)

return out
}



Exception 0xC0000005 [STATUS_ACCESS_VIOLATION]
Module: C:\Windows\SysWOW64\KernelBase.dll
Address: 0x76C3A9F2

WOOPS!!

VS_Fan
2nd August 2017, 07:07
Does DCT=1 have the same issues with BlkSize=8 that doesn't use FFTW?It looks like your problem is not related to DCT=1 in MAnalyse, but instead with different blocksizes and overlaps in MAnalyse and MRecalculate.

I had a similar crash problem with FFTW related to mvtools2 in a script some time ago with SET’s avisyth 2.6 MT and Firesledge’s mvtools 2.6.0.5. So I tried my old solution in your script, appending mt=False to MSuper, MAnalyse and MRecalculate, but that didn’t help. It still crashes.

Then I tried changing MRecalculate with the same blocksize and overlap you used in MAnalyse. This effectively prevents the crash in your script. Although it unfortunately is not what you intend to do, I hope this helps to find a potential bug in MVTools-pfmod.

MysteryX
2nd August 2017, 17:59
Indeed it crashes with the combination of BlkSize and Overlap. If I set Overlap=0, it doesn't crash.

Performance-wise, BlkSize=8 runs at 51% CPU with 8 threads (1080p with 0 overlap)

FPS (min | max | average): 1.308 | 101671 | 8.866
Memory usage (phys | virt): 1531 | 1537 MiB
Thread count: 29
CPU usage (average): 51%


BlkSize=16 runs at 39% CPU and is much slower

FPS (min | max | average): 0.313 | 83516 | 3.048
Memory usage (phys | virt): 1429 | 1431 MiB
Thread count: 29
CPU usage (average): 39%


BlkSize=12 is even slower

FPS (min | max | average): 0.294 | 93537 | 2.691
Memory usage (phys | virt): 1387 | 1389 MiB
Thread count: 29
CPU usage (average): 39%

BlkSize=8 with DCT=0 runs at 64% CPU and is only twice faster than DCT=1

FPS (min | max | average): 2.481 | 97435 | 15.34
Memory usage (phys | virt): 1528 | 1540 MiB
Thread count: 29
CPU usage (average): 64%

manolito
2nd August 2017, 18:40
Which version of fftw3.dll are you guys using? The plugin archive comes with three different versions (float, double and long), and after doing some research I always use the float version. Could different versions be responsible for the speed differences with DCT=1 ?

StainlessS
2nd August 2017, 18:42
Already posted about it somewhere, Pinterf fixed it in his later builds.
OverLap has to be 0 in some builds on final use of vectors.

Something bout it here:

https://forum.doom9.org/showthread.php?p=1785084#post1785084
https://forum.doom9.org/showthread.php?p=1785099#post1785099
https://forum.doom9.org/showthread.php?p=1785795#post1785795

EDIT:
Mani, libfftw3f-3.dll. Also use renamed to fftw3.dll (Although some plugins were fixed to use either name).

poisondeathray
2nd August 2017, 19:07
Does what feisty say about the vpy version have anything to do with it ?

mvtools got this little "temporal" parameter that requires a linear frame request, it's incompatible with multi threading and got removed in the VS versions (both jackoneill's and mine)
Maybe it was on in ur avs mt mess and got the shit all fucked up
https://forum.doom9.org/showthread.php?p=1813996#post1813996

The error message I got when testing the one in post 359 seemed related, something about threading incompatible blah blah. Sorry I don't have the exact error message right now. The vpy version didn't crash with the same settings

If so, would it be a better approach to modify mvtools-pfmod and use the settings without restrictions ? Is it even possible and what would be the pros/cons of doing it ? eg Would it "break" other things?

MysteryX
2nd August 2017, 19:10
MvTools2 has bugs to fix but Pinterf is on holidays still for the next 2 weeks and you won't hear from him until then

MysteryX
23rd August 2017, 17:06
From what I understand, SAD calculation is central to MvTools2. It takes a large amount of data in, does a very linear processing, and returns only the sum.

This is where GPU processing would excel! Especially with DCT=1. If anyone wants to take that as a project.

burfadel
24th August 2017, 04:22
To overcome transfer inefficiency the more done on the GPU before the transfer back the better. More like transfer to GPU, series of commands, transfer back.

PinterF, any chance of porting over the 'STAR' search method from x265 (it itself ported). It has the effectiveness of exhaustive search and is about as fast as UMH, sometimes faster. Additionally it may not even be optimised to it's full extent in AVX, AVX2 etc, so x265 could potentially benefit as well.

MysteryX
24th August 2017, 19:01
Is SVPFlow1 (https://www.svp-team.com/wiki/Manual:SVPflow)'s source code available somewhere? If someone wants to look into adding some GPU acceleration, using code from that library would be a good place to start -- but I can't find it anywhere.

MysteryX
24th August 2017, 19:45
Linking to some bugs here (https://forum.doom9.org/showthread.php?p=1816184#post1816184)

MysteryX
24th August 2017, 22:11
Here's the source code of SVPFlow1 which uses GPU acceleration
https://www.svp-team.com/files/gpl/svpflow1-src.zip

pinterf
25th August 2017, 14:57
Does DCT=1 have the same issues with BlkSize=8 that doesn't use FFTW?


ColorBarsHD()
ConvertToYV12()
jm_fps()
Prefetch(8)

function jm_fps(clip source, float "fps")
{
fps = default(fps, 60)
fps_num = int(fps * 1000)
fps_den = 1000

prefiltered = RemoveGrain(source, 22)
super = MSuper(source, hpad = 16, vpad = 16, levels = 1) # one level is enough for MRecalculate
superfilt = MSuper(prefiltered, hpad = 16, vpad = 16) # all levels for MAnalyse
backward = MAnalyse(superfilt, isb = true, blksize = 8, overlap = 4, search = 3, dct = 1)
forward = MAnalyse(superfilt, isb = false, blksize = 8, overlap = 4, search = 3, dct = 1)
forward_re = MRecalculate(super, forward, blksize = 4, overlap = 2, thSAD = 100)
backward_re = MRecalculate(super, backward, blksize = 4, overlap = 2, thSAD = 100)
out = MFlowFps(source, super, backward_re, forward_re, num = fps_num, den = fps_den, blend = false, ml = 200, mask = 2)

return out
}



Exception 0xC0000005 [STATUS_ACCESS_VIOLATION]
Module: C:\Windows\SysWOW64\KernelBase.dll
Address: 0x76C3A9F2

WOOPS!!
WOOPS indeed!
Spent a day on this issue. Thanks for the script, the memory exception appeared immediately. After catching the exception, it turned out that a non-valid motion vector resulted in a memory read past the bottom line of the frame. What? Nonzero motion vectors for a static colorbar clip? Finally it turned out that in mt mode sometimes real motion vectors were generated, even for a blank black clip.

The problem is that the assembly code that calculates integer dct for 8x8 block sizes is _not_ thread safe. It has a single internal buffer of 8x8 words and there is a possibility that the threads are using it parallelly, thus messing up the internal calculations.

At least this is my assumption. Providing a new buffer parameter for this assembly routine (different one for each filter instance), the problem disappeared and the results became consistent (same input -> same output).

GMJCZP
25th August 2017, 15:04
Hello pinterf, what happened to what I put in the post #353. Thanks.

pinterf
25th August 2017, 15:26
Hello pinterf, what happened to what I put in the post #353. Thanks.
"I noticed that the parameter search = 5 (Umh) produces identical results as search = 4 (Hex). In x264 the results are different."
Umh starts with cross search then with a "ring" of radius 4 (or rings with radius 4, 8, ... depending on the search param), and is finally using hex search.

The two methods are different by looking at the code, though there is a comment saying that "// my mod: do not shift the center after Cross"

MysteryX
25th August 2017, 19:34
Welcome back! Perhaps you could look into the "MRecalculate: wrong pixel type" error I'm getting when combining FRC with mClean as a priority? This one should be easy to fix and is blocking me

GMJCZP
25th August 2017, 21:12
Umh starts with cross search then with a "ring" of radius 4 (or rings with radius 4, 8, ... depending on the search param), and is finally using hex search.

The two methods are different by looking at the code, though there is a comment saying that "// my mod: do not shift the center after Cross"

What? :confused:

MysteryX
25th August 2017, 22:08
It seems MvTools2 is the plugin everybody uses yet nobody understands and nobody wants to fix. There are tons of bugs that have been there since the start and that were never fixed.

As for MT issues with DCT=1, the VapourSynth version works perfectly fine so the ff3d library isn't responsible for the issues.

pinterf
28th August 2017, 07:48
It seems MvTools2 is the plugin everybody uses yet nobody understands and nobody wants to fix. There are tons of bugs that have been there since the start and that were never fixed.
Good. You can start fixing those tons of bugs... If you want, of course.

MysteryX
28th August 2017, 15:24
Good. You can start fixing those tons of bugs... If you want, of course.
I tried but gave up before getting local compilation to work.

pinterf
30th August 2017, 10:41
Back-from-the-holiday edition.

Download MvTools2 2.7.22 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.22)

- 2.7.22 (20170830)
Misc: Stop using version suffix .22
Fix: [DCT 8x8@8bit] garbage on x64: internal assembly code did not save xmm6/xmm7
Fix: [DCT 8x8@8bit] safe multithreading for integer DCT (8x8 block size, 8 bit video): assembly had a single working buffer.
Fix: [MDegrain] did not release input motion vector clips in destructor, possible hang at script closing. Bug since 2.7.1.22 (introducing MDegrain4/5)
Mod: fftw conversion constant of sqrt(2)/2 is more accurate (was:0.707), 16 bit formats may benefit (by feisty2)
Fix: SSE4 assembly instructions in x64, broke on non-SSE4 processors

This release fixes some ancient issues.

Multithreaded scripts using the integer DCT path (8x8 block size, 8 bits) now are producing identical results for each runs. Sor far they were different because of the single common internal buffer, which got overwritten and used by different threads simultaneously. With special input clips (like ColorbarsHD) it resulted in access violation. Thanks for MysteryX for the report and the script.

After an analysis with integer dct, the x64 version is now giving the same result as the 32-bit version. Previously it was different and wrong, because the assembly code did not save xmm6 and xmm7 registers, which is compulsory on x64. This one was a very hard-to-find problems.

yup
30th August 2017, 15:23
pinterf :thanks: for update.
Now some my scripts work stable.
But I see strange behaviour when open scripts in VirtualDubMod, I do not see error message if I writen script with error related to MVTools functions, during this VirtatualDub hung and not response.
I can not close video in Vitualdub, only close Vitualdub.
Job control also do not work.
Please advice.

yup.

pinterf :thanks:
With last update issue gone.
yup.

MysteryX
30th August 2017, 17:59
Previously it was different and wrong, because the assembly code did not save xmm6 and xmm7 registers, which is compulsory on x64.
:eek:

How much time did you spend on this?

btw did you have time to look at what is causing the weird "MReclaculate: wrong pixel type" error?

FranceBB
30th August 2017, 18:27
Thanks for your hard work, really appreciated! :)
Works like a charm in XP x86.

GMJCZP
31st August 2017, 01:15
pinterf, I appreciate your efforts. But I still doubt why dct = 4 and dct = 5 produce identical results, and of course with dct=0.

pinterf
31st August 2017, 15:21
pinterf, I appreciate your efforts. But I still doubt why dct = 4 and dct = 5 produce identical results, and of course with dct=0.

From an earlier post:
"noticed that the parameter search = 5 (Umh) produces identical results as search = 4 (Hex). In x264 the results are different."

Now I'm confused, dct or search parameter? Or both? Is there any parameter combination that produces different result? Could you help me by posting a script which I can use for testing?

GMJCZP
31st August 2017, 15:31
Script as example:

Here (https://forum.doom9.org/showthread.php?p=1813061#post1813061)

Sorry if I was confusing you. It's search and not dct parameter.

If for example, I want to use search= 5 in MRecalculate the result is equal to search =4, which should not be.

burfadel
31st August 2017, 16:03
I'm presuming hex and umh are from x264, x265 used those from x264. x265 also has STAR like I mentioned earlier. If you're looking into hex and umh, might be something to consider since it's performance is between hex and umh, but performs like exhaustive.

real.finder
2nd September 2017, 23:23
So, now, with the latest VapourSynth version of this MVTools, how would one write the Stab script with these new Depans in MVTools? I'm using Staxrip 1.6 x64, VapourSynth filter setup if that helps.


you should post here https://forum.doom9.org/forumdisplay.php?f=82

tebasuna51
3rd September 2017, 10:30
Lynx_TWO post moved to https://forum.doom9.org/showthread.php?t=174854

MysteryX
8th September 2017, 20:38
I'm getting a bunch of issues compiling.

First, YASM v1.3 doesn't work, need to use YASM v1.2 which works.

Then, I got a bunch of errors with mvtools.rc, which maybe is because I'd need to install MFC just for that. I commented the file and it worked.

Debug compilation works, but release gives me this:
cannot open input file 'Win32\Release\mvtools\Bilinear.obj'

Looking into the "MRecalculate: wrong pixel type" error.

First, the error isn't when processing the prefilter clip, but rather, is complaining that MAnalyze on the prefilter returned a different type than what we're trying to re-analyze.

The weird thing is that loading the prefilter with AviSource or LWLibavVideoSource gives a different pixel type.

LWLibavVideoSource gives pixel type -1610612720
AviSource gives pixel type -1610612728

Is there a way to easily know in the debugger what these values represent?

Now I'm testing the latest version of mClean with the latest version of mvtools2 and somehow it's now working as a prefilter. However, performance is atrocious!! (with no MT)


Pref=LWLibavVideoSource("Pref.avi")
FrameRateConverter(60, preset="slower", Prefilter=Pref)

FPS (min | max | average): 0.113 | 6.759 | 0.541
Memory usage (phys | virt): 1024 | 1031 MiB
Thread count: 27
CPU usage (average): 11%


FrameRateConverter(60, preset="slower", Prefilter=mClean(rn=10))

FPS (cur | min | max | avg): 0.032 | 0.028 | 6.813 | 0.129
Memory usage (phys | virt): 1099 | 1175 MiB
Thread count: 21
CPU usage (current | average): 12% | 12%

Groucho2004
8th September 2017, 21:32
Then, I got a bunch of errors with mvtools.rc, which maybe is because I'd need to install MFC just for that. I commented the file and it worked.
You should only need winres.h and of course the rc compiler which is part of the platform SDK. Make sure you have the SDK installed and the environment set up.

Edit: I see that the .rc file does include "afxres.h". Simplify the file like this:
#include <winres.h>

VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,6,0,5
PRODUCTVERSION 2,6,0,5
FILEOS VOS_NT
FILETYPE VFT_DLL
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "Motion estimation and compensation"
VALUE "CompanyName", "A.G.Balakhnin aka Fizick, fizick@avisynth.org.ru"
VALUE "FileDescription", "MVTools plugin for AviSynth "
VALUE "FileVersion", "2.6.0.5"
VALUE "InternalName", "mvtools"
VALUE "LegalCopyright", "2004 Manao, 2005 Fizick, 2008 TSchniede under GNU GPL v2"
VALUE "OriginalFilename", "mvtools.dll"
VALUE "ProductName", "mvtools"
VALUE "ProductVersion", "2, 6, 0, 5"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END


Alternatively, try this (https://stackoverflow.com/questions/35436654/cant-open-resource-file-in-vs-2015-cant-open-include-file-afxres-h).

LWLibavVideoSource gives pixel type -1610612720
AviSource gives pixel type -1610612728

Is there a way to easily know in the debugger what these values represent?
From avisynth.h:
// YV12 must be 0xA000008 2.5 Baked API will see all new planar as YV12
// I420 must be 0xA000010

-1610612720 = 0xA000010 = i420
-1610612728 = 0xA000008 = YV12

MysteryX
9th September 2017, 20:21
-1610612720 = 0xA000010 = i420
-1610612728 = 0xA000008 = YV12
What's the difference between YV12 and I420?

mClean takes 20 minutes to encode.
FrameRateConverter(preset="slower") takes 3 hours on a 3 minutes 1080p clip

FrameRateConverter(preset="slower", prefilter=mClean(rn=10)) now does work (Pinterf, did you change something here?) but... with 4 instances, it would take at least 22 hours of work!! if it ever finishes

I tried running the prefilter into a separate script and loading it with AviSource. Then I get again "MRecalculate: wrong pixel type"

This script, however, works. (but SLOW and taking a LOT of memory!!)

LWLibavVideoSource("Preview.avi", cache=False)
AudioDub(LWLibavAudioSource("Preview.avi", cache=False))
Pref=AviSource("PreviewPref.avs")
ConvertToYV16().ConvertToYV12()
FrameRateConverter(NewNum=60, NewDen=1, Preset="slower", prefilter=Pref)


In terms of debugging, I wouldn't even know where to look.

Groucho2004
9th September 2017, 21:14
What's the difference between YV12 and I420?
Why don't you just search for YV12/i420 in avisynth.h and see how the values are constructed?
I think this is the main difference:
CS_VPlaneFirst = 1 << 3, // YV12, YV16, YV24, YV411, YUV9
CS_UPlaneFirst = 1 << 4, // I420
...
...
CS_YV12 = CS_GENERIC_YUV420 | CS_Sample_Bits_8, // YVU 4:2:0 planar
CS_I420 = CS_PLANAR | CS_YUV | CS_Sample_Bits_8 | CS_UPlaneFirst | CS_Sub_Height_2 | CS_Sub_Width_2, // YUV 4:2:0 planar

MysteryX
9th September 2017, 21:26
uh... the difference is YVU vs YUV !? so something along the chain isn't handling that right. It could be anywhere though.

This bug started happening when converting the prefilter to 16-bit and then back to 8-bit.

Then it has been partially resolved in the latest version of MvTools (?)

TheFluff
9th September 2017, 21:47
People being overly specific and comparing format constants directly when they should be using IsYV12() has a long history in Avisynth. It's extremely rarely for filters to treat U and V differently so most filters don't need to know the plane order. I wrote this Avisynth wiki page (http://avisynth.nl/index.php/I420) a long time ago because I got annoyed about people repeating the same mistake.

You can try SwapUV if you want to try a workaround, but I'm unsure if that swaps the format constant or the actual plane pointers.

MysteryX
9th September 2017, 23:33
Yeah I was thinking of Swap, but then it's "working" with the latest version, in most cases. In the code, IsYV12 wouldn't work because it's comparing whether the format being recalculated is the same format that was analyzed, thus it compares both constants.

I just tried this code and it's working. I get a stable 0.333fps on a single instance.


P="Encoder\"
LoadPlugin(P+"MP_Pipeline.dll")
SetMemoryMax(1)

MP_Pipeline("""
### inherit start ###
P="Encoder\"
LoadPlugin(P+"LSMASHSource.dll")
LoadPlugin(P+"MvTools2.dll")
LoadPlugin(P+"MaskTools2.dll")
LoadPlugin(P+"FFT3DFilter.dll")
LoadPlugin(P+"ModPlus.dll")
LoadPlugin(P+"RgTools.dll")
LoadPlugin(P+"DCTFilter.dll")
Import(P+"MClean.avsi")
Import(P+"FrameRateConverter.avsi")
LoadPlugin(P+"FrameRateConverter.dll")
file="Like a Cat.mp4"
### inherit end ###

LWLibavVideoSource(file, cache=False)
MClean(rn=10)
### prefetch: 2, 2
### ###

Pref=last
LWLibavVideoSource(file, cache=False)
FrameRateConverter(60, preset="slower", Prefilter=Pref)
### prefetch: 2, 2
### ###
""")

AudioDub(LWLibavAudioSource(file, cache=False))


However, running this over 4 instances gives still unreasonable performance, perhaps because I'm running out of memory with 8GB. I get 0.6fps giving an encoding time of 9h.

The only thing that works well if I want to use mClean as a prefilter is to first encode into an AVI and then reload that into the main script.

MysteryX
10th September 2017, 05:56
I just realized something.

I have this video
Video: MPEG4 Video (H264) 1920x1080 25fps 3268kbps [V: h264 high L4.0, yuv420p, 1920x1080, 3268 kb/s]

After encoding with FrameRateConverter it became
Video: I420 1920x1080 60fps [V: rawvideo, yuv420p, 1920x1080]

This means the output of MFlowFps is mistakenly I420 instead of YV12, and when that's being re-fed as input for another round of MAnalyze/MRecalculate, that causes a format mismatch.

Groucho2004
10th September 2017, 08:47
I just realized something.

I have this video
Video: MPEG4 Video (H264) 1920x1080 25fps 3268kbps [V: h264 high L4.0, yuv420p, 1920x1080, 3268 kb/s]

After encoding with FrameRateConverter it became
Video: I420 1920x1080 60fps [V: rawvideo, yuv420p, 1920x1080]

This means the output of MFlowFps is mistakenly I420 instead of YV12, and when that's being re-fed as input for another round of MAnalyze/MRecalculate, that causes a format mismatch.
I don't know what "encoding with FrameRateConverter" means but you can easily check the returned color space of a script with AVSMeter. It has the correct mappings of returned values according to the latest AVS+ header.

pinterf
11th September 2017, 10:32
The output format of MFlowFps should be the same as of the input clip.

burfadel
24th September 2017, 10:09
There seems to be a bug in MScaleVect that causes a shift to the left, as reported by MysteryX in mClean v1.8. I didn't notice it before because I wasn't looking for it, but I can see now! It isn't related to blocksize or other settings, and even the simplest of uses. It affects areas of motion more which makes sense, and is only slight, but problematic when not doing chroma processing or doing chroma processing separately. I'm guessing it may also fractionally affect picture fidelity.

Basic example:
blksize=16
blksizeV=16
overlap=4
overlapV=4

super = MSuper (hpad=16, vpad=16)
supersc = MSuper(BicubicResize(Width/2, Height/2), hpad=16/2, vpad=16/2)

bvec2 = MAnalyse (supersc, isb = true, delta = 2, blksize=blksize/2, blksizeV=blksizeV/2, overlap=overlap/2, overlapV=overlapV/2)
bvec1 = MAnalyse (super, isb = true, delta = 1, blksize=blksize, blksizeV=blksizeV, overlap=overlap, overlapV=overlapV)
fvec1 = MAnalyse (super, isb = false, delta = 1, blksize=blksize, blksizeV=blksizeV, overlap=overlap, overlapV=overlapV)
fvec2 = MAnalyse (supersc, isb = false, delta = 2, blksize=blksize/2, blksizeV=blksizeV/2, overlap=overlap/2, overlapV=overlapV/2)

bvec2 = MscaleVect (bvec2, 2)
fvec2 = MscaleVect (fvec2, 2)

Mdegrain2(super, bvec2, bvec1, fvec1, fvec2)

It also occurs if you use MScaleVect right through:
blksize=16
blksizeV=16
overlap=4
overlapV=4

super = MSuper (hpad=16, vpad=16)
supersc = MSuper(BicubicResize(Width/2, Height/2), hpad=16/2, vpad=16/2)

bvec2 = MAnalyse (supersc, isb = true, delta = 2, blksize=blksize/2, blksizeV=blksizeV/2, overlap=overlap/2, overlapV=overlapV/2)
bvec1 = MAnalyse (supersc, isb = true, delta = 1, blksize=blksize/2, blksizeV=blksizeV/2, overlap=overlap/2, overlapV=overlapV/2)
fvec1 = MAnalyse (supersc, isb = false, delta = 1, blksize=blksize/2, blksizeV=blksizeV/2, overlap=overlap/2, overlapV=overlapV/2)
fvec2 = MAnalyse (supersc, isb = false, delta = 2, blksize=blksize/2, blksizeV=blksizeV/2, overlap=overlap/2, overlapV=overlapV/2)

bvec2 = MscaleVect (bvec2, 2)
bvec1 = MscaleVect (bvec1, 2)
fvec1 = MscaleVect (fvec1, 2)
fvec2 = MscaleVect (fvec2, 2)

Mdegrain2(super, bvec2, bvec1, fvec1, fvec2)

This would affect all functions that use MScaleVect, which is why it probably doesn't work very well with MFlowFPS.

pinterf
25th September 2017, 15:14
There seems to be a bug in MScaleVect that causes a shift to the left, as reported by MysteryX in mClean v1.8. I didn't notice it before because I wasn't looking for it, but I can see now! It isn't related to blocksize or other settings, and even the simplest of uses. It affects areas of motion more which makes sense, and is only slight, but problematic when not doing chroma processing or doing chroma processing separately. I'm guessing it may also fractionally affect picture fidelity.
I have checked the source (https://github.com/pinterf/mvtools/blob/mvtools-pfmod/Sources/MScaleVect.cpp#L162), vectors are scaled with multiplication by the factor, add 0.5 as rounding, then casted back to integer.

Just an idea:

Casting to integer simply strips the decimal part off, but I think the rounder value should should be -0.5 when x or y part of the vector is negative
(x,y) = (2,3) -> (2*2+0.5, 3*2 + 0.5) -> (4.5, 6.5) -> (4,6)
(x,y) = (-2,-3) -> (-2*2+0.5, -3*2 + 0.5) -> (-3.5, -5.5) -> (-3,-5)

Obviously the results for negative vector components are incorrect.
-1 scaled by 2 remains -1
-2 scaled by 2 is -3, etc...

I don't know if the shifts you are experiencing can be explained by this logic, but anyway, I can build a test version and provide a link to you.

burfadel
25th September 2017, 15:51
Sounds good. MysteryX might also be interested in it for FrameRateConverter.

EDIT: Thanks Pinterf for the test build, it works much better! I presume you got the reply pm I wrote. After testing I was short on time and sent it in a hurry.

pinterf
12th October 2017, 14:05
New build: MvTools2 2.7.23 with depans

Download:
https://github.com/pinterf/mvtools/releases/tag/2.7.23

- 2.7.23 (20171012)
Fix: MScaleVect wrong rounding of scaled motion vectors with negative components.
e.g. proper scaling (-1;-2) to (-2;-4) instead of (-1,-3)

Thanks for the patience.

Taurus
12th October 2017, 15:21
Thank You,Sir!:thanks:

burfadel
12th October 2017, 16:48
Yes, thankyou :)

FranceBB
12th October 2017, 18:58
Thank you! :D

nhope
31st October 2017, 05:28
Does MVTools-pfmod in itself require libfftw3f-3.dll? If so, is it just for certain functions? The requirements section of the QTGMC wiki (http://avisynth.nl/index.php/QTGMC#Requirements) says it does, but I don't find that stated in any MVTools documentation.

pinterf
31st October 2017, 08:57
Does MVTools-pfmod in itself require libfftw3f-3.dll? If so, is it just for certain functions? The requirements section of the QTGMC wiki (http://avisynth.nl/index.php/QTGMC#Requirements) says it does, but I don't find that stated in any MVTools documentation.
Used in MAnalyze when dct parameter is not 0. 8x8 block size in 8-bit clips is an exception, because it uses integer fft instead

nhope
31st October 2017, 10:25
Thank you for the clarification pinterf.

MysteryX
15th November 2017, 06:35
I was wondering, is it possible to calculate the vectors on a 8-bit clip and then apply them on a 16-bit? King of like the ScaleVect function but that scales the bit depth. Analyzing vectors in 16-bit takes WAY longer.

pinterf
15th November 2017, 09:32
I was wondering, is it possible to calculate the vectors on a 8-bit clip and then apply them on a 16-bit? King of like the ScaleVect function but that scales the bit depth. Analyzing vectors in 16-bit takes WAY longer.
It could work like MScaleVect, but bit-depth difference (instead of blocksize) should affect SAD readjustment.

On the other hand, I planned to revise 10-16 bit SAD functions, now they are simd intrinsics, which can be changed into faster hand written asm. And it can be even faster for 10 or 12 bits, taking into consideration of possible sum overflows.

MysteryX
15th November 2017, 18:03
and there was the addition of STAR search method which would be interesting when you have time for that

MysteryX
5th December 2017, 05:39
btw it has been a while now... any chance for the bug regarding DCT=1 being slow with MT to be fixed?

pinterf
5th December 2017, 06:10
How do you know it's a bug and not something that is inevitable when using floating point fft from this external library?

MysteryX
5th December 2017, 18:59
The VapourSynth version works perfectly fine and is using the same library AFAIK.

pinterf
5th December 2017, 19:07
New release.

Download MvTools2 2.7.24 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.24)

A fix for a crash (see topic (https://forum.doom9.org/showthread.php?t=175076)) in MFlowBlur. I think it was there from the beginnings.

And there is a smart speedup upon MysteryX idea: generate vectors in 8 bits, then use MScaleVect to make it usable for an e.g. 16 bit MDegrain. On my pre-AVX2 PC it gave me more than 50% speedup for a basic MDegrain3 scenario. Try and give feedback.

- 2.7.24 (20171205)
Fix: MFlowBlur: possible access violation crash when nPel>1
New: MScaleVect parameter 'bits'. e.g. Analyze 8 bit clips, use their vectors for 16 bits
Move project to VS2017

For MScaleVect see documentation in the release pack, in the Documentation folder: mvtools2.html.

In brief: MScaleVect has a new parameter: 'bits'. When specified, the default value of the scale parameter is 1.0 instead of 2.0. So when you use 'bits' only, then the vectors won't be scaled by default by 2.

Example: basic process, analyze in 16 bits

a=..source
bit=16
blksize = 16
blksizeV = 16
a8=a
a=a.ConvertBits(bit)

sup = a.MSuper(pel=2) #pel=2

fv1 = sup.MAnalyse(isb=false, delta=1, overlap=ov, blksize = blksize, blksizev = blksizev)
bv1 = sup.MAnalyse(isb=true, delta=1, overlap=ov, blksize = blksize, blksizev = blksizev)
fv2 = sup.MAnalyse(isb=false, delta=2, overlap=ov, blksize = blksize, blksizev = blksizev)
bv2 = sup.MAnalyse(isb=true, delta=2, overlap=ov, blksize = blksize, blksizev = blksizev)
fv3 = sup.MAnalyse(isb=false, delta=3, overlap=ov, blksize = blksize, blksizev = blksizev)
bv3 = sup.MAnalyse(isb=true, delta=3, overlap=ov, blksize = blksize, blksizev = blksizev)

a.MDegrain3(Sup, bv1, fv1, bv2, fv2, bv3, fv3, thSAD=1000)

faster way resulting in almost similar result


a=..source
ov=8
bit=16
blksize = 16
blksizeV = 16
a8=a
a=a.ConvertBits(bit)

sup = a.MSuper(pel=2)
sup8 = a8.MSuper(pel=2)

fv1 = sup8.MAnalyse(isb=false, delta=1, overlap=ov, blksize = blksize, blksizev = blksizev)
bv1 = sup8.MAnalyse(isb=true, delta=1, overlap=ov, blksize = blksize, blksizev = blksizev)
fv2 = sup8.MAnalyse(isb=false, delta=2, overlap=ov, blksize = blksize, blksizev = blksizev)
bv2 = sup8.MAnalyse(isb=true, delta=2, overlap=ov, blksize = blksize, blksizev = blksizev)
fv3 = sup8.MAnalyse(isb=false, delta=3, overlap=ov, blksize = blksize, blksizev = blksizev)
bv3 = sup8.MAnalyse(isb=true, delta=3, overlap=ov, blksize = blksize, blksizev = blksizev)
fv1 = fv1.MScalevect(bits=16)
bv1 = bv1.MScalevect(bits=16)
fv2 = fv2.MScalevect(bits=16)
bv2 = bv2.MScalevect(bits=16)
fv3 = fv3.MScalevect(bits=16)
bv3 = bv3.MScalevect(bits=16)

a.MDegrain3(Sup, bv1, fv1, bv2, fv2, bv3, fv3, thSAD=1000)

real.finder
5th December 2017, 21:57
New release.

Download MvTools2 2.7.24 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.24)


thanks, now we can use MAnalyze with high bit without need to filtering all things in high bit for 8 bit clips especially when chroma=false, I think this can make it more accurate for filtering 8 bit clips since the motion Analyze done in HBD

aside form that, when masktools turn come for update?

MysteryX
6th December 2017, 02:40
Great job on the update!

Quality-wise, I'd be curious as to the difference between analyzing vectors in 8-bit or 16-bit, but since 16-bit processing was prohibitively slow and we were always better off using a slower preset in 8-bit, the real comparison should be between 8-bit processing and 8-bit analysis + 16-bit motions, both in terms of quality and performance.

How do you know it's a bug and not something that is inevitable when using floating point fft from this external library?
Perhaps you could give it a try with VapourSynth to be sure?

Other people have reported it was perfectly stable with 100% CPU usage.

Other great feature would be STAR search method. You can't use that library for that but you can copy/paste it from x265 library.

pinterf
6th December 2017, 09:02
Other great feature would be STAR search method. You can't use that library for that but you can copy/paste it from x265 library.
Copy-paste??? Have you seen the source in mvtools and the one in x265? Spent quite a few hours on investigating the feature but couldn't get a grip on it. I found no common points between the two sources. Right now I don't feel like spending days or weeks on the problem.

MysteryX
6th December 2017, 12:33
Copy-paste??? Have you seen the source in mvtools and the one in x265? Spent quite a few hours on investigating the feature but couldn't get a grip on it. I found no common points between the two sources. Right now I don't feel like spending days or weeks on the problem.
Ya copy/paste seems to work better in Word than in C++, somehow

Groucho2004
6th December 2017, 13:08
Ya copy/paste seems to work better in Word than in C++, somehow
Hilarious! :D:D

MysteryX
6th December 2017, 17:33
but then when I was working for L'Oreal in Paris, my job was mostly to port code from one of their core framework to another (back-porting), running on different versions of .NET

Copy/paste served well.

but .NET isn't C++ :)

Gavino
6th December 2017, 18:19
but then when I was working for L'Oreal in Paris, my job was mostly to port code from one of their core framework to another (back-porting), running on different versions of .NET

Copy/paste served well.
It may well have been appropriate for this particular job (I don't know), but your approach sounds a bit like cargo-cult programming.

https://en.wikipedia.org/wiki/Cargo_cult_programming
"The term cargo cult programmer may apply when an unskilled or novice computer programmer (or one inexperienced with the problem at hand) copies some program code from one place to another with little or no understanding of how it works or whether it is required in its new position."

MysteryX
6th December 2017, 18:28
It may well have been appropriate for this particular job (I don't know), but your approach sounds a bit like cargo-cult programming.
Simply L'Oreal is building all their e-commerce websites over a platform that they keep upgrading over time, and while many of their websites use their latest platform, the large website I was responsible for (using 50GB databases and $200k of sales per day!!) stayed on an older version of their platform because specific optimizations were required for that website -- and then sometimes the newer features were needed in that older platform and thus had to be back-ported.

This is no different than any other company. As Windows or Linux get security fixes, those fixes are back-ported to older versions.

https://en.wikipedia.org/wiki/Cargo_cult_programming
"The term cargo cult programmer may apply when an unskilled or novice computer programmer (or one inexperienced with the problem at hand) copies some program code from one place to another with little or no understanding of how it works or whether it is required in its new position."
This sounds like what's needed to port STAR, whatever it is! Pinterf, tried that (https://www.google.com/search?q=cult+programming+tutorial)?

real.finder
12th December 2017, 17:29
so I back to this https://forum.doom9.org/showthread.php?p=1783190#post1783190

with 8 bit motion analyze

https://s8.postimg.org/54o0jeyb5/8bit_an_55.png (https://postimg.org/image/54o0jeyb5/)

then with 16 bit motion analyze

https://s8.postimg.org/qflknf0xd/16bit_an_55.png (https://postimg.org/image/qflknf0xd/)


LSMASHVideoSource("chroma.mp4")
c=last

ConvertBits(16)
SMDegrain(globals=3,chroma=false )
global fv1 = fv1.MScalevect(bits=8)
global bv1 = bv1.MScalevect(bits=8)
global fv2 = fv2.MScalevect(bits=8)
global bv2 = bv2.MScalevect(bits=8)
#~ SMDegrain(globals=3,chroma=false )

c
SMDegrain(globals=1)
ConvertBits(8)


There is an improvement in some places, but some few others are inverse (worst)

burfadel
3rd February 2018, 04:56
With MVtools 2.7.24, it says in the included docs (as well as the original for MVTools) that the parameters for MSCDetection include Ysc, however if specifying Ysc it says MSCDetection does not have a named argument "Ysc".

Additionally, no matter what settings for thSCD1 and thSCD2 I use, the whole output is either completely black or completely white for extended periods when using a Y8 source (even in 8-bit). Isn't the output just supposed to be white for the first frame of a detected scenechange? Creates scene detection mask clip from motion vectors data. The mask is created both on the luma and on chroma planes. Output without scene change is 0.
I'm looking to invert this so scene changes are black and the rest is white in the mask. How do the other functions like MFlowFPS, MDegrain etc work internally regarding scene changes presuming they are working correctly?

If using an 8-bit Y12 source with chroma channels, the output is just a single colour like pink or green! Using the default settings, the whole 29 minute show of the clip I used for Masktools (UK Men Behaving Badly), using the Y12 8 bit source there was just a bit of pink output at the beginning for a couple of seconds and the rest was in green. For Y8 it was white at the beginning for those few seconds and the rest of the show was black. There were of course a quite a lot of scene changes that were meant to be there!

pinterf
4th February 2018, 10:01
With MVtools 2.7.24, it says in the included docs (as well as the original for MVTools) that the parameters for MSCDetection include Ysc, however if specifying Ysc it says MSCDetection does not have a named argument "Ysc".
Good catch. Contrary to the documentation the implemented name of the parameter is Yth (and as I see it was the case in the old 2.5.x times), which is obviously wrong, because it has the very same purpose as in MMask. It seems that this parameter was never used as a named parameter and probably left on the default.

Additionally, no matter what settings for thSCD1 and thSCD2 I use, the whole output is either completely black or completely white for extended periods when using a Y8 source (even in 8-bit). Isn't the output just supposed to be white for the first frame of a detected scenechange?
I'm looking to invert this so scene changes are black and the rest is white in the mask. How do the other functions like MFlowFPS, MDegrain etc work internally regarding scene changes presuming they are working correctly?

If using an 8-bit Y12 source with chroma channels, the output is just a single colour like pink or green! Using the default settings, the whole 29 minute show of the clip I used for Masktools (UK Men Behaving Badly), using the Y12 8 bit source there was just a bit of pink output at the beginning for a couple of seconds and the rest was in green. For Y8 it was white at the beginning for those few seconds and the rest of the show was black. There were of course a quite a lot of scene changes that were meant to be there!
(Y12 is YV12 I suppose, and not a 12 bit greyscale)
Once StainlessS provided me this test script, could you try this, this works for me.

<source>
ConvertBits(8) #or whatever

Function EndOfSceneClip(clip c,Int "thSCD1",Int "thSCD2") { # All Luma Samples set 255 at EOS
thSCD1=Default(thSCD1,400) thSCD2=Default(thSCD2,130)
sup=c.MSuper(pel=1,sharp=0,rfilter=2,hpad=16, vpad=16)
bv=sup.MAnalyse(isb=true, delta=1,blksize=16/*,overlap=8*/)
Return c.MSCDetection(bv,thSCD1=thSCD1,thSCD2=thSCD2)
}

Function StartOfSceneClip(clip c,Int "thSCD1",Int "thSCD2") { # All Luma Samples set 255 at SOS
thSCD1=Default(thSCD1,400) thSCD2=Default(thSCD2,130)
sup=c.MSuper(pel=1,sharp=0,rfilter=2,hpad=16, vpad=16)
fv=sup.MAnalyse(isb=false,delta=1,blksize=16/*,overlap=8*/)
Return c.MSCDetection(fv,thSCD1=thSCD1,thSCD2=thSCD2)
}

EOS = EndOfSceneClip()
SOS = StartOfSceneClip()
#return EOS
SSS="""
e = EOS.AverageLuma
s = SOS.AverageLuma
Subtitle(String(current_frame)+String(e,"] EOS=%.1f")+String(s," : SOS=%.1f"))
(e!=0.0)
\ ? Subtitle("End Of Scene",Size=48,Text_Color=$FF0000,Y=Height/2-24,Align=5)
\ : (s!=0.0) ? Subtitle("Start Of Scene",Size=48,Text_Color=$0000FF,Y=Height/2+24,Align=5)
\ : NOP
return last
"""

Scriptclip(SSS)
ConvertBits(8)

burfadel
4th February 2018, 12:05
Yes that works :). So how do I translate that into a mask such that it is only white at the start frame of a scene change? I want to reuse a calculate forward search 'fvec1'. The documentation makes it sound like it was a simple process of outputting such a mask.

I guess it would also be a handy inclusion in the documentation.

feisty2
4th February 2018, 12:20
but then when I was working for L'Oreal in Paris, my job was mostly to port code from one of their core framework to another (back-porting), running on different versions of .NET

Copy/paste served well.

but .NET isn't C++ :)

now I think its a bit unfair to put older C++(98, 03) and recent C++(11 and later) in the same category tho, they have very different type systems and thus have very different syntax for pretty much everything, even the most basic stuff like defining a variable or a function

the older C++ has a nominal type system, the type system inherited from C and also adopted in some other C influenced languages like java or c#, recent C++ has an inferred and structural type system with "auto" being the one and only type throughout almost the entire language, yes even for function parameters, the only type would be "auto" since C++20 (Concepts TS), so for OOP interfaces and inheritances between types are now rendered useless in C++20, instead replace them with (static variant of) duck typing OOP like in Python or JavaScript

human language, older C++ is syntactically closer to C and java, recent C++ is syntactically closer to Python and JavaScript

`Orum
13th February 2018, 18:42
I'm seeing some strange color shifting when doing 16-bit processing with MDeGrainN (it does not occur with 8-bit), toward U-/V- (AKA green). First, let me share the script I wrote to simplify using it:
################################
# Scripted_MDeGrain by `Orum #
# v0.3 on 2017-06-04 #
################################

# *NOTE* Some defaults are changed!
# Differing defaults: overlap

function Scripted_MDeGrain(clip c, bool "chroma", bool "mt", int "hpad", int "vpad", int "pel", int "MSlevels", int "sharp", int "rfilter", int "blksize", \
int "blksizeV", int "MAlevels", int "search", int "searchparam", int "pelsearch", bool "truemotion", int "lambda", int "lsad", bool "globalm", int "plevel", \
int "pnew", int "pzero", int "pglobal", int "overlap", int "overlapV", int "dct", int "divide", int "sadx264", int "badSAD", int "badrange", bool "meander", \
bool "temporal", bool "trymany", bool "multi", int "tr", int "thSAD", int "thSADC", int "plane", int "limit", int "limitC", int "thSCD1", int "thSCD2", \
bool "lsb", int "thSAD2", int "thSADC2", bool "debugSCD") {

# Shared params
chroma = default(chroma, true) # Use chroma (in addition to luma)?
mt = default(mt, true) # Use multi-threading?
tr = default(tr, 2) # Temporal radius of motion vector search

# MSuper params
hpad = default(hpad, 8) # Horizontal padding for better motion estimation
vpad = default(vpad, 8) # Vertical padding for better motion estimation
pel = default(pel, 2) # Accuracy of motion estimation (1, 2, or 4)
MSlevels = default(MSlevels, 0) # Number of hierarchical levels in super clip frames (0 = all)
sharp = default(sharp, 2) # Subpixel interpolation when pel > 1 (0 to 2)
rfilter = default(rfilter, 2) # Hierarchical levels smoothing filter (0 to 4)

# MAnalyse params
blksize = default(blksize, 8) # Horizontal block size (4, 8, or 16)
blksizeV = default(blksizeV, blksize) # Vertical block size (4, 8, or 16 - must be <= blksize?)
MAlevels = default(MAlevels, 0) # The number of levels used in the hierarchical analysis while searching for MVs
search = default(search, 4) # See readme (0 to 5)
searchparam = default(searchparam, 2) # Meaning dependant on value of search; see readme
pelsearch = default(pelsearch, pel) # Searchparam at finer levels
truemotion = default(truemotion, true) # Influences other parameter's defaults
lambda = default(lambda, truemotion ? 1000 * blksize * blksizeV / 64 : 0) # Coherence of the vector field
lsad = default(lsad, truemotion ? 1200 : 400) # SAD limit for lambda (recommended > 1000 w/ truemotion)
globalm = default(globalm, truemotion) # Estimate global motion? (only supports pans, not zoom/rotate)
plevel = default(plevel, truemotion ? 1 : 0) # Penalty for lambda level scaling (0 to 2)
pnew = default(pnew, truemotion ? 50 : 0) # Penalty to SAD cost for candidate vectors
pzero = default(pzero, pnew) # Penalty to SAD cost for zero vector
pglobal = default(pglobal, 0) # Penalty to SAD cost for global vector
overlap = default(overlap, blksize/2) # Horizontal block overlap (must be even & < blksize)
overlapV = default(overlapV, overlap) # Vertical block overlap (must be even & < blksizeV)
dct = default(dct, 0) # Use DCT for SAD calculation (0 to 10; see readme)
divide = default(divide, 0) # Post-processing for MVs (0 to 2; see readme)
sadx264 = default(sadx264, 0) # Use SAD from x264 if available (0 to 12; see readme)
badSAD = default(badSAD, 10000) # SAD threshold to widen search for bad vectors (10000 = disable)
badrange = default(badrange, 24) # Range (radius) of search for bad blocks (use positive values for UMH, negative for Exhaustive)
meander = default(meander, true)
temporal = default(temporal, false)
trymany = default(trymany, false)
multi = default(multi, false)

# MDeGrain params
thSAD = default(thSAD, 400) # SAD threshold for luma plane
thSADC = default(thSADC, thSAD) # SAD threshold for chroma planes
plane = default(plane, 4) # Set which planes to process (0 to 4; 0 = Y, 1 = U, 2 = V, 3 = UV, 4 = YUV)
limit = default(limit, 255) # Limit luma change (0 = filter has no effect, 255 = unlimited)
limitC = default(limitC, limit) # Limit chroma change (0 = filter has no effect, 255 = unlimited)
thSCD1 = default(thSCD1, 400) # Block change threshold for a scene cut
thSCD2 = default(thSCD2, 130) # Percent of blocks that must change to be a scene cut (0 to 255; 0 = 0%, 130 = 51%, 255 = 100%)
lsb = default(lsb, false)
thSAD2 = default(thSAD2, thSAD)
thSADC2 = default(thSADC2, thSADC)

# Added custom params
debugSCD = default(debugSCD, false) # Debug scene change detection thresholds (green = no cut, magenta = cut)

sup = c.MSuper(hpad=hpad, vpad=vpad, pel=pel, levels=MSlevels, chroma=chroma, sharp=sharp, rfilter=rfilter, mt=mt)
mvs = sup.MAnalyse(blksize=blksize, blksizeV=blksizeV, levels=MAlevels, search=search, searchparam=searchparam, pelsearch=pelsearch, lambda=lambda, chroma=chroma, delta=tr, truemotion=truemotion, lsad=lsad, plevel=plevel, global=globalm, pnew=pnew, pzero=pzero, pglobal=pglobal, overlap=overlap, overlapV=overlapV, dct=dct, divide=divide, sadx264=sadx264, badSAD=badSAD, badrange=badrange, meander=meander, temporal=temporal, trymany=trymany, multi=true, mt=mt)
mvd = c.MDeGrainN(sup, mvs, tr, thSAD=thSAD, thSADC=thSADC, plane=plane, limit=limit, limitC=limitC, thSCD1=thSCD1, thSCD2=thSCD2, lsb=lsb, thSAD2=thSAD2, thSADC2=thSADC2, mt=mt)

debugSCD ? StackVertical(mvd.Crop(0, 0, -0, -8), c.MSCDetection(mvs.SelectEvery(tr * 2, 1), thSCD1=thSCD1, thSCD2=thSCD2).Crop(0, 0, -0, 8)) : mvd
}

And now for the script to demonstrate the problem:
src = ColorBars(pixel_type="YV24").AddGrain(var=5, uvar=5)
ebd = src.Scripted_MDeGrain(tr=2, thSAD=150, lsb=false)
sbd = src.Scripted_MDeGrain(tr=2, thSAD=150, lsb=true).ConvertFromStacked(16).ConvertBits(8)

Interleave( \
src.Histogram("color").Crop(640, 0, -0, -224).Subtitle("source"), \
ebd.Histogram("color").Crop(640, 0, -0, -224).Subtitle("8 bit degrain"), \
sbd.Histogram("color").Crop(640, 0, -0, -224).Subtitle("16 bit degrain") \
)

Trim(999, 1001)

...which when run should output this:
https://a.pomf.cat/rngahx.png

You can clearly see the dots "migrate" toward the upper left when using the 16-bit processing. I concede that this could instead be an issue with either my script or ConvertFromStacked()/ConvertBits(), so I'd like to see if anyone else can confirm the issue is indeed in MVTools.

Edit: Forgot to mention, this is with MVTools v2.7.24, and AviSynth+ r2580

Edit2: Also, I can at least say ConvertFromStacked()/ConvertBits() are not the problem, as simply cropping to the size of the source clip instead of using those functions results in the same problem.

Edit3: The shift is perhaps even easier to spot if using Histogram("levels") instead of in the "color" mode. You can also see that this shift affects even the luma.
https://a.pomf.cat/tqupow.png

poisondeathray
13th February 2018, 23:23
^It doesn't seem to affect SMDegrain, or at least not as much for U,V .

eg. If you replace with

ebd2 = src.smdegrain(tr=2, thsad=150, lsb=false)
sbd2 = src.smdegrain(tr=2, thsad=150, lsb=true, lsb_out=true).ConvertFromStacked(16).ConvertBits(8)

interleave(src, ebd2,sbd2)
histogram("levels")

I'm not familiar with "Scripted_MDeGrain" but I would have a closer look at that to see why

`Orum
14th February 2018, 00:40
I don't use SMDegrain because it does a lot of other things within the filter that I don't want it to do (it uses several other filters IIRC), and back when I originally wrote Scripted_MDegrain it didn't even even exist. Everything within my filter should be covered by MVTools itself or the built-in functions to AviSynth.

I'm slightly curious as to why SMDegrain doesn't have as many problems, but I suspect it's due to the numerous other filters it applies.

poisondeathray
14th February 2018, 02:13
I don't use SMDegrain because it does a lot of other things within the filter that I don't want it to do

My understanding is it doesn't do anything else unless you explicitly specify it. By default TR=1 is the default MDegrain1 , TR=2 is the default MDegrain2, etc.... ie. it's just a simple wrapper for MDegrain , unless you specify the other options


I'm slightly curious as to why SMDegrain doesn't have as many problems, but I suspect it's due to the numerous other filters it applies.


I think it uses dither tools for the lsb part , so that might be the difference .

raffriff42
14th February 2018, 04:55
I'm seeing some strange color shifting when doing 16-bit processing with MDeGrainN (it does not occur with 8-bit), toward U-/V-
...

Edit3: The shift is perhaps even easier to spot if using Histogram("levels") instead of in the "color" mode.
You can also see that this shift affects even the luma.
https://a.pomf.cat/tqupow.png
This is the ConvertBits rounding error first discussed here (https://forum.doom9.org/showthread.php?p=1820991#post1820991) (although only luma shift was noticed back then, not chroma).
Use ConvertBits(8, dither=0)
EDIT or use ColorYUV(off_y=0.48, off_u=0.48, off_v=0.48).ConvertBits(8)

poisondeathray
14th February 2018, 05:11
This is the ConvertBits rounding error first discussed here (https://forum.doom9.org/showthread.php?p=1820991#post1820991).
Use ConvertBits(8, dither=0)
EDIT or use ColorYUV(off_y=0.48, off_u=0.48, off_v=0.48).ConvertBits(8)

When he just crops lsb without using convertbits, the error is still there. So it cannot be ConvertBits rounding issue



Edit2: Also, I can at least say ConvertFromStacked()/ConvertBits() are not the problem, as simply cropping to the size of the source clip instead of using those functions results in the same problem.

raffriff42
14th February 2018, 05:17
Doing that does not round, it truncates, which is the nature of the bug. No wonder they look the same.

poisondeathray
14th February 2018, 05:27
Doing that does not round, it truncates, which is the nature of the bug. No wonder they look the same.

That makes sense

DitherPost also works, which I'm guessing is what smdegrain uses

`Orum
14th February 2018, 06:01
Ah, that makes sense. Hopefully that will get fixed upstream soon, as so few utilities support anything beyond 8-bit, so the functions will see lots of use for previewing. Those that aren't aware of the bug will probably be just as puzzled as I was.

Thanks.

real.finder
14th February 2018, 20:30
I don't use SMDegrain because it does a lot of other things within the filter that I don't want it to do (it uses several other filters IIRC), and back when I originally wrote Scripted_MDegrain it didn't even even exist. Everything within my filter should be covered by MVTools itself or the built-in functions to AviSynth.



all used plugins by default are MaskTools2 and MVTools2

and you can set tv_range=false and it will be only MVTools2

pinterf
15th February 2018, 16:35
I'm seeing some strange color shifting when doing 16-bit processing with MDeGrainN (it does not occur with 8-bit), toward U-/V- (AKA green). First, let me share the script I wrote to simplify using it:
Thanks, well documented case and it seems to be a tough and very interesting problem, already spent a lot of hours on it.

First I found that 16 bit Degrain results (either stacked (since 2.6.0.5) or native) are not rounded from a 32 bit intermediate. Internally there is a 11-bit extra precision when Overlap is used. Before dropping that extra 11 bit accuracy and converting back to 8..16 bits, a 2^10 rounder should be added to have the final result.

Nor is the 8 bit code perfect, there is a 6 bit shift and its rounding at an earlier phase, and a non-rounding 5 bit shift (6+5=11) when the final result is created from a 16 bit intermediate buffer.

When I have put the proper rounding in the 16bit-like paths, the stacked version became OK, but the native still held a shift, but _only_ after ConvertBits(8). Which is a simple bit shift, the very same as striping off the lower part from a stacked-16 clip.

The script which was adding the noise is good to test. Noise is random, but on average it should be zeroed out. I'm testing with clips with uniform 128-129-128-129 pixel values, plus noise.

How could we turn the shift into numbers instead of looking at Histogram?

We can examine the native 16 bit MDegrain2 result using the AverageLuma runtime function. Interestingly, it showed similar (but of course 256 times as much) and correct result, as the 8 bit Degrain result.

But right after we are stripping the lower byte (=ConvertBits(8)), the AverageLuma result becomes much lower. E.g. AverageLuma=32696 (=127.71*256) becomes 127.42 after converting to 8 bits. Probably that means that there is only a minor residual error somewhere, which should be investigated. (And of course: at wht step does the difference appear between the stacked and the native 16 bit method.

real.finder
17th February 2018, 02:33
since the native 16 bit is slower than lsb, even with this https://forum.doom9.org/showthread.php?p=1833823#post1833823 it's little faster but still way slower than the lsb method

can mdegrain has "bits" parameter? so it can be used instead of lsb with avs+

Motenai Yoda
20th February 2018, 05:10
since the native 16 bit is slower than lsb, even with this https://forum.doom9.org/showthread.php?p=1833823#post1833823 it's little faster but still way slower than the lsb method

can mdegrain has "bits" parameter? so it can be used instead of lsb with avs+

IIRC lsb isn't 16bit processing but 8bit input -> 16bit output
also you can use ie convertbits(10,dither=1) before mdegrain stuff and convertbits(16) after.
also having a rounding option other than truncate/dithering options will be good.

real.finder
20th February 2018, 14:33
IIRC lsb isn't 16bit processing but 8bit input -> 16bit output
also you can use ie convertbits(10,dither=1) before mdegrain stuff and convertbits(16) after.
also having a rounding option other than truncate/dithering options will be good.

yes in mvtools there are only lsb output, 8 input 16 lsb output

the bits parameter will do same thing with bits=16, and it's should be faster than lsb, and can use another bit setting like 12 for more speed, and can use 10 bit clip (for 10 bit source and output 16 bit or any other depending on the settings) or others, let see what pinterf say

pinterf
20th February 2018, 18:22
since the native 16 bit is slower than lsb, even with this https://forum.doom9.org/showthread.php?p=1833823#post1833823 it's little faster but still way slower than the lsb method

can mdegrain has "bits" parameter? so it can be used instead of lsb with avs+
Open doors.

Since I had found the reason of another mysterious crash, namely 64bit x264 exited when a specific Qtgmc + Tivtc script was used. The culprit was an ancient assembler mmx code used in MSuper. This code did not clear mmx state, as the original asm code did not issue emms, and the Microsoft x64 mode lacks _mm_empty() command (unlike the Intel compiler possibly used in the 2.6.0.5 era). The result was a crash, x264_64.exe probably was conflicted with the non-restored FPU/MMX states.

So after having inserted the missing 'emms' instruction it became rock solid. But I was so angry on MSuper's mmx heritage that I started to backport the sse2 intrinsic rewrite from VapourSynth mvtools. Then I added 10-16 bit sse2 versions. So MSuper is much faster now in 16bits (50+%).

As a side-effect MSuper now works in 32bit float (no SSE2 yet).

Having a 32 bit float MSuper, I was wondering what happens in a 32bit float MDegrain? (Primarily to see that the 16bit-mode color shift would be seen in 32bit mode, using the artifical example in the previous posts)

I made MDegrain able to use arbitrary bit-depth Super clip with vectors created in 8-16 bit mode.
For example we can have vectors created in 16 bit mode and use MDegrain2 on a 32bit float clip by simply passing a 32bit Super clip for MDegrain.

I have to clean up the code, there was quite a bit of work with implementing these features.

And I still need to run tests because 8 bit MDegrain with overlaps uses a strange rounding but since it exists in the C code and used in the asm assembler files also (copy paste?), I need to know whether it is intentional on a bug.
There is a 11 bit precision integer arithmetic that is converted back in two steps: lose first 6 bit (,sum up them) then lose 5 bits.

In 16 bits (and stacked) mode: final_pixel = (x + 1024) / 2048
In 8 bit: final_pixel = ((x + 256) >> 6) >> 5
I don't think the latter is correct. It results an 0.125 increase on average in the final pixel values.

Probably it should be: final_pixel = ((x + 32) >> 6) + 16) >> 5 ?

pinterf
27th February 2018, 16:20
Download MvTools2 2.7.25 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.25)

There were quite a big changes, so please test it.
Apart from the time-consuming mmx state bugfix there is a significant change in MDegrain worth to mention.

Source and Super clip format is now independent of the motion vector clip formats. (apart from the subsampling differences which should be the same - I'm lazy).

This means: one can Degrain even a 32bit float (new!) clip with e.g. 8 bit vectors. Pass a 8 bit clip to Super, then to Analyse and get the vectors.

Then use these vectors in MDegrain, while passing a 32 bit source and a 32 bit Super clip.

- 2.7.25 (20180227)
Fix: x64: not-cleared mmx state in MSuper assembly code would cause crash later, e.g. in x264 encoding, depending on following filters.
Fix: MSCDetection SC value parameter name to Ysc from Yth (must be an ancient typo), docs are OK, the fix is now mentioned in docs
MSuper: import 8 bit sse2 interpolators from mvtools-vs. Extend them for 10-16bits (faster super clip). Some filters are still todo.
MSuper: support 32bit float clips, which can be used later by MDegrains (but not for MAnalyse)
MDegrains: allow degraining clip with different bit depth from vectors. Clip and Super must be the same bit depth
MDegrains: consistently use limit and limitC, 255 do nothing, otherwise scale 0-254 value to the current bit-depth range
Overlaps: more correct internal rounding for 8 bits:
old: pixel = Sum( (tmp + 256) >> 6) >> 5
new: pixel = (Sum( (tmp + 32) >> 6) + 16) >> 5
Overlaps: round for 16bits
old: pixel = Sum(tmp) >> 11
new: pixel = (Sum(tmp) + 1024) >> 11
Overlaps: 32bit float (but still use the original 11 bit window constants)
Project: change from yasm to nasm.

real.finder
27th February 2018, 23:06
thanks

and the "bits" parameter in MDegrains? :rolleyes:

pinterf
27th February 2018, 23:55
What is your speed difference of a e.g. MDegrain2 when passing 8/16/32bit clip and super, but all with 8 bit vectors?

real.finder
28th February 2018, 00:34
What is your speed difference of a e.g. MDegrain2 when passing 8/16/32bit clip and super, but all with 8 bit vectors?

oh, this time native is fast, the one that make it slower last time was MScalevect()

but still lsb a bit faster than native

all 8 bit:- 13.93 fps

native 16 with 8 bit vectors:- 13.34 fps

8 bit with lsb:- 13.60 fps

native 32 with 8 bit vectors:- 11 fps

the test done with ColorBars(width=640, height=480, pixel_type="yv12").AddGrainC

tormento
28th February 2018, 14:04
but still lsb a bit faster than native
"Precision" is the same? Effectiveness in removing noise? Perceived quality output?

I am a old aged noob, I prefer to have smart guys opinions about matters I just play with. :)

real.finder
28th February 2018, 18:44
"Precision" is the same? Effectiveness in removing noise? Perceived quality output?

I am a old aged noob, I prefer to have smart guys opinions about matters I just play with. :)

they should be same in the case above

HBD or lsb should give no banding output mean it will more quality but has some unseen noise, so 8bit should removing more noise

but anyway let see what pinterf say

burfadel
28th February 2018, 21:41
Wouldn't the effective block size in the analysis be different between lsb and native 16 bit? If so it will affect processing speed and possibly output quality.

real.finder
1st March 2018, 03:32
Wouldn't the effective block size in the analysis be different between lsb and native 16 bit? If so it will affect processing speed and possibly output quality.

not always

https://forum.doom9.org/showpost.php?p=1827085&postcount=424

and yes motion analysis in 16 is slower

tormento
1st March 2018, 13:24
they should be same in the case above
From DGDecNV manual:

fulldepth: true/false (default: false)
When fulldepth=true and the encoded video is HEVC 10-bit or 12-bit, then DGSource() delivers 16-bit data to Avisynth with the unused lower bits zeroed. The reported pixel format is CS_YUV420P16. If either of the two conditions are not met, then DGSource() delivers 8-bit YV12 or I420 data, as determined by the i420 parameter. When fulldepth=false and the video is HEVC 10-bit or 12-bit, then the video is dithered down to 8-bit for delivery. If you need a reduced color space (less than 16 bits) for your high-bit-depth processing, you can use ConvertBits() as needed after your DGSource() call.

How should I feed that 16 bit stream to SMDegrain? LSB is not an option in this case, I think. The funny part would be also to output a dithered 10 bit video to feed x265 in Main10 profile or 8 bit to feed x264. Without thinking, at this moment, to HDR.

real.finder
1st March 2018, 14:02
From DGDecNV manual:

fulldepth: true/false (default: false)
When fulldepth=true and the encoded video is HEVC 10-bit or 12-bit, then DGSource() delivers 16-bit data to Avisynth with the unused lower bits zeroed. The reported pixel format is CS_YUV420P16. If either of the two conditions are not met, then DGSource() delivers 8-bit YV12 or I420 data, as determined by the i420 parameter. When fulldepth=false and the video is HEVC 10-bit or 12-bit, then the video is dithered down to 8-bit for delivery. If you need a reduced color space (less than 16 bits) for your high-bit-depth processing, you can use ConvertBits() as needed after your DGSource() call.

How should I feed that 16 bit stream to SMDegrain? LSB is not an option in this case, I think. The funny part would be also to output a dithered 10 bit video to feed x265 in Main10 profile or 8 bit to feed x264. Without thinking, at this moment, to HDR.

that for UHD BD or whatever original HBD source, in most cases your original source is 8 bit, and if it UHD then I don't think it's need any filtering or even re-encoding

anyway I don't know anything about DGDecNV, but ffms2 do it without any parameter and for avs+ it will output the HBD as it

and if you feed native HBD to SMDegrain it will work in most cases (if all filters that used are support HBD which I think in your cases all them are support HBD nowday)

and of course lsb is not option if your source is HBD, since mvtools has only lsb output

tormento
1st March 2018, 16:17
and of course lsb is not option if your source is HBD, since mvtools has only lsb output
I have read html again and what I have understood is:

lsb= true makes 32 bit denoising

lsb_in = true is used to get the source as native 16 bit (right?)

lsb_out = true outputs 16 bit clip as output

mode = 0…9 convert from internal 32bit to 8 bit (would be nice to have 10 or 12 too).

So, if I have a 16 bit video input (i.e. 10 bit with all upper 0), I should use lsb=true+lsb_in=true+lsb_out=true (unless you develop a mode for 10 and 12 bit), right?

pinterf
1st March 2018, 18:37
How on Earth is 32bit denoising achieved?

real.finder
1st March 2018, 22:29
I have read html again and what I have understood is:

lsb= true makes 32 bit denoising

lsb_in = true is used to get the source as native 16 bit (right?)

lsb_out = true outputs 16 bit clip as output

mode = 0Â…9 convert from internal 32bit to 8 bit (would be nice to have 10 or 12 too).

So, if I have a 16 bit video input (i.e. 10 bit with all upper 0), I should use lsb=true+lsb_in=true+lsb_out=true (unless you develop a mode for 10 and 12 bit), right?

these (lsb things) in SMDegrain are hack for the lsb (which it's hack by itself!), they use some dither tools (http://avisynth.nl/index.php/Dither_tools) method for do this, cuz there are no real lsb_in for mvtools (MDegrain*), mvtools has only lsb parameter that use 8bit input and output 16 bit as lsb, and lsb is not native in first place! it's hack use 8bit clip with double height

and this dither tools method (that used to support lsb_in by dogway) will not be real 16 bit, even if it better than doing 8bit

in short, for SMDegrain lsb and lsb_out are real 16 bit and it's ok for use them, but they still hack, lsb_in in SMDegrain will not be real 16 bit

and for dither back to 8 bit modes as pinterf said, it's not 32 bit, it's just 16 bit stacked

and these mode come from dither tools again, not in or from mvtools!

pinterf
1st March 2018, 22:48
Next version will come with that "bits" or whatever parameter that returns native 16bit instead of the stacked one from 8 bit source. The mv bitdepth independent inputs could be applied to other filters as well, I think.

tormento
2nd March 2018, 10:21
The mv bitdepth independent inputs could be applied to other filters as well, I think.
So, if I understood well, at the moment a DGDecNV output from DGDecNV, that outputs a Ultra HD BD from 10 bits to 16bits with upper 0, is not natively useful when applying filters in a avisynth script with mvtools or dither, correct? We need dither (RGTools) update too, right?

pinterf
2nd March 2018, 10:35
So, if I understood well, at the moment a DGDecNV output from DGDecNV, that outputs a Ultra HD BD from 10 bits to 16bits with upper 0, is not natively useful when applying filters in a avisynth script with mvtools or dither, correct? We need dither (RGTools) update too, right?
I meant that probably the same process - like with MDegrain was done - could be applied on MFlowXXX (using motion vectors from 8 bit clip (which is faster than the 10+bit path) and use them directly with 10+ bits clips)

tormento
2nd March 2018, 12:16
I meant that probably the same process - like with MDegrain was done - could be applied on MFlowXXX (using motion vectors from 8 bit clip (which is faster than the 10+bit path) and use them directly with 10+ bits clips)
Understood. I know x265 Main10 is still a bit new and "experimental", especially with HDR. Ultra HD BDs are out and I would like to play a bit with them :)

pinterf
2nd March 2018, 12:30
Understood. I know x265 Main10 is still a bit new and "experimental", especially with HDR. Ultra HD BDs are out and I would like to play a bit with them :)
10bit motion vectors (=10bit SAD) should be much faster than a generic 16bit one, checking this will be among of my next experiments.

pinterf
6th March 2018, 23:06
Next version will come with that "bits" or whatever parameter that returns native 16bit instead of the stacked one from 8 bit source. The mv bitdepth independent inputs could be applied to other filters as well, I think.
I'm ready with making native 16bit MDegrain output instead of the stacked one and now testing.

A new bool "out16" parameter was intruduced in MDegrains, which is basically the same as lsb=true but outputs native 16bit instead.

Quick tests show that the speed gain is not that much (comparing lsb=true and out16=true), 4-10% for a colorbars-addgrain-super-analyze-degrain session. Larger MDegrain level results in smaller gain.

real.finder
7th March 2018, 00:11
I'm ready with making native 16bit MDegrain output instead of the stacked one and now testing.

A new bool "out16" parameter was intruduced in MDegrains, which is basically the same as lsb=true but outputs native 16bit instead.

Quick tests show that the speed gain is not that much (comparing lsb=true and out16=true), 4-10% for a colorbars-addgrain-super-analyze-degrain session. Larger MDegrain level results in smaller gain.

4-10% are very good gain in this case

and if you can make it as int "bits" it will be better since user can use more option in this case to make good Speed vs Quality Balance :)

pinterf
7th March 2018, 08:56
4-10% are very good gain in this case

and if you can make it as int "bits" it will be better since user can use more option in this case to make good Speed vs Quality Balance :)
'Bits' cannot help with making it faster. Let me summarize.

MDegrain speed is primarily depends on the MAnalyze bitdepth: 8 bit super clip is fast, 10-16bits is not so fast (but I think it's still acceptable). As I mentioned, most of the time is spent on SAD calculation. I have a single code for the 10-16bits (2 bytes/pixel) case which can do even 16bit safely w/o overflow. If I have plenty of times, 10 and 12 bits could be optimized (partial sums of diffs would need only 16bits instead of 32 bits w/o overflow, which means lighter and faster 10bit SAD code) as the x264 or x265 project does.

O.K., we have the vectors with either 8bit or 10+bit method, the weigthed averaging in MDegrain is not a big bottleneck but there are still differences between source/target bitdepth combinations. Speedwise we have no difference between using 10 or 16 bit sources (and super).

8 bit source:
- basic: weighted avg calculation on 16bits rounded back to 8 bits, (overlaps result 16 bits), final result 8 bits
- lsb=true: weighted avg calc 16bits and kept (msb and lsb planes), (overlaps 32 bit), final result is 16 bits in the two 8 bit 'planes'
- out16=true: same as lsb=true but the intermediate calculation does not have to work with two 'planes' (msb and lsb), we have a single buffer which is good for speed.

10-16 bit source:
weighted avg calc 32bits rounded back to 16 bits, (overlaps 32 bit), result 16 bits

32 bit float source:
the averaging weights are still in 0-255 range, and the weight of the overlap windows are still in the 0-2048 range but the calculation is kept in floats.

weight: the averaging weight of motion matched backward and forward blocks from each clip (proportional with the block SADs)

real.finder
7th March 2018, 15:08
I see, but let's say that we want 32 bit output from 8 bit or 10 bit or whatever?

pinterf
7th March 2018, 15:37
I see, but let's say that we want 32 bit output from 8 bit or 10 bit or whatever?
All that I would do that I call ConvertBits when the result is ready. But I don't think it's the filter's task.

real.finder
7th March 2018, 15:47
All that I would do that I call ConvertBits when the result is ready. But I don't think it's the filter's task.

I mean as the lsb and out16 method

with bool out16 we can't do 16bit input > 32bit output, unless you add another bool as out32, or make it as int bits :)

pinterf
7th March 2018, 16:19
The 16 bit integer and 32 bit float output is substantially different inside and even needs preparation on the Super clip's level.
MDegrain is a smearing process, 16 bit integer precision is more than enough for it, I think.
When you want 32 bit output, you have to feed both the clip _and_ the super clip as 32bit float.

The idea of out16 and lsb is just not cutting back the bits of one intermediate integer processing step.

pinterf
14th March 2018, 15:22
New build, time to test and tweak your scripts again.
Download MvTools2 2.7.26 with Depans (https://github.com/pinterf/mvtools/releases/tag/2.7.26)

- 2.7.26 (20180314)
-New: MDegrain1-6 and N: new parameter bool "out16" = false. If set, 8 bit input results in native 16bit output (like lsb=true hack but this is native).
Faster than lsb=true by up to 12% (i7-7700)
-Faster: special 10 bit SAD functions instead of the generic 10-16bit one.
Depending on the block size, 4-17% gain for a typical MDegrain1-5 session

real.finder
14th March 2018, 15:51
thank you pinterf

time for new SMDegrain update

tormento
14th March 2018, 23:44
Depending on the block size, 4-17% gain for a typical MDegrain1-5 session
Did you mean MDegrain1-6?

pinterf
14th March 2018, 23:50
Yes. The 6th sense included :)

burfadel
15th March 2018, 03:56
Will this extend to 12 and 14 bits later?

tormento
15th March 2018, 07:44
Will this extend to 12 and 14 bits later
10 bit as it's a requirement of h265 Main10 profile.

Other 2 modes, AFAIK, are used on professional editing only.

tormento
15th March 2018, 08:14
New build, time to test and tweak your scripts again.
tr=4, lsb=true 10,41 fps
tr=4, 16 bit 11.96 fps +14,9%
tr=6, lsb=true 8,28 fps
tr=6, 16 bit 9,41 fps +13,6%

/me happy

P.S: When I am really desperate with dancing noise I use tr=9 (my psycological limit). Do you think there would be any speed difference with a software native version?

pinterf
18th March 2018, 09:59
New build with a small fix for an MDepan parameter. Thanks to veins1 for the report.

Download MvTools2 2.7.27 with Depans (https://github.com/pinterf/mvtools/releases/tag/2.7.27)

Change log (incl. the previous one)
- 2.7.27 (20180318)
- Fix: MDepan: use zerow parameter. The parameter had no effect probably since it had been introduced. (veins1)
- MDepan: report MT mode for Avisynth+. MT_MULTI_INSTANCE, except for logfile writing output mode when it reports MT_SERIALIZED.
(other filters already have proper registration, MDepan was missed)

- 2.7.26 (20180314)
-New: MDegrain1-6 and N: new parameter bool "out16" = false. If set, 8 bit input results in native 16bit output (like lsb=true hack but this is native).
Faster than lsb=true by up to 12% (i7-7700)
-Faster: special 10 bit SAD functions instead of the generic 10-16bit one.
Depending on the block size, 4-17% gain for a typical MDegrain1-6 session

pinterf
23rd March 2018, 14:44
New build

Download MvTools2 2.7.28 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.28)

- 2.7.28 (20180323)
- Fix: in MDegrain1-6/N allow Y8 input for out16 parameter

tormento
23rd March 2018, 15:37
@pinterf

Please get a look here (https://forum.doom9.org/showthread.php?p=1837202#post1837202). It's a tiny job for you and it's often used with after MVTools :)

burfadel
24th March 2018, 06:56
I've come across a couple of things with MDegrainN. The first is the tr parameter. At the moment, instead of specifying tr=3 (for example), you have to leave it as a number, such that MDegrainN (super, multi_vec, 3). Wouldn't it be 'more ideal' to be able to specify tr=3 rather than just having a loose number there?

The second issue is Mrecalculate doesn't work with MAnalyse multi clip for MDegrainN.

In this most basic of running it, the following works:
super = MSuper()
multi_vec = MAnalyse (super, multi=true, delta=4)
MDegrainN (super, multi_vec, 4)

This doesn't:
super = MSuper ()
multi_vec = MAnalyse (super, multi=true, delta=4)
multi_vec = MRecalculate(multi_vec, tr=4)
MDegrainN (super, multi_vec, 4)

It errors with:
MRecalculate: Super clip does not contain needed color data
which isn't actually true (specying chroma and planes etc doesn't help).

I also have a couple of questions. What benefit does MDegrainN provide, for example in the script I quoted above, over using MDegrain4? Does it save memory, faster etc? Or is it purely for the use of large temporal radiuses like 10 for example?

Secondly, for MRecalculate, there's the option:
smooth

This is method for dividing coarse blocks into smaller ones.
0 Use motion of nearest block.
1 Bilinear interpolation of 4 neighbors.

Would there be any benefit from an adding an option 2 for bicubic interpolation, since it's 'cleaner'?

Thanks :)

pinterf
3rd April 2018, 12:23
New build
Download MvTools2 2.7.29 with Depans (https://github.com/pinterf/mvtools/releases/tag/2.7.29)

Thanks for zorrozork for the report.

Fix: MFlowInter (and possibly other MFlow...) crash with specific combination
of analyze parameters (e.g. blkSize=16,overlapv=4,divide=1).
Bug existed since at least 2.5.11.22

pinterf
5th April 2018, 15:43
New build
Download MvTools2 2.7.30 with Depans (https://github.com/pinterf/mvtools/releases/tag/2.7.30)

Thanks for zorrozork for testing further.

- 2.7.30 (20180405)
Fix: crash in MFlowInter (and possibly other MFlow...). v2.7.29 revelead this additional bug (which was not even 100% reproducible),
this fix is basically the 2nd part of the solution.

- 2.7.29 (20180403)
Fix: MFlowInter (and possibly other MFlow...) crash with specific combination of analyze parameters (e.g. blkSize=16,overlapv=4,divide=1)
Bug existed since at least 2.5.11.22

pinterf
9th April 2018, 10:26
New build
Download MvTools2 2.7.31 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.31)

- 2.7.31 (20180409)
Fix: MFlow: SC detection after having the mv clip. Fixed in 2.5.11.22 but was missed during 2.6.0.5 merge.
Fix: MFlow: crash in 16bit 4:2:0, mode=1
Fix: MDegrain, out16=true: Green bottom lines when overlap blocks are not covering the full vertical area

FranceBB
10th April 2018, 02:05
Thank you for the new version. I might not comment at every release, but your work is really appreciated pinterf! :D

Seedmanc
8th September 2018, 22:14
Is truemotion really not supposed to be used with blocksizes above 16? Whenever I set it to true at 24 but especially 32 the video gets absolutely destroyed compared to truemotion false or blocksize 16 or below (using mflowfps for example).
I assume this is all due to the SAD thresholds/defaults being (still and why?) defined as absolute values instead of relative to block area and hence requiring the user to calculate them manually for the new blocksizes. But what should I use for 32? I tried multiplying lsad and lambda by 8 or 16, it didn't help.

pinterf
19th October 2018, 15:45
New build
Download MvTools2 2.7.32 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.32)

Thanks to Seedmanc for the report and providing useful test cases.

Change log
- 2.7.32 (20181018)
MAnalyze: Enhance mt mode report for Avisynth+: MT_SERIALIZED instead of MT_MULTI_INSTANCE when temporal=true or using output file.
MAnalyze: fix a possible internal overflow on larger blocksizes and lambda combinations. e.g. truemotion=true with blksize=32

pinterf
22nd October 2018, 08:12
New build

Download MvTools2 2.7.33 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.33)

Thanks to zorrozork and Seedmanc for the report.

**2.7.33 (20181021)**
- Fix: MFlowXX: random access violation caused by enlarged vectors pointing on out-of-frame positions

**2.7.32 (20181018)**
- New: MAnalyze: Enhance mt mode report for Avisynth+: MT_SERIALIZED instead of MT_MULTI_INSTANCE when temporal=true or using output file.
- Fix: MAnalyze: fix a possible internal overflow on larger blocksizes and lambda combinations. e.g. truemotion=true with blksize=32

ChaosKing
22nd October 2018, 09:20
I think you forgot to upload the binary, there is no release download.

FranceBB
22nd October 2018, 09:49
I think you forgot to upload the binary, there is no release download.

It's here https://github.com/pinterf/mvtools/releases/download/2.7.33/mvtools-2.7.33-with-depans.7z

He added it to the release page of Github ;)

ChaosKing
22nd October 2018, 10:18
Did you clicked on that link? I get a 404 error

//Edit
link works now

Sharc
22nd October 2018, 11:58
Thank you for the new version. I might not comment at every release, but your work is really appreciated pinterf! :D
+1
Thank you pinterf

pinterf
8th November 2018, 16:52
New build
Download MvTools2 2.7.34 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.34)
- 2.7.34 (20181108)
MFlowInter: Use less memory, eliminates ten full-frame internal buffers


This release is a side-effect of investigating memory issues when StainlessS' Duplicity2 script invoked plenty of MFlowInter instances and running the script in 32-bit Vdub2 resulted in crashes due to low memory. In a specific parameter scenario memory consumption reported by avsmeter went from 220/1624MiB to 213/1356MiB.

StainlessS
8th November 2018, 17:02
Sensational my man.
Ta very much :)

FranceBB
9th November 2018, 02:24
Ferenc, thank you for your efforts. ;)

pinterf
14th November 2018, 09:26
New build, a fix, thanks zorrozork for the report, his current project is really a stress test for possible parameter variations.

The other modifications are just experiments, pure leisure.

Download MvTools2 2.7.35 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.35)

- 2.7.35 (20181113)
MFlowXXX: Slight speed gain by putting the out-of-frame vector check to resizer
Fix: MAnalyze: Fix a possible internal overflow on larger blocksizes with small overlap e.g. BlkSize=32, OverlapX=0, OverlapY=4
MSuper: Planar RGB support. Now MSuper supports Y and YUV and planar RGB 8-32 bits, and YUY2
note: different filters may support only a limited set of super clip formats.
MFlowFPS: Planar RGB support: generate vectors in YUV, use RGB input and super clip
MFlowFPS: less memory for 4:4:4 and greyscale
MFlowFPS: a bit faster 4:4:4, much faster greyscale
MFlowFPS: support different bit depth for clip and the vectors (use vectors from 8 bit analysis for a 16 bit clip)

pinterf
21st November 2018, 09:39
New build ahoy!
Download MvTools2 2.7.36 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.36)

Zork keeps feeding mvtools with a million parameter variations in his optimizer project.
These fixes heal a rather extreme case but nevertheless a smooth operation is always better than a funny divbyzero message :)

**2.7.36 (20181120)**
- Fix: Allow overlap operation when there are only two blocks in either horizontal or vertical direction (was: division by 0 crash)
- Fix: Fallback to overlap=0 mode when block count is only 1 in either h or v direction (was: undefined behaviour)
The cases above occured for small frame sizes, when frame size and overlap values resulted in less than 3 blocks in a direction.
- Misc: update html docs with overlap drawing and others.

pinterf
28th November 2018, 10:09
New build.
Download MvTools2 2.7.37 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.37)

I have also noticed a small speed gain in some generic scripts (basic qtgmc fast)

**2.7.37 (20181128)**
- MCompensate: limit thSAD, thSAD2, thSCD1 to valid range 0-(8x8x255) (e.g. given thSAD = 100000 will go back to 16320)
- Fix: MCompensate: use int64 to avoid internal thSAD and thSAD2 overflow typically happen at bigger block sizes or large thSAD parameter value.
- MCompensate: SSE2 (8bit) and SSE4 (10-16 bit) overlap result calculation
- Changed: SAD 8x8, 8x4, 4x4, 4x8 to use SSE2 instead of MMX registers
- Fix: MDegrain if overlap<>0: missing rounder in rightmost 8 pixels for non-mod8 width 8 bit clips
- Fix: MSuper artifacts at 10-32 bits and nPel==4
- New: MCompensate 32 bit float and planar RGB support (by using motion vectors made from 8-16 bit YUV clip).
Input and super clip can be of a different format than the one used for motion vector creation. (Similar to MDegrain1-6)

FranceBB
28th November 2018, 19:06
Thank you very much indeed! :D

StainlessS
1st December 2018, 12:19
Small prob,


LoadVirtualDubPlugin ("Deshaker.vdf", "deshaker", preroll=0) # FAILS, "Error 0x7e"
LoadVirtualDubPlugin (".\Deshaker.vdf", "deshaker", preroll=0) # FAILS, "Error 0x7e"
#LoadVirtualDubPlugin ("D:\ShakeRattleAndRoll\Deshaker.vdf", "deshaker", preroll=0) # OK

pinterf
1st December 2018, 12:36
(offtopic here) Have you tried putting deshaker.vdf to plugins+ directory? Avisynth+ places vdubfilter.dll in plugins+ and not plugins.

StainlessS
1st December 2018, 12:51
(offtopic here)
Oops, yep, thought it was Avs+ thread, sorry.

I currently have it in both plugins and Plugins+. (x86 avs+)
I have to leave home this instant, already bout 1/2 hour late for appointment.

pinterf
9th December 2018, 21:03
Bugfix release, thanks Seedmanc!
Download MvTools2 2.7.38 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.38)
- 2.7.38 (20181209)
MCompensate: Fix regression in latest v37: overlap=0 crash - ouch, sorry
MAnalyze DCT: FFTW float: quicker postprocess of DCT'd blocks, now is correct for non power-of-2 block sizes e.g. 12 or 24 (no effect on 8x8 for which fast integer DCT is used)
MAnalyze DCT: more consistent handling of post DCT internal normalization for non-square block sizes.

MysteryX
15th December 2018, 13:27
I've been out for a while (up the mountains in China) and... wow Pinterf you've been on fire!

pinterf
2nd January 2019, 11:58
Happy New Year!
New build, a bugfix (thanks ErazorTT for the report) and an MDegrain extension.
Download MvTools2 2.7.39 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.39)

- 2.7.39 (20190102)
- MSuper: fix 16 bits, pel=2, sharp=2, which caused bottom-section artifacts for MDegrain using 8 bit vector origin and 16 bit real clip
- MDegrain1-6,N: Enhanced:
Input clip (and super) format now is fully independent from vector clip's base format (subsampling had to be the same before)
E.g. make motion vector clips from a YV12 source and apply them on a 8-32 bit 4:4:4 input

StainlessS
27th January 2019, 05:39
And a Happy New Year to you too sir :)

Small prob in first two (mvtools docs) examples:


# To show the motion vectors ( forward ) :
AVISource("c:\test.avi") # or MPEG2Source, DirectShowSource, some previous filter, etc
vectors = MSuper().MAnalyse(isb = false)
MShow(vectors) # implicit last works properly # ERROR:- MShow: Wrong Super Frame Clip


FIXED

AVISource("c:\test.avi") # or MPEG2Source, DirectShowSource, some previous filter, etc
Last=MSuper() # Assigns implicit last with Super clip
vectors = Last.MAnalyse(isb = false) # Implicit Last = super, 1st arg
Last.MShow(vectors) # Implicit Last = super, 1st arg


2nd example similar prob isb=true.

pinterf
29th January 2019, 11:56
Fixed, thanks

pinterf
12th February 2019, 17:24
New build
Download MvTools2 2.7.40 with depans (https://github.com/pinterf/mvtools/releases/tag/2.7.40)

A bugfix, thanks to zorr a.k.a. father of "Zopti" (formerly Avisynth Optimizer) for the report.
Another bugfix for the 16 bit MFlowInter version.

Then, perhaps this version a milestone release.
Most filters fully support 8-16 bit and 32 bit float with greyscale, YUV and Planar RGB videos.
MDegrain family, MCompensate, MFlowXX family, MSuper all can handle practically any Avisynth+ input formats.
It was quite a bit of modification, I hope bugs (small or big) will fly elsewhere, at least there won’t be many.

Have fun.

- 2.7.40 (20190212)
- Fix: MFlowInter possible crash with specific parameter and colorspace settings.
- Fix: MFlowInter possible overflow at 16 bit clips (artifacts)
- MFlow, MFlowInter, MFlowFPS, MFlowBlur, MBlockFPS: support all 8-16 and 32 bit float Y, YUV (4:2:0, 4:2:2, 4:4:4) and planar RGB color spaces.
Input clip format is independent from the ones used for getting motion vectors.

FranceBB
12th February 2019, 21:10
Thank you, pinterf, very appreciated, as always!
I just tested it with a 10bit yv16 source brought to 16bit yv24 and it works:


FFMpegSource2("test.mov", fpsnum=25000, fpsden=1000)

ConvertBits(16)

Converttoyuv444(matrix="Rec709", interlaced=false)

super=MSuper(pel=1, hpad=0, vpad=0)
backward_1=MAnalyse(super, chroma=false, isb=true, blksize=16, blksizev=16, searchparam=3, plevel=0, search=3, badrange=(-24))
forward_1 =MAnalyse(super, chroma=false, isb=false, blksize=16, blksizev=16, searchparam=3, plevel=0, search=3, badrange=(-24))
backward_2 = MRecalculate(super, chroma=false, backward_1, blksize=8, blksizev=8, searchparam=0, search=3)
forward_2 = MRecalculate(super, chroma=false, forward_1, blksize=8, blksizev=8, searchparam=0, search=3)
MBlockFps(super, backward_2, forward_2, num=50000, den=1000, mode=0)


it correctly returns a 16bit 4:4:4 50fps file.
Thank you! :)

StainlessS
12th February 2019, 21:50
FranceBB,
backward_2 = MRecalculate(super, chroma=false, backward_1, blksize=8, blksizev=8, searchparam=0, search=3)

search, searchparam, pelsearch

search decides the type of search at every level, searchparam is an additional parameter (step, radius) for this search, and pelsearch is the radius parameter at finest (pel) level.
Below are the possible values for the search type:

...

3 Exhaustive search, searchparam is the radius (square side is 2*radius+1). It is slow, but it gives the best results, SAD-wise.

In MRecalculate, with square side = 1, does that mean that it searches only 1 pixel side to side, up and down, or NONE.

Not sure if problem, just asking. [EDIT: ie, is your MRecalculate a timewasting NOP]

tormento
13th April 2019, 11:27
A curiosity came to me about degraining using larger frame span: beside having less noise, can we say the output is more accurate and/or better quality, given same other parameters, as we are evaluating more frames?

althor1138
13th April 2019, 18:37
I've been using this function on 2.7.33 and it's always worked. Today I upgraded to the latest 2.7.40 and the output clip is the same as the input clip(nothing has been filtered). I've sifted through the new readme and couldn't figure what's changed to make it not work. If some kind soul could take a look below and point out what is wrong I'd greatly appreciate it. Using avs+ r2772 mt x64 btw.

EDIT: I had to revert back to 2.7.34 before the function started working as expected.

EDIT2: starting with 2.7.35 and up it works in yv12 yv24 colorspace but not yuy2.

EDIT3: Ah but it works with yv16 as well. So I guess yuy2 was dropped? In any case, problem solved. Sorry to bother you all.

#Motion Compensated Temporalsoften
function TSMC(clip input, int "tradius", int "mthresh", int "lumathresh", int "blocksize")
{
tradius=default(tradius,5)

mthresh=default(mthresh,70)

lumathresh=default(lumathresh,255)

blocksize=default(blocksize,4)

prefilt=input.blur(1.58)
super=MSuper(input, pel=2,mt=false)
superfilt=MSuper(prefilt,pel=2,mt=false)

multivectors=Manalyse(superfilt,multi=true,delta=tradius,mt=false)
multivectors2=Mrecalculate(superfilt,multivectors,thsad=mthresh,tr=tradius,mt=false,blksize=blocksize,overlap=2)
mc=Mcompensate(input,super,multivectors2,thsad=mthresh,mt=false,tr=tradius,center=true)
dnmc=mc.temporalsoften(tradius,lumathresh,lumathresh,15,2)
decimate=selectevery(dnmc,tradius * 2 + 1,tradius)
return(decimate)
}

pinterf
2nd May 2019, 09:50
New build, includes an important fix for YUY2 users who experienced troubles after 2.7.35.

Download MvTools with Depans 2.7.41 (https://github.com/pinterf/mvtools/releases/tag/2.7.41)

Now with 2x2 DLL versions, compiled with v142 and v141_xp toolset. XP users please use the latter.

Planar RGB support for DepanStabilize is the first mod that I made for myself. I'm using it in my neverending (neverstarting) 8mm film restoration project to have a stabilized intermediate file in the same format (I have RGB source) for better days when I'll have more time for do further filtering.

MvTools2 2.7.41 (20190502)

Fix: regression since 2.7.35: MSuper chroma for non-planar YUY2 (Thanks to mkauf)
Project moved to Visual Studio 2019, v141_xp and v142 toolset

Depan 2.13.1.4 (20190502)
DepanStabilize planar RGB 8-16 bits support: Generate motion vectors with mvtools MDepan, use it for DepanStabilize. Input clip can be planar RGB.
add missing roundings to some internal interpolation calculations

DepanEstimate 2.10.0.3 (20190502)
simple rebuild

tormento
5th May 2019, 10:27
New build, includes an important fix for YUY2 users who experienced troubles after 2.7.35.
In the documentation, overlap.png is present from FFT3DFilter one ;)

FranceBB
5th May 2019, 17:30
Now with 2x2 DLL versions, compiled with v142 and v141_xp toolset. XP users please use the latter.

My other XP computer says "thank you". :D
By the way, v141_xp is still there in Visual Studio 2019, but this time Microsoft clearly stated that is deprecated, sadly (I noticed it when I upgraded from Visual Studio 2017 to 2019): Picture (https://i.imgur.com/MHi6hEv.png)

Anyway, thank you, Ferenc, your work is always very appreciated.

Dreamject
17th May 2019, 22:55
Sorry, can you write or give an instruction how to use this and can it be used for SVP parameters , I ported SVPgenerator to clear avs (I'm newbe in avs and not a coder, script can be stupid) and wanna know can I adapt it https://forum.doom9.org/showthread.php?t=176268

real.finder
28th May 2019, 21:05
is it ok to use convertbits() with Msuper super clip?

pinterf
29th May 2019, 13:48
is it ok to use convertbits() with Msuper super clip?
I'm not 100% sure. There is a hack (as a result of lacking frame properties) with the VideoInfo structure, super clip passes padding and plane handling information through a pointer which is stuffed into num_audio_samples videoinfo field. And audio_samples_per_second if set to zero.

If this videoinfo information is copied between filters _and_ the source MSuper instance is not freed up (the memory for this extra clip info is allocated there inside), you can do with a super clip whatever you want (except size modification)

real.finder
29th May 2019, 19:14
I'm not 100% sure. There is a hack (as a result of lacking frame properties) with the VideoInfo structure, super clip passes padding and plane handling information through a pointer which is stuffed into num_audio_samples videoinfo field. And audio_samples_per_second if set to zero.

If this videoinfo information is copied between filters _and_ the source MSuper instance is not freed up (the memory for this extra clip info is allocated there inside), you can do with a super clip whatever you want (except size modification)

well, in last update of SMDegrain it's seems work

magnetite
26th June 2019, 01:45
Does MDegrain make use of multithreading? I didn't see it on the mtmodes.avsi list, so I wasn't sure.

pinterf
26th June 2019, 05:34
Reports itself as MT_MULTI_INSTANCE automatically.

StainlessS
5th November 2019, 13:34
Is this an mvtools2 bug for Occlusion Mask ?


Function VectorTest(Int "Delta",Float "Time",Int "MaskT",Int "BlkSz",Int "XStep",Bool "Align",Bool "HFlip",String "CS") {
/*
VectorTest(), An MvTools2::MFlowInter folly. by StainlessS @ Doom9 : https://forum.doom9.org/showthread.php?t=175373

Req AVS+ or GSCript, GRunt, MvTools2, RT_Stats v1.43+
Avs v2.58, Avs/+ v2.60.

Delta, Default 1. As for MvTools2
Time, Default 50.0, As for MvTools2
MaskT, Default 3, As for MvTools2::MMask(kind=MASK_TYPE), 0=Motion, 1=Sad, 2=Occlusion, 3=Horizontal, 4=Vertical, 5=ColorMap
BlkSz, Default 4, As for MvTools2
XStep, Default 8, Motion per frame of synthesized clip.
Align, Default True, Aligns forward vector frame n+Delta to n. False show frame n of forward vector.
HFlip, Default False, False, Animate from Right to Left, else Left to Right.
(Right to Left is less confusing, same direction that the frames come in from).
CS, Avs v2.5 defaults "YV12" else "Y8".

Returns RGB32 clip.
*/
Function MTyp(Int n) {Return " Type="+Select(n,"Motion","Sad","Occlusion","Horizontal","Vertical","ColorMap")}
myName="VectorTest: "
IsAvsPlus=(FindStr(UCase(versionString),"AVISYNTH+")!=0) HasGScript=RT_FunctionExist("GScript")
HasGrunt=RT_FunctionExist("GScriptclip") HasMvTools2=RT_FunctionExist("MSuper") Is26=VersionNumber>=2.6
Assert(IsAvsPlus||HasGscript,myName+"Essential AVS+ or GScript installed")
Assert(HasGrunt,myName+"Essential GRunt installed") Assert(HasMvTools2,myName+"Essential MvTools2 installed")
Delta=Default(Delta,1) Time=Default(Time,50.0) MaskT=Default(MaskT,3) BlkSz=DefaulT(BlkSz,4)
XStep=Default(XStep,8) Align=Default(Align,True) HFlip=Default(HFlip,False)
CS=Default(CS,Is26?"Y8":"YV12")
OLap=(BlkSz>=4)?BlkSz/2:RT_Undefined
# OLap=RT_Undefined # EDIT: Fixes Weirdness
FuncS="""
Function Fn(clip c,Int Delta,Float Time,Int XStep,Bool Align,Bool HFlip,String mType) {
c n=current_frame
Hit=(Height-20)/5
if(Align) {
Steps=640/XStep
x=((n+1)*XStep) + (Delta*XStep/2)
x=Min(x,(Steps-1)*XStep)
x=HFlip?x:639-x
cF=RT_YPlaneMin(n=n,x=x,y=Round(2.5*Hit)+20,w=1,h=1)-128
cB=RT_YPlaneMin(n=n,x=x,y=Round(3.5*Hit)+20,w=1,h=1)-128
Z=c.BlankClip(width=1,height=1,Color=$FFFFFF,Length=1)
OverLay(Z,x=x,y=Round(2.5*Hit)+20)
OverLay(Z,x=x,y=Round(3.5*Hit)+20)
Subtitle(RT_String("@x=%d FGrey=128%+d : BGrey=128%+d",x,cF,cB))
} else {
Subtitle("Align=False, Colors NOT shown")
}
Subtitle(String(n,"SRC[n=%.0f] (1st interp srcS)") , Y=0.5*Hit+20,Align=5)
Subtitle(String(n+Delta,"SRC[n+Delta=%.0f] (2nd interp srcE)") , Y=1.5*Hit+20,Align=5)
(Align)
\ ? Subtitle(String(n+Delta,"FVEC[n+DELTA=%.0f]")+mType+ " (Aligned)" , Y=2.5*Hit+20,Align=5)
\ : Subtitle(String(n,"FVEC[n=%.0f]")+mType , Y=2.5*Hit+20,Align=5)
Subtitle(String(n,"BVEC[n=%.0f]")+mType , Y=3.5*Hit+20,Align=5)
Subtitle(string(n+Delta*Time/100.0,"MFlowInter Predicted @ [%.2f]") , Y=4.5*Hit+20,Align=5)
Return Last
}
Wid=640 Hit=64 Steps=Wid/XStep
White=BlankClip(width=WID,height=HIT,Length=1,Color=$FFFFFF,Pixel_type=CS) Black=White.BlankClip srcS=Black.BlankClip(Length=0)
For(i=1,Steps-1) { W=White.Crop(0,0,i*XStep,0) K=Black.Crop(0,0,Wid-W.Width,0) Frm=StackHorizontal(K,W) srcS=srcS++Frm }
srcS=(HFlip)?srcS.FlipHorizontal:srcS
srcE=SrcS.Loop(0,0,Delta-1) # Delete Delta frames, end interp src
super=srcS.MSuper(pel=2,hpad=16,vpad=16)
fvec =MAnalyse(super, isb=false, blksize=BlkSz, overlap=OLap, delta=Delta, truemotion=true)
bvec =MAnalyse(super, isb=true, blksize=BlkSz, overlap=OLap, delta=Delta, truemotion=true)
inter=srcS.MFlowInter(super, bvec,fvec, time=Time)
mbv=srcS.MMask(bvec,kind=MaskT) mfv=srcS.MMask(fvec,kind=MaskT)
mfv=(Align)?mfv.Loop(0,0,Delta-1):mfv # Align, Delete DELTA frames from start, align n+delta with n
TXT=SrcS.BlankClip(Height=20,Length=1,Color=$404040)
StackVertical(TXT,srcS,SrcE,MFV,MBV,Inter)
mType=mTyp(MaskT)
ARGS = "Delta,Time,XStep,Align,HFlip,MType"
Last.GScriptClip("Fn(last, "+ARGS+")", local=true, args=ARGS)
DIR=(HFlip) ? " : ---->" : " : <----"
TXT=TXT.Subtitle(String(Delta,"Delta=%.0f")+String(Time," : Time=%.2f")+
\ String(BLKSZ," : BLKSZ=%.0f")+String(XSTEP," : XSTEP=%.0f")+" : ALIGN="+String(ALIGN)+" : HFlip="+String(HFlip)+DIR)
return StackVertical(TXT,Last)
"""
IsAvsPlus?Eval(FuncS):GScript(FuncS)
Return Last.ConvertToRGB32
}

# 0=Motion, 1=Sad, 2=Occlusion, 3=Horizontal, 4=Vertical, 5=ColorMap

VectorTest(Delta=2,MaskT=2,Align=FALSE)


Frame 41 (normal, no FWD vector Occlusion mask weirdness)
https://i.postimg.cc/qM2NNFDg/41.jpg (https://postimages.org/)

Frame 42
https://i.postimg.cc/RZ3b1cf3/42.jpg (https://postimages.org/)

Frame 43
https://i.postimg.cc/3rnLPLF4/43.jpg (https://postimages.org/)

Frame 44
https://i.postimg.cc/1XtKmQrg/44.jpg (https://postimages.org/)

Frame 45 (back to normal again)
https://i.postimg.cc/SsQ6dh5Z/45.jpg (https://postimages.org/)

Forward vectors go through a 4 frame cycle, normal, a bit wierd, very weird, a bit weird, back to normal again.
Backward vectors no weirdness.
EDIT: Weirdness above Type on the FVEC line.

EDIT: I've observed similar occlusion weirdness in clip where occlusion appears near top of frame where seemingly sky is pretty much uniform grey [greyscale clip].

EDIT: Changed to ALIGN=False and re-upped images.

EDIT: Above script was only really intended for Horizontal motion mask examination.

EDIT: I suspect that weirdness might be connected with overlap.

EDIT:
If you change this

OLap=(BlkSz>=4)?BlkSz/2:RT_Undefined


OLap=RT_Undefined

Weirdness disappears [EDIT: And occlusions get fatter and then slimmer as clip progresses though the 4 frame cycle, for both FWD and BWD masks]

EDIT: I still dont have much clue how that occlusion stuff works.

EDIT: I note that author of YFRC

# Author: RunForLife(Oleg Yushko) http://videomontazh.com.ua
# http://avisynth.nl/index.php/YFRC

uses only backwards Occlusion mask, here posted mod as YFRC2() by RaffRiff42:- https://forum.doom9.org/showthread.php?p=1804170

Below, both SAD masks used, but only BAK backward Occlusion mask.

## "EM" - error or artifact mask
EM = C.MMask(bak, ml=190, kind=1) [** kind=SAD *]
EM = EM.Overlay(
\ C.MMask(fwd, ml=190, kind=1).DeleteFrame(0),
\ opacity=0.5, mode="lighten")

EM = EM.Overlay(
\ C.MMask(bak, ml=64, kind=2).mt_inpand, [** kind=occlusion *]
\ opacity=0.5, mode="lighten")

StainlessS
8th November 2019, 03:26
Further to above, a bit more weirdness.

Actually, weirdness on forward vectors when movement from right to left, but on backward vectors when movement left to right.

Here script to show more masks over several frames.

script (requires V.C. Mohan Grid plug if SHOWGRID=true)

MASKT=2 # 0, 2, 3 ONLY : 0=Motion, 2=Occlusion, 3=Horizontal motion
HFLIP=true # Direction, true=Left to right
XSTEP=8 # Movement step size per frame of white movement moving over black
BLKSZ=4 # MAnalyse BlkSize
Weird=true # Show Weird Occlusion masks
SHOWGRID=true # Show Grid, Req V.C. Mohan Grid Plugins.
#####################
##### END Config ####
#####################
CS="YV12"
Wid=960
Hit=48
DELTA=2
TIME=50.0
Steps=Wid/XStep
White=BlankClip(width=WID,height=HIT,Length=1,Color=$FFFFFF,Pixel_type=CS)
Black=White.BlankClip srcS=Black.BlankClip(Length=0)
For(i=1,Steps-1) {
W=White.Crop(0,0,i*XStep,0) K=Black.Crop(0,0,Wid-W.Width,0) Frm=StackHorizontal(K,W) srcS=srcS++Frm
}
srcS=(HFlip)?srcS.FlipHorizontal:srcS
srcE=SrcS.Loop(0,0,Delta-1) # Delete Delta frames, end interp src
OLap=(Weird)?2:Undefined
super=srcS.MSuper(pel=2,hpad=16,vpad=16,chroma=false)
fvec = MAnalyse(super, isb=false, blksize=BlkSz,Overlap=OLap,delta=Delta, truemotion=true,chroma=false)
bvec = MAnalyse(super, isb=true, blksize=BlkSz,Overlap=OLap,delta=Delta, truemotion=true,chroma=false)
inter= srcS.MFlowInter(super, bvec,fvec, time=Time).Greyscale
mfv0 = srcS.MMask(fvec,kind=MaskT).Greyscale # n
mfvS1= mfv0.DuplicateFrame(0) # n-1
mfv1 = mfv0.DeleteFrame(0) # n+1
mfv2 = mfv1.DeleteFrame(0) # n+2
mfv3 = mfv2.DeleteFrame(0) # n+3
mfv4 = mfv3.DeleteFrame(0) # n+4
mbv0 = srcS.MMask(bvec,kind=MaskT).Greyscale # n
mbvS1= mbv0.DuplicateFrame(0) # n-1
mbv1 = mbv0.DeleteFrame(0) # n+1
mbv2 = mbv1.DeleteFrame(0) # n+2
mbv3 = mbv2.DeleteFrame(0) # n+3
mbv4 = mbv3.DeleteFrame(0) # n+4
DIR=(HFlip) ? " : ---->" : " : <----"
TXT=SrcS.BlankClip(Height=20,Length=1,Color=$404040).Subtitle(String(Delta,"Delta=%.0f")+String(Time," : Time=%.2f")+
\ String(BLKSZ," : BLKSZ=%.0f")+String(XSTEP," : XSTEP=%.0f")+" : HFlip="+String(HFlip)+DIR)
StackVertical(srcS,SrcE,Inter,mfvS1,mbvS1,mfv0,mbv0,mfv1,mbv1,mfv2,mbv2,mfv3,mbv3,mfv4,mbv4)

COL=$FF00FF
(SHOWGRID)?grid(Lineint=8,Color=COL,bColor=COL,vbColor=COL):NOP
mType=mTyp(MaskT)
ARGS = "Delta,Time,XStep,HFlip,MType"
Last.GScriptClip("Fn(last, "+ARGS+")", local=true, args=ARGS)

Return StackVertical(TXT,Last).ConvertToRGB32

Function MTyp(Int n) {Return " Type="+Select(n,"Motion","Sad","Occlusion","Horizontal","Vertical","ColorMap")}

Function Fn(clip c,Int Delta,Float Time,Int XStep,Bool HFlip,String mType) {
c n=current_frame
Hit=Height/15
Steps=Width/XStep
x=((n+1)*XStep) + (Delta*XStep/2)
x=Min(x,(Steps-1)*XStep)
x=HFlip?x:Width-1-x
Subtitle(String(n,"SRC[n=%.0f] (1st interp srcS)") , Y=0.5*Hit,Align=5)
Subtitle(String(n+Delta,"SRC[n+Delta=%.0f] (2nd interp srcE)") , Y=1.5*Hit,Align=5)
Subtitle(string(n+Delta*Time/100.0,"MFlowInter Predicted @ [%.2f]") , Y=2.5*Hit,Align=5)
Subtitle(String(n-1,"FVEC[n-1=%.0f]")+mType,Y=3.5*Hit,Align=5)
Subtitle(String(n-1,"BVEC[n-1=%.0f]")+mType,Y=4.5*Hit,Align=5)
Subtitle(String(n+0,"FVEC[n+0=%.0f]")+mType,Y=5.5*Hit,Align=5)
Subtitle(String(n+0,"BVEC[n+0=%.0f]")+mType,Y=6.5*Hit,Align=5)
Subtitle(String(n+1,"FVEC[n+1=%.0f]")+mType,Y=7.5*Hit,Align=5)
Subtitle(String(n+1,"BVEC[n+1=%.0f]")+mType,Y=8.5*Hit,Align=5)
Subtitle(String(n+2,"FVEC[n+2=%.0f]")+mType,Y=9.5*Hit,Align=5)
Subtitle(String(n+2,"BVEC[n+2=%.0f]")+mType,Y=10.5*Hit,Align=5)
Subtitle(String(n+3,"FVEC[n+3=%.0f]")+mType,Y=11.5*Hit,Align=5)
Subtitle(String(n+3,"BVEC[n+3=%.0f]")+mType,Y=12.5*Hit,Align=5)
Subtitle(String(n+4,"FVEC[n+4=%.0f]")+mType,Y=13.5*Hit,Align=5)
Subtitle(String(n+4,"BVEC[n+4=%.0f]")+mType,Y=14.5*Hit,Align=5)
Return Last
}


Here showing white motion coming in from the left.

Mask=2, Occlusion (weirdness on backward vectors)
https://i.postimg.cc/xCzLmY02/M2.jpg (https://postimages.org/)

Mask=0, Motion (its a bit faint) [relevant for frame n, bvec n+0 and fvec n+delta(2)]
https://i.postimg.cc/vTyx6Vqr/M0.jpg (https://postimages.org/)

Mask=3, Horizontal Motion [relevant for frame n, bvec n+0 and fvec n+delta(2)]
https://i.postimg.cc/wM93BdMF/M3.jpg (https://postimages.org/)

Src frame 24 has stepped 2 * 8 pixels at frame 26, each little mark on grid are 8 pixels apart.

manolito
8th November 2019, 20:35
Can you tell if only the pinterf-mod versions are affected by this "weirdness", or is it also present in the latest Fizick version mvtools-v2.5.11.22 ?

StainlessS
9th November 2019, 10:17
Thanks for taking an interest Mani,
And Yip, it does same in Avisynth v2.60, mvtools2 from mvtools-v2.5.11.22.zip (avs version 2.60 dll dated 26/Apr/2016).

just add Gscript wrapper as this [where not Avs+]


GScript("""
For(i=1,Steps-1) {
W=White.Crop(0,0,i*XStep,0) K=Black.Crop(0,0,Wid-W.Width,0) Frm=StackHorizontal(K,W) srcS=srcS++Frm
}
""")


Can you reproduce.

EDIT: I think the first script in post #520 should work as is (with Avs+ OR GScript, and at least version v2.60 standard, +Grid for 2nd script)

EDIT:
EDIT: I still dont have much clue how that occlusion stuff works.

EDIT: I note that author of YFRC

# Author: RunForLife(Oleg Yushko) http://videomontazh.com.ua
# http://avisynth.nl/index.php/YFRC

uses only backwards Occlusion mask, here posted mod as YFRC2() by RaffRiff42:- https://forum.doom9.org/showthread.php?p=1804170

Below, both SAD masks used, but only BAK backward Occlusion mask.

## "EM" - error or artifact mask
EM = C.MMask(bak, ml=190, kind=1) [** kind=SAD *]
EM = EM.Overlay(
\ C.MMask(fwd, ml=190, kind=1).DeleteFrame(0),
\ opacity=0.5, mode="lighten")

EM = EM.Overlay(
\ C.MMask(bak, ml=64, kind=2).mt_inpand, [** kind=occlusion *]
\ opacity=0.5, mode="lighten")


I think above, that backward Occlusion mask should be mixed first with backward SAD mask, same for forward, and then those two mixed together.
(Dont know how MysteryX does it [EDIT: FrameRateConverter], I havnt looked)

pinterf
18th November 2019, 11:59
When you visualize the vectors (a have put that line right after your vector generation lines, you can see that the forward vectors are not uniform at the top and right lines.

[...]
mbv=srcS.MMask(bvec,kind=MaskT)
mfv=srcS.MMask(fvec,kind=MaskT)
return StackVertical(MShow(super,fvec).SubTitle("MShow fvec"),MShow(super,bvec).SubTitle("MShow bvec"))

Then change block size to 8, BlkSz=8, (default is 4 in your test script), then you can see other strange things

StainlessS
18th November 2019, 19:05
Mod to VectorTest script as per Pinterf observation.

Function VectorTest(Int "Delta",Float "Time",Int "MaskT",Int "BlkSz",Int "XStep",Bool "Align",Bool "HFlip",String "CS") {
/*
VectorTest(), An MvTools2::MFlowInter folly. by StainlessS @ Doom9 : https://forum.doom9.org/showthread.php?t=175373

Req AVS+ or GSCript, GRunt, MvTools2, RT_Stats v1.43+
Avs v2.58, Avs/+ v2.60.

Delta, Default 1. As for MvTools2
Time, Default 50.0, As for MvTools2
MaskT, Default 3, As for MvTools2::MMask(kind=MASK_TYPE), 0=Motion, 1=Sad, 2=Occlusion, 3=Horizontal, 4=Vertical, 5=ColorMap
BlkSz, Default 4, As for MvTools2
XStep, Default 8, Motion per frame of synthesized clip.
Align, Default True, Aligns forward vector frame n+Delta to n. False show frame n of forward vector.
HFlip, Default False, False, Animate from Right to Left, else Left to Right.
(Right to Left is less confusing, same direction that the frames come in from).
CS, Avs v2.5 defaults "YV12" else "Y8".

Returns RGB32 clip.
*/
Function MTyp(Int n) {Return " Type="+Select(n,"Motion","Sad","Occlusion","Horizontal","Vertical","ColorMap")}
myName="VectorTest: "
IsAvsPlus=(FindStr(UCase(versionString),"AVISYNTH+")!=0) HasGScript=RT_FunctionExist("GScript")
HasGrunt=RT_FunctionExist("GScriptclip") HasMvTools2=RT_FunctionExist("MSuper") Is26=VersionNumber>=2.6
Assert(IsAvsPlus||HasGscript,myName+"Essential AVS+ or GScript installed")
Assert(HasGrunt,myName+"Essential GRunt installed") Assert(HasMvTools2,myName+"Essential MvTools2 installed")
Delta=Default(Delta,1) Time=Default(Time,50.0) MaskT=Default(MaskT,3) BlkSz=DefaulT(BlkSz,4)
XStep=Default(XStep,8) Align=Default(Align,True) HFlip=Default(HFlip,False)
CS=Default(CS,Is26?"Y8":"YV12")
OLap=(BlkSz>=4)?BlkSz/2:RT_Undefined
# OLap=RT_Undefined
FuncS="""
Function Fn(clip c,Int Delta,Float Time,Int XStep,Bool Align,Bool HFlip,String mType) {
c n=current_frame
Hit=(Height-20)/5
if(Align) {
Steps=640/XStep
x=((n+1)*XStep) + (Delta*XStep/2)
x=Min(x,(Steps-1)*XStep)
x=HFlip?x:639-x
cF=RT_YPlaneMin(n=n,x=x,y=Round(2.5*Hit)+20,w=1,h=1)-128
cB=RT_YPlaneMin(n=n,x=x,y=Round(3.5*Hit)+20,w=1,h=1)-128
Z=c.BlankClip(width=1,height=1,Color=$FFFFFF,Length=1)
OverLay(Z,x=x,y=Round(2.5*Hit)+20)
OverLay(Z,x=x,y=Round(3.5*Hit)+20)
Subtitle(RT_String("@x=%d FGrey=128%+d : BGrey=128%+d",x,cF,cB))
} else {
Subtitle("Align=False, Colors NOT shown")
}
Subtitle(String(n,"SRC[n=%.0f] (1st interp srcS)") , Y=0.5*Hit+20,Align=5)
Subtitle(String(n+Delta,"SRC[n+Delta=%.0f] (2nd interp srcE)") , Y=1.5*Hit+20,Align=5)
(Align)
\ ? Subtitle(String(n+Delta,"FVEC[n+DELTA=%.0f]")+mType+ " (Aligned)" , Y=2.5*Hit+20,Align=5)
\ : Subtitle(String(n,"FVEC[n=%.0f]")+mType , Y=2.5*Hit+20,Align=5)
Subtitle(String(n,"BVEC[n=%.0f]")+mType , Y=3.5*Hit+20,Align=5)
Subtitle(string(n+Delta*Time/100.0,"MFlowInter Predicted @ [%.2f]") , Y=4.5*Hit+20,Align=5)
Return Last
}
Wid=640 Hit=64 Steps=Wid/XStep
White=BlankClip(width=WID,height=HIT,Length=1,Color=$FFFFFF,Pixel_type=CS) Black=White.BlankClip srcS=Black.BlankClip(Length=0)
For(i=1,Steps-1) { W=White.Crop(0,0,i*XStep,0) K=Black.Crop(0,0,Wid-W.Width,0) Frm=StackHorizontal(K,W) srcS=srcS++Frm }
srcS=(HFlip)?srcS.FlipHorizontal:srcS
srcE=SrcS.Loop(0,0,Delta-1) # Delete Delta frames, end interp src
super=srcS.MSuper(pel=2,hpad=16,vpad=16)
fvec =MAnalyse(super, isb=false, blksize=BlkSz, overlap=OLap, delta=Delta, truemotion=true)
bvec =MAnalyse(super, isb=true, blksize=BlkSz, overlap=OLap, delta=Delta, truemotion=true)
inter=srcS.MFlowInter(super, bvec,fvec, time=Time)
mbv=srcS.MMask(bvec,kind=MaskT)
mfv=srcS.MMask(fvec,kind=MaskT)

return StackVertical(MShow(super,fvec).SubTitle("MShow fvec"),MShow(super,bvec).SubTitle("MShow bvec")) ### RETURN EARLY

mfv=(Align)?mfv.Loop(0,0,Delta-1):mfv # Align, Delete DELTA frames from start, align n+delta with n
DIR=(HFlip) ? " : ---->" : " : <----"
TXT=SrcS.BlankClip(Height=20,Length=1,Color=$404040)
StackVertical(TXT,srcS,SrcE,MFV,MBV,Inter)
mType=mTyp(MaskT)
ARGS = "Delta,Time,XStep,Align,HFlip,MType"
Last.GScriptClip("Fn(last, "+ARGS+")", local=true, args=ARGS)
TXT=TXT.Subtitle(String(Delta,"Delta=%.0f")+String(Time," : Time=%.2f")+
\ String(BLKSZ," : BLKSZ=%.0f")+String(XSTEP," : XSTEP=%.0f")+" : ALIGN="+String(ALIGN)+" : HFlip="+String(HFlip)+DIR)
return StackVertical(TXT,Last)
"""
IsAvsPlus?Eval(FuncS):GScript(FuncS)
Return Last.ConvertToRGB32
}

# 0=Motion, 1=Sad, 2=Occlusion, 3=Horizontal, 4=Vertical, 5=ColorMap

VectorTest(Delta=2,MaskT=2,HFlip=false,BlkSz=8,Align=True)


frame 41 [EDIT: BVEC looks correct-ish, but is it twice as wide as it should be ???, maybe white moving left, and black moving right, sort of ]
https://i.postimg.cc/mrDGTWcZ/vt41.jpg (https://postimages.org/)

frame 42
https://i.postimg.cc/dtjMdVrt/vt42.jpg (https://postimages.org/)

frame 43
https://i.postimg.cc/1RDbh3Wc/vt43.jpg (https://postimages.org/)

frame 44
https://i.postimg.cc/FzvWs0Pb/vt44.jpg (https://postimages.org/)

frame 45 [EDIT: BVEC looks correct-ish, but is it twice as wide as it should be ???, maybe white moving left, and black moving right, sort of ]
https://i.postimg.cc/MpHsT6YL/vt45.jpg (https://postimages.org/)

'curiouser and curiouser' cried Alice.

EDIT: Frame 41 (top one) cropped and point resized a bit

Crop(288,112,34,-14)
PointResize(width*16,height*16)

https://i.postimg.cc/HnHYRfs9/Vectortest-Copy-01.jpg (https://postimg.cc/CBPpfr8R)

MeteorRain
27th April 2020, 12:13
Bump.

I took a few hours having a quick scan in the source code.

MCTD is basically MDegrain(lots of MAnalyze()), so to increase the speed, a very quick test would be to run MAnalyze in parallel. I suppose mvtools cannot run under multi-threading mode yet because it crashed right away.

I'm thinking maybe I should plan to backport VapourSynth-mvtools instead of trying to clean up the original code.

How much difference are there (apart from the synth platform) between the 2 code base?

tormento
27th April 2020, 12:24
How much difference are there (apart from the synth platform) between the 2 code base?
From a user POV (and that's why I stopped using VS), mdegrain goes up to 6 (I wish I had up to 9, that I use A LOT on heavily grained old BW sources) and there is mdegrain N too.

Boulder
27th April 2020, 12:39
Bump.

I took a few hours having a quick scan in the source code.

MCTD is basically MDegrain(lots of MAnalyze()), so to increase the speed, a very quick test would be to run MAnalyze in parallel. I suppose mvtools cannot run under multi-threading mode yet because it crashed right away.

I'm thinking maybe I should plan to backport VapourSynth-mvtools instead of trying to clean up the original code.

How much difference are there (apart from the synth platform) between the 2 code base?
I'm not sure if pinterf has already included the changes the SVP project has made in MAnalyse, the VS version should contain them.

tormento
27th April 2020, 13:14
MvTools with Depans 2.7.41
Is there any reason why mdegrainN is less efficient than mdegrainX, where x=1…6? I am not talking about speed but about denoising.

I was doing some tests on noise vs details preservation and I panned from mdegrain4 to mdegrain9 as tr=4…9 parameter in SMDegrain. It was the only parameter I changed. The table speaks for itself:

tr=4 5.237,20 kb/s
tr=5 5.116,45 kb/s
tr=6 5.021,69 kb/s
tr=7 5.067,22 kb/s <- at this point there is a regression
tr=8 5.008,13 kb/s
tr=9 4.963,75 kb/s

I have tried different thsad values and I have found the same pattern.

Any idea?

pinterf
27th April 2020, 13:45
I'm not sure if pinterf has already included the changes the SVP project has made in MAnalyse, the VS version should contain them.
Those changes are incorporated (stop analyzing and gathering further SAD if the given threshold is already reached)

pinterf
27th April 2020, 14:01
Bump.

I took a few hours having a quick scan in the source code.

MCTD is basically MDegrain(lots of MAnalyze()), so to increase the speed, a very quick test would be to run MAnalyze in parallel. I suppose mvtools cannot run under multi-threading mode yet because it crashed right away.

I does run in mt, and for historical reasons it still have its internal mt (need external avstp.dll and mt=true).
I wonder about the crash details it's been a long while since I received report on it.


I'm thinking maybe I should plan to backport VapourSynth-mvtools instead of trying to clean up the original code.

How much difference are there (apart from the synth platform) between the 2 code base?

VS started from an earlier mvtools version. My version took an mvtools version which worked on x64 (original one never had x64 version) this one had internal mt in many functions, which I told you about (mt flag).

Then came .a 22 version from Fizick (still only for YV12 and YUY2), so both VS and my fork had to be updated our already heavily changed sources with those changes.

Then my version was updated with finer block sizes, float support, made motion vector formats independent from the format of the clip applied on (use mv from 8 bit search and apply on 16 or 32 bit clip in MDegrain, huge save in time) 4-6 versions of MDegrain (it's MDegrainN that has internal mt). And others which I cannot remember without looking at the 2.7 changelog.

edit:
plus differences:
MDegrain: out16 parameter, which outputs 16 bit result from 8 bit input
scaleCSAD parameter in MAnalyze (which has internal mt as well), basically chroma SAD is made consistent between 4:2:0, 4:2:2 and 4:4:4 format but you can fine tune it.

pinterf
27th April 2020, 14:07
Is there any reason why mdegrainN is less efficient than mdegrainX, where x=1…6? I am not talking about speed but about denoising.

I was doing some tests on noise vs details preservation and I panned from mdegrain4 to mdegrain9 as tr=4…9 parameter in SMDegrain. It was the only parameter I changed. The table speaks for itself:

tr=4 5.237,20 kb/s
tr=5 5.116,45 kb/s
tr=6 5.021,69 kb/s
tr=7 5.067,22 kb/s <- at this point there is a regression
tr=8 5.008,13 kb/s
tr=9 4.963,75 kb/s

I have tried different thsad values and I have found the same pattern.

Any idea?
MDegrainN falls back to native MDegrain1,2,3... when the thSad and thSad2 parameters are the same, try with different ThSad2 if it differs even by one, it will call original MDegrainN

tormento
27th April 2020, 14:14
MDegrainN falls back to native MDegrain1,2,3... when the thSad and thSad2 parameters are the same
Please explain me more about this fallback.

If it falls back, shouldn’t I have the same results? And it falls back, to which MDegrain?

pinterf
27th April 2020, 14:19
E.g. MDegrainN with tr=3 will be redirected to MDegrain3 (different code) if ThSad2 = ThSad. Over 6 since there is no matching MDegrain7, it remains in the original MDegrainN code.

tormento
27th April 2020, 14:22
E.g. MDegrainN with tr=3 will be redirected to MDegrain3 (different code) if ThSad2 = ThSad. Over 6 since there is no matching MDegrain7, it remains in the original MDegrainN code.
Ok but my question was totally different. :p

Why over 6 is there a regression in efficiency? You can clearly see the step up in bitrate from 6 to 7.

pinterf
27th April 2020, 14:30
The codes are different a bit, MDegrainN is full generic code capable of handling many clips. I cannot remember now in which part it is different from normal MDegrain. (Internal accuracy, processing order?)
Try comparing MDegrainN(tr=6) with MDegrain6, how much is the difference? (and force using the N version by giving a slightly different ThSad2 param)

tormento
27th April 2020, 17:00
Try comparing MDegrainN(tr=6) with MDegrain6, how much is the difference? (and force using the N version by giving a slightly different ThSad2 param)
SMDegrain use internally different values already:

thSAD=default( thSAD, 300 )
thSAD2=int(thSAD/2)

so the values of tr>6 use MDegrainN code.

real.finder
27th April 2020, 18:58
For me, I am completely satisfied with MVTools-pfmod

the only thing that missed is float clip motion analysis, but since not all other filters work with float clip as f3kdb or there are even many filters still in 2.5 era, I think MVTools-pfmod is ok as it, and also I didn't note any MT problem

tormento
27th April 2020, 19:08
For me, I am completely satisfied with MVTools-pfmod
Perhaps a single, generic and optimized MDegrainN would be the best thing.

Why are there different version for the same function?

Lot of plugins have different working ranges but there is one plugin only for all of them.

real.finder
27th April 2020, 19:15
Perhaps a single, generic and optimized MDegrainN would be the best thing.

Why are there different version for the same function?

Lot of plugins have different working ranges but there is one plugin only for all of them.

for avs/avs+ it's only one now (MVTools-pfmod) since it has all features of the others

in vs there are 2, and since I don't use vs so I don't care :)

tormento
27th April 2020, 19:18
for avs/avs+ it's only one now (MVTools-pfmod) since it has all features

I mean having MDegrain1...MDegrain6 and MDegrainN.

real.finder
27th April 2020, 19:19
I mean having MDegrain1...MDegrain6 and MDegrainN.

that features :D

I think we talked a lot about this before

tormento
27th April 2020, 19:23
that features :D



I think we talked a lot about this before



Wouldn’t be easier to maintain and optimize a single generic function instead of 7 or 4 in the case of VS?

real.finder
27th April 2020, 19:27
Wouldn’t be easier to maintain and optimize a single generic function instead of 7 or 4 in the case of VS?

which one in vs? the main one is MDegrain1...MDegrain3 IIRC

anyway, MDegrain1...MDegrain6 is faster than use MDegrainN with 1-6

that why it's features

pinterf
27th April 2020, 20:09
For me, I am completely satisfied with MVTools-pfmod

the only thing that missed is float clip motion analysis, but since not all other filters work with float clip as f3kdb or there are even many filters still in 2.5 era, I think MVTools-pfmod is ok as it, and also I didn't note any MT problem
Why need motion analysis in float? In most cases you cannot even separate 8 bit results from 10 or 16 bit results. Do the motion analysis fast, in 8 or 10 bits. Then apply it on the 32 bit float clip. MDegrain, MFlow, etc.. all work with float. You can even do it on RGB, while motion analysis can be done on the YUV ceonverted clip. I have a feeling that 32 bit float is not even enough for SAD, it has only 23 significant bits afaik, while mvtools is using 32 or 64 bits for summing up SADs. I think it is more interesting to examine the effect of mv precision if we put motion vectors to floating point.
And we are talking about precision? What is the base data we are working on? It's not even a linear one. Did anybody do tests on making vectors from a more linear 16 bit data converted from a 8 or 10 bit source? We do averaging, resizing, adding and subtracting and interpolating on gamma distorted videos. I think it's not the float clip-based analysis which is the bottleneck.

real.finder
27th April 2020, 20:47
Why need motion analysis in float? In most cases you cannot even separate 8 bit results from 10 or 16 bit results. Do the motion analysis fast, in 8 or 10 bits. Then apply it on the 32 bit float clip. MDegrain, MFlow, etc.. all work with float. You can even do it on RGB, while motion analysis can be done on the YUV ceonverted clip. I have a feeling that 32 bit float is not even enough for SAD, it has only 23 significant bits afaik, while mvtools is using 32 or 64 bits for summing up SADs. I think it is more interesting to examine the effect of mv precision if we put motion vectors to floating point.
And we are talking about precision? What is the base data we are working on? It's not even a linear one. Did anybody do tests on making vectors from a more linear 16 bit data converted from a 8 or 10 bit source? We do averaging, resizing, adding and subtracting and interpolating on gamma distorted videos. I think it's not the float clip-based analysis which is the bottleneck.

maybe it's needed in extreme cases https://forum.doom9.org/showpost.php?p=1906890&postcount=168

pinterf
27th April 2020, 21:53
Yep, I've read it, I'd like to know more about those edge cases, I admit there can be cases but I could only see that the script is SMDegrain, which is not mvtools alone. Or SMDegrain was only demonstrating the speed difference?
O.K. then questions will come: In what part was it better? Was the result visually more appealing in general? Or did it have better noise reduction, or it did better interpolation in MFlow or in a similar filter?

(for myself: ) If the reason was of having a full floating point mvtools, I'd interested in the real reason (which we may even cannot tell without debug output):
having float (or double?) SAD collecting, finer motion vectors or only just being the clip float in the denoising or whatever process?
(Note that integer VS-mvtools version cannot handle float clip with doing mv prediction from a 8-16 bits clip, in avs mvtools float speed penalty is not that much).

Poor ChaosKing :), he just said what he experienced;
I really wanted to ask him about these things that came into my mind but I felt tired to really go into deeper analysis. (The topic is indeed an interesting one)

ChaosKing
27th April 2020, 23:03
With better quality I meant less artifacts :D
I know I posted comparison pics somewhere, but I can't find it.

And since mvtools-sf only supports 32bit precision (and mvtools does not), we can't know if it is just a "better" implementation or because it is more "precise".

I remember one scene where this problem can be observed. I will try to make a test with vs and avs mvtools soon.

EDIT
The edge case was observed with smdegrain.

StainlessS
28th April 2020, 00:15
Chaos, Was trying to find your images, and have seen links to zopti thread, perhaps in there somewhere.
Any of these images familiar:- https://www.google.com/search?source=univ&tbm=isch&q=%22chaosking%22+near+(%22mvtools%22+%26+%22smdegrain%22)&sa=X&ved=2ahUKEwjF8ZTp3InpAhXIUxUIHUo9BokQsAR6BAgHEAE&biw=1920&bih=886

MeteorRain
28th April 2020, 01:02
I does run in mt, and for historical reasons it still have its internal mt (need external avstp.dll and mt=true).
I wonder about the crash details it's been a long while since I received report on it.

I didn't try MT or avstp. I was simply trying to parallelize GetFrame() call in MDegrain to fetch multiple upstream MAnalyze results. I got some incorrect pointers to read but I didn't dig deeper.

I just checked the code, it was marked as MT_MULTI_INSTANCE, so it cannot be run in multi-threading.

feisty2
28th April 2020, 04:18
Why need motion analysis in float? In most cases you cannot even separate 8 bit results from 10 or 16 bit results. Do the motion analysis fast, in 8 or 10 bits. Then apply it on the 32 bit float clip. MDegrain, MFlow, etc.. all work with float. You can even do it on RGB, while motion analysis can be done on the YUV ceonverted clip. I have a feeling that 32 bit float is not even enough for SAD, it has only 23 significant bits afaik, while mvtools is using 32 or 64 bits for summing up SADs. I think it is more interesting to examine the effect of mv precision if we put motion vectors to floating point.
And we are talking about precision? What is the base data we are working on? It's not even a linear one. Did anybody do tests on making vectors from a more linear 16 bit data converted from a 8 or 10 bit source? We do averaging, resizing, adding and subtracting and interpolating on gamma distorted videos. I think it's not the float clip-based analysis which is the bottleneck.

the internal precision of mvtools-sf is double, it even requires the double precision fftw3, not fftw3-f.

ChaosKing
28th April 2020, 06:47
Chaos, Was trying to find your images, and have seen links to zopti thread, perhaps in there somewhere.
Any of these images familiar:- https://www.google.com/search?source=univ&tbm=isch&q=%22chaosking%22+near+(%22mvtools%22+%26+%22smdegrain%22)&sa=X&ved=2ahUKEwjF8ZTp3InpAhXIUxUIHUo9BokQsAR6BAgHEAE&biw=1920&bih=886

Nope. But at least I learned a new img search technique :D
It was a frame from the Lupin III bluray (season 1, Anime from 1971)

ChaosKing
28th April 2020, 07:23
I just quickly looked over some scenes I remember had problems. They look fine now... So either the bugs were fixed over time or even worse: my ffms2 version was not frame accurate back then :devil:

EDIT
I think I have a VS portable folder with plugins and scripts from that time somewhere. Then I could check for sure.

tormento
3rd May 2020, 09:36
I have just noticed about SVPFlow, using GPU. Is it a feature that can be ported in MVTools too?

MeteorRain
3rd May 2020, 10:49
Is the GPU feature open source? My memory told me it's closed source.

tormento
3rd May 2020, 12:11
Is the GPU feature open source? My memory told me it's closed source.


I didn’t mean to import it but to take the idea to develop same or similar workflow.

DJATOM
3rd May 2020, 12:21
OpticFlow sources can be obtained via Nvidia developer site (https://developer.nvidia.com/opticalflow-sdk)

Selur
3rd May 2020, 17:57
SVP Team did share a modified mvtools2 over at
The latest version of modified MVTools is 2.5.11.9 (28.02.2012) and it's based on official MVTools 2.5.11.3 release (19.09.2011).
The distribution includes:

mvtools2.dll library (requires VC++ 2008 SP1 run-time)
sources of modified MVTools2
libflowsse.dll and libflowgpu.dll libraries
sample script
readme and licenses


source: https://www.svp-team.com/wiki/Plugins:_MVTools2

magnetite
3rd May 2020, 19:34
Speaking of GPU acceleration, I was curious if something like MDegrain could use it? Reason I ask is because there are other GPU based denoisers out there, such as FFT3DGPU and KNLMeansCL.

tormento
3rd May 2020, 19:41
SVP Team did share a modified mvtools2
Nice but a bit outdated since based on MVTools 2.5.11.3.

Pinterf? MeteorRain? :)

Reel.Deel
3rd May 2020, 20:22
SVP Team did share a modified mvtools2 over at

source: https://www.svp-team.com/wiki/Plugins:_MVTools2

The SVP version includes these changes:


MAnalyse: Can be faster than original version (with chroma=true) by 20-40%, look at PlaneOfBlocks.h for changes. Also there's one additional parameter: search_coarse ....


MFinest: This function is commented out in latest MVTools 2.5 versions and it's obviously a mistake cause it can helps a lot with caching the big frame for hpel (pel=2) and qpel (pel=4) modes.


MSmoothFps: It's a completely new function that encapsulates MFlow, MFlowFps and MBlockFps functionality and with GPU support enabled ..... Note: this part is not open source so ....


The MAnalyze change was included in the VS port in the early stages, discussion starts here: https://forum.doom9.org/showthread.php?p=1695899#post1695899

Pinterf later mades those changes as well (additional search_coarse parameter is not included): https://forum.doom9.org/showthread.php?p=1790290#post1790290

-----
Edit:
OpticFlow sources can be obtained via Nvidia developer site (https://developer.nvidia.com/opticalflow-sdk)

The SVPFlow plugin already has a function that uses this. Too bad is closed source.


SVSmoothFps_NVOF(): The same as SVSmoothFps but the motion vectors are acquired in-place via NVidia Optical Flow API so there's no need for SVSuper/SVAnalyse at all.

tormento
3rd May 2020, 20:41
IMHO the way to go is to offload as many loads to GPU as possible. Of course this will change some paradigma. The power of modern GPUs is undeniable, more power for same bucks than CPUs.

Emulgator
13th May 2020, 10:18
Hi pinterf !
Many thanks for your continued work on useful plugins and Avisynth+ !
Donation time for me. HowTo ?

pinterf
23rd May 2020, 20:55
New release, please test it.
https://github.com/pinterf/mvtools/releases/tag/2.7.42

Update after Boulder's request: limit and limitc parameters of MDegrain functions were integer and accepted values 0-255. (unlike the VapourSynth version which does not auto scale parameters)

So far for 16 bit output the minimum "1" would still mean 256 levels.

Now limit and limitc parameters are of float type.
By specifying limit=0.1*255 you can effectively limit the change to 25 for a 16bit clip.

The other big change is that functions are now copying frame properties when using Avisynth+ 3.6. Frame properties are not used however, that is the filters simply do not choke them and do not put them to dev/null :)

The Depan-family update contains only this new fp-copy feature, there is no functional change there.

- 2.7.42 (20200522)
- MDegrain family: limit and limitc to float, allowing more granurality for 10+ bit depth
- Update Avisynth headers, use V8 interface frame property copy if available

zybex
27th May 2020, 23:12
Hello everyone.

Dear pinterf

Thanks for the support and further development of the MVTools-pfmod filter.
But unfortunately, I found one annoying and unpleasant bug that I can’t put up with, because I'm a perfectionist.

All versions of this filter (x86 and x64) that are newer than the original latest version v2.5.11.22 from Fizick contain this bug:
for "MDegrain2" command:
The coding result is different every time.

I checked all of these versions:
2.6.0.5 / 2.7.0.22c / 2.7.0.1 / 2.7.34 / 2.7.39 / 2.7.40 / 2.7.41 / 2.7.42
this bug is present in all of them

The differences are in the heap of different pixels in the heap of different frames, and as a rule, starting from about the middle of the video with a length of 3 minutes. Visually, these differences are almost imperceptible, but they are, and there are a lot of them, and this I think affects the quality of compression of MPEG4 codecs.
Moreover, there are more differences if you encode in AVI XviD VFW and less if you encode in AVI x264-Lossless VFW.

How to check this problem?
You make 3 attempts to encode the same AVS file in a row, you get 3 different AVI files. As a rule, their length will be slightly different, already by this sign it can be judged that there are differences in the frames. But even if in two of the three AVI files the length is the same, then anyway, by bitwise comparing them (fc /b file1.avi file2.avi >log), it turns out that they have differences.
If necessary, I can later lay out instructions on how to find exactly which frames differ in different AVI video files through AVISynth, then you can save them as pictures and compare them visually through "Beyond Compare 3".

Here are the contents of my AVS script:
(I just simplified the script as much as possible for the test so that other commands and filters did not affect the test)

LoadPlugin("C:\Program Files (x86)\AviSynth\plugins\DGDecode.dll")
LoadPlugin("C:\Program Files (x86)\AviSynth\plugins\mvtools2.dll")
mpeg2source("Michael Gray - The Weekend.d2v")
super = MSuper (hpad=8, vpad=8, pel=4, levels=0, chroma=true, sharp=2, rfilter=1)
backward_vec1 = MAnalyse(super, blksize=16, search=5, isb=true, delta=1, overlap=8)
backward_vec2 = MAnalyse(super, blksize=16, search=5, isb=true, delta=2, overlap=8)
forward_vec1 = MAnalyse(super, blksize=16, search=5, isb=false, delta=1, overlap=8)
forward_vec2 = MAnalyse(super, blksize=16, search=5, isb=false, delta=2, overlap=8)
MDegrain2(super, backward_vec1, forward_vec1, backward_vec2, forward_vec2, thSAD=200, plane=0)

Here is my source (DVD VOB music video)
http://worldclips.ru/clips/Michael+Gray/The+Weekend+%28feat+Shena%29
(you need to log in to download it)

DGDecode.dll - v1.5.8.0 x86
http://rationalqm.us/dgmpgdec/dgmpgdec158.zip
DGDecode.dll - v1.5.8.0 x64
http://www.mediafire.com/?c0wmemj5jam

the original latest version v2.5.11.22 from Fizick (good, no bugs)
www.avisynth.nl/users/fizick/mvtools/mvtools-v2.5.11.22.zip

I use VirtualDub2, but the result does not depend on the version of VirtualDub.

Please try to fix this bug, and achieve a stable encoding result using the MVTools-pfmod filter so that three different encoding attempts give the same encoding result bit by bit (for "XviD 1.3.7 VFW" and "x264-Lossless VFW").

P.S.
I would reconcile myself to using this slower but more stable version v2.5.11.22 from Fizick, but I decided to switch to AVISynth+ and use x64 versions of filters and multi-threading, but unfortunately v2.5.11.22 does not have x64 version.

feisty2
28th May 2020, 07:34
the problem does not exist in vaporsynth mvtools, there must be some uninitialized memory bug left unfixed in the avs branch.

pinterf
28th May 2020, 08:17
the problem does not exist in vaporsynth mvtools, there must be some uninitialized memory bug left unfixed in the avs branch.
Yep, seems a nasty one, if it happens with 2.6.0.5.
And I'm so happy since I was able to read the site's warning and I could refresh my knowledge in Russian I have started learning in school for some 40 years ago :)

pinterf
28th May 2020, 08:33
But unfortunately, I found one annoying and unpleasant bug that I can’t put up with, because I'm a perfectionist.

Created an issue on my git repo

StainlessS
28th May 2020, 12:42
@ Zybex,
Not many posts since you joined in 2007, this one a gem :goodpost:
Thanks.

pinterf
28th May 2020, 12:49
@Zybex: Could not reproduce. 8 out of 8 sessions are bit identical. Do you have accidentally an avstp.dll in your plugins directory?
Edit: yes. avstp.dll provides internal multithreading for specific Mvtools2 filters. Such filters have a bool "mt" parameter, default=true. (see in html docs)
So if avstp.dll exists, all such functions are working with internal multithreading.

This feature is part of mvtools since 2.6.0.5. And because this version was my base version, all versions I released later have inherited its behaviour.

In your specific case, choose one
- remove avstp.dll
- add an mt=false for MAnalyze (this is the culprit)
- wait until I or someone finds the bug

zybex
28th May 2020, 13:29
@Zybex: Could not reproduce. 8 out of 8 sessions are bit identical. Do you have accidentally an avstp.dll in your plugins directory?

Yes, i have it here:

c:\Program Files (x86)\AviSynth+\plugins64\avstp.dll
c:\Program Files (x86)\AviSynth\plugins\avstp.dll

Is it wrong ?

real.finder
28th May 2020, 13:32
Yes, i have it here:

c:\Program Files (x86)\AviSynth+\plugins64\avstp.dll
c:\Program Files (x86)\AviSynth\plugins\avstp.dll

Is it wrong ?

try after remove it

pinterf
28th May 2020, 13:40
Yes, i have it here:

c:\Program Files (x86)\AviSynth+\plugins64\avstp.dll
c:\Program Files (x86)\AviSynth\plugins\avstp.dll

Is it wrong ?
Not wrong, but for MAnalyze something is buggy.

zybex
28th May 2020, 23:15
@Zybex:
In your specific case, choose one
- remove avstp.dll
- add an mt=false for MAnalyze (this is the culprit)

@pinterf

Thank you for the quick and correct hint of ways to solve the problem of instability of the encoding result in MPEG-4. It really turned out that way.

The most correct method to solve the problem:
- add multithreading disable to the "MAnalyze" function by adding the command "mt=false"

So my script turned out like this:

LoadPlugin("C:\Program Files (x86)\AviSynth\plugins\DGDecode.dll")
LoadPlugin("C:\Program Files (x86)\AviSynth\plugins\mvtools2.dll")
mpeg2source("Michael Gray - The Weekend.d2v")
super = MSuper (hpad=8, vpad=8, pel=4, levels=0, chroma=true, sharp=2, rfilter=1)
backward_vec1 = MAnalyse(super, blksize=16, search=5, isb=true, delta=1, overlap=8, mt=false)
backward_vec2 = MAnalyse(super, blksize=16, search=5, isb=true, delta=2, overlap=8, mt=false)
forward_vec1 = MAnalyse(super, blksize=16, search=5, isb=false, delta=1, overlap=8, mt=false)
forward_vec2 = MAnalyse(super, blksize=16, search=5, isb=false, delta=2, overlap=8, mt=false)
MDegrain2(super, backward_vec1, forward_vec1, backward_vec2, forward_vec2, thSAD=200, plane=0)

And this completely solved the problem of instability of the encoding result, for "MVTools-pfmod v2.7.42" x86 and x64.

But at the same time, the CPU load became 2 times less, and the processing time now became 2 times longer.

In the same way, the option to delete the file "avstp.dll" solved the problem, but this is the wrong solution to the problem, because this will disable multithreading in all filters that support it.

I think it’s worth adding a comment to the instruction for the "MVTools-pfmod" filter regarding the need to add "mt=false" to "MAnalyze"

I don’t know why this problem manifests so far only with me.

Just in case, my PC configuration:
CPU: Intel Core i5-6500 3.20Ghz
RAM: 16Gb
OS: Windows 10 Corporate LTSC x64 10.0.17763.1131

As I understand it, the version "v2.5.11.22 from Fizick" does not have this problem because it initially does not support multithreading for the "MAnalyze" function at all and does not have the command "mt=" .

Nevertheless, it would be good to fix and achieve stable operation of the "MVTools-pfmod" filter without having to disable multithreading in MAnalyze, because using this filter without multithreading slows it down by 2 times - this is very disappointing.

P.S.
after adding commands to the script:
SetFilterMTMode ("DEFAULT_MT_MODE", 2) # at the beginning of the script
Prefetch (4) # at the end of the script
processing speed has increased significantly and it suits me

DJATOM
29th May 2020, 02:02
There's actually avs+ multithreading available for the task, so just ditch avstp and add prefetch(4) in the end. It will be even faster

StainlessS
29th May 2020, 02:04
Nevertheless, it would be good to fix and achieve stable operation of the "MVTools-pfmod" filter without having to disable multithreading in MAnalyze, because using this filter without multithreading slows it down by 2 times - this is very disappointing.

Not wrong, but for MAnalyze something is buggy.

I think Pinterf wanted you to remove the avstp.dll or disable MT to see if it did indeed avoid the problem, so as to be sure that mt in MAnalyze is the culprit, it is I think not suggested that this is a permanent fix.

ravewulf
29th May 2020, 04:47
Make sure you have the AviSynth+ build from https://github.com/AviSynth/AviSynthPlus/releases then use the modified script below.

LoadPlugin("C:\Program Files (x86)\AviSynth\plugins\DGDecode.dll")
LoadPlugin("C:\Program Files (x86)\AviSynth\plugins\mvtools2.dll")
mpeg2source("Michael Gray - The Weekend.d2v")
super = MSuper (hpad=8, vpad=8, pel=4, levels=0, chroma=true, sharp=2, rfilter=1)
backward_vec1 = MAnalyse(super, blksize=16, search=5, isb=true, delta=1, overlap=8, mt=false)
backward_vec2 = MAnalyse(super, blksize=16, search=5, isb=true, delta=2, overlap=8, mt=false)
forward_vec1 = MAnalyse(super, blksize=16, search=5, isb=false, delta=1, overlap=8, mt=false)
forward_vec2 = MAnalyse(super, blksize=16, search=5, isb=false, delta=2, overlap=8, mt=false)
MDegrain2(super, backward_vec1, forward_vec1, backward_vec2, forward_vec2, thSAD=200, plane=0)
Prefetch(4) #Controls how many threads to use

Try playing around with the number of threads to maximize the performance. On my own systems, 1.5x the number of physical cores seems to work well

Athlon II X4 640 (4 cores) = Prefetch(6)
Ryzen 7 1700 (8 cores/16 threads)= Prefetch(12)
Ryzen 9 3900X (12 cores/24 threads) = Prefetch(18)

zybex
29th May 2020, 10:44
Try playing around with the number of threads to maximize the performance.

yes, after adding commands to the script:
SetFilterMTMode ("DEFAULT_MT_MODE", 2) # at the beginning of the script
Prefetch (4) # at the end of the script
processing speed has increased significantly and it suits me.

thank you for reminding.

real.finder
1st June 2020, 09:21
bug in mcompensate when using grayscale

colorbars()
converttoy8
clp=last
super = clp.MSuper(pel=2, sharp=1)

bv1 = manalyse(super,isb=true, truemotion=false, delta=1,blksize=16,overlap=8)
fv1 = manalyse(super,Isb=false, truemotion=false, delta=1,blksize=16,overlap=8)

bc1 = mcompensate(clp, super,bv1)
fc1 = mcompensate(clp, super,fv1)

interleave(fc1, clp, bc1)

it crash

Groucho2004
1st June 2020, 09:41
it crash
I can reproduce that:
Exception 0xC0000005 [STATUS_ACCESS_VIOLATION]
Module: C:\Windows\system32\VCRUNTIME140.dll
Address: 0x000007FEEB9E1749

pinterf
2nd June 2020, 09:43
New build with MCompensate greyscale+overlaps issue fix:
MvTools2 2.7.43 + depans (https://github.com/pinterf/mvtools/releases/tag/2.7.43)

real.finder
2nd June 2020, 11:39
New build with MCompensate greyscale+overlaps issue fix:
MvTools2 2.7.43 + depans (https://github.com/pinterf/mvtools/releases/tag/2.7.43)

yes, this fix greyscale issue :thanks:

Boulder
3rd June 2020, 12:27
Would something like this be close to creating vectors with hierachical motion estimation? I was thinking of testing it with UHD sources, the old methods may have difficulties in fast motion with framesize being so huge.

super_quarter = clip.Spline36Resize(width=clip.width/4, height=clip.height/4).MSuper(pel=1)
super_half = clip.Spline36Resize(width=clip.width/2, height=clip.height/2).MSuper(pel=1)
super_full = clip.MSuper(pel=1)

fv1 = super_quarter.MAnalyse(isb = false, blksize=16, overlap=8)
bv1 = super_quarter.MAnalyse(isb = true, blksize=16, overlap=8)
fv1 = MScaleVect(fv1, 2)
bv1 = MScaleVect(bv1, 2)
fv1 = super_half.MRecalculate(fv1, blksize=16, overlap=8)
bv1 = super_half.MRecalculate(bv1, blksize=16, overlap=8)
fv1 = MScaleVect(fv1, 2)
bv1 = MScaleVect(bv1, 2)
fv1 = super_full.MRecalculate(fv1, blksize=16, overlap=8)
bv1 = super_full.MRecalculate(bv1, blksize=16, overlap=8)


http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/AV0405/ZAMPOGLU/Hierarchicalestimation.html

feisty2
3rd June 2020, 17:07
how is it any different from gradually decreasing blksize on the same super clip, keeping the blksize fixed while upsizing the super clip is essentially the same as keeping the super clip fixed while decreasing the blksize, they cover the same percentage of the image area

feisty2
3rd June 2020, 17:27
except the quality would be much better if all hierarchies of motion estimation were conducted at the finest level, larger blksize on the finest super clip is much more accurate than smaller blksize on a reduced super clip, even tho both methods have the same receptive field.

Boulder
3rd June 2020, 18:18
Isn't the radius of searching essential in this case? In the quarter and half sized super clip, it covers a larger area around the block.
I did test that approach briefly and it produced worse vectors than simply reducing the blocksize with recalculating. It also found movement quite deep inside the black borders (movie Interstellar, which has them IMAX parts to fill the whole frame at times so no cropping allowed).

feisty2
3rd June 2020, 18:24
then you simply specify a larger "searchparam" if you want a larger radius. also I haven't checked the exact definition of "radius" in mvtools, if it is relative to the block size, then resizing the super clip won't implicitly increase the radius.

zybex
15th June 2020, 13:33
Hello to all.

Please tell me the real correct examples of writing the lines necessary for the operation of the commands "MDeGrain6" and "MDeGrainN".

I am using the "MDegrain2" command now in this variant:

super = MSuper (hpad=8, vpad=8, pel=4, levels=0, chroma=true, sharp=2, rfilter=1)
backward_vec1 = MAnalyse(super, blksize=16, search=5, isb=true, delta=1, overlap=8, mt=false)
backward_vec2 = MAnalyse(super, blksize=16, search=5, isb=true, delta=2, overlap=8, mt=false)
forward_vec1 = MAnalyse(super, blksize=16, search=5, isb=false, delta=1, overlap=8, mt=false)
forward_vec2 = MAnalyse(super, blksize=16, search=5, isb=false, delta=2, overlap=8, mt=false)
MDegrain2(super, backward_vec1, forward_vec1, backward_vec2, forward_vec2, thSAD=400, plane=0)

I am satisfied with the numerical values of the parameters prescribed in these lines, I would not want to change them without real need.
But I need to achieve better and / or more accurate noise suppression (perhaps due to the use of additional lines and commands "MDeGrain6" and "MDeGrainN" instead of "MDegrain2").

My source is very noisy.

https://postimg.cc/gallery/MXRr427

StainlessS
15th June 2020, 14:25
@Zybex, Any good as example

Posted by Hello_hello

function MDegrainNL(clip c, int "thSAD", int "thSAD2", int "TR", int "BLKSize", int "Overlap", bool "MT", bool "LSB")
{
thSAD = default(thSAD, 150) # Denoising strength
thSAD2 = default(thSAD2, thSAD/2)
TR = default(TR, 1) # Temporal radius
BLKSize = default(BLKSize, 16) # Block size
Overlap = default(Overlap, 4) # Block overlap
MT = default(MT, True) # Internal multithreading
LSB = default(LSB, False) # 16-bit

Super = MSuper(c, MT=MT)
Multi_Vec = MAnalyse(Super, Multi=True, Delta=TR, BLKSize=BLKSize, Overlap=Overlap, MT=MT)
MDegrainN(c, Super, Multi_Vec, TR, thSAD=thSAD, thSAD2=thSAD2, MT=MT, LSB=LSB)
}

https://forum.doom9.org/showthread.php?p=1861146#post1861146

EDIT: TR seems to govern Temporal Radius, eg 6 for MDegrain6 equiv.

EDIT: Or something like this (untested, everything just repeats)

super = MSuper (hpad=8, vpad=8, pel=4, levels=0, chroma=true, sharp=2, rfilter=1)

backward_vec1 = MAnalyse(super, blksize=16, search=5, isb=true, delta=1, overlap=8, mt=false)
backward_vec2 = MAnalyse(super, blksize=16, search=5, isb=true, delta=2, overlap=8, mt=false)
backward_vec3 = MAnalyse(super, blksize=16, search=5, isb=true, delta=3, overlap=8, mt=false)
backward_vec4 = MAnalyse(super, blksize=16, search=5, isb=true, delta=4, overlap=8, mt=false)
backward_vec5 = MAnalyse(super, blksize=16, search=5, isb=true, delta=5, overlap=8, mt=false)
backward_vec6 = MAnalyse(super, blksize=16, search=5, isb=true, delta=6, overlap=8, mt=false)

forward_vec1 = MAnalyse(super, blksize=16, search=5, isb=false, delta=1, overlap=8, mt=false)
forward_vec2 = MAnalyse(super, blksize=16, search=5, isb=false, delta=2, overlap=8, mt=false)
forward_vec3 = MAnalyse(super, blksize=16, search=5, isb=false, delta=3, overlap=8, mt=false)
forward_vec4 = MAnalyse(super, blksize=16, search=5, isb=false, delta=4, overlap=8, mt=false)
forward_vec5 = MAnalyse(super, blksize=16, search=5, isb=false, delta=5, overlap=8, mt=false)
forward_vec6 = MAnalyse(super, blksize=16, search=5, isb=false, delta=6, overlap=8, mt=false)

MDegrain6(super,
\ backward_vec1, forward_vec1,
\ backward_vec2, forward_vec2,
\ backward_vec3, forward_vec3,
\ backward_vec4, forward_vec4,
\ backward_vec5, forward_vec5,
\ backward_vec6, forward_vec6,
\ thSAD=400, plane=0)

MDegrain6 req 6 pairs of vectors, etc.

zybex
15th June 2020, 16:31
@StainlessS

Many thanks.

Your option for "MDegrainN", I'm still in the process of debugging, so far I can’t start working with my parameters there. So far only managed to run with a poor degree of noise reduction.

Your option for "MDegrain6" worked perfectly, the result is much better than with "MDegrain2", noise is significantly better suppressed.


MDegrain2 (plane=0 Luma=On Chroma=Off)
https://i.postimg.cc/ZqJ7DPjw/245-MDegrain2.png (https://postimages.org/)


MDegrain6 (plane=0 Luma=On Chroma=Off)
https://i.postimg.cc/Zqj7k9M4/245-MDegrain6.png (https://postimages.org/)

MDegrain6 (plane=4 Luma=On Chroma=On)
https://i.postimg.cc/gjxjG9gJ/245-MDegrain6-plane-4-Luma-On-Chroma-On.png (https://postimages.org/)

Source
https://i.postimg.cc/2CmMLqt6/245-Source-Color-Gamma-Corrected.png (https://postimages.org/)

zybex
22nd June 2020, 15:41
I discovered a new condition for the appearance of an unstable result of processing the "MDegrain2" command.

The problem appears in "AVISynth+ x64" (3.6.0 r3276) and "mvtools-2.7.42 x64" (and "2.7.43") when using the "Crop" command in front of a group of commands used by "MDegrain2", and when the external "Multithreading" in "AVISynth+" is turned on, even if the parameter "mt=false" is present in the command "MAnalyse".

Please fix that issue.

I encode in "x264 VFW Lossless" (core 152 r2851bm)
https://www.videohelp.com/download/x264vfw_full_44_2851bm_44825.exe
via "VirtualDub2 x64" build 44282
https://sourceforge.net/projects/vdfiltermod/files/VirtualDub%20pack/version%2020/VirtualDub2_44282.zip/download

The differences are in the heap of different pixels in the heap of different frames.
Visually, these differences are almost imperceptible, but they are, and there are a lot of them.

Example of the difference in frames (comparison through the program "Beyond Compare"):

https://i.postimg.cc/wB7B60k2/2395-Crop-to-416-MDegrain2-Unstable.png (https://postimg.cc/wtYz25ZR)

How to check this problem ?
You make 3 attempts to encode the same AVS file in a row, you get 3 different AVI files. As a rule, their length will be slightly different, already by this sign it can be judged that there are differences in the frames. But even if in two of the three AVI files the length is the same, then anyway, by bitwise comparing them (fc / b file1.avi file2.avi> log), it turns out that they have differences.
If necessary, I can later lay out the instructions on how to find exactly which frames differ in different AVI video files through AVISynth, then you can save them as pictures and compare them visually through "Beyond Compare 3".

==========================================
The original frame size in the file: 720x576 (with black stripes bottom and top).

The processing result is stable, there are no problems - under one of these conditions:
- "Crop" is not used before the group of commands used by "MDegrain2", and "Crop" is not used at all
- "Crop" is used only after a group of commands used by "MDegrain2"
- the entire command block responsible for "MDegrain2" has been deleted, and only the "Crop" command has been left
- disabled "Multithreading" by adding # before "Prefetch (4)"

The processing result is unstable, there is a problem - under one of these conditions:
- Crop is used (to 720x416 or 720x404) in front of a group of commands used by MDegrain2,
with "Multithreading" enabled:
SetFilterMTMode ("DEFAULT_MT_MODE", 2) # at the beginning of the AVS script
Prefetch (4) # at the end of the AVS script

I tried to solve the problem in such ways, but this did not help:
- SetFilterMTMode ("MAnalyse", 3)
- SetFilterMTMode ("MDegrain2", 3)

========================================
Here are the contents of my AVS script:
(I just simplified the script as much as possible for the test so that other commands and filters did not affect the test)

SetFilterMTMode("DEFAULT_MT_MODE", 2)
LoadPlugin("C:\Program Files (x86)\AviSynth+\plugins64\DGDecode.dll")
LoadPlugin("C:\Program Files (x86)\AviSynth+\plugins64\mvtools2.dll")

mpeg2source("The Weekend (feat Shena).d2v")

Crop(0,80,-0,-80) #(left,top,right,bottom)

# this block refers to a filter "MDegrain2"
super = MSuper (hpad=8, vpad=8, pel=4, levels=0, chroma=true, sharp=2, rfilter=1)
backward_vec1 = MAnalyse(super, blksize=16, search=5, isb=true, delta=1, overlap=8, mt=false)
backward_vec2 = MAnalyse(super, blksize=16, search=5, isb=true, delta=2, overlap=8, mt=false)
forward_vec1 = MAnalyse(super, blksize=16, search=5, isb=false, delta=1, overlap=8, mt=false)
forward_vec2 = MAnalyse(super, blksize=16, search=5, isb=false, delta=2, overlap=8, mt=false)
MDegrain2(super, backward_vec1, forward_vec1, backward_vec2, forward_vec2, thSAD=200, plane=0)
# end of block

Prefetch(4)

========================================
Here is my source (DVD VOB music video) - same as before
http://worldclips.ru/clips/Michael+Gray/The+Weekend+%28feat+Shena%29
(you need to log in to download it)

DGDecode.dll - v1.5.8.0 x64
http://www.mediafire.com/?c0wmemj5jam

I use the file "SetFilterMTModes.avsi" in the plugins folder "c:\Program Files (x86)\AviSynth+\plugins64"
from here: https://publishwith.me/ep/pad/view/ro.rDkwcdWn4k9/latest
But even without using it, the problem of instability also exists.

pinterf
25th June 2020, 08:49
Thanks, very nice report, reproduced but it's very hard to grab it.
It doesn't even need MDegrain2, reproducible only MShow-ing the first forward vector.
MShow(super, forward_vec1)
It'll take a longer time.

zybex
25th June 2020, 09:07
It'll take a longer time.
OK.
Better late than never :-)

VS_Fan
25th June 2020, 16:29
DGDecode.dll - v1.5.8.0 x64That's a very old build/version of that plugin. You could use a more recent version: MPEG2DecPlus / D2VSource (http://avisynth.nl/index.php/MPEG2DecPlus). That could help with your problem

zybex
26th June 2020, 11:59
That could help with your problem

No, this does not solve the problem.

I changed to "DGSource" from "DGDecodeNV.dll (http://rationalqm.us/dgdecnv/dgdecnv.html)" (build 2053 by 24 May 2020) (instead of "mpeg2source" from "DGDecode.dll"), the problem remains.

FranceBB
17th August 2020, 11:03
Hi there.
I was going to perform temporal degrain as usual when I noticed something weird:


source=FFMpegSource2("Cricket.mov", atrack=-1)
soccer=trim(source, 0, 1534)
soccer_fields=AssumeTFF(soccer)
soccer_bob=Bob(soccer_fields)
soccer_cropped=Crop(soccer_bob, 64, 18, -32, -16)
soccer_super=MSuper(soccer_cropped, pel=2, sharp=1)
soccer_bv1=MAnalyse(soccer_super, isb = true, delta = 1, overlap=4)
soccer_fv1=MAnalyse(soccer_super, isb = false, delta = 1, overlap=4)
soccer_bv2=MAnalyse(soccer_super, isb = true, delta = 2, overlap=4)
soccer_fv2=MAnalyse(soccer_super, isb = false, delta = 2, overlap=4)
soccer_degrain=MDegrain2(soccer_super, soccer_bv1, soccer_fv1, soccer_bv2, soccer_fv2,thSADC=200, thSAD=200)
soccer_SD=DebilinearResizeMT(soccer_degrain, 720, 576)


This doesn't work as MSuper doesn't recognize "soccer_cropped" as "clip", therefore MDegrain2 at the end complains about an invalid input.
On the other hand, this works:


source=FFMpegSource2("Cricket.mov", atrack=-1)
soccer=trim(source, 0, 1534)
soccer_fields=AssumeTFF(soccer)
soccer_bob=Bob(soccer_fields)
Crop(soccer_bob, 64, 18, -32, -16)
soccer_super=MSuper(pel=2, sharp=1)
soccer_bv1=MAnalyse(soccer_super, isb = true, delta = 1, overlap=4)
soccer_fv1=MAnalyse(soccer_super, isb = false, delta = 1, overlap=4)
soccer_bv2=MAnalyse(soccer_super, isb = true, delta = 2, overlap=4)
soccer_fv2=MAnalyse(soccer_super, isb = false, delta = 2, overlap=4)
soccer_degrain=MDegrain2(soccer_super, soccer_bv1, soccer_fv1, soccer_bv2, soccer_fv2,thSADC=200, thSAD=200)
soccer_SD=DebilinearResizeMT(soccer_degrain, 720, 576)


Is it intended?
I mean, the first parameter of MSuper is supposed to be clip, right? Why doesn't it accept my custom name?





Side note: to those wondering, I'm not gonna use "Bob", but I use it for quick and dirt previews 'cause otherwise it would take forever for QTGMC to load a preview.

Boulder
17th August 2020, 12:02
Does it work with soccer_super=soccer_cropped.MSuper(pel=2, sharp=1) ?

FranceBB
17th August 2020, 13:14
Does it work with soccer_super=soccer_cropped.MSuper(pel=2, sharp=1) ?

Yep, it works.

wonkey_monkey
17th August 2020, 18:31
There have been some odd things going on with the old "implicit last" in recent version(s) of Avisynth:

https://forum.doom9.org/showthread.php?t=181351&page=32

https://forum.doom9.org/showthread.php?t=181747

FranceBB
17th August 2020, 21:47
There have been some odd things going on with the old "implicit last" in recent version(s) of Avisynth:

https://forum.doom9.org/showthread.php?t=181351&page=32

https://forum.doom9.org/showthread.php?t=181747

I see... so it's not filter-specific as it affects other plugins as well... That explains it... Thanks.

StainlessS
17th August 2020, 21:53
Hi there.
I was going to perform temporal degrain as usual when I noticed something weird:


source=FFMpegSource2("Cricket.mov", atrack=-1)
soccer=trim(source, 0, 1534)
soccer_fields=AssumeTFF(soccer)
soccer_bob=Bob(soccer_fields)
soccer_cropped=Crop(soccer_bob, 64, 18, -32, -16)
soccer_super=MSuper(soccer_cropped, pel=2, sharp=1) # MSuper aint got no clip, and no Last defined !!!
soccer_bv1=MAnalyse(soccer_super, isb = true, delta = 1, overlap=4)
soccer_fv1=MAnalyse(soccer_super, isb = false, delta = 1, overlap=4)
soccer_bv2=MAnalyse(soccer_super, isb = true, delta = 2, overlap=4)
soccer_fv2=MAnalyse(soccer_super, isb = false, delta = 2, overlap=4)
soccer_degrain=MDegrain2(soccer_super, soccer_bv1, soccer_fv1, soccer_bv2, soccer_fv2,thSADC=200, thSAD=200)
soccer_SD=DebilinearResizeMT(soccer_degrain, 720, 576)


This doesn't work as MSuper doesn't recognize "soccer_cropped" as "clip", therefore MDegrain2 at the end complains about an invalid input.
On the other hand, this works:


source=FFMpegSource2("Cricket.mov", atrack=-1)
soccer=trim(source, 0, 1534)
soccer_fields=AssumeTFF(soccer)
soccer_bob=Bob(soccer_fields)
Crop(soccer_bob, 64, 18, -32, -16) # Assigns to implicit Last, so below MSuper gets from implicit Last and works OK.
soccer_super=MSuper(pel=2, sharp=1)
soccer_bv1=MAnalyse(soccer_super, isb = true, delta = 1, overlap=4)
soccer_fv1=MAnalyse(soccer_super, isb = false, delta = 1, overlap=4)
soccer_bv2=MAnalyse(soccer_super, isb = true, delta = 2, overlap=4)
soccer_fv2=MAnalyse(soccer_super, isb = false, delta = 2, overlap=4)
soccer_degrain=MDegrain2(soccer_super, soccer_bv1, soccer_fv1, soccer_bv2, soccer_fv2,thSADC=200, thSAD=200)
soccer_SD=DebilinearResizeMT(soccer_degrain, 720, 576)


Is it intended?
I mean, the first parameter of MSuper is supposed to be clip, right? Why doesn't it accept my custom name?


1st code block, you dont give a clip to MSuper, and Last is undefined.
2nd one, works because crop supplies implicit last with a clip, so it works, your script was at fault.

FranceBB
17th August 2020, 22:03
1st code block, you dont give a clip to MSuper, and Last is undefined.

But I gave "soccer_cropped" as first argument to MSuper which is the output from "Crop" and of course, since it's the very first argument, I expect it to be used as a clip. Why isn't it used as a clip?

soccer_super=MSuper(soccer_cropped, pel=2, sharp=1)

StainlessS
17th August 2020, 22:05
Oops sorry, I was looking for soccer_cropped.MSuper() not Msuper(soccer_cropped)
NOT your script fault. :( Senility, you gotta luv it, always good for a laugh.

Wonkey is correct, funny happenings of late.

FranceBB
17th August 2020, 22:19
Senility, you gotta luv it, always good for a laugh.

Nah, not your fault, the script is a bit messy to read and it may seem "stupid" given that I could have left everything as it was, but it's actually part of a bigger, more complicated script, hence the need to assign those names... I've basically got a series of events in the same tape, but whoever dubbed the thing through a VTR at the time clearly didn't care about things like inactive lines and reverse fields and levels and many other things. Heck, in some points I even had to make a mask by hand to make sure the pitch looked almost the same from every camera... (and I don't have the cameras, I had to TRIM every single part... It was a hell of a job, but apparently my boss likes that game particularly... I don't know why, though, as his favorite team lost in the Champion's League final, so to me it would be something to forget, not remember xD I shouldn't comment any further, though, as he might be lurking on Doom9, especially since he knows that I spend much time here...)


Anyway, the thing is that David is right, there have been some weird things going on in the latest AVS+ version that affect a series of filters on the "last" argument, so it's not bonded to MVTools...

(Side Note: by "David" I mean Wonkey Monkey, although I never understood why he changed his nickname a while ago xD)

feisty2
19th August 2020, 07:05
@pinterf

there's something fishy with MRecalculate, it seems we need to scale up searchparam when refining vectors to a smaller block size to get the correct result.
theoretically, this

vec = sup.MAnalyze(blksize=64, overlap=32, search=3, searchparam=2, badrange=-24)
vec = sup.MRecalculate(vec, blksize=2, overlap=1, search=3, searchparam=2, thsad=0)
MDegrainN(clp, sup, vec, thsad=2000)

should be identical to simply

vec = sup.MAnalyze(blksize=2, overlap=1, search=3, searchparam=2, badrange=-24)
MDegrainN(clp, sup, vec, thsad=2000)

but the results are far from being identical, the one using MRecalculate has A LOT of residual ghosting artifacts from blksize=64. To produce something similar to the one without MRecalculate (I'm not sure if it's bit-identical tho), you have to scale searchparam up to 64 for MRecalculate

vec = sup.MAnalyze(blksize=64, overlap=32, search=3, searchparam=2, badrange=-24)
vec = sup.MRecalculate(vec, blksize=2, overlap=1, search=3, searchparam=64, thsad=0)
MDegrainN(clp, sup, vec, thsad=2000)


have you checked if this is a bug or something?

Boulder
18th October 2020, 12:06
I posted an issue to the MVTools2 Github tracker, but I'll post it here as well in case someone can verify my findings.

This is a rather strange issue and I don't know if MVTools, Avisynth+, AVS2YUV or x265 is the real culprit.. nevertheless, I was able to determine that MVTools can be used to trigger it.

Using this kind of a script (don't worry about the supermdg bit being "unneeded", I used my denoising function as a base), I get jerky movement in the beginning of the encoded clip where the Enterprise appears on the screen. This happens if Prefetch is used - if I comment it out, no problems. The defect is not consistent between encodes, for example these are two consecutive test encodes with the same script and encoder parameters:

encoded 198 frames in 37.80s (5.24 fps), 1742.24 kb/s, Avg QP:24.60
encoded 198 frames in 36.98s (5.35 fps), 1721.16 kb/s, Avg QP:24.59

dgsource("c:\x265\tng\tngjerk.dgi")
convertbits(16)
superanalyse = msuper(pel=2, sharp=2, rfilter=4, chroma=true)
supermdg = msuper(pel=2, levels=1, sharp=2, rfilter=4, chroma=true)
fv1 = manalyse(superanalyse, isb=false, delta=1, blksize=16, overlap=8, search=5, searchparam=16, pelsearch=8, truemotion=false)
bv1 = manalyse(superanalyse, isb=true, delta=1, blksize=16, overlap=8, search=5, searchparam=16, pelsearch=8, truemotion=false)
mdegrain1(supermdg, bv1, fv1, thsad=100, thsadc=100)
Prefetch(threads=24, frames=24)

The encoder command line is this:
c:\x265\avs2yuv64.exe -no-mt -depth 16 "c:\x265\tng\tngjerk.avs" - | c:\x265\x265.exe -F 2 --input - --y4m --input-depth 16 --dither --sar 1:1 --profile main10 --ctu 32 --preset slower --merange 58 --crf 19 --output "c:\x265\tng\tng.hevc"

The cache settings are these:
SetMemoryMax(20480)
SetCacheMode(1)
Cache mode 2 didn't change things, still jerky.

I just tested removing truemotion=false from the script and the defect is gone. However, in my earlier tests this was also not very consistent and seemed to depend also on the x265 parameters.

Some samples:
https://drive.google.com/file/d/1e3c3Ysp80URNSQRQRABweoD41Sao3PQo/view?usp=sharing (original)
https://drive.google.com/file/d/1OdNCGdB0gqtBEQWgmlbAW0ndDyg95ugG/view?usp=sharing (with Prefetch, jerky)
https://drive.google.com/file/d/1NpToBeb7yFBjTPKS0-XR4V6zTT0ytxQm/view?usp=sharing (without Prefetch, no issues)


EDIT: just remembered this issue: https://forum.doom9.org/showthread.php?p=1698102#post1698102
Seems that adding RequestLinear(clim=100) after DGSource fixes the issue.

pinterf
14th December 2020, 19:03
New MvTools 2.7.44 (https://github.com/pinterf/mvtools/releases/tag/2.7.44)

- 2.7.44 (20201214)
- MAnalyze: fix motion vector generation inconsistencies across multiple runs.
Note: when internal multithreading is used (avstp + mt=true), inconsistencies will still occur by design.

StainlessS
14th December 2020, 20:20
Cheers P.

FranceBB
18th December 2020, 09:21
x86 and x64 builds
Windows XP is still supported, special DLLs with v141_xp toolset

ain't that sweet? Thanks! :D

takla
5th January 2021, 04:28
Is it known that large thSAD values (even the default 400) produces artefacts?
You can use this 25 seconds lossless video to test filters on yourself (https://www.mediafire.com/file/ps0j63m2t6pgqx8/RAW.mkv/file)

I'll use frame 480 in the examples below.
Raw, no filters.
https://i.ibb.co/XCHfPLD/RAW.png

MDegrainNL (https://pastebin.com/raw/NARWiZL7)(original from hello_hello (https://forum.doom9.org/showthread.php?p=1861146#post1861146), somewhat modified by me)
No artefacts of any kind and decent denoising.
https://i.ibb.co/175QJmg/MDegrain-NL-th-SAD150.png

MDegrainNL thSAD=400 (check the characters head for black pixels, also faded outlines)
https://i.ibb.co/30ZJrk0/MDegrain-NL-th-SAD400.png

The amount of artefacts are even worse with something like MCDegrainSharp (http://forum.doom9.net/showpost.php?p=1855907&postcount=31) to the point I'd never use or recommend it to anyone

MCDegrainSharp(truemotion=false) (check for the massive artefact on the wall under the characters head)
https://i.ibb.co/16fPMGz/MCDegrain-Sharp-TM-False.png

MCDegrainSharp(truemotion=true) (less obvious artefact with truemotion enabled, but it is still there, almost the same spot, just slightly shifted to the right)
https://i.ibb.co/gdxhG4P/MCDegrain-Sharp-TM-True.png

I also used ConvertBits(16) before the filter and ConvertBits(bits=10, dither=1) after.

real.finder
5th January 2021, 06:11
yes it's known thing, it's all about the motion vectors will be wrong in cases like fades or dark frames like this, in your case (dark frames) you can use Dither_Luma_Rebuild to feed super clip for motion analysis to get better motion vectors

Boulder
5th January 2021, 11:33
It would be interesting to see how the vectors look (MShow) and if the issue can be helped by using Dither_Luma_Rebuild or MRecalculate or dct=1 or dct=5.

takla
5th January 2021, 21:14
MDegrainNL_v1 (16-235, old) (https://pastebin.com/2nhsZuZX)
MDegrainNL_v2 (0-255, new, more accurate) (https://pastebin.com/Wi3K7f74)

v1
https://i.ibb.co/175QJmg/MDegrain-NL-th-SAD150.png

v2
https://i.ibb.co/3yJc9xg/NEW.png

If you zoom in, and look very hard you can see the characters nose hole slightly better in the v2 version. At basically no performance penalty, this is a nice improvement. I will do some more tests with higher thSAD later.

In the meantime, if someone could give me some help on how to add MRecalculate i'd appreciate it.

ChaosKing
5th January 2021, 21:18
From the SMDegrain wiki http://avisynth.nl/index.php/SMDegrain

Str float (0.0-8.0, default 1.0)
Gamma correction. With this parameter you control the strength of the brightening of the prefilter clip, good for when problems with dark areas arise. Using this internally instead of externally creates less quantization artifacts, since it's done in the same stage as the TV->PC range conversion.

takla
6th January 2021, 00:04
MDegrainNL_v3 (https://pastebin.com/MVRCnxsr)

Added (pre)blur to suppress initial noise, for better motion vectors.

(I did play around with pre-amping gamma, which indeed got rid of the smaller black artefacts at higher thSAD. You can add gamma_y=128 to ColorYUV if you need a higher thSAD. For me though the sweetspot is 150, as increasing it to 200 didn't really change filesize but slightly dimmed the nose hole again)

Overall the v3 provided better denoising, performance and no artefacts, when compared to SMDegrain(defaults) and MCDegrainSharp(defaults) on the test clip posted above.

takla
10th January 2021, 07:01
One more update to this script:


function MDegrainNext(clip Input, int "thSAD", int "thSADC", int "TR", int "BLKSize", int "Overlap", float "Sharpen", float "Blur")
{
thSAD = default(thSAD, 150)
thSADC = default(thSADC, thSAD)
TR = default(TR, 3)
BLKSize = default(BLKSize, 16)
Overlap = default(Overlap, BLKSize/2)
Sharpen = default(Sharpen, 0.2)
Blur = default(Blur, 1.0)

Super_Sharp = Input.Sharpen(Sharpen).MSuper(pel=1)
Super_Blur = Input.Blur(Blur).MSuper(pel=1)
Multi_Vector = Super_Blur.MAnalyse(Multi=True, Delta=TR, BLKSize=BLKSize, Overlap=Overlap)

Input.MDegrainN(Super_Sharp, Multi_Vector, TR, thSAD=thSAD, thSAD2=thSAD/2, thSADC=thSADC, thSADC2=thSADC/2)
}


Info:

MDegrainNext v1 Documentation
Original by hello_hello https://forum.doom9.org/showpost.php?p=1861146&postcount=10
Modified by Takla

Why did I mod this: Needed something easy to read that only makes use of internal functions (excluding MVTools2)
This script is intended to be set-and-forget, with a superb quality-to-speed ratio and no artefacts.

thSAD & thSADC = Luma & Chroma Noise sensitivity.
Leave as is.
Values too low can cause blockiness and too high can cause black spot artefacts.
Default is 150 & thSADC=thSAD.

thSAD2 & thSADC2 = Noise sensitivity falloff.
Leave as is.
Default is thSAD/2 & thSADC/2.

TR = Temporal Radius.
The main setting you should be tweaking.
Higher values allow for more noise to be removed, at the cost of speed.
Higher values might also require you to lower thSAD to avoid black spot artefacts.
Default is 3.

BLKSize = Block size in pixels.
Lower means slower and more accurate but not necessary visible better.
Default is 16.
Recommendation: 540p=8, 1080p=16, 2160p=32

Overlap = Modifies Block size behaviour.
Leave as is.
Use BLKSize/4 for the best quality-to-speed ratio.
Use BLKSize/2 to preserve very fine detail. Slower.
Default is BLKSize/2.

Sharpen = Increases sharpness.
Much more accurate when used with Super, instead of calling it as a standalone after MDegrainNext.
You only want to do a little bit of sharpening, as it will increase bitrate requirements.
You can always sharpen more via media player (mpv or mpc).
Good values are 0.1 to 0.5.
Default is 0.2.

Blur = (Pre)blurs the input to avoid false motion vectors.
Allows for more accurate motion vectors.
Good values are 0.5 to 1.0, or 1.58 for very noisy sources.
Default is 1.0.


And maybe change pel back to 2 for SD videos.

tormento
2nd February 2021, 15:38
MDegrain: out16 parameter, which outputs 16 bit result from 8 bit input
Would be possible to have out10 parameter, as it is the most used bit depth with x265, and out12, for HDR, or the 16 number is given from a stacked image and so only 8 multiples can be used?

DJATOM
2nd February 2021, 16:11
But that can be achieved by simply put ConvertBits(10/12/14) after MDegrain :)

tormento
2nd February 2021, 16:13
But that can be achieved by simply put ConvertBits(10/12/14) after MDegrain :)
I am doing various benchmarks and out16 outperforms any other kind of script with ConvertBits. I will post results very soon.

Boulder
2nd February 2021, 16:31
It's very odd if it does that. I would expect it to be internally like ConvertBits(16) at the end of the whole processing chain.

pinterf
2nd February 2021, 17:01
out16 is simply omitting a final conversion of the intermediate result back to 8 bits. This internal result is always of 16 bits precision for 8 bit sources. This is the same as lsb_out works but the result is not stacked but a real 16 bit clip.

tormento
2nd February 2021, 17:09
Please look here (https://forum.doom9.org/showthread.php?p=1935035#post1935035).
out16 is simply omitting a final conversion of the intermediate result back to 8 bits. This internal result is always of 16 bits precision for 8 bit sources. This is the same as lsb_out works but the result is not stacked but a real 16 bit clip.
So why there is so much difference between the results? 16 bit source should give the same result as out16 and 10/12 bit source should be a lot faster than out16 too.

pinterf
2nd February 2021, 17:13
SMDegrain <> MDegrain

tormento
2nd February 2021, 17:15
SMDegrain <> MDegrain
I understand. As I asked before, would it be possible to have 10 bit internal precision and output for 8 bit source too instead of 16 only?

real.finder
2nd February 2021, 17:37
I understand. As I asked before, would it be possible to have 10 bit internal precision and output for 8 bit source too instead of 16 only?

start read from here https://forum.doom9.org/showthread.php?p=1835712#post1835712

takla
3rd February 2021, 17:26
I understand. As I asked before, would it be possible to have 10 bit internal precision and output for 8 bit source too instead of 16 only?

Why not do the following with an 8 bit source:


ConvertBits(16)
MDegrain()
ConvertBits(bits=10, dither=1)


As explained here (https://forum.doom9.org/showpost.php?p=1835712&postcount=464), 10 to 16 bit makes no difference in speed and so you should either convert to 16bit or don't use out16 / ConvertBits at all.

joka
26th March 2021, 14:08
If I use MCompensate
s = c.MSuper(pel=2)
vb1 = s.MAnalyse(isb=false, delta=1, blksize=bs, overlap=ov)
cp1 = c.MCompensate(s, vb1)

and provide blksize and overlap I get (depending on the parameters) an unprocessed strip (with cp1 == c) on the bottom and the right border.
Further evaluation shows the same for MDeGrain (output of MDeGrain == c). With MDeGrain it is easier to compare/see. Height / width of strip depends on parameters.

Examples:
blksize/overlap
8/0 ok., nothing
8/4 ok., nothing
16/0 bottom
16/8 ok., nothing
32/0 bottom
32/8 bottom, right
32/16 bottom
64/0 bottom, right

Clip size is 1440x1080.
I use mvtools-2.7.43-with-depans20200602, AMD x64.

Do I something wrong? Is this a known issue? Exists a workaroud?

StainlessS
26th March 2021, 15:57
Joka, try same with 2.2.7.44:- https://github.com/pinterf/mvtools/releases
Change log
** 2.7.44 (20201214)**

MAnalyze: fix motion vector generation inconsistencies across multiple runs.
Note: when internal multithreading is used (avstp + mt=true), inconsistencies will still occur by design.


EDIT: Always a good idea to try latest version before reporting problem, if same then re-submit problem report.

pinterf
26th March 2021, 16:35
MDegrain is simply copying 'uncovered' bottom and right regions. Uncovered means that these pixels are not covered by whole blocks of the given blocksize.

joka
27th March 2021, 15:03
Good to know. I tested blksize/overlap - 24/12. This seems to solve it for clip size 1440/1080 and 1920/1080.
Thank you pinterf.

zorr
6th May 2021, 00:13
The current documentation on MAnalyse states about overlap: "Must be even and less than block size (up to blksize/2 for MCompensate)".

However, when I try overlap > blksize/2 I get this error message "MAnalyse: overlap must be less or equal than half block size". I don't have MCompensate in the script. MVTools x64 version 2.7.44.

So is the documentation or the code wrong? :confused:

EDIT: Seems like MAnalyse also doesn't accept negative levels.

zorr
6th May 2021, 22:02
The current documentation on MAnalyse states about overlap: "Must be even and less than block size (up to blksize/2 for MCompensate)".

I confirmed that this is just an error in the documentation (and it has been like that a long time). I do wonder though would it be possible to get rid of this limitation. It's usually the largest possible overlap that gives the best quality so it would be interesting to see if the trend (larger = better) would continue even with overlap > blksize/2.

EDIT: Seems like MAnalyse also doesn't accept negative levels.

This was my own error, the levels parameter was just too negative and there weren't any levels left.

Dogway
3rd June 2021, 10:36
Would it make sense to implement a half pel option to increase speed for UHD clips or is it the same as increasing blksize and overlap?

Boulder
3rd June 2021, 14:39
Isn't half pel the same as pel=2?

Dogway
3rd June 2021, 14:52
I meant pel=0.5, double pel in mvtools terms

StainlessS
3rd June 2021, 15:05
I meant pel=0.5, double pel in mvtools terms
Would that not have [a sort of] effect of lowering effective resolutuion of the result clip ?
[would seem to me that pel=1, and bigger blocksize, is the way to go]

Dogway
3rd June 2021, 15:25
I don't think so, many prefilters use gaussian type blurs for easier motion search, lowering the resolution is just the same but with less pixels (faster). Also many UHDs are upscaled conversions.

I don't know what others have to say, seems to me that pel=2 would also equal to pel=1 and smaller blocksize?

feisty2
4th June 2021, 06:52
it is equivalent to performing motion estimation on a downscaled version of the video, then you 2x upscale the motion vectors

StainlessS
4th June 2021, 12:49
it is equivalent to performing motion estimation on a downscaled version of the video, then you 2x upscale the motion vectors

And, Would that not have [a sort of] effect of lowering effective resolution of the result clip ?

EDIT: Arh, the new avatar is a cat or something, hard to figure out what it is.

Dogway
4th June 2021, 13:44
it is equivalent to performing motion estimation on a downscaled version of the video, then you 2x upscale the motion vectors

Wow, thanks, already updated SMDegrain with the changes, didn't remember MScaleVect

tormento
4th June 2021, 14:11
Wow, thanks, already updated SMDegrain with the changes, didn't remember MScaleVect
Where is it? :)

Dogway
4th June 2021, 14:20
Haven't uploaded yet, it's 3 times faster but there's some bad motion vectors of some sorts that I'm debugging.

tormento
4th June 2021, 14:21
it's 3 times faster
WTF.

Will wait your debugged version for next encodings.

StainlessS
4th June 2021, 15:03
Maybe downscaled pel=2, [about] same as normal scale pel=1. [but downscale faster]

kedautinh12
4th June 2021, 16:17
3 times faster????? Wth??

Dogway
4th June 2021, 18:47
Ok, here it is RC3 (https://github.com/Dogway/Avisynth-Scripts/blob/master/SMDegrain%20v.3.2.0d/SMDegrain%20v3.2.0d.avsi), the problem was that UHD is PQ encoded so the little contrast makes values behave differently, so I recommend to decode and tonemap beforehand or at least feed one as a prefilter.
Then obviously you are getting 1080p vectors, which aren't as good as 2160p vectors, but also not worse than 1080p in any case. I tried different settings but no one made a sustainable improvement except for "limit", so for UHD is by default set to 2, play with the value.
I also continued with the cleanup, added and removed a few more things.

tormento
4th June 2021, 19:34
Ok, here it is RC3
Will try ASAP.
I recommend to decode and tonemap beforehand or at least feed one as a prefilter.
Mmmm.... could you implement some?

P.S: Do you plan to keep on relying on ZF_Shared?

Dogway
4th June 2021, 19:58
Yes, it's on my todo list for Transforms Pack 2.0, but it's not going to happen soon, in any case it's going to be CPU bound and hence slow.

I recommend you to use DGHDRtoSDR(mode="pq",white=100), it's CUDA based.

tormento
4th June 2021, 20:04
I recommend you to use DGHDRtoSDR
Please, if you find some time, implement different tone mapping as you did with prefilter parameter.

Dogway
4th June 2021, 20:16
Yes that's my plan, in the realm of what is possible with avs+ I will try to run a per-scene rolling average of peak luminance.

tormento
4th June 2021, 21:16
Yes that's my plan, in the realm of what is possible with avs+ I will try to run a per-scene rolling average of peak luminance.


That would be great. I have tried to convert Zack Snyder’s Justice League from HDR to SDR and I found they used different peak for every scene. I quit the project. If you want to have a good benchmark, try with it.

zorr
7th June 2021, 23:24
Hi, the docs on MBlockFps say there is parameter float thres (0). It however doesn't exist, instead I found (looking at the code) that there is parameter ml.

It looks like ml should be a float value as the function signature has defined it as double

MVBlockFps::MVBlockFps(
PClip _child, PClip _super, PClip mvbw, PClip mvfw,
unsigned int _num, unsigned int _den, int _mode, double _ml, bool _blend,
sad_t nSCD1, int nSCD2, bool _isse2, bool _planar, bool mt_flag,
IScriptEnvironment* env
)

It doesn't seem to accept a float value though, the error message is "Script error: the named argument "ml" to MBlockFPS had the wrong type". Integer values work fine.

Also if anyone knows what's the recommended range for the ml parameter and is it perhaps dependent on the mode? I have a theory that modes 0-3 have a completely different range (0.0 - 1.0 ?) than the other modes but I haven't been able to test it because ml doesn't accept a float.

patul
8th June 2021, 03:11
Zorr,

While the wiki is seemed to be not updated yet, if you check here (http://www.avisynth.nl/users/fizick/mvtools/mvtools2.html), the ml value is not 0.0-1.0, but

ml: mask scale factor. Default=100.

But I don't know, whether pinterf made any changes on this.

EDIT:
I think what happened was, pinterf forked mvtools from Firesledge's version 2.6.0.5, the float thres(0) was there, hence the documentation. Then along the way pinterf partially merged changes from Fizick's with double _ml parameter in this commit (https://github.com/pinterf/mvtools/commit/28ab958b7f34b67c94ad2c1db42dd3ae781acec1#diff-0e54059c778bbb5448b3f35026dc516cce97c60971caecf40b6cc035f13ae158), however the documentation was still the Firesledge's version.

kedautinh12
8th June 2021, 05:52
For pinterf ver, you can check wiki here:
https://github.com/pinterf/mvtools/tree/mvtools-pfmod/Documentation

pinterf
8th June 2021, 06:10
For pinterf ver, you can check wiki here:
https://github.com/pinterf/mvtools/tree/mvtools-pfmod/Documentation
Thanks for pointing that, yes, specifically the mvtools2.html which I maintain, and is included in the downloadable release packages as well.

patul
8th June 2021, 06:50
@pinterf, what about thres & ml parameters mentioned by zorr above (and also edited part of my post)?

pinterf
8th June 2021, 07:36
It seems that in MBlockFps the ml parameter was left as 'integer' instead of float. This must be a bug.
MMask, MFlowInter, MFlowFPS are all float.

env->AddFunction("MMask", "cc[ml]f[gamma]f[kind]i[time]f[Ysc]i[thSCD1]i[thSCD2]i[isse]b[planar]b", Create_MVMask, 0);
env->AddFunction("MFlowInter", "cccc[time]f[ml]fb[thSCD1]i[thSCD2]i[isse]b[planar]b[tclip]c", Create_MVFlowInter, 0);
env->AddFunction("MFlowFps", "cccc[num]i[den]i[mask]i[ml]f[blend]b[thSCD1]i[thSCD2]i[isse]b[planar]b[optDebug]i", Create_MVFlowFps, 0);
env->AddFunction("MBlockFps", "cccc[num]i[den]i[mode]i[B][ml]i[blend]b[thSCD1]i[thSCD2]i[isse]b[planar]b[mt]b", Create_MVBlockFps, 0);

EDIT: I'm gonna arrange a fix soon

pinterf
8th June 2021, 09:11
Mvtools2 2.7.45
https://github.com/pinterf/mvtools/releases/tag/2.7.45

kedautinh12
8th June 2021, 09:25
Thanks

GMJCZP
8th June 2021, 12:32
Thank you very much.

real.finder
8th June 2021, 18:18
new out32 seems broken
super_search = MSuper(rfilter=4)

bv2 = super_search.MAnalyse(isb = true, delta = 2, overlap= 4)
bv1 = super_search.MAnalyse(isb = true, delta = 1, overlap= 4)
fv1 = super_search.MAnalyse(isb = false, delta = 1, overlap= 4)
fv2 = super_search.MAnalyse(isb = false, delta = 2, overlap= 4)

MDegrain2(MSuper(levels=1), bv1, fv1, bv2, fv2, out32=true, thSAD=300, thSADC=150)

with 8bit input it give 8bit output, with 10-16 input give same bitdepth as input but also pink output

pinterf
8th June 2021, 19:00
As I wrote in the change log, do not use it. Experiment/debug/fun better not knowing about it. Even the name is stupid, because I intended to test the internal overlaps calculation simplificatiin to use floats instead of integer magic which rounds at least twice during the process. I' going to test when it is worth to use it. Either speed or quality-wise. So it is only for me but I appreciate the feedback.

zorr
8th June 2021, 21:19
Thanks for pointing that, yes, specifically the mvtools2.html which I maintain, and is included in the downloadable release packages as well.

Yes, that's the one I was looking at. But it's fixed in the latest release, thanks!

tormento
9th June 2021, 16:20
There is a mistype in MVTools-2.7.45 html:

gf<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang='en' xml:lang='en' xmlns="http://www.w3.org/1999/xhtml">

zorr
19th June 2021, 23:11
For me the new SIMD intrinsics code for MSuper: rfilter=0 and 1 is a bit slower than the old SSE version. The impact was about 50ms in a script with 4 x MSuper, 4 x MAnalyse and 2 x MFlowFPS which takes about 4 seconds to run (this of course depends a lot on the parameters of the other functions).

However the new MSuper: sharp=1 version is faster.

pinterf
21st June 2021, 10:54
For me the new SIMD intrinsics code for MSuper: rfilter=0 and 1 is a bit slower than the old SSE version. The impact was about 50ms in a script with 4 x MSuper, 4 x MAnalyse and 2 x MFlowFPS which takes about 4 seconds to run (this of course depends a lot on the parameters of the other functions).

However the new MSuper: sharp=1 version is faster.
I suppose bit depth is 8, and processor type is at least sse 4.1?
EDIT: In the original asm code there was a missing rounder, which was fixed (reference methods in C were O.K.). This means that the new version one more addition and an extra register to use. But I think the speed difference for this change is probably neglible in the final benchmark for x64, but probably even for 32 bit versions.
EDIT2: sse4.1 has difference and is quicker than sse2 only in 10+ bit clips using the modes above.

zorr
21st June 2021, 22:02
I suppose bit depth is 8, and processor type is at least sse 4.1?

Correct, I tested on Ryzen 3900X. The measurement was done using one thread only (and no prefetch), median of 10 runs. Consistent and repeatable.

EDIT: In the original asm code there was a missing rounder, which was fixed (reference methods in C were O.K.). This means that the new version one more addition and an extra register to use.

Correct code is of course more important than a minor performance regression, and this is really very minor. Thanks!

MysteryX
27th June 2021, 18:47
There is MvTools for Avisynth and also a VapourSynth version here (https://github.com/dubhater/vapoursynth-mvtools). What's weird is that the Mask output is completely different between Avisynth and VapourSynth libraries; I'd guess the VapourSynth one is more accurate by fixing some bugs in the old Avisynth code.

However the VapourSynth Mask code doesn't support 16-bit (https://github.com/dubhater/vapoursynth-mvtools/issues/16), and Analyze code could be expanded to support blksize 12 and 24. The author of the VapourSynth library has no plan on fixing those anytime soon. Perhaps someone else could take on these tasks, and as I mentioned elsewhere -- it wouldn't be hard to make those libraries work on both platforms at once with just a bit of code abstraction. And Pinterf, you're very familiar with the whole MvTools codebase, and know how to write assembly code, so that probably would be easiest for you (if you find time!)

real.finder
27th June 2021, 18:58
it wouldn't be hard to make those libraries work on both platforms

maybe, but vs devs don't do this even if the plugin already work on both https://forum.doom9.org/showpost.php?p=1944391&postcount=1330 so why you ask avs+ dev about this?!

MysteryX
27th June 2021, 19:47
maybe, but vs devs don't do this even if the plugin already work on both https://forum.doom9.org/showpost.php?p=1944391&postcount=1330 so why you ask avs+ dev about this?!
Perhaps devs didn't realize how easy it is to make it work for both; it's actually easier because it separates Avisynth/VapourSynth management from the more complex plugin code.

Perhaps there's also silent rivalry between one platform or the other. But really it makes no sense.

In the future I'd just write plugins working for both out-of-the-box. The extra code needed is just boilerplate copy/paste from one project to the next.

btw Avisynth has a lot more devs. VapourSynth platform is good but lacks in devs.

real.finder
27th June 2021, 20:27
I think VapourSynth has a lot more devs not avs+ https://github.com/HomeOfVapourSynthEvolution and many others! except scripting cases and tools like Avspmod (which gispos do nice work about it) avs+ only got pinterf, Asd-g and qyot27 for now and some plugins makers like wonkey_monkey and StainlessS

Also vs now got no more features than avs+ since 3.7 release (avs+ now has Cross Platforms and new Syntax additions like Array and another new things and frame properties), and in same time VapourSynth now lost win7 users!

And at least for doom9 community avs+ got the vast majority of users https://forum.doom9.org/showthread.php?t=182887 but I think VapourSynth still got majority of Discord Anime fansub encoders

feisty2
27th June 2021, 20:58
there's no "rivalry" per se. it's more of a general lack of interest. most plugin developers are themselves the user of a particular frameserver program, and they develop plugins for whatever they use. very few people use both avs and vs.

MysteryX
27th June 2021, 22:49
there's no "rivalry" per se. it's more of a general lack of interest. most plugin developers are themselves the user of a particular frameserver program, and they develop plugins for whatever they use. very few people use both avs and vs.
That was the case for me; hence porting anything to VapourSynth was not a priority at all. Primarily because I didn't know how and nobody has instructions for it.

But once you know -- and with the right boilerplate code -- writing for both is just as easy. I wouldn't be a bad idea for me to produce a video of quickly porting a plugin to work on both.

As for MvTools2, it wouldn't be a bad idea either to explore why the mask is so different in both versions; and perhaps even merge them instead of having 2 separate code-bases to maintain.

MysteryX
28th June 2021, 17:28
Also vs now got no more features than avs+ since 3.7 release (avs+ now has Cross Platforms and new Syntax additions like Array and another new things and frame properties), and in
wow Avisynth made a lot of progress lately! I'm not seeing those in the 3.7 change log though, where can I read about those newer additions?

StainlessS
28th June 2021, 17:40
There are a few repo's about [I get confused too],
Pinterf [2772-MT]:- https://github.com/pinterf/AviSynthPlus/tree/master
Quot27[3.7.0]:- https://github.com/AviSynth/AviSynthPlus/releases

[there might be more, I aint sure :) ]

EDIT: thanks RF.

real.finder
28th June 2021, 17:43
wow Avisynth made a lot of progress lately! I'm not seeing those in the 3.7 change log though, where can I read about those newer additions?

in fact those changes was before 3.7 but 3.7 are more stable than 3.6

most of those changes come from backport from avsneo you can read https://forum.doom9.org/showthread.php?t=181351 and "Did you know" from pinterf starting from https://forum.doom9.org/showthread.php?p=1913646#post1913646

real.finder
28th June 2021, 17:47
There are a few repo's about [I get confused too],
Pinterf [2772-MT]:- https://github.com/pinterf/AviSynthPlus/tree/master
Quot27[3.7.0]:- https://github.com/AviSynth/AviSynthPlus/releases

[there might be more, I aint sure :) ]

https://github.com/pinterf/AviSynthPlus/tree/master is dead now, pinterf now adding changes directly to https://github.com/AviSynth/AviSynthPlus which is the main and original repo not only Quot27

pinterf
2nd July 2021, 11:46
wow Avisynth made a lot of progress lately! I'm not seeing those in the 3.7 change log though, where can I read about those newer additions?
See readme.history in https://github.com/AviSynth/AviSynthPlus/tree/master/distrib/Readme
(in fact they are almost the same, the readme_history.txt is a bit more verbose, mostly for older features)
These files are copied in the Avisynth installation folder as well and in my intermediate test 'files-only' builds

zorr
3rd July 2021, 23:06
I'd like to experiment with manipulating the vectors created by MAnalyse. First something simple like calculating multiple variations and taking the median. But it would also be fun and perhaps useful to go full Inception and feed the vectors back into MVTools for temporal denoising. There's a lot of potential for new/improved functionality if the vectors could be manipulated in ordinary AviSynth code.

So I'd like to request a new MStoreVect / MRestoreVect format which has these features:
-outputs the vector X and Y components so that each is represented by a single pixel
-X coordinates separated from Y coordinates (this makes manipulation easier)
-vectors would start from X coordinate 0 (the header data would be padded)
-image width would be the number of horizontal blocks

It would then be easy to grab the vectors with Crop, manipulate them and restore them back into the original image and then back into MVTools with MRestoreVect.

I looked at the vector's definition, X and Y are integers so that would mean the clip would need to be Y32 but since that means floats the whole range cannot be represented (only 24 bits). However, the maximum realistic vector lengths should be about pel*clip.width so it should easily fit into 16bits (or am I not understanding something?). I think even 8 bits is enough for most cases, movement could still be <= 31 pixels per frame with pel 4 (assuming only frames N-1 and N+1 are used).

It would perhaps be useful to be able to recalculate the SAD values after the vectors have been updated, but that's just a bonus feature, being able to manipulate the vectors would already be great!

What do you think pinterf, is this feasible and not too burdensome to implement? :)

tormento
4th July 2021, 08:17
I'd like to experiment with manipulating the vectors created by MAnalyse.
How much I would like that all these efforts could one day arise to a MVCUDA version.

Dogway
4th July 2021, 17:23
Currently mvtools is the bottleneck of most scripts, I calculated that for a 2h feature we need a performance of at least 5fps to finish an encode in 10h, good value for an overnight encode. I think this is still a bit far when using refinemotion (a must in my book) -1080p @ 16-bit-.

tormento
5th July 2021, 07:18
Currently mvtools is the bottleneck of most scripts, I calculated that for a 2h feature we need a performance of at least 5fps to finish an encode in 10h, good value for an overnight encode. I think this is still a bit far when using refinemotion (a must in my book) -1080p @ 16-bit-.
Can you explain me the use of trymany and the best case scenario? The MVTool documentation is not really explicit.

arnea
5th October 2021, 19:02
I need to use MDepan with super clip created with negative delta (i.e. I want to stabilize clip globally in relation to one specific frame). However MDepan does not support this at the moment. There is a check in constructor that throws error when mvclip.nDeltaFrame is not 1.

What needs to be changed in order to make it work? I could do the modifications but perhaps someone can point me in right direction.

For background: I scanned an old 8mm films using Wolverine Hawkeye scanner. The films were in bad condition and the frames are not aligned with each other. I did an overscan and hoped to use the perforation as an anchor for stabilization. My plan was to crop frames so that only perforation part was left and calculate the needed shifts based on this clip. Then apply to the shifts to the original clip so that all frames are aligned with each other and finally crop the clip so that only image area remains. I do not want to stabilize or process the clip itself - I want to keep the original camera movements.

Most of the stabilizers do the stabilization in relation to previous frame or frames. Those stabilizers removed the quick jumping from frame to frame, but frames still slowly drifted. My thinking was that I should calculate the needed shifts in relation to single (first) frame of the clip.

MVtools is so far the only stabilizer that allows to specify single reference frame. I planned to create offsets for Depan and then use it to do the stabilization but alas for some reason it is not supported by MDepan.

Or are there any other stabilizers that could do this?

arnea
5th October 2021, 20:01
I read the MVDepan.cpp source and at first it seems that when I do forward search and set the range to 0 then it should be ok.

real.finder
8th October 2021, 05:25
don't know if it possible to add more things from 2.5.11.9-svp (https://web.archive.org/web/20150206030422/http://www.svp-team.com/files/gpl/mvtools-2.5.11.9-svp.zip) same as https://forum.doom9.org/showthread.php?p=1704418&highlight=search_coarse#post1704418 but seems one of the reasons that vs port act in a different way (aside from hpad and vpad are 8 in avs but in vs they are 16)

using this YV12 source (https://www.sendspace.com/file/jpne22)

AVISource("mv test.avi")
super_search = MSuper(hpad=16,vpad=16)

bv1 = super_search.MAnalyse(isb = true, delta = 1, overlap= 4)

MMask(last, bv1)

in frame 1 (2nd one) I got

https://i.postimg.cc/xqKjwCYz/avs.png (https://postimg.cc/xqKjwCYz)
in avs mvtools in x64 avs+

and
https://i.postimg.cc/wtr6gYyn/avs-svp.png (https://postimg.cc/wtr6gYyn)
in old mvtools-svp in avs

and
import vapoursynth as vs
core = vs.get_core()
clip=core.lsmas.LWLibavSource(source=r'mv test.avi')
super_search = core.mv.Super(clip)

bv1 = core.mv.Analyse(super_search, isb = True, delta = 1, overlap= 4)

clip=core.mv.Mask(clip, bv1)
clip.set_output()
https://i.postimg.cc/ZWzDd732/vs.png (https://postimg.cc/ZWzDd732)
in vs

maybe those can help https://github.com/dubhater/vapoursynth-mvtools/commit/fb96fd14fbee05ba72e80faff23e3b0d65db7f9b and https://github.com/dubhater/vapoursynth-mvtools/commit/6f5d0134fd3c2322da23b53f8f770eda9f2700f9

making avs act same will break the compatibility with existing scripts so they should be activated with some parameter

wonkey_monkey
8th October 2021, 10:40
Arnea,

I have a plugin in development which should do exactly what you want. I've been meaning to release it for a while but haven't got round to it yet.

Can you post a sample so I can test it?

DTL
8th October 2021, 17:05
I see note on the last release at github:

experimental avx2 for MDegrain1..6 (was not worth speedwise on my i7700 - memory transfer is bottleneck)

I currently interested in MDegrainN with tr about 12 (about 1 second of time at 25fps). So it mostly probable will be memory limited so with current design it is no help of put more SIMD optimizations ?

May be try to walk to 'segmented frame' memory approach as frame size moves from SD to UHD is not possible to fit several frames into cache (even largest L2/L3). So it may be less easy to handle in program but it will allow the time-axis data of several frames to be in the cache at the same time. May be it can be simulated now with scripting - like cut frame to pieces and process in sequential order (or may be better in separate threads). It will also introduce more hardness with inner-frame edges of pieces (or may be just skip some possible to process blocks as they move between pieces of frame).

Also I read many about DRAM pages switching but still can not found good examples how to use it for real optimizations. But also for fastest access to some limited in size block of data it is better to store it in the same DRAM page. Finding what is DRAM page size at given hardware execution system may be separate task and (physical) addresses DRAM pages start/end. Because as I understand the DRAM page size is about equal to Row number of bits in current DRAM modules and it may greatly depends on the physical memory installed.
Also because of virtual memory approach in Windows it may required special memory allocation routine to allocate contiguous physical memory area (having some fixed number of physical DRAM pages and aligned to DRAM page start/end address). It may be solved in ring0 by installing custom driver providing memory allocation function to user-space with contiguous physical addressing.
Unfortunately AllocateUserPhysicalPages() in user-mode can not provide physical pages to be contiguous in physical addressing. It looks on todays Windows only MmAllocateContiguousMemory() in kernel mode may helps.
So it looks good to make some custom memory manager with system-startup driver (when physical memory allocation still not very fragmented and it is possibly to allocate large enough buffers for MDegrainN to run) and test it for performance for read-write between addresses to determine the actual DRAM pages start/end borders.
As article https://www.researchgate.net/publication/333939622_Design_of_Processing-Inside-Memory_Optimized_for_DRAM_Behaviors shows - the mapping of physical addresses to DRAM rows may be easy enough like some MSB of address encodes rows and all other LSBs encode something else inside row (that is natural to try to get less possible rows/(pages)-switching with sequential memory access). But the exact bit of PHY address where the rows addressing starts may be need to be determined. As the article shows the 'size' of PHY DRAM page (i.e. when rows start to switch) may be 14 LSB bits of address that is about 16 kBytes. 8 typical Windows-OS pages of 4 kBytes.

Not sure how much it may help with hardly memory-bound processing but it still may be some step in performance with still limited to host CPU and host memory software.

Also as I already post in some thread 'segmented frame' approach of frame buffers in memory layout may be useful with most of large-frames processing because with HD/UHD frames the row stride become very large and easily run-outs of L1 cache size if trying to access even small 8x8 block of 1 frame. So the hardware auto-prefetch looks like can not handle such memory access well and start to re-write many caches with non-needed prefetched data. So reading one 8x8 block of 1 frame and next 8x8 block of other frame cause great cache re-write and wipe old data (useful for processing neibour blocks). Also may be with accessing different DRAM physical pages so forcing memory to page-switching (closing current row and opening other) and degrade poor performance even more.
From https://my.eng.utah.edu/~cs7810/pres/11-7810-12.pdf
Row buffers act as a cache within DRAM
 Row buffer hit: ~20 ns access time (must only move
data from row buffer to pins)
 Empty row buffer access: ~40 ns (must first read
arrays, then move data from row buffer to pins)
 Row buffer conflict: ~60 ns (must first writeback the
existing row, then read new row, then move data to pins)
So it may be good to organize DRAM access at processing with using most of current 'open row /DRAM page' for read-write and attempt to keep in CPU cache read data from later used DRAM pages. It may possibly helps to performance.

pinterf
8th October 2021, 17:32
Degrain itself is quick. Most time is spent in vector search, working with 8x8 pixel blocks not even requires the sse xmm registers in 8 bit videos.

DTL
8th October 2021, 19:28
As I understand vector search in many frames sequence require fetching of the small blocks (like 8x8) from all frames from close enough distance inside each frame. Also if it uses planar data and all 3 channels - is x3 more pain on fetching bytes from different DRAM pages/rows. So interleaved formats really not very bad for processing colour data.
So may be before start of processing perform re-arranging of input data in the way to maximize DRAM row/page hits with the current memory access pattern (and may be change pattern if possible too). As noted the presentation the memory controller in the system tries to re-arrange memory access to maximize row/page hit rate but it is good to help starting from application.

Yes - it will add the time for re-packing before and after processing as Avisynth currently do not support 'segmented frame (tiled ?)' formats for in and out to plugins. But if performance benefit will be more than loss on re-packing it will help.

Current 1920x1080 planar 16bit Y plane have stride of 3840 bytes and 16 kByte DRAM page fits only about 4 rows of frame. The UHD 4K is even worse. For fetching data for even 8x8 block the 1 more DRAM page switch required for 2K and +3 switches for 4K. One idea about segmenting was - if the H and V access distance is about equal - so make segment to fit 1 DRAM page size as a square. Like 16K page and 16bit samples - 64(2byte)x128. Many 8x8 blocks will fit into 1 DRAM page and search with large enough radius will also hit with 1 DRAM page for the reading of whole 8x8 blocks.

If vector search is performed with many reads from small frame's areas (it possibly will be cached in some form) - it may be better to re-arrange parts of frames before processing to sit in less number of DRAM pages. Will try to look at the typical RAM accessing pattern at the vector search.

"working with 8x8 pixel blocks not even requires the sse xmm registers in 8 bit videos."

So memory-bounding is so awful that even SSE 128bit make almost no help in speed ?

DTL
8th October 2021, 21:18
Tried to test segmented frame processing:

Function DG(clip c)
{
tr=12
super=MSuper(c,pel=1)
multi_vec=MAnalyse(super, multi=true, delta=tr, overlap=4)
return MDegrainN(c, super, multi_vec, tr, thSAD=400, thSAD2=250)
}

.. 1920x1080 separated fields clip here YV12

ExtractY()

lg=Crop(0,0,1920,256)
DG(lg)



and cutted to 128x128 pieces:

Function DG(clip c)
{
tr=12
super=MSuper(c,pel=1)
multi_vec=MAnalyse(super, multi=true, delta=tr, overlap=4)
return MDegrainN(c, super, multi_vec, tr, thSAD=400, thSAD2=250)
}


ExtractY()

dg01=Crop(0,0,128,128).DG()
dg02=Crop(128,0,128,128).DG()
dg03=Crop(128*2,0,128,128).DG()
dg04=Crop(128*3,0,128,128).DG()
dg05=Crop(128*4,0,128,128).DG()
dg06=Crop(128*5,0,128,128).DG()
dg07=Crop(128*6,0,128,128).DG()
dg08=Crop(128*7,0,128,128).DG()
dg09=Crop(128*8,0,128,128).DG()
dg010=Crop(128*9,0,128,128).DG()
dg011=Crop(128*10,0,128,128).DG()
dg012=Crop(128*11,0,128,128).DG()
dg013=Crop(128*12,0,128,128).DG()
dg014=Crop(128*13,0,128,128).DG()
dg015=Crop(128*14,0,128,128).DG()


dg101=Crop(0,128,128,128).DG()
dg102=Crop(128,128,128,128).DG()
dg103=Crop(128*2,128,128,128).DG()
dg104=Crop(128*3,128,128,128).DG()
dg105=Crop(128*4,128,128,128).DG()
dg106=Crop(128*5,128,128,128).DG()
dg107=Crop(128*6,128,128,128).DG()
dg108=Crop(128*7,128,128,128).DG()
dg109=Crop(128*8,128,128,128).DG()
dg110=Crop(128*9,128,128,128).DG()
dg111=Crop(128*10,128,128,128).DG()
dg112=Crop(128*11,128,128,128).DG()
dg113=Crop(128*12,128,128,128).DG()
dg114=Crop(128*13,128,128,128).DG()
dg115=Crop(128*14,128,128,128).DG()


up=StackHorizontal(dg01,dg02,dg03,dg04,dg05,dg06,dg07,dg08,dg09,dg010,dg011,dg012,dg013,dg014,dg015)
lo=StackHorizontal(dg101,dg102,dg103,dg104,dg105,dg106,dg107,dg108,dg109,dg110,dg111,dg112,dg113,dg114,dg115)
StackVertical(up,lo)


The 128x128 pieces version of Y8 format works about 4% faster at Core2Duo E7500 CPU. Though it have some more cut/stack operations. And uses non-DRAMpage aligned buffers. May be with 128x128 frames it makes less vector search operations ?

With 128x256 size of piece and 1920x512 total frame size it is about 5.5% faster. Here system have 2 channels and they can also add +1 bit before row switching so may be actual 'size of fastest memory contiguous area' may be from 8 to 32 kBytes and may be more depending on channels number, ranks and bank size. But there also some sad info - at some systems memory controller may XOR some row LSBs with other address bits to make some stride arrays access (large enough - like 100 kBytes) to hit same row. So real rows switching addresses is not monotonically increases even in physical address space. So exact performance gain of attempt to data exchange to same rows of SDRAMs as much as possible depends on the current machine configuraion and settings of memory controller (may be only mainboard manufacturer knows how it is configured - it is not even OS config usually).

real.finder
9th October 2021, 07:10
making avs act same will break the compatibility with existing scripts so they should be activated with some parameter

I note that setting lsad=0 (MAnalyse(isb = true, delta = 1, overlap= 4, lsad=0)) will crash
https://i.postimg.cc/c4hJcVrF/Untitled.png (https://postimages.org/)
but it's fine in vs, is there are bug that vs mvtools fixed or vs mvtools has hidden changes (that prevent it from happen) as always?

edit:

another news, vs mvtools v7 (edit: I am in v21 now and it still same as v7) act very similar to svp
https://i.postimg.cc/XpQrBztY/vs-mvtools-v7.png (https://postimg.cc/XpQrBztY)

pinterf
9th October 2021, 07:45
Div by zero is real crash and usually indicates a bug, at least a missing parameter validity check. Minimal script is available or I should just use that mvanalize line?

real.finder
9th October 2021, 08:14
Div by zero is real crash and usually indicates a bug, at least a missing parameter validity check. Minimal script is available or I should just use that mvanalize line?

AVISource("mv test.avi (https://www.sendspace.com/file/jpne22)")
super_search = MSuper(hpad=16,vpad=16)

bv1 = super_search.MAnalyse(isb = true, delta = 1, overlap= 4, lsad=0)

MMask(last, bv1)

also update for vs mvtools case, even v23 work same as avs one! I was use VapourSynth64Portable_2020_09_06.7z since long time and now even new download of VapourSynth64Portable_2020_09_06.7z give similar output to avs! I Shouldn't have overwrite the libmvtools that in old VapourSynth64Portable_2020_09_06!

DTL
9th October 2021, 22:23
Some question about building with GCC from msys2 (it looks I damage my VisualStudio2015 install trying to clean winsxs directory so it can not even open project properties window):
The files looks like built OK. The only warnings about NOMINMAX define.
The built .dlls (mvtools2.dll and depans) looks like loads into Avisynth (require some additional gcc .dlls - libgcc_s_seh-1.dll , libstdc++-6.dll , libwinpthread-1.dll ).
But at attempt to run script - Avisynth throws errors: Can not found MSuper, MAnalyse, MDegrainN functions.

Latest Msys2, gcc version 10.3.0 (Rev5, Built by MSYS2 project). Used 64bit msys2 and minigw64. Latest testbuild of Avisynth+ from pinterf (3.7.0 (r3382, 3.7, x86_64).
Latest sources from github - mvtools-2.7.45 .

Also attempt to build Debug versions (for debugging and profiling with source text) with command

cmake --build . --config Debug

Build .dlls of the same size as --config Release (about 13 MByte for mvtools2.dll).

qyot27
9th October 2021, 22:53
Don't build C++ interface plugins with GCC unless you know what you're doing. Or you're on Linux. Or Mac. Or BSD. Or Haiku.

DTL
10th October 2021, 00:20
Readme.md directly lists the build method of GCC and cmake at msys2. And listed make and build commands work and produces result .dlls. May be it require special versions of each tool (not listed) ?
I do not even have idea how to debug why functions not visible from loaded .dll. Without any other error.

May be required special headers from windows sdk ? And not from installed to msys2 gcc ? I also do not know why it reqiure additional .dlls from GCC to run (load). May be some settings required for 'static linking' ?

DTL
11th October 2021, 06:46
At work I have VS2019 and it build OK.

First strange finding - the disabling of multi-leveling makes MAnalyse significally faster. Test build of mvtools.dll with disabled leveling (use only one 'full-frame' level as I think) https://drive.google.com/file/d/1NQsxPB-kB6AtlE2IbE7fg0bOC2COFfP7/view?usp=sharing .
Changing is MAnalyse.cpp add line 261 nLevelsMax = 1;

At practical

tr = 12 # Temporal radius
super = MSuper ()
multi_vec = MAnalyse (super, search=3, searchparam=8, multi=true, delta=tr,overlap=4)
MDegrainN (super, multi_vec, tr, thSAD=400, thSAD2=150)


Also it allows super = MSuper (levels = 1) without throwing error by MAnalyse about not enough levels.
Speedup about 2 times. If it works OK (I still made few tests but looks like working for degraining without visible bugs for now) it may be good to add one more user-param to MAnalyse like 'maxlevels'.

I look into motion search code - it looks it uses 'block vs plane' search and it is not very fiendly with gross SIMD streams processing (and may be not friendly with CUDA/GPU acceleration). But it allows to use non-esa type of logical speed-up.
I think of trying to add 'brute-force' method of simple full-esa 'plane vs plane' comparizon of located in CPU cache planes and selecting best SAD for output.
It is re-write possibly starting from PlaneOfBlocks::SearchMVs() function. Do any documentation available for the output formay of data returned by this function ?
I see the method of writing output file of MVs - it is simple enough like frame number and x,y,SAD of each block. But the return by MAnalyse 'motion clip' looks like more complex.

Addition: As found later the minimum good value for nLevelsMax is 2 because with 1 the searchparam=2 internally and user-defined searchparam (search raduis) not used (looks only one level always uses searchparam=2) . Started to make AVX2 sad functions for radius 2. For larger radius AVX512 will be very useful (less reload data from cache). Current state of design - at github https://github.com/DTL2020/mvtools .
As I see the most easy and some speed-up (possibly about 2..3 times) is re-write PlaneOfBlocks::ExhaustiveSearch(different block size and radus) for processing without branching and at register file of CPU. It possibly available up to searchparam=4 with AVX2-capable CPU. The asm core of ExhaustiveSearch8x8_sp2_avx2() is mostly finished but I still do not know what is the output format of x,y coordinates (usually processed by CheckMV()) - relative to center of block (i.e. -2..2 for s=2) or absolute in the 'workarea' grid ?

DTL
14th October 2021, 13:45
About luma-only search and possible gross colour errors with close luma different colour tones:
It is an idea to perform search with Y + sort of Hue channel from HSB colour space. Skip Saturation channel and it will possibly cause much rare and less visible saturation errors.
And processing 2 planes instead of 3 will increase search speed to about 1/3. To make something looking to Hue plane without slow trigonometry from UV channels we need to found some simple and fast math. I think may be even just mix half bits of U and V 8bit channels to form some 8bit bitpacks inherits some variance from U and V channels and put it to 'colour-sad' search pass.

anton_foy
14th October 2021, 16:40
About luma-only search and possible gross colour errors with close luma different colour tones:
It is an idea to perform search with Y + sort of Hue channel from HSB colour space. Skip Saturation channel and it will possibly cause much rare and less visible saturation errors.
And processing 2 planes instead of 3 will increase search speed to about 1/3. To make something looking to Hue plane without slow trigonometry from UV channels we need to found some simple and fast math. I think may be even just mix half bits of U and V 8bit channels to form some 8bit bitpacks inherits some variance from U and V channels and put it to 'colour-sad' search pass.

Interesting. Is this the same phenomenon of washed out saturation and losing hues due to overfiltering? I see this especially when filtering chroma with fft3dfilter and other "spatial" denoisers. Dogway mentioned a while ago that he had started to write a YUV to HSL conversion script, maybe this would come in handy?

DTL
14th October 2021, 17:17
"Is this the same phenomenon of washed out saturation and losing hues due to overfiltering?"

It was idea how to workaround issue described in https://forum.doom9.org/showthread.php?p=1783361#post1783361 . Without full processing of both colour-difference planes.
Now I see at CheckMV():

sad_t sad=LumaSAD<pixel_t>(workarea, GetRefBlock(workarea, vx, vy));
cost += sad + ((penaltyNew*(safe_sad_t)sad) >> 8);
if(cost>=workarea.nMinCost) return;

sad_t saduv = (chroma) ? ScaleSadChroma(SADCHROMA(workarea.pSrc[1], nSrcPitch[1], GetRefBlockU(workarea, vx, vy), nRefPitch[1])
+ SADCHROMA(workarea.pSrc[2], nSrcPitch[2], GetRefBlockV(workarea, vx, vy), nRefPitch[2]), effective_chromaSADscale) : 0;
cost += saduv + ((penaltyNew*(safe_sad_t)saduv) >> 8);

So it first full process 1 plane (Y usually) and if chroma=true (default) - compute sads for 2 more planes (typically UV). And resulted sad = luma_sad+chroma_sad. But chroma_sad collected from 2 planes (sad_u + sad_v). If the most horrible bug is about chroma tone only - so we can re-arrange chroma data from 2 planes into 1 plane (close to Hue in HSB model for example) and skip 1 of 3 planes search. It will be 'in-between' solution between limited quality luma-only search (sometime causing chroma tone mixing artefacts) and full 3-planes search (more slower).

Unfortunately Avisynth looks like not support converting of YUV into HSB for example and MAnalyse still do not have coded-in selection of planes for search (like 1, or 1+2, or 1+2+3). So it is some work to the future.
Though it is now possible with extract/combine planes to make something like Y + CromaTone mix of channels. Though using of simply pure U or V will already works better in compare with Y-only. But it is better to think about colour-science how to prepare the most useful 8bit data from 2x8 bit U+V channels for best colour tone discrimination. With simple enough math for speed. Full quality YUV to HSB convert require trigonimetric that is very slow with high precision. May be simply selecting upper or lower 4 bits and blend will be enough. But it is require some thinking higher of lower of U and V is better etc. It is not need to follow some high tolerance colour description - it just need to be unique identifier of colour tone. May be simply drop bit-depth of UV to 4 bit and combine to 8bit though they code mostly saturation and colour tone (and very few of brightness) and we need more colour tone.

"YUV to HSL conversion script,"

High quality YUV to HSL require sin/cos/tan and it is very slow. I think we will found some much faster solution for this special task (not need to use derived Hue-like-channel in high quality output).
Wiki lists selection of min/max and case-like processing (of difference and division) to calculate H(ue) https://en.wikipedia.org/wiki/HSL_and_HSV . That is also no good for speed.

DTL
14th October 2021, 20:56
Some first possibly working testbuild with VS2017 - https://drive.google.com/file/d/15v64hHVv2vtB87qddLaZYGHXXKWfpZ9S/view?usp=sharing . For new AVX2 exhaustive search way.
Only chroma=false and searchparam=2 (default ?) and 4. Full levels esa search is search=3 but one of levels always esa(radius=2) so it possibly will partially works on most of search methods. Block size only default 8x8.
Tested only in SDE intel AVX simulator in debug build (still not have AVX-capable chip at my home). So can not measure the performance. Will have access to AVX-capable cpu only at my work a few days in a month.
The MDegrainN triggers some assert (do not know why - may be VS2017 not completely compatible with mvtools project also ?) . So tested with MDegrain2() in debug build.

Unfortunately the new functions still require sadly check for input vector validity - the calling of search with invalid vectors need to be fixed in the future because it may slow process with non-needed checks. If disabled - it will run-out of buffers addresses and crash.

The MShow displays vectors differs from old search (Expanding search) but degrain looks like works without visible blurring so the vectors looks like not very bad.

DTL
15th October 2021, 15:25
Design ideas about Y+PseudoHueSat 8+8bit samples SAD processing: (instead of YUV 8+8+8 bit typically (up to) 3 passes)

1. Hue looks like naturally 2D essence so if unrolled to 1D will have discontinuity point. Unfortunately CPU can not process SAD of 4+4 low and high packs of bits of 8bit byte. (Or I still do not know if some math possible). This discontinuity + natural noise will cause large changes of PHS value near some colour tone and it will cause this colour tone blocks to treat as non-equal so they will not be denoised. We can only place it to some rare enough colour tone (I think close to Magenta). The simple 4-quadrants adjusting of the colour tone where discontinuity is happens is feeding PHS() calculation function with +-U and/or +-V values.

2. The Y+PHS coded plane may be processed with 1 pass SAD SIMD AVX2 same (close to) as for 16x8 block size of 8bit samples.

3. Simple enough calculation of PHS value from UV: (in 8bit unsigned, center to 127 codelevel for green colour tone and/or zero saturation)
(DiamondAngle(U,V)-2)*Sat(UV)*some_norm+127.
where
DiamondAngle(x,y):

float DiamondAngle(float y, float x)
{
if (y >= 0)
return (x >= 0 ? y / (x + y) : 1 - x / (-x + y));
else
return (x < 0 ? 2 - y / (-x - y) : 3 + x / (x - y));
} //x and y in 0..1 range, out is 0..4 range.

and Sat(x,y) about ((abs(U)+abs(V)) >> some_norm_value) - sort of saturation.
It may be made as SIMD calculation at runtime or may be simple LUT of 8=f(8,8) bit values that is 16 kBytes in size and will fit in L1 cache. Good to test both ways.

DTL
16th October 2021, 12:59
Some working release for test: https://github.com/DTL2020/mvtools/releases/tag/2.7.45-1 .
Due to no user-controls yet it have many build versions:
mvtools2.dll - standard PseudoEPZSearch, Esa search and searchparam 2 and 4 with chroma=false uses new AVX2 SAD.
mvtools2_ml1.dll - maxlevels limited to 1, searchparam only 2.
mvtools2_ml1.dll - maxlevels limited to 2.
mvtools2_glob_med_pred_ml2.dll - maxlevels limited to 2, only global and medium MV predictors, medium speed and quality
mvtools2_no_pred_ml1.dll maxlevels limited to 1, no predictors, fastest speed, lowest motion search quality.

Test script (1080i source):

SeparateFields()
tr=12
super=MSuper(last,chroma=true)
multi_vec=MAnalyse (super, multi=true, delta=tr, search=3, searchparam=2, overlap=2, chroma=false)
MDegrainN(last,super, multi_vec, tr, thSAD=300, thSAD2=200)
Weave()


CPU i5-9600K
AVSMeter results (fps):
release-2.7.45: 7.2
mvtools2.dll: 9.53
mvtools2_glob_med_pred_ml2.dll: 11.46
mvtools2_ml1.dll: 11.31
mvtools2_ml2.dll: 10.03
mvtools2_no_pred_ml1.dll: 18.35

Test encoding average datarate with x264 (no MdegrainN : 24252) (kbit/s)
release-2.7.45: 7866
mvtools2.dll: 7812
mvtools2_glob_med_pred_ml2.dll: 8464
mvtools2_ml1.dll: 8376
mvtools2_ml2.dll: 7844
mvtools2_no_pred_ml1.dll: 9342

So 'compression ratio' with best motion search (slowest) is about 3.08 and worst (fastest) is about 2.6. With difference in MAnalyse speed about 2 times.

So it is really greatly limited with memory-access for SADs for both Refine() search and predictors testing. Attempt to add Prefetch* into FetchPredictors() helps nothing - it really need to reorganize data in memory for better access with predictors-defined pattern.

Pull-request with current version created. Current idea is to add new user-input control like 'predictors=(all, partial, none)' and 'levels=(1,2,all/auto) for MAnalyse. To control quality/speed ratio.

tormento
16th October 2021, 14:44
So 'compression ratio' with best motion search (slowest) is about 3.08 and worst (fastest) is about 2.6. With difference in MAnalyse speed about 2 times.
You could run some synthetic benchmark such as SSIM or PSNR. Not always less is better, IMHO.

DTL
23rd October 2021, 09:46
Do the project compatible with Intel C++ compiler (integrated in Visual Studio) ?

I see some include defines about Intel_compiler. Also from command line I can compile and build .lib with Intel C++ 19.1 (from Parallel Studio XE 2020) for linking with VisualStudio 2019 all other build. (Excluding that .cpp from build in VS2019).

But when I try to switch 'Platform Toolset' to Intel compiler in Visual Studio (or even for the selected .cpp files) - the strange happens: Visual Studio project dies with unability to open project (mvtools) properties pages and unability to build. Same happens with VisualStudio 2017 and 2019 (tried 16.3 and 16.8). The only way to fix - to replace VS project files (.sln, .vsxproj) from the old state.
May be the VS project files are not compatible with IDE Visual Studio with Intel C++ build tools ? May special command line batch file exist to build mvtools.dll from Intel C++ command line interface (environment) ?

I want to try IntelC++ compiler build to test for speed and with many available hardware-specific optimisations.

You could run some synthetic benchmark such as SSIM or PSNR. Not always less is better, IMHO.

It need to be very syntetic because with degrain we do not have 'clean' source to compare with. So only way is to get some clean enough source and to add syntetic noise.

There are possible 2 types of errors with motion search for MDegrain:

1. Block marked as equal (SAD below theshold) by error.
2. Block search missed (not found any better position in compare with initial).

The 1 type errors cause blurring at motion areas and make output MPEG speed lower. It is most bad error because it typically good visible.
The 2 type errors only decrease degrain ratio (typically on motion areas) that is less visble.

kedautinh12
23rd October 2021, 10:12
I meet error notice when use last ver MVTool2 with TemporalDegrain2Mod


Avisynth script error:
Evaaluate: Unhandled C++ exception!
(C:/Program Files (x86)/Avisynth+/plugin64+/TemparalDegrain-v2.3.1MOD.avsi, line 276)


Turnback to old ver 2.7.44 error was gone
Location error
https://github.com/kedaitinh12/AVSPlus-Plugins/blob/b21b35baf0556e120d2de63ff7557bb5d9c3005d/TemporalDegrain-v2.3.1MOD.avsi#L276

My script:

TemporalDegrain2(limitFFT=2, postFFT=6)

pinterf
23rd October 2021, 18:25
Hi kedautinh12, I'd need the clip width and height and video format (e.g. YV12?)

tormento
23rd October 2021, 19:52
It need to be very syntetic because with degrain we do not have 'clean' source to compare with. So only way is to get some clean enough source and to add syntetic noise.
I meant to compare from previous version of MVTools and your ones.

kedautinh12
23rd October 2021, 21:07
Hi kedautinh12, I'd need the clip width and height and video format (e.g. YV12?)

Here:
https://drive.google.com/file/d/1JrfnSTpy-C961AP7Ww-HI-yXnZpBnsbK/view?usp=drivesdk

pinterf
23rd October 2021, 21:18
Here: ...
Thanks for the sample clip, so far it works nicely with 2.7.45 at 0.61 fps (no Prefetch)

I've got no NVidia card on developer machine so I'm using

TemporalDegrain2(limitFFT=2, postFFT=5) # BM3DCPU

instead.

arnea
23rd October 2021, 22:00
I need to use MDepan with super clip created with negative delta (i.e. I want to stabilize clip globally in relation to one specific frame). However MDepan does not support this at the moment. There is a check in constructor that throws error when mvclip.nDeltaFrame is not 1.

...

Or are there any other stabilizers that could do this?

I've made some progress on this. wonkey_donkey has a plugin in development that did quite good job on the test clip that I provided. However the plugin is not ready yet.

I tried to change the MDepan plugin and removed the check for negative delta. It worked, Depan plugin stabilized the video, but there was still too much movement across the clip.

I then decided to implement my own ideas about using sprocket holes to match the frames globally. It took some time, but it's ready now: https://github.com/arnean/PerfPan Not very efficient implementation, but it worked on the single clip I have at the moment. I will scan more films and see how it behaves.

kedautinh12
26th October 2021, 15:36
Thanks for the sample clip, so far it works nicely with 2.7.45 at 0.61 fps (no Prefetch)

I've got no NVidia card on developer machine so I'm using

TemporalDegrain2(limitFFT=2, postFFT=5) # BM3DCPU

instead.

I check again and find out my nvidia driver only standard and no dch. I install dch driver and it's work correctly

DTL
27th October 2021, 11:05
Sort of *need for testers* request:

For test-release https://github.com/DTL2020/mvtools/releases/tag/r2.7.46-pre.a.01 (also copy to google disk because of frequent repository removing for forking new actual version - https://drive.google.com/file/d/1Qm5H42ia6wYsD-ckFmU1Nalhl72qut4J/view?usp=sharing ).

Recommended testscript:

tr = 8 # Temporal radius - need testing low (2..3 and high values like 10+)
super = MSuper ()
multi_vec = MAnalyse (super, multi=true, delta=tr,chroma=false,mt=false, levels=2)
MDegrainN (super, multi_vec, tr, thSAD=400, thSAD2=400-1)


2 test cases:
1. Early skip of processing blocks with zero weight. It adds 2 conditions of zero checks that can decrease speed but if weight is zero it skips fetching from memory ref block and skips its processing that will increase speed. The total influence on speed depends on thSAD value and noise level in the processed footage. (Zero weights occur when blockSAD > thSAD and blockSAD increases with increasing of noise amplitude).

Files: mvtools2_ww_es.dll - use early zero weight skip, mvtools2_ww_ns.dll - use old all blocks processing without condiitons. Currently fast zero weight skip only used in MDegrainN_sse2 so to test with low tr (2..3 the thSAD must be different from thSAD2 - to use MDegrainN instead of MDegrain2,3). Required tested tr values - low as about 2..3 and higer like 10.

2. Modification of weights of blocks to average. Old/classic MVtools uses additional weighting of blocks below thSAD with linear function
f(x)=(thSAD^2-blockSAD^2)/(thSAD^2+blockSAD^2)
It causes the blockSADs close to thSAD(2) to get low weights (close to zero if blockSAD slightly below thSAD). That decreases degrain ratio but may help to prevent more blurring if 'Type1' error occur (block have SAD below thSAD but it is not noised block but different block (moved/scaled/rotated etc).
So using same sad-wise method for both motion compensating and selecting (and weigthing) blocks for avaraging is not totally error-free and nice. And may need more logical supplementing.
So it looks the 'weighting of weights' method is the great field for finetuning and need to be additional user-param for MDegrain*() functions.
Currently for test is 2 builds:
mvtools2_ww_es.dll - old/classic linear weighting of weights
mvtools2_eqw_es.dll - equal weighting of all blocks below thSAD(2). It is also a bit faster because no double float division is required.
The using of thSAD2 in MDegrainN only a bit lower thSAD increase degrain ratio but may cause more blurring (and other bugs) with motion.
Test task: to check if mvtools2_eqw_es.dll produce better degrain ratio with all other equal params (tr mostly and thSAD(2)) and if introduce some visual quality degradation - to describe it. It possibly applies to all MDegrain* functions because of MDegrain3.h header file.

These builds also may contain test of OpenMP in MAnalyse() enabled to it better to disable avstp mt for MAnalyse(). Also MAnalyse() have new params
optSearchOption=0 (default), if =1 - use new _avx2 esa search functions for search=3 and searchparam=2,3,4 (3 and 4 still not debugged in this build), and block size 8x8 and chroma=false and nPel=1 (in MSuper).
optPredictorType=0 (default), if =1 - use partial predictors (faster but less vectors found and less degrain quality), if =2 - use no predictors - faster than (1) but less quality. To use searchparam > 2 the 'levels' must be >1.

One bad use case for 'classic' weights weighting:
The natural photon-shot noise have Poisson distrubution (coming to Gauss with practically large numbers of photons per sample) and it have both low and high deviations from mean value. It cause SAD deviations also low and high.
When block with high SAD deviation is in tr-scope of degrain process (but still below thSAD) it got low weight to most of other blocks and low include its content to other blocks. But when processing reach this block - all other blocks in tr-scope got low weights and this block keeps most of its deviation after weighted-averaging. And in MPEG-compression later this block treats as different block and increases bit number for frame.
I think 1-pass idea of comparing current block SAD with others is not perfect - may be better to compare 'previous-averaged' (that is close to expected block looking) SAD with others. But it looks like need multi-pass degraining. With second SAD-search process of '1-pass-degrained plane' with input source. May be it is hard to implement in 1-pass scripting without intermediate 1-pass degrained full plane output to temp file.

So current thSAD value need to be high enough to make good weights for blocks with large noise-deviated SADs but low enough to decrease rate of 'block not equal' errors. I think this contradiction may be somehow (better) resolved. With sad-independent weighting (simple averaging of all tr-scope blocks with sad below trSAD) we can have lower thSAD value with still catching into processing the more blocks with high noise-deviated SADs.

Dogway
1st November 2021, 22:03
I think some MDegrain values are not auto-scaled for 32-bit float, as I could see limit and limitc, didn't test more.

Dogway
13th November 2021, 14:13
2 weeks later but with the same issue, the wiki (http://avisynth.nl/index.php/MVTools)states that MDegrain and MSuper support 32-bit float, yet all I get is a black screen.

ConvertBits(32)

super_search = ConvertBits(8).MSuper(rfilter=4)
bv1 = super_search.MAnalyse(isb = true, delta = 1, overlap= 4)
fv1 = super_search.MAnalyse(isb = false, delta = 1, overlap= 4)
MDegrain1(MSuper(levels=1), bv1, fv1, thSAD=300, thSADC=150)

DTL
13th November 2021, 14:49
Looks like a bug in 32-bit codepath. It looks MDegrainN have some support of 32bit format but in C-reference only (slow). PlanarRGB 32bit same black screen also.

Update - some testbuild with SIMD-based FetchPredictors() - https://github.com/DTL2020/mvtools/releases/tag/r.2.7.46-a.03 . It looks it was slow because of too many conditional tests and branching in the CheckMV() and Median(). Now it is fully redesigned to SSE(4.1 minimum required). The clipping may differs from old versions so new is only called with optSearchOption > 0. So now full-predictors MAnalyse should run faster on CPUs SSE4.1+ and with all possible other options sets + additional speedup for blocks 8x8 8bit luma=false pel=1 with AVX2-capable chips.

DTL
20th November 2021, 12:03
FranceBB,
In MRecalculate, with square side = 1, does that mean that it searches only 1 pixel side to side, up and down, or NONE.

Not sure if problem, just asking. [EDIT: ie, is your MRecalculate a timewasting NOP]

It looks like hidden (still) undocumented feature of MAnalyse - it ignores user-input of searchparam at the finest (largest) level of search and always use searchparam=pel at finest/largest level. So setting to zero do not disables search at finest level.
I think it is optimization idea of old developers because in other case it is better to allow user to feed a vector/array of searchparams for each search level to find best speed/quality balance. Or at least add more user-input param like searchparamfinest=int or useequalsearchparamatalllevels=bool.
There is still idea that with fast enough search engine it possible to make something like pel=1 sp=2 levels=1 faster in compare with pel=1 sp=1 levels=2. But currently the program do not allow to actually use sp > pel at the fastest processing with level=1 and perform silent fallback to sp=pel.
Because each level require full-frame memory recall (but each next level buffer size is 1/4 of previous). So if memory speed is final limit of speed - the 1 pass search with levels=1 may be faster in compare with 2 pass levels=2 (1 + 1/4 memory).

takla
21st November 2021, 17:37
@DTL

With my Ryzen 3900x:

2.7.45 (mvtools-2.7.45-with-depans20210608)
time=70.115s

2.7.46 (Release_2.7.46_pre_a_03 AVX2)
time=63.457s

Using these settings (https://forum.doom9.org/showthread.php?t=183192)
Except this: ConvertBits(8, dither=1)
ffmpeg -benchmark -i TEST.avs -c:v ffv1 TEST.mkv

Very nice speed-up. Filesize was identical too.

DTL
21st November 2021, 19:44
Thank you for testing and report.

There is many new changes since that test-build. Now when fixing optPredictorType=2 (something like 'only hierarchical predictor' mode) I found may be useful method of returning different SAD value from MAnalyse to MDegrain and it significally helps in some cases of noise or noise-like aliasing of interlaced camera. It is return sad not from finest level of search but from prevoius.
Currently fixed mode of optPredictorType=2 works like this (it possibly the only possilble mode for this limiting preictor mode) but works acceptable only with levels=1 or 2. May produce severe artifacts with levels >2. But it still fastest mode for possibly lowes quality degrain work. Also with levels 2 and more it start to blur more and more (still do not know why - may be too many low-sad values).

But in optPredictorType=1 this 'previous-level sad return' maybe controlled only for finest level (using hidden still working feature of nSearchParam==1 at finest level) so it allow to use optPredictorType=1 with any levels number (the 2 is faster in compare with auto/all like 6). It is also possible in 'all predictors' mode optPredictorType=0 if required (still not added).

So current latest testbuild - https://github.com/DTL2020/mvtools/releases/tag/r.2.7.46-a.04 . The executables *sf.dll return special sad from non-finest level to MAnalyse. It typically 2 or more times lower in compare with 'standard' sad so allow to use lower thSAD(2) values in MDegrain. With too high thSAD it may cause more artifacts like visibility of blocks edges/corners so may require increasing of overlap param (I currently use overlap=2). So require more precise thSAD adjusting per given content. If this feature will be found as useful it may be additional user-switch param.

Current optSearchOption valid values:
0 - standard processing equal to 2.7.45 (for compatibility)
1 - partial SIMD optimizations for all options may be used. Like ClipMV, FetchPredictors. Exhaustive search (type=3) for searchparam 1 and 2 (and 3,4) is new AVX2-based. Though I see the r=3 and r=4 is of low use because default r=2 for levels except finest (slowest) and at finest/slowest level uses the fixed r=1 uses.
2 - special 'preset=fast' for degraining work, have hardcoded fixed many 'default' params for faster execution (less conditions checks).
Currently aggregated and fixed params for optSearchOption=2:
blksize = blksizeV = required to be 8,
search=3,
searchparam=2,
pel = required to be 1 in MSuper
chroma = false,
outfile = disabled,
dct = disabled,
badSAD = (infinite,disabled)
badrange = (disabled),
temporal = false,
trymany = false,
required CPU opts: SSE, SSE4.1, AVX2.

There may be also the very first 'tech demo' of multi-(4)-blocks search with optSearchOption=3 but it still not work for degrain at all - simply test for speed possible more SIMD-oriented processing on AVX2-capable chips.

My typical production using script currently is about

tr=12
super=MSuper(chroma=true, mt=false, pel=1)
multi_vec=MAnalyse (super, multi=true, delta=tr, search=3, searchparam=2, overlap=2, chroma=false, mt=false, optSearchOption=2, optPredictorType=1,levels=4)
MDegrainN(last,super, multi_vec, tr, thSAD=175, thSAD2=160, mt=false,wpow=4)

takla
22nd November 2021, 01:24
@DTL


function EZdenoise(clip Input, int "thSAD", int "thSADC", int "TR", int "BLKSize", int "Overlap")
{
thSAD = default(thSAD, 150)
thSADC = default(thSADC, thSAD)
TR = default(TR, 3)
BLKSize = default(BLKSize, 8)
Overlap = default(Overlap, BLKSize/2)

Super = Input.MSuper(pel=1)
Multi_Vector = Super.MAnalyse(Multi=True, Delta=TR, BLKSize=BLKSize, Overlap=Overlap, optSearchOption=1)

Input.MDegrainN(Super, Multi_Vector, TR, thSAD=thSAD, thSAD2=thSAD/2, thSADC=thSADC, thSADC2=thSADC/2)
}



LWLibavVideoSource("C:\Users\Admin\Documents\01.mkv")
Trim(0, 1440)
ConvertBits(16)
EZdenoise()
ConvertBits(8, dither=1)
Prefetch(12, 48)



2.7.45
time=70.115s

2.7.46
optSearchOption=0
time=63.457s

2.7.46
optSearchOption=1
time=58.777s


optSearchOption=0

is ~10% faster then the original
optSearchOption=1

is ~16% faster then the original

Very nice speedups. Thank you very much!

tormento
22nd November 2021, 07:51
There is many new changes since that test-build.
I'd like to test them too. Do they offer any difference in speed/quality when using with "old" default parameters such as replacement of the stable build?

DTL
22nd November 2021, 10:55
2.7.46
optSearchOption=0
time=63.457s'

Do you see any difference between intel (ic) and msvc builds at AMD CPU ? With optSearchOption=0 most of C program should run as 2.7.45 but may be release 2.7.45 was build with only SSE2 instructions enabled and latest is with AVX2 and intel C builds are multi-file IPO and for not very old CoffeLake family.
The intel compiler provides options for optimizations to about 15 or more chip families so the final 2.7.46 release may be build to 15+ different executables for endusers to test for best speed at existing CPU. The building from sources at user-side for current CPU is not comnon for Winsows users I see.

takla
22nd November 2021, 11:20
@DTL

I see no big difference between the 4 DLLs no matter if sf or std, intel or msvc.

With optSearchOption=0 the time is always around 62 seconds (if there is a difference here, it is very hard to measure because Ryzen CPU-Boost is very sensitive to temperature and each encoding run changes temperature, obviously)

DTL
22nd November 2021, 13:01
"Do they offer any difference in speed/quality when using with "old" default parameters such as replacement of the stable build?"

If it change quality so it definitely not bit-compatible with old release. Pinterf ask to keep bit-identical output for old options set. So most of new additions that possibly can give any different result is guarded with optSearchOption > 0.

The min/max SIMD operations in ClipMV() may not be completely compatible with old C-version of compare.
The Median(), and check of MotionDistortion() for 4 predictors in all-predictors path should be compatible. But still not placed to 'old path' (that is search_mv_slice()). Most new is only in SO=2.
Also checking of MotionDistortion may be even faster in SSE2 instead of AVX2 because less gathering operations of sources in long 256bit vector and paralleling of execution ports in some new chips. It is in 'to do' list.

There is also some 'need much testing' optimization of removing paranoid IsVectorOK() test in search functions. I think it is mostly non needed in the most of frame area and only protect from out of buffer access and crash near edges. The current fix to DyMin/DyMax calculation is included only in SO=2 now (also for compatibility with old processing). But may be enabled with SO=1 in all options path. Currently SO=2 is very limited in possible options and only 8x8 block size.

Though some small (test) optimizations like non-cached stores in InterpolatePredictors and MDegrainN will work with all old options (if SSE2 present).
The non-cached store in MDegrainN may still not be visibly helpful before next re-write to one-bus-transaction 64byte transfers of source and result. It is in 'to do' list.

"because Ryzen CPU-Boost is very sensitive to temperature and each encoding run changes temperature, obviously"

Yes - the temperature speed trottling makes testing of each small optimization visibly hard. And the more really optimization loads the SIMD execution ports and register file - the faster and more heat production and CPU speed trottling. So I typically stop spend time to test each small SIMD optimization.

There is also one more hidden feature (because no info messages available in Avisynth without stop processing) - the MAnalyse tries to allocate buffer of large pages for 'vectors'. If it fails in fallback to standard pages. The only way to check if allocation of largepages is success is in Win10 use RAMMap tool. In Win7 it may fails to display too. The indirect way is look into AVSMeter RAM memory usage report - if largepages were allocated - the displayed amount of used RAM will be reduced (to several MB or 10ths MB). Because largepages allocations do not included in most of software reports of used memory. Also to use it - the process owner (user) must enable Lock Pages in memory Privilege in Windows administration ( https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/enable-the-lock-pages-in-memory-option-windows?view=sql-server-ver15 ). It is default not set for all users and Administrators too in standard Microsoft-supplied versions of Windows (may be enabled in special user-builds). The diagnostic messages at obtaining this privilege for process at startup of MAnalyse is disabled (because it fails processing completely in todays AVS). May be some user-side log console is exist to silently throw diagnostic ? May be windows events -> software events ?
And the most probability of successive allocation is after fresh windows reboot (or use special memory defragment tools - external to Microsoft). I see Win10 typically keeps some small (about 256 MB) pool of non-fragmented memory for lp-allocations (possibly) if total RAM installed is large enough (may be > 1..4 GB) but may be only if there were no full-RAM applications running before, etc. For typical use of MAnalyse only about 1 largepage of 4 MB is required (for frame sizes up to 4K) and per each thread in AVS+ MT running (internal avstp MT use only one buffer for all threads). So it typically success long time after system reboot in Win10 and fast start fallback to standard pages in Win7 with 4 Gb memory installed.

DTL
22nd November 2021, 13:19
@DTL
With optSearchOption=0 the time is always around 62 seconds (if there is a difference here, it is very hard to measure because Ryzen CPU-Boost is very sensitive to temperature and each encoding run changes temperature, obviously)

It is more interesting to see results of optSearchOption=2 (it uses block size 8x8 only) and may be SO=3 at AMD massive-multicore CPU chip (it currently only can run without crash with command like optSearchOption=3, levels=2. Levels=1 may cause crash, though is fastest.)

I will try to make AVX512 SO=4 (placeholder) to see the benefit of 16-blocks processing vs 4 (SO=3) - at work we have 2 HP new workstations with new Zeons Gold with AVX512. May be at next week.

Currently with preliminary speed tests at i5-9600K the 4-blocks processing SO=3 is about 3x faster in compare with 2.7.45. Though the 'predictors mode' is close to PT=2 that is of lowest quality. With PT=1 the speed benefit may be visibly less.

takla
23rd November 2021, 03:51
@DTL
Can you explain what "Levels" is supposed to do? I tried levels=0 (default) and levels=4 but it only affected file size. Encoding time was not affected.
Does a higher level value increase degrain quantity? or quality?
Also, what is "wpow=4" in your mdegrain example?

Here are some more tests. This time I've locked my Ryzen 3900x CPU to 4.2GHz to ignore temperature affecting encoding time.

Also, In my testings, optSearchOption=2, optPredictorType=1 is the same speed-wise (47.5sec) as when just using chroma=false for MAnalyse. So I'll have to check frames for visual differences.

mvtools2_msvc_SO2std.dll
optSearchOption=1
time=59.720s
time=59.145s

mvtools2_msvc_SO2sf.dll
optSearchOption=0
time=61.502s
optSearchOption=1
time=57.792s
time=57.683s

-

2.7.45
overlap=4

mt=false
time=68.609s

mt=true
time=68.898s
time=69.167s
783.145 KB

search=3, searchparam=2
783.145 KB
time=69.688s

levels=4
time=68.481s
782.730 KB
search=3, searchparam=2
time=70.952s

-

2.7.46

mvtools2_msvc_SO2sf.dll
optSearchOption=2, optPredictorType=1, levels=0
time=47.453s
782.938 KB

levels=4
time=47.477s
782.441 KB

optPredictorType=0, levels=0
rtime=59.138s
783.150 KB

DTL
23rd November 2021, 11:15
"Can you explain what "Levels" is supposed to do? I tried levels=0 (default) and levels=4 but it only affected file size. Encoding time was not affected.
Does a higher level value increase degrain quantity? or quality?"

It is one of the most important param for speed/quality balance. It is important to understand the multi-levels hierarchical search process for adjusting params for quality/speed balance of degraining.
The input image is progressively shrinked 2 times to form a sequence of levels for searcing. So level 0 is largest (may be pel=2 is even 2 larger), level 1 is twice smaller in linear size (1/4 of samples size), level 2 is 1/4 smaller linear and 1/16 of samples count and so on.

So the most important things for speed happens at level 0 and partially at level 1. All other levels are very small and almost invisible in processing time.

Levels are counting from 0. But param levels=0 mean 'all levels' that for typical HD frame is about 6 (0,1,2,3,4,5). Lowering number of used levels cause lost of the very long vectors (when moving in the frame is fast enough). It is typically very rare. So for precise motion compensating work using all levels is good idea to get max quality of fast moving objects. But for degraining work it is of low priority because it just mean lower degraining on fast moving objects (and they are rare and low visible). So for practical degraining the used levels may be limited to 0,1 or may be 0,1,2 (the levels param is total count so 0,1 mean levels=2 and 0,1,2 means levels=3). The fastest (about +1/4 speed of MAnalyse) is levels=1 but quality is lowest (it can not found vectors >1 in size, so it mostly static areas only degraining and for very slow motion).

Understanding levels is important because it is planned to put the individual levels control for better speed/quality balance. In the next versions it is planned to use 'vectors/arrays' params instead of scalar allowing to adjust search params for each level. It will allow to use faster method for slowest/largest level 0 while keeping levels 1,2 and more processing for catching more longer vectors.
So in current version optPredictorsType=0 mean use same 'all predictors' mode at all levels and in newer versions optPredictorsType="2,1,0" mean use fastest PT=2 at level 0, medium PT=1 at level 1, standard PT=0 at level 2 and others.

To see speedup in 2.7.45 and current testbuilds you can set levels=1 (mean only largest level 0 in processing, skipping all others). There is small difference in speed between levels=0 (all) and levels=4 (0,1,2,3) because all major sized levels 0,1,2 is in the processing.

" what is "wpow=4" in your mdegrain example?"

It is new param to control internal weighting of blocks in averaging process in MDegrain (currently only for N but pinterf will propagate it to all other Degrains because with equal thSADs and tr< 6 the other Degrains are used). In old versions wpow=2 internally and not controlled by user.
https://i6.imageban.ru/out/2021/11/23/83efd2f4e0bd78cfb70f92e3413f7c44.png
Setting wpow >2 (valid is 1,2,3,4,5,6,7) allow to increase block weight and get more 'degrain power' with same thSAD and possibly lower blurring. Max 7 mean no additional weighting (all blocks inside thSAD threshold with equal weight) cause max degrain power but may increase artifacts.

"mt=false
time=68.609s"

Do you really use internal MT with avstp.dll ? I see at modern intel CPUs internal MT is always slower in compare with AVS MT. Also mixing avstp-mt + AVS is very great speed penalty. So I only use AVS MT (Prefetch(numthreads) at the end of script) and always disable internal avstp-mt (or just delete avstp.dll from search path and working path). If you do not really have avstp.dll in the system it is just skipped option (do nothing).

"SO2std.dll"

*std.dll and *sf.dll should be of the same speed and only provided for test degrain quality in special cases of noise and noise-like aliasing/moire. So for tests you can use either ic*std or msvc*std which is best for speed at AMD CPU (after one short test and keep selected .dll for all other tests).

"optSearchOption=2, optPredictorType=1, levels=0
time=47.453s"

For a bit better speed you can set levels=2 (only 0 and 1 level used). It may increase filesize a bit.

Do optSearchOption=3 can start (not crash) at your system ? With new ideas I think it may be 'adaptive block size' processing with increasing block to close to 16x16 (the 4x1 of 8x8 is equal to 16x16 in samples count, and 2x2 of 8x8 is equal to 16x16 block in shape too) if vector field locally is enough coherent and still keep refining quality close to 8x8 block size. Also if 4x 8x8 fits in AVX2 register file it is worth to try to make new AVX2 functions for 16x16 block size exhaustive search and look at speed.

"In my testings, optSearchOption=2, optPredictorType=1 is the same speed-wise (47.5sec) as when just using chroma=false for MAnalyse. "

May be something else limit the speed ? Do you test raw performance of the script with AVSMeter or it is encodings time with MPEG-encoder ?

takla
23rd November 2021, 12:30
@DTL

Do you really use internal MT with avstp.dll ? I see at modern intel CPUs internal MT is always slower in compare with AVS MT. Also mixing avstp-mt + AVS is very great speed penalty. So I only use AVS MT (Prefetch(numthreads) at the end of script) and always disable internal avstp-mt (or just delete avstp.dll from search path and working path). If you do not really have avstp.dll in the system it is just skipped option (do nothing).

Oh, ok. Good to know. Yeah I don't have that avstp.dll. That is probably also why my tests show no difference between mt=true or false. I just wanted to test that setting because you had it in your example script. I too use prefetch for my scripts.

*std.dll and *sf.dll should be of the same speed and only provided for test degrain quality in special cases of noise and noise-like aliasing/moire. So for tests you can use either ic*std or msvc*std which is best for speed at AMD CPU (after one short test and keep selected .dll for all other tests).

sf.dll was consistently ~2 seconds faster, as you can see from my tests.

And thank you on the explanation for levels and wpow :)

DTL
23rd November 2021, 12:37
"sf.dll was consistently ~2 seconds faster"

It is strange enough. It returns significantly different sad (lower) values to MDegrainN and require thSAD re-adjusting for lower values (about 1.5 times lower in compare with no-sf version) otherwise can cause more blurring. It is special testcase.

" I don't have that avstp.dll."

Yes - that mean internal avstp-based mt simply can not run. But typically avisynth users with many plugins installed may have avstp.dll in the search path (or plugins folder or..) and it will be loaded. Currently MVtools do not emit any diagnostic messages - I think to add to windows applications evens (at windows builds) so they can be read by windows event viewer.

"you had it in your example script."

I set mt=false to strictly disables internal mt if system can found avstp.dll somewhere inside many folders (I can keep it for testing somewhere). The default for MVtools is to use internal mt if avstp.dll is found somewhere and it can greatly reduce performance.

Also I think of testing 'ultrafast' 'predictor-mode' with interpolated vectors but not checked/refined at slowest 0-level at all. It may be optPredictorType=3 but for best use require 'multi-params' input for setting this mode only for level 0 and setting some 'real' predictor mode for smaller levels to base interpolation at.

tormento
23rd November 2021, 16:24
"sf.dll was consistently ~2 seconds faster"
Is it possible to have a non AVX2 build?

Unfortunately my system is too old to support it.

DTL
23rd November 2021, 18:55
"Is it possible to have a non AVX2 build?"

I hope you have at least SSE4.2 ? I will make SSE build with intel c version optimized up to SSE 4.2. Msvc build will be up to SSE2 in old C but to use optSearchOption=1 some optimizations it is require SSE 4.1 minimum.

tormento
23rd November 2021, 19:00
I hope you have at least SSE4.2 ? I will make SSE build with intel c version optimized up to SSE 4.2.
I have Sandy Bridge, i.e. up to AVX instruction set.

DTL
23rd November 2021, 21:00
So all SSE versions should work. Also you can use optSearchOption=1 to enable some 'universal' up to SSE4.1 optimizations in vectors data preparation.
Here is todays evening build - https://github.com/DTL2020/mvtools/releases/tag/r.2.7.46-a.05 . Have sse and avx2 folders and I hope intel .dlls is correct.

Added optPredictorType 3 and 4.
3 - only check the SAD of the predictor from level 1 at level 0. No refining search at level 0. SAD value should be typical.
4 - only use interpolated vectors and SAD from level 1 at level 0 . No SAD check at level 0. (SAD value is reduced typically, same as with *sf.dll with PT=1, and thSAD in MDegrainN need to be lower).
Should work with any other options - no special requirements.

PT=3 and PT=4 require levels > 1. It mean there should be some smaller levels to perform 'real' vectors search before level 0. (levels=0 that is 'all/auto' also valid). The fastest should be PT=4 - use interpolated vectors from level 1 without check or refining. But the SAD value will be lower typically so thSAD adjustment in MDegrainN required (typically to about 1.5x lower).

As currently no 'vector/array' inputs to values it is equal to optPredictorType="3,1" and "4,1" (currenty hardcoded inside GroupofPlanes) that mean use PT=3 or 4 at level 0 and use PT=1 (medium) at all other levels.

tormento
23rd November 2021, 21:32
So all SSE versions should work. Also you can use optSearchOption=1 to enable some 'universal' up to SSE4.1 optimizations in vectors data preparation.
Thanks for the SSE build. Will check it ASAP.

Unfortunately I mostly use mvtools inside SMDegrain so I can't pass options beside the preset ones.

DTL
23rd November 2021, 22:01
Unfortunately I mostly use mvtools inside SMDegrain so I can't pass options beside the preset ones.

For MdegrainN (if you use tr > 6) I think you can add wpow param to line 386 of https://github.com/Dogway/Avisynth-Scripts/blob/e6ed53e432cbd9ee631befafed3b5884cfd8505a/SMDegrain%20v3.3.8d/SMDegrain%20v3.3.8d.avsi#L386

And MAnalyse for tr > 6 looks like line 314 https://github.com/Dogway/Avisynth-Scripts/blob/e6ed53e432cbd9ee631befafed3b5884cfd8505a/SMDegrain%20v3.3.8d/SMDegrain%20v3.3.8d.avsi#L314
Simply add new params optSearchOption=1 and optPredictorType (>1 if try to test it) to the end of arguments.

To try skip MRecalculate it is possibly need to set something like Refinemotion to false. The download link from wiki http://avisynth.nl/index.php/SMDegrain is 404-dead. So I think it is the latest version at github found.

tormento
23rd November 2021, 23:15
The download link from wiki is 404-dead
Dogway took the helm back (https://github.com/Dogway/Avisynth-Scripts). Why to link to the dead wiki page?

DTL
23rd November 2021, 23:31
I typically try to download avisynth stuff from that wiki links. Hope they up to date. Instead of searching forums or github for tons of versions not known if in new or old, stable or not state etc. So wiki is also old and not updated ?

I read Dogway post about the need of 16*16 block for HD. I have an idea how to put possibly faster search to SIMD but it also need AVX2 to load full 16*16 source block and leave place for SAD results. To prevent source block reload from cache at each search step. So no very great results expected for pre-AVX2 CPUs. There may be small optimizations like putting to SSE SIMD InterpolatePredictors and MotionDistortion for multi-vector search. But anyway any possibly not-bitexact operation with old version will be separated with optSearchOption >0. To have ability to quick test if it cause new issues for example.

I mostly interested how the silently Exhaustive search was changed to Expanding search but the same search=3 option number and naming in the documentation remain. Though with penaltyNew >0 it will gives different results from exhaustive for the minimum SAD from the all tested search positions.
I have an idea how to make exact simulation of current Expanding search from AVX2 search SADs array but it will be slower. So it is good to see test reports if old expanding search really need/better and worth to spend time to made separate version of function for it.

Expanding search is not isotropic because of fixed positions scan sequence and if vector with equally low SAD will be found from the start of search - it will be output as a result if even vector with better SAD exist and with same radius. And with increase of penaltyNew it become worse.

tormento
24th November 2021, 10:06
I typically try to download avisynth stuff from that wiki links.
I tried the two SSE builds, both Intel Compiler and MSVC. To have a real world comparison I did a small encode with the script

SetMemoryMax()
SetFilterMTMode("DEFAULT_MT_MODE", 2)
LoadPlugin("D:\Eseguibili\Media\DGDecNV\DGDecodeNV.dll")
DGSource("F:\In\2_23 Brazil (director's cut)\brazil.dgi",ct=24,cb=24,cl=0,cr=0)
ConvertBits(16)
SMDegrain (tr=6, thSAD=600, refinemotion=true, contrasharp=false, PreFilter=4, plane=4, chroma=true)
fmtc_bitdepth (bits=8,dmode=8)
Prefetch(6)

without any alpha optimization, i.e. I simply replaced the dll.

They are a bit slower than the stable one.

2.7·45
encoded 4128 frames, 4.39 fps, 3771.03 kb/s, duration 0:15:41.11

pre5ic
encoded 4128 frames, 4.16 fps, 3771.03 kb/s, duration 0:16:32.76

pre5msvc
encoded 4128 frames, 4.28 fps, 3771.03 kb/s, duration 0:16:04.20

The resulting files are identical in size, differing only a few bytes in the initial part. However they are mkv, not 264 as I probably should have done to have a clear compare and it's matroska perhaps adding some info about data time and so on.

You told something about SSE4.2 optimization. Couldn't you make it as default in the SSE builds instead of having to add as switch? I am plain sure anybody here has a CPU capable of supporting them.

DTL
24th November 2021, 14:37
"They are a bit slower than the stable one."

It is also a subject to test why. May be non-cached stores may be not good for some use cases and need to be put to special 'searchoption' number (not default zero).

"Couldn't you make it as default in the SSE builds instead of having to add as switch?"

It can not be default because it may produce not equal result with old versions. Only possible is to create many testbuilds with enabled/disabled different methods. Will try to do soon.

kedautinh12
24th November 2021, 18:44
Link died

tormento
24th November 2021, 19:16
Here is a testbuilds for users of scripts without set of params to MAnalyse
None of those are working.

I can't even get a nice error, they simply produce a 0 size file.

DTL
24th November 2021, 19:47
Oh - it looks at least error with hard setting of optPredictorType inside - it looks everywhere is PT=0. Sorry - not tested it for output result after build. Will try to look what is wrong.

"simply produce a 0 size file."

May be it simply crash at startup. Can you look in system evens viewer or drwatson log - may it have some crash records ? It is strange - it should use only SSE instructions up to SSE 4.1 and checked at Intel Core2Duo E7500. Will enable check for required SSE version in next testbuild.

Edit: Found source of one error - Visual Studio opens for editing files form different copy of the project. So all .dlls were build from equal sources. Will rebuild now. Though it not shows why processing not make any result.

DTL
24th November 2021, 21:28
Well - new fixed testbuild and checked for run at Core2Duo E7500: https://drive.google.com/file/d/1ry35P1JddVd_9rv8kG3fosPGlV6BiyeY/view?usp=sharing

Have both SO0 and SO1 builds for all PT values.
The PT2 versions removed because can not run correctly without limiting levels to about 2..3. PT4 require lowering of thSAD to about 1.5 times lower in compare with other.

On E7500 old CPU optSearchOption=1 with some new SSE optimizations enabled runs slower - it looks not all old SSE CPUs can run faster with SSE versions of functions instead of C. So it definitely can not be non-controlled enabled in final release.

DTL
26th November 2021, 01:08
Issue found with latest testbuild : crash with block size 16x16 and (ALIGN_SOURCEBLOCK = 1 'asb1' in file names) (aligned copy disabled). With default padding = 8. If increase padding to 16 (in Msuper) - crash not happens. So users of scripts with default MSuper params (hpad=vpad=8) will have crash if using faster 'asb1' builds with block size 16x16. Looks x264 SSE2 and SSSE3 16x16 SAD functions was not tested with disabling aligned copy of source block.
Hope for some workaround for this issue. Current user-side workaround - increase hpad and vpad to about blocksize or larger if crash occur.

Dogway
30th November 2021, 16:14
I got a BSOD with latest official build, trying to return a scaled MV clip... I panicked. Lost my dev version script of SMDegrain (filled with zeros), luckily it wasn't much, only a few commented expressions and notes.

This was more or less the trigger. I was trying to check bv1 clip dimensions to debug an issue I was having.
Environment:
i7-4790K
Win7-SP1 x64
AVS+ test29 x64
no avstp.dll in plugin path


setmemorymax(2048)
DGSource(bluray source)
ConvertBits(16)
w=width()
h=height()
bicubicresize(w*2,h*2)

pref8 = ConvertBits(8, dither=-1)
pref8 = pref8.BilinearResize(w, h)
pref8 = pref8.ConvertToYUV420(false,"","MPEG1","spline16","top_left").ConvertBits(16)
pref8 = pref8.ex_Luma_Rebuild(S0=3.0,c=0.0625,uv=3,tv_range=true,fulls=false).ConvertBits(8, dither=-1)

super_search = MSuper(pref8, pel=1, chroma=true, hpad=0, vpad=0, sharp=1, rfilter=4, mt=true)
Recalculate = MSuper(pref8, pel=1, chroma=true, hpad=0, vpad=0, sharp=1, rfilter=4, mt=true,levels=1)
bv1 = super_search.MAnalyse(isb = true, delta = 1, overlap=8, blksize= 16, search=4, chroma=true, truemotion=false, divide=0, dct=0, searchparam=2, pelsearch=1, temporal=false, trymany=false, scaleCSAD=1, mt=true)
bv1 = MRecalculate(Recalculate, bv1, overlap=4,blksize=8, thSAD=200, chroma=true, truemotion=false, divide=0, dct=0, scaleCSAD=1, mt=true)
bv1 = bv1.MScaleVect()

bv1

# without prefetch, in avspmod

pinterf
30th November 2021, 16:55
I got a BSOD with latest official build, trying to return a scaled MV clip... I panicked. Lost my dev version script of SMDegrain (filled with zeros), luckily it wasn't much, only a few commented expressions and notes.

This was more or less the trigger. I was trying to check bv1 clip dimensions to debug an issue I was having.
Environment:
i7-4790K
Win7-SP1 x64
AVS+ test29 x64
no avstp.dll in plugin path


setmemorymax(2048)
DGSource(bluray source)
ConvertBits(16)
w=width()
h=height()
bicubicresize(w*2,h*2)

pref8 = ConvertBits(8, dither=-1)
pref8 = pref8.BilinearResize(w, h)
pref8 = pref8.ConvertToYUV420(false,"","MPEG1","spline16","top_left").ConvertBits(16)
pref8 = pref8.ex_Luma_Rebuild(S0=3.0,c=0.0625,uv=3,tv_range=true,fulls=false).ConvertBits(8, dither=-1)

super_search = MSuper(pref8, pel=1, chroma=true, hpad=0, vpad=0, sharp=1, rfilter=4, mt=true)
Recalculate = MSuper(pref8, pel=1, chroma=true, hpad=0, vpad=0, sharp=1, rfilter=4, mt=true,levels=1)
bv1 = super_search.MAnalyse(isb = true, delta = 1, overlap=8, blksize= 16, search=4, chroma=true, truemotion=false, divide=0, dct=0, searchparam=2, pelsearch=1, temporal=false, trymany=false, scaleCSAD=1, mt=true)
bv1 = MRecalculate(Recalculate, bv1, overlap=4,blksize=8, thSAD=200, chroma=true, truemotion=false, divide=0, dct=0, scaleCSAD=1, mt=true)
bv1 = bv1.MScaleVect()

bv1

# without prefetch, in avspmod

I've changed the source filter to a ColorbarsHD().
bv1 is a 172444 x 1 sized RGB32 clip. Works for me from avsmeter64 and in 64 bit avspmod as well.

Dogway
30th November 2021, 17:30
Oh well, thanks for testing, I didn't feel brave enough to reproduce. I guess the long sized clip did something to my RAM, also I was running low on disk space so it could be a thing. I thought bv1 was similar to msuper clip. Now I will try to debug without returning mv clips, lesson learned.

DTL
3rd December 2021, 12:31
Small important update based on pinterf sources from 9 November 2021 - https://drive.google.com/file/d/1EEYaSzC3JL1Y-4SRj2Cr_sLkBNGUgows/view?usp=sharing . Should run stable with block size 16.

Added check of coordinates of predictors to skip repeated check of already checked predictor. Should make optPredictorType=0 (all predictors, old default) close to PT1 in speed while still kepping all possible predictors.
In real footage many predictors are equal (of Zero, Global, Median and 4 neibour, also may be +Temporal if enabled)) so keeping track of already checked predictors saves form some calls to single SAD() function that is not SIMD-friendly and hard to optimize.
Speed is content-dependent so the completely static sources like ColorBars() will give more speed. So better to test speed on real footage with different movements. Included also very small SSE41 optimizations in separate file and hardcoded inside SO=1 for users of old scripts.

kedautinh12
3rd December 2021, 15:45
Any chance for x86 ver?? :D

DTL
3rd December 2021, 17:31
It built by system - https://drive.google.com/file/d/1B6Exq4tp6QV6Ao5xZjqGpw_BPAcBaiI9/view?usp=sharing

but not any good tested if work correctly.

tormento
7th December 2021, 18:20
Small important update based on pinterf sources from 9 November 2021
Tested SSE41 builds thoroughly, both standard and SO1.

I am now using the SO1 version, instead of stable one, because of its speed and good results.

If you want to try a SSE42 build, my CPU supports it and perhaps we can get a little speed bump.

DTL
7th December 2021, 23:20
Later it looks I found a bug in that build from December 3 - it may cause skipping some valuable predictors and decrease degraining quality. Hope bugfixed build - (both x64 and x86)
https://drive.google.com/file/d/1kMcDG7v5lb3HM2PFMFwrGs2H8JBx3Pl1/view?usp=sharing

"SSE42 build, my CPU supports it and perhaps we can get a little speed bump."

Unfortunately SSE4.2 do not adds any significant. The only way to boost performance with all predictors and all levels refining - either AVX2 or better AVX512 capable chip.

For old CPUs only possible to try 'logical optimizations' like PT=4 mode - with pure interpolated prediction at level 0. It may provide lower quality of degraning but fastest possible mode. Also it is planed to put to SIMD (of low family like simple SSE) the InterpolatePrediction() function and it may also add some speed at SSE-level chips. But it still of lower priority - I currently in developing of multi-blocks search for AVX2 and AVX512 and interesting in the difference between 4/8 blocks AVX2 processing vs 16/32 blocks AVX512 processing. Of blocksize 8x8.
Today the 4Blocks 8x8 sp1 avx2 function looks like converted from pure tech speed test to something working for degraining.

Addition: PT=4 do require re-adjusting thSAD value in MDegrain (lower to about 1.5 times from 'standard' because it output SAD from level 1 and it typically lower). Using 'standard' thSAD value may cause too much detail blurring as usual too high setting of thSAD.

tormento
8th December 2021, 04:49
Hope bugfixed build
Can you release for SSE41 too?

Thanks.

DTL
8th December 2021, 08:17
I hope all possible SSE enabled. I just not put it to the file name. Only possible is add intel compiler build for some exact chip family - you have Sandy Bridge ? It may be a bit faster.

tormento
8th December 2021, 08:19
you have Sandy Bridge ? It may be a bit faster.
Yep, good old i7-2600k. Best Intel CPU ever :)

DTL
8th December 2021, 08:25
I think the best home chip is about i5-11400 now. But it looks it need about 200 watt unlocked power and cooler to run with AVX512 at good performance. If run with rated TDP 65 watt limit it looks will self-limiting to much lower performance level.

tormento
8th December 2021, 08:32
I think the best home chip is about i5-11400 now. But it looks it need about 200 watt unlocked power and cooler to run with AVX512 at good performance. If run with rated TDP 65 watt limit it looks will self-limiting to much lower performance level.


Alder Lake is a nice beast, unfortunately you have to disable E-Cores to have AVX-512 back.

FranceBB
8th December 2021, 11:48
The only way to boost performance with all predictors and all levels refining - either AVX2 or better AVX512 capable chip.

AVX512?
Bring it on for the next stable release, Sky servers will thank you for the AVX512 build speed-up! :D

https://c.tenor.com/VY3BZMLHJ_8AAAAC/come-to-me-dr-evil.gif

DTL
8th December 2021, 12:43
Alder Lake is a nice beast, unfortunately you have to disable E-Cores to have AVX-512 back.

As I understand if Windows task planner is not very bad it can load both P and E cores and E also helps. But I not sure how thread will detect if it can use AVX512 version of function or not. Also pricing for Adler Lake may be much more in compare with lower Rocket Lake like 11400.

As for DDR5 vs DDR4 - I not sure if it makes lot difference. As I see with typical latency about 50 ns the real random access byte-read speed is about 20 MBytes/s. And linear transfer is typical > 50 GBytes/s nowdays. The gap is about 2500 times. Unfortunately progress in latency at SDRAM is about 2 times at about 2 decades.

Can you make test of speed for 64x16 vs 16x64 block processing ? At old Core 2 Duo E7500 CPU I got about 60% of speed difference. But at i5-9600 and i5-11500 much less (looks latest intels have better hardware prefetchers tuned and really have about 10 times more cache).
I think about re-design of MDegrainN memory access pattern for better speed of memory access but it also need time and data if it will significantly helps to newer CPUs.

"AVX512?"

Yes - it have 4 times larger register file and allow to process 4 times more blocks in a single search op (if vector coherency domain is large enough - that is frequently happens). But it looks something still bad with consumer-level AVX512 intels - testers reports of large power overbudget if try to load CPU with calculation and not limit power at motherboard power supply. So it either over-heated (with small funny box cooler) and auto-trottle speed or overload motherboard power supply and crash/BSOD/etc of even burn motherboard. I personally have really burn-out motherboard at Pentium2 time - it was 2 slots and 1 of 2 once burn at night.
So it looks 14 nm intel can not run with AVX512 processing even at nominal frequency and start to auto-trottle itself. So the performance at consumer-level AVX512 chips may be still limited. Or very good (water ?) cooler required and special motherboard with large power over-limiting over rated chip TDP (like 3x times larger). I wonder how server-class intel chips with > 10 cores of AVX512 work at full speed for years.
I hope newer 7nm intel chips will be less power-hungry at AVX512 processing. But it still the future.

" will thank you for the AVX512 build speed-up!"

Unfortunately creating 'massive multi-block' processing versions of search functions takes lots of time for checking. The 'very simple' 4blocks sp1 AVX2 function take visible part of day to check all 4 blocks x 8 positions_each_block = 32 test points. And for AVX512 it is planned up to 32 blocks - 32x8=256 test points. Or require to build special test software for automation testing task. And for level>0 the sp2 versions required that have 24..25 search positions for each block - it is 32x25=800 points to test for full checking. The performance of new hardware quickly outperform the performance of user to create programs for it.
I hope AVX512 16/32 blocks 'tech demo' of SearchOption=4 will soon be available to check for possible speedup of AVX512.

FranceBB
8th December 2021, 13:27
I wonder how server-class intel chips with > 10 cores of AVX512 work at full speed for years.

Dunno, but they just do and the clock doesn't go down. On the other hand, we're talking about CPUs with a much lower clock than in the consumer versions. in my case the CPU has 56c/112th with base clock 2.20GHz. Whenever I use AVX2, it goes up to 2.50GHz even at 100% usage, however, if I try to do the same with AVX512, it will go down to 2.20GHz, which, again, ain't bad 'cause that's the base/standard CPU clock frequency.



I hope newer 7nm intel chips will be less power-hungry at AVX512 processing. But it still the future.


Perhaps. Fingers crossed, though. :)



Unfortunately creating 'massive multi-block' processing versions of search functions takes lots of time for checking. The 'very simple' 4blocks sp1 AVX2 function take visible part of day to check all 4 blocks x 8 positions_each_block = 32 test points. And for AVX512 it is planned up to 32 blocks - 32x8=256 test points. Or require to build special test software for automation testing task. And for level>0 the sp2 versions required that have 24..25 search positions for each block - it is 32x25=800 points to test for full checking. The performance of new hardware quickly outperform the performance of user to create programs for it.


Ah, yeah, right, I see...


I hope AVX512 16/32 blocks 'tech demo' of SearchOption=4 will soon be available to check for possible speedup of AVX512.

Well, fingers crossed again, then. :)

Dogway
8th December 2021, 14:03
I'm talking about future future but Intel chips will start to make sense again after Meteor Lake, but personally will wait until Luna or Nova Lake, when new tech like big-little, TDP and DDR5 issues (and prices!) settle down. In any case I don't think heat issues will improve so I see myself switching from my current 140mm rad to a 280mm one.

DTL
8th December 2021, 15:33
In the future future I think it is good to make 'auto-degrain' version with some preset output target SNR. And auto-adjustment of tr and thSAD values to reach this preset output target SNR.

We have everyday lots of different footages with different camera gain settings so even with about equal cameras the relative noise levels still very different from outdoor shootings with good lighting and low gain and noise to indoor opera/balet show with poor lighting and high relative noise levels from raised gain at cameras. So to use large tr and thSAD values for worst noise will take more time and degrade quality at low noise footages. Some automation required. Like statistical analysis of medium/average SAD coming from MAnalyse and backward adjusting of tr and thSAD from MDegrainN.

tormento
8th December 2021, 17:20
But I not sure how thread will detect if it can use AVX512 version of function or not.
Der8auer's test shows that AVX512 work only when E-cores are disabled, at least for Alder Lake. There is a tradeoff, yet to be know, between the E-cores you lose and the performance increase of AVX512. Unfortunately nobody tested the difference yet on this forum.
Can you make test of speed for 64x16 vs 16x64 block processing?
Yes if you do proper versions without having to put hand to the AVSI I use. :)
I think about re-design of MDegrainN memory access pattern for better speed of memory access but it also need time and data if it will significantly helps to newer CPUs.
Is there any chance you will port MVTools to CUDA, Vulkan or OpenCL? Than would help a lot more and nowadays it's much more widespread to have a fast GPU than the latest CPU.
So it looks 14 nm intel can not run with AVX512 processing even at nominal frequency and start to auto-trottle itself.
Motherboards automatically lower the multiplier of 2 or more. If you want to keep good performances and disable that setting in bios, your only solution is to use a very good liquid cooling system, at least 360mm.

Dogway
8th December 2021, 17:57
I have thought on adding some auto-tune algo, based on variance or stdev, but it implies sampling a portion of the clip and I don't know how user friendly that would be.
If you offhand the portion sampling to the filter it will spend most of the time trying to find a "flat" area to sample and yet it would fail based on luminance based grain.

Maybe the first option might be better, there are many estimators so it's a matter of finding one that works nice with SAD. SAD is a simple L1-norm if I'm not mistaken. I will run some tests.

EDIT: test

# 8-bit input
Crop(1278, 0, -462, -868)
a=ex_median("IQM5")

# 5x5 block SAD
SAD = Expr(last,a,"
x[-2,-2] y[-2,-2] - abs x[-1,-2] y[-1,-2] - abs x[0,-2] y[0,-2] - abs x[1,-2] y[1,-2] - abs x[2,-2] y[2,-2] - abs
x[-2,-1] y[-2,-1] - abs x[-1,-1] y[-1,-1] - abs x[0,-1] y[0,-1] - abs x[1,-1] y[1,-1] - abs x[2,-1] y[2,-1] - abs
x[-2,0] y[-2,0] - abs x[-1,0] y[-1,0] - abs x[0,0] y[0,0] - abs x[1,0] y[1,0] - abs x[2,0] y[2,0] - abs
x[-2,1] y[-2,1] - abs x[-1,1] y[-1,1] - abs x[0,1] y[0,1] - abs x[1,1] y[1,1] - abs x[2,1] y[2,1] - abs
x[-2,2] y[-2,2] - abs x[-1,2] y[-1,2] - abs x[0,2] y[0,2] - abs x[1,2] y[1,2] - abs x[2,2] y[2,2] - abs
+ + + + + + + + + + + + + + + + + + + + + + + +
","")

ScriptClip( function[a, SAD] () {
str = AverageLuma(SAD)*5
subtitle(string(str)) } )

DTL
8th December 2021, 18:59
"test shows that AVX512 work only when E-cores are disabled, at least for Alder Lake."

It looks Microsoft was not ready to such hybrid chips and still no official threading API to support thread signaling if it use some instructions set and to chip Threads Planner to use this data and not allow some threads to be switched to non-supported core and crash. So it either all active cores use AVX512 or application will crash when Thread Planner will occasionally switch it to E-core.

"Is there any chance you will port MVTools to CUDA, Vulkan or OpenCL?"

There is already some version of CUDA-based processing. I do not have fast GPUs of CUDA-capable. That versions may be limited in max tr value ? Or only fixed to MDegrain1,2,3, ?
In the very theory I think about distributed processing of MAnalyse with workers based on any hardware (CPU/GPU/ASIC etc) but it still not help to the MDegrainN that is not very fast curently too. And to put MDegrainN do GPU with all frame processing it looks required too much of onboard memory (it scan via 2*tr ref frames for each output frame, for tr=30 and UHD 8Msamples frame with pel=1 it is about 1.5 GBytes memory minimum, the current tr max is 128). MAnalyse only scan via current and 1 ref frame for each call of MDegrainN GetFrame() so each src-ref pair may be offloaded to small enough worker. Anyway it is too much redesign and I not any good C programmer - I can only make simple C programs and assembler. Nowdays as Microsoft disables inline asm in x64 programs it is intrinsics-based. Some known issue about intrinsics based program - https://stackoverflow.com/questions/70261138/force-compiler-to-use-memory-operand-from-intrinsics/70261394#70261394 . So it will more or less depend on compiler and need to make it compatible with many compilers and select the best by speed of output executable.

"# 5x5 block SAD"

In the MShow it can be switched showsad to 'true' - Allows to show the mean (scaled to block 8x8) SAD after compensating the picture

I think its value is good correlated with the SNR.

With script:

LoadPlugin("mvtools2.dll")
LoadPlugin("AddGrainC.dll")

ColorBarsHD(1920,1080)

AddGrain(0)
Trim(0,250)
super = MSuper (pel=1)
forward_vec1 = MAnalyse(super, isb = false, search=3, searchparam=2, chroma=false, delta = 1, mt=false)
MShow(super,forward_vec1, showsad=true)


addgrain=0 sad=0 (infinite SNR)
addgrain=1 sad=68
addgrain=2 sad=96
addgrain=4 sad=136
addgrain=8 sad=191
addgrain=16 sad=271

"do proper versions without having to put hand to the AVSI I use"

Here is 2 tests (with that latest .dlls with PT4 for possibly fastest speed of MAnalyse to look at MDegrainN raw speed):

LoadPlugin("mvtools2_asb16_ivc_SO1_PT4.dll")

ColorBarsHD(1920,1080)
Trim(0,1000)

tr = 12 # Temporal radius

super = MSuper (pel=1, hpad=64, vpad=64)
multi_vec = MAnalyse (super, multi=true, blksize=64, blksizeV=16, delta=tr,chroma=false,mt=false, levels=2)
MDegrainN (super, multi_vec, tr, thSAD=300, thSAD2=300-1, mt=false)

Prefetch(2)


vs


LoadPlugin("mvtools2_asb16_ivc_SO1_PT4.dll")

ColorBarsHD(1920,1080)
Trim(0,1000)

tr = 12 # Temporal radius

super = MSuper (pel=1, hpad=64, vpad=64)
multi_vec = MAnalyse (super, multi=true, blksize=16, blksizeV=64, delta=tr,chroma=false,mt=false, levels=2)
MDegrainN (super, multi_vec, tr, thSAD=300, thSAD2=300-1, mt=false)

Prefetch(2)


The second with vertical block 16x64 runs significantly slow at my iCore2 Duo E7500 CPU. Like 8 fps vs 13.5 fps. Though it somehow depends on hpad and vpad values. It is also a point to check why.

tormento
8th December 2021, 21:26
It looks Microsoft was not ready
I think it's Intel side. Alder Lake has the same architecture of Xeon ones and they do support AVX512.
There is already some version of CUDA-based processing
You mean SVP? AFAIK it's paid and really limited.
I do not have fast GPUs of CUDA-capable
A 1060 one should be really cheap now. Even a 1050 could be enought to try CUDA or other primitives.
And to put MDegrainN do GPU with all frame processing it looks required too much of onboard memory
KNLMeansCL and BDMV do a good job and memory is a culprit if you do heavy MT only. I don't know if the memory requirements are the same but I can easily process a 1080p source with 6 threads on a 3GB video card. AFAIK GPUs are good at heavily parallelized tasks. Perhaps the MDegrain part could work, as I can see that GPU filters, until now. are noise related.

FranceBB
8th December 2021, 22:20
Nowdays as Microsoft disables inline asm in x64 programs it is intrinsics-based.

What's the difference between inline assembly and manually written intrinsics? Aren't intrinsics specialised parts of the program written in assembly? Is the difference the fact that with intrinsics you can tell which instructions set to use dynamically while with inline assembly you can't and it would just fail if you try to execute a program which has AVX2 in a CPU that supports SSE4.2?

A couple of other questions:

- do you think we will ever get to a point in which compilers will be smart enough to generate fast enough code automatically at compile time while targeting an instruction set so that manually written intrinsics won't be necessary/worth writing or will it ever be science fiction?

- with the increasing number of high level languages and many young programmers taking the short route and using rust, python, electron, etc do you think there's gonna be a drop in performance in the near future as less and less people will be able to code in C++, let alone write instrinsics in assembly?


You mean SVP? AFAIK it's paid and really limited.

I think he means the Japanese Avisynth Neo version, which is based on a much older version of MVTools and the documentation of which is entirely in Japanese, so... Good Luck xD

qyot27
8th December 2021, 22:54
What's the difference between inline assembly and manually written intrinsics? Aren't intrinsics specialised parts of the program written in assembly? Is the difference the fact that with intrinsics you can tell which instructions set to use dynamically while with inline assembly you can't and it would just fail if you try to execute a program which has AVX2 in a CPU that supports SSE4.2?
It's easier to show it than describe it, in a sense.

Inline assembly is using the actual assembly code syntax itself, inside the code. It's usually compiler-specific as well, at least to a certain degree. Stuff like NASM assembly probably doesn't count, as even though it does go down to the base commands, it's slid in externally and parsed by a dedicated program. Some inline assembly does still exist in the AviSynth+ sources, like this block in PluginManager.cpp (which, because of how this works, can only be used when building with MSVC for 32-bit):
https://github.com/AviSynth/AviSynthPlus/blob/master/avs_core/core/PluginManager.cpp#L1210

Intrinsics, on the other hand, are largely compiler-provided shortcuts to the CPU's SIMD instructions that are able to be used more like regular C/C++, as keywords when the code needs to target particular instructions. For example, here in focus_sse.cpp:
https://github.com/AviSynth/AviSynthPlus/blob/master/avs_core/filters/intel/focus_sse.cpp#L157

All those __m128i and _mm_**_** calls? Those are the intrinsics.


Runtime dispatch of a particular feature set doesn't have anything to do with inline asm vs. intrinsics; that's purely on either the compiler or the programmer setting up dispatching correctly. If a SIMD instruction your CPU doesn't support gets through, the program will crash with a SIGILL when you try to run it. How compilers treat the regular C/C++ code can factor into this as well: if the compiler was told to optimize everything for an instruction set your CPU doesn't support, it'll translate the compiled C/C++ code into SIMD that doesn't exist on that CPU, and you'll get a SIGILL (this isn't as much of a problem with MSVC, but it can be a big one with GCC).

Generally, this is why Release builds of just about anything don't have myriad different builds compiled for every permutation of CPU out there: the plain code was left with the general optimizations the compiler can do but not any SIMD translation, and any inline asm or intrinsics are only active under codepaths it can detect are needed. Or at best, there's a baseline minimum CPU the plain code gets optimized for (one example would be FFMS2 and the whole thing over -msse/-march=pentium3 or -msse2 on 32-bit builds).

DTL
8th December 2021, 23:42
"I think it's Intel side. Alder Lake has the same architecture of Xeon ones and they do support AVX512."

I do not think Xeons have hybrid of different cores with different instructions sets. I think Adler Lake is the first chip with this design. And it require special software support.

"You mean SVP? AFAIK it's paid and really limited."

I see that thread - https://forum.doom9.org/showthread.php?t=183476 it is about SVSuper and SVAnalyse and uses GPU ? Also pinterf point to some project - https://github.com/pinterf/AviSynthCUDAFilters/tree/master/KTGMC .

"What's the difference between inline assembly and manually written intrinsics? "

Intrinsincs is semi-asm semi-C. Mostly special C operators more or less mapped to 'real' hardware CPU instructions (also containing many 'virtual' macros that is a sequences of instructions more or less on the compiler decision). One of the possible issue - it do not have method of pointing to memory operand where avaialble (currently). So if compiler fail to understand programmer's idea it is only possible to send complain to compiler's designer and waiting to next patched release if possible. Or write separate asm file to the project manually.

"you can tell which instructions set to use dynamically while with inline assembly you can't and it would just fail if you try to execute a program which has AVX2 in a CPU that supports SSE4.2?"

No. With intrinsics programmer must design separate functions for each large-vector co-processor type (SSE2/AVX2/AVX512 and future). Instructions sets between different large-vector co-processors are not compatible.

"- do you think we will ever get to a point in which compilers will be smart enough to generate fast enough code automatically at compile time while targeting an instruction set so that manually written intrinsics won't be necessary/worth writing or will it ever be science fiction?"

No. Each hardware SIMD large-vector co-processor architecture require special and separated design of program and they are not completely 'expandable' between different SIMD families and generations. They even do not inherit instructions sets completely with advances of generations - SSE have unique minpos() instruction and in it 128bit SSE4.1 only. Not exist in the next AVX2 and AVX512 and looks like not any replacing. So after SAD calculation in AVX2 or AVX512 instructions it is required to go down to 128bit SSE and use minpos() to found where is the min SAD positioned. It still faster in compare with going to 'general purpose core' and use loop with compare-based search for minimum member of vector. And SkyLake and possibly newer chips have 3 execution ports for minpos() instruction so after 4 clocktics latency it can output 3 minpos results per clock.
AVX2 256bit have mpsadbw() that not propagated to AVX512 and as I see the dbsadbw() in AVX512 can not be used as complete replacing. mpsadbw can be used for search up to sp3 full positions and sp3.5 with reduced 1 column. And dbsadbw only for sp1 (and for larger sp with data shift/reloading but it is a performance penalty).
So the already created program design can not be easily ported to next generation of large-vector co-processor. So the 'AVX512' search function is actually mix of different instructions sets down to SSE. Fortunately chips are still backward-compatible and AVX512 chip can execute SSE instructions though there is some penalty of going down from 512bit vectors to 128bit and back.

"- with the increasing number of high level languages and many young programmers taking the short route and using rust, python, electron, etc do you think there's gonna be a drop in performance in the near future as less and less people will be able to code in C++, let alone write instrinsics in assembly?"

It need to be separated 'general purpose Computer usage' and 'special data processing'. The general purpose computer usage is enough serviced by any high level programming language and general purpose CPU part of core. The special data processing is typically usage of special SIMD co-processor. The SIMD large-vector co-processor is highly integrated in general purpose CPU core but still have its special instructions set (and limited in operations) and separated register file (different size and 'word width' for each family). Any compiler with knowledge about its presence can use its register file for some temporal storage or even some data processing. And unlikely will be any compilers from 'general purpose' high level programming languages to SIMD co-processor (intel promises for 'auto-parallelization' where possible and where available but it still require too much preparation work from programmer). Because it is special purpose processing engine and not compatible with typical high level programming language. Though the intrinsics support can be made to any high level compiler. In theory it is possible to make special compiler for auto-creating designs for different SIMD co-processors but it is sort of the far future and the number of useful tasks will be still very limited. Mostly real is special libraries of functions designed for selected SIMD co-processor family.

tormento
8th December 2021, 23:51
I do not think Xeons have hybrid of different cores with different instructions sets.
Sapphire Rapids will have the same architecture, at least for Golden Cove (P-cores). I dunno if it will have E-cores too, even if I have my doubts about it.

Would you please explain me the differences between each search options and parameter options? I saw you compiled plain version, search option 1 and SO1 plus parameter 4. How are them different, speed and quality wise?

DTL
9th December 2021, 00:01
"plain version, search option 1 and SO1 plus parameter 4. How are them different, speed and quality wise?"

Plain is controlled by parameters optSearchOption(0,1) and optPredictorType(0,1,2,4).

SO1 is hardcoded optSearchOption=1 - it should be like you tested + fixed bug with skipping some predictors. Full quality (default PredictorType=0).

SO1_PT4 - is hardcoded optSearchOption=1 optPredictorType=4. It is special demo of 'logical optimization' - skipping level 0 processing and output interpolated (scattered to 4 larger buffer positions) prediction from level 1 (other levels uses PT=0 - full predictors). It should be fastest but quality may be more or less degrade depending on content. May be it will be useful for 'drafting' work or other. Require lowering thSAD value at MDegrain (I hope it is controlled in the typical script functions params) to about 1.5 times lower in compare with 'standard'.

" I dunno if it will have E-cores too."

I think Xeon customers are not interested in paying thousands for low-performance Effective cores. And re-design software to use mixed cores chip.

tormento
9th December 2021, 00:05
SO1 is hardcoded optSearchOption=1
Quality wise, is it better, worse or on par with stable?
It should be fastest but quality may be more or less degrade depending on content.
I already have idea where to use it, such as double SMDegrain calls, on the first one.

DTL
9th December 2021, 00:07
"Quality wise, is it better, worse or on par with stable?"

It should be very close.

"double SMDegrain calls, on the first one."

Yes - may be good example. But you can not mix different .dlls with equal functions names in 1 script. To use PT4 in one script it is required to load 'universal options-controlled .dll' and set param optPredictorType=4 to the draft MAnalyse().

tormento
9th December 2021, 11:04
Yes - may be good example. But you can not mix different .dlls with equal functions names in 1 script. To use PT4 in one script it is required to load 'universal options-controlled .dll' and set param optPredictorType=4 to the draft MAnalyse().
I thought about it just after posted. I hope dogway will adopt your version when stable.

DTL
9th December 2021, 16:11
Some not very great about AVX-512 in Adler Lake - https://www.anandtech.com/show/17047/the-intel-12th-gen-core-i912900k-review-hybrid-performance-brings-hybrid-complexity/2

Though speedbonus of AVX-512 if correctly used by software is about 3..4x over the old chips.

DTL
11th December 2021, 00:02
Some fresh info about first testing of SO3 (4 blocks 8x8 AVX2 processing) and SO4 (16 blocks 8x8 AVX512 processing) on
1. i5-11600 (2 DIMMs single sided (1 ranks) installed, possibly 2 channels)

2. Xeon Gold 6134 (all 6 memory channels should be installed in HP workstation)

Current results:
1. i5-11600 in raw MAnalyse performance (MDegrain rows processing close to disabled - only 1 st column left) about 2 times slower in best case (195 vs 104 fps).
2. SO3 4 blocks AVX2 processing in current testbuild a bit better at Xeon and a bit slower at i5-11600 in compare with AVX512 16 blocks processing. It looks even 4 blocks AVX2 processing takes all available memory bandwidth. And task still severily memory bound.
3. SO3 at Xeon (with 6 memory channels) is about 60% faster SO2 (1 block SIMD search). At i5-11600 - about 40% faster.
4. Some simple attempt of prefetching source blocks (about +3..+4 groups of blocks in advance) at all systems make a bit better performance (about 2..3%) so it is good to adjust manual prefetches. The hardware prefetchers not completely nice. And it also points to severe memory speed bounding of task.
5. At Xeon 8cores and 16 Hyperthreading switching from 8 to 16 threads good adds performance - about 40%. At i5-11600 8 cores 16 Hyperthreading - switching from 8 to 16 threads almost change nothing (may be 2 single rank DIMMs in 2 channels too low in speed to use > 8 threads).

So todo list:
1. Finish debug SO3 first.
2. Try to re-write MDegrainN processing to lines-based for the total frame width scan instead of current blocks-based. And test its speed difference.

DTL
28th December 2021, 10:55
"Is there any chance you will port MVTools to CUDA, Vulkan or OpenCL? Than would help a lot more and nowadays it's much more widespread to have a fast GPU than the latest CPU."

It looks we come to the limit of current architecture of 'triplet' MDegrainN + Avisynth-API + MAnalyse.

It uses frames memory management by Avisynth and in host-CPU memory. It is working with host-CPU for MAnalyse but not effective with ME-engine on separate HW-accelerator board.

With current architecture to create MVs for N output frames of N MDegrain threads it is require to upload to HWAcc board in worst case (2_x_tr)_x_2 x_N frames. With partial optimization of keeping Src resource reference for all calls to MAnalyse it can be lowered to (2_x_tr)_x_N . But with full optimization with resource management in HWacc board by one coordinator process it will be close to N only.

So in best case we need to ask Avisynth core developers to add HWAcc frames memory management so any filter in the Avisynth environment can only point to the resource ID (frame buffer) already loaded to HWAcc memory instead of re-uploading it every time.

I see in DeviceManager.cpp of Avisynth something about CUDA, but current ME-API from Microsoft is based on DirectX-graphics API resources operation (upload/download to DirectX/GPU-domain and interfacing with ME-engine). It is less specific of HW manufacturer but still specific for Windows OS and also not Linux/UNIX compatible (directly, may be wine ?).

The current may be easy to implement solutions may be:
1. Make DX12-ME option for MAnalyse to be compatible with all other filters of MVtools but it will be most ineffective with data transfer speed to HWAcc.

2. Make separate version of MDegrain(X/N) with direct interfacing with DX12-ME and working without MAnalyse. It will have its own tracking of loaded to HWAcc resources (frames) and decrease upload traffic.
It is still not compatible with AVS-MT nicely because each instance of MDegrain(X/N) will create its own pool of uploaded frames to HWAcc and it is also not best way.

3. Make again internal MT MDegrain(X/N) using existing avstp.dll (cured from freezing) or some other MT. It can manage its single pool of uploaded to HWAcc frames and use all host CPU cores for degraining processing. It may be not best solution for large processing scripts using AVS-MT ? Is it possible to run only one instance of MDegrainN in AVS-MT environment and many other filters ?

Current data flow in DX12-ME processing with ME engine in HW video encoder:
https://i3.imageban.ru/out/2021/12/28/2d0f003450a61a41ec96a46d57035af9.png

DTL
1st February 2022, 11:30
Make design idea how to make pel=2 and pel=4 processing faster:

In the old days the CPUs were slow and for sub-pel processing MSuper create 4x for pel=2 and 16x for pel=4 sub-shifted copies of input frame and the special GetBlock(x,y) function returns pointer to the sub-shifted full size sub-plane. This cause increasing read memory to 4x and 16x for pel 2 and 4. But close to zero CPU load for getting sub-shifted ref block for processing.

Todays CPUs much faster in computing and todays PC architecture still very slow in host RAM speed and its latency and caches sizes are too low to fit so many buffers.

So is an idea - to make sub-shifting of ref block 'on-request'. So simply add +1 block-sized buffer to MAnalyse and MDegrain 'workspace' and modify GetBlock(x,y) function to create sub-shifted block from single full-sized ref plane and return pointer to temp buf of this sub-shifted ref block. It will not be compatible with optSearchOption > 1 of Manalyse many search functions (for now it will increase search radius from 2 to 4 for pel=2 and only radius=4 SIMD search may be used - larger still not created but possible with AVX512).

Need an idea how to control this from mvtools params. In best way it should started from MSuper() - not create sub-shifted planes at all but send bit-flag of 'new pel' processing to Manalyse and Mdegrain. May be encode it as a bitfield in nPel value (currently it is 1 or 2 or 4) it is 0,1,2 bits set. So may be set 3rd bit to indicate 'new pel' processing ?

tormento
1st February 2022, 16:34
Make design idea how to make pel=2 and pel=4 processing faster
I know you are working really hard and I appreciate your fantastic job but, if you want to pursue the directx path, better you find a way to introduce HBD support.

Just my 2 cents. ;)

DTL
1st February 2022, 19:28
"a way to introduce HBD support."

DX12_ME API currently do not support anything but NV12 for MVs search input. And it 8bit YV12 format. The MDegrainN is support any old mvtools2 (the only float looks like broken somewhere but I think noone use it) inputs that 16bit also.

Current main sad limit - no overlap support with DX12_ME only search (may be overlap may be added with additional MRecalculate() before MDegrainN - but it will make processing slower and may remove most of benefit of DX12_ME pel up to 4 speed).

The DirectX/DirectCompute can have full functions of onCPU mvtools but may be in some future. Currently only 1 of 3 tasks is in active development - the SAD calculating on DirectCompute-ComputeShader because it not exist with DX12_ME output. The MVs search (including overlap mode) and MDegrainN is still for future. It may not give very large speedup for me - my system with i5-9600K CPU still very slow with x264 encoding. So with full degraining offload to accelerator I will got only about 2x total transcoding speed. Currently with pel=4 ME engine load is about 30% only and I mostly interesting in putting its resources to help x264 in speed - see https://forum.doom9.org/showthread.php?p=1962723#post1962723 .

About pure onCPU pel>1 we have big field of new SIMD functions:

1. Sub-shift to temp buf in RAM(cache) and feeding separate search functiion. (For each pel, block size)
2. Load src + ref blocks in register file and perform sub-shift + search in register file only (require to load interpolation kernel in register file too). It looks only possible with AVX2 or better AVX512 register file even for small 8x8 block.

Ceppo
13th February 2022, 19:28
There is an adobe plugin called Twixtor that allows blend interpolation like mvtools and another mode where it takes one of the interpolated frames and returns it without blending it. This mode would require only one motion vector and may give better interpolation result, at least Twixtor user say that this mode is often superior to blend. Is there any chance to get this blend free interpolating function?

DTL
16th February 2022, 11:05
I think it is important addition to the project - to add interface for input/output of moving data from MAnalyse to user-accessible format inside scripting environment and read back to client filters.

I read Dogway already ask for some way to get MVs from MAnalyse to check.

As I found with static images (static parts of moving images) processing - https://forum.doom9.org/showthread.php?p=1963966#post1963966 - the 2frames based MAnalyse search can not decrease noise on temporal axis and so the MVs data between MAnalyse and MDegrain client when processing noised sources may require additional filtering. I can add some form of temporal filtering to MDegrainN but it may be very content-dependent and may be it is good to allow many external non-C programmers developers to experiment with in-between motion data processing before final MDegrain blending.

Currently it looks we do not have common/standard exchange formats for motion data. With DX12 the Microsoft way of exchange is converting to 2D texture of 16+16 bit signed 2 component format (size of texture = number of blocks HxV). But it only provide translate motion x,y data.

For current AVS+ it is idea to convert to RGBPS format texture/clip with mapping as
R - x
G - y
B - SAD

And may be make 2 additional functions to convert MAnalyse output pseudo-clip to MotionData-RGBPS and back. So users of scripts with sample-accesing functions may try to read or read and send back processed (filtered) motion data to the downstream client filters. May be it is enough to provide motion data only per level=0 and not all other levels (MDegrain only uses level=0 data ?).

In the best future we need some extended format may be like XML (?) with many motion (transform) params for each block:
1. Translate (x,y)
2. Rotate (rz (rx, ry) ?)
3. Scale (sx,sy)
4. Skew (.., sx, sy)
5..
N. SAD scalar unsigned data

May be for multi-movement search engines use set of separated RGBPS or Y-PS clips for each type of movement (translate/rotate/scale/etc). So if client filter can accept different types of motion data it will accept several input motion-clips. It will keep compatibility with old versions/scripts.

DTL
6th March 2022, 11:30
A couple of other questions:
- do you think we will ever get to a point in which compilers will be smart enough to generate fast enough code automatically at compile time while targeting an instruction set so that manually written intrinsics won't be necessary/worth writing or will it ever be science fiction?



Some more information about motion search on non-CPU data compute accelerators:

1. Good information: The data compute accelerators also support dedicated hardware instructions for many SAD computing on input vectors - the msad4 intrinsinc in HLSL: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-msad4 . Also have an example for searching position of reference pattern in a buffer. That mean the SAD-based motion search form current MAnalyse may be more efficiently ported into Compute Shader version.

2. The very strange situation about 'low level' programming of compute accelerators: It not support 'assembler' level programming. Only C-like languages. Example of question about direct 'assembler-level' programming of accelerator - https://stackoverflow.com/questions/55813432/how-to-compile-from-shader-assembler-code-in-directx-11 .
For NVIDIA CUDA - https://stackoverflow.com/questions/7353136/is-there-an-assembly-language-for-cuda .

So it mean currently the compiler must produce as best as possible executable result for accelerator and no manual hand-crafting is possible (not officially supported). Programmer need to use higher-level functions intrinsics or simple C-like statements. That is partial answer on the question about current and may be future state of compiler optimizations for at least part of current computing hardware (and may be typically higher in performance in compare with host desktop CPU). May be accelerators from different manufacturers are not fully compatible with instructions sets so even in 'compiled' state the program may still use some pseudo-code for further adapting to executing hardware at runtime.

It looks AMD also will someday support AVX512 register file and some instructions. https://www.extremetech.com/computing/325888-gigabyte-leaks-amd-zen-4-details-5nm-avx-512-96-cores-12-channel-ddr5
So it is good to test the sub-sample processing with upsizing of 1x level to 2x or 4x for pel=2 and pel=4 search in MAnalyse and shifting for MDegrainN on AVX512 functions.

FranceBB
13th March 2022, 14:36
It looks AMD also will someday support AVX512 register file and some instructions. https://www.extremetech.com/computing/325888-gigabyte-leaks-amd-zen-4-details-5nm-avx-512-96-cores-12-channel-ddr5
So it is good to test the sub-sample processing with upsizing of 1x level to 2x or 4x for pel=2 and pel=4 search in MAnalyse and shifting for MDegrainN on AVX512 functions.

Thanks for the info. Honestly, when I had to purchase new servers in 2019, I went again for Intel Xeon mostly due to the fact that they were the only ones supporting AVX-512. They're encoding files through Avisynth and either x262/Libavcodec MPEG-2 Encoder or x264 on a daily basis, calling then the mxf muxer (either BBC BMX or the closed source paid Omneon mxf muxer provided by Harmonic). I do make use of MVTools extensively for the Tape Remastering workflows put in place in Summer 2020 after Derek's suggestion, so seeing a speed improvement in there would be nice. I'm not planning to get any new servers anytime soon as I'm re-allocating old AVID Transcode servers to become "new" Avisynth servers. They're just low speed 10c/20th Intel Xeon with AVX2 only, so nothing compared to the three 56c/112th AVX-512 beasts I bought in 2019, but they're gonna do the job. I guess the time to perhaps try an AMD test bench for professional encoding use in servers MIGHT come in 2025 if I'll have to buy more servers, but for the time being, I guess I'm gonna be fine as I have a farm with:

- 3 Intel Xeon 56c/112th AVX-512 128 GB of RAM
- 2 Intel Xeon 20c/40th AVX-2 64 GB of RAM
- 1 Intel Xeon 10c/20th AVX-2 32 GB of RAM (old server)

and soon-ish I'm gonna have 19 more of those, so:

- 20 Intel Xeon 10c/20th AVX-2 32 GB of RAM (old server)

that should take care of all the extra work and ideally the 3 monsters will pick up and handle almost only the ProRes, XAVC, MJPEG2000 etc UHD clips and the other ones will take care of the old/legacy XDCAM-50 FULL HD version and the MPEG-2 12 Mbit/s Long GOP M=3 N=15 SD version of movies, tv series etc.

The only nag is that for SD versions only I always have to call ommcp.exe and remux with the Omneon muxer 'cause Omneon playout ports have their own special flag and they don't follow the normal container's flag or stream's flag for aspect ratio. This is because once you flag it within Omneon, it will tell the playback port what to do, so not only whether it's 4:3 or 16:9 but also whether you want to crop it, add borders, leave it as it is etc.

I really honestly wish SD to die 'cause encoding 2022 movies in SD BT601 only to serve some people really breaks my heart.

DTL
28th June 2022, 09:01
Made some graphics to show how MDegrain works with incoming SAD deviations and for understanding how to set thSAD (and wpow) value for different input noise-based SAD distributions.

https://i4.imageban.ru/out/2022/06/28/44eb4fb767b05f134515006c7a979dc0.png

Also attached to post to keep at this server.

As for thSCD1 value: The current ideas it shoud be at least as great as thSAD. Default thSCD1 looks like 400, so if increasing thSAD above 400 it may required to raise thSCD1 too or it will work as internal thSAD limiter and will also throw-away blocks from processing completely because detected as scene-changed blocks and completely wrongly compensated.

As for AVX512:

Currently I am in the finishing process of testing new processing mode for MDegrainN and pel > 1 with inside CPU core generating sub-pel compensated block instead of fetchig of pre-computed by MSuper() block from host memory (using old fully pel-refined super clip to 4x size for pel=2 and 16x size for pel=4). It works about good and faster but for best speed require processing inside register file of chip. So the AVX2 512 bytes sized register file is enough only for 8x8 8bit and lower block sizes (so can only fully service YV12 8 bit colour format with 8x8 luma and 4x4 chroma blocks, the 4:2:2 YV16 may be added with 4x8 chroma block size but not sure if it is widely used, also not sure if it supported by current mvtools at all). For any larger it is better to use 2048 bytes AVX512 register file (also with a bit faster processing of twice longer vectors). So todays 8x8 16bit blocks and 16x16 16bit blocks already require AVX512 for best speed.

The 16bit 8x8 and 16x16 blocks processing AVX2 functions can be designed but will have lower performance because of store-load temp results from register file to L1d cache and back and it ruines speed to a factor about 5. Not total function speed but internal partial operations touching memory susbsystem like cache. Main reason of these functions will be to save RAM usage and it also adds to processing speed.

I also will post a test sample of MAnalyse with same 'runtime-calculating' pel >1 blocks fetching. But it looks even at UMH optimized search it still slower in compare with pre-calculated super-clip of pel=4 about 2 times at i5-9600K chip. Will try to test at i5-11600 chip with AVX512 versions of sub-shift functions too later.

So the main speed benefit of new MDegrainN processing of pel >1 is when using ME hardware accelerator so the most speed limit was memory fetching of blocks from large 16x sized pel=4 super clip at 4K resolutions. It is about 1.2 fps at i5-9600K with old super clip mode and about 6 fps with new inside chip shifting of 1x sized frames.

tormento
28th June 2022, 10:45
Made some graphics to show how MDegrain works with incoming SAD deviations and for understanding how to set thSAD (and wpow) value for different input noise-based SAD distributions.
How this graph would help us to find the correct values for parameters? I am looking at it and I am "a bit" confused.

What is the latest version that of MVTools that I can use with SMDegrain with no AVSI modification, withouth AVX2/512 requirement?

DTL
28th June 2022, 15:00
"How this graph would help us to find the correct values for parameters?"

I hope it can help to understand MDegrainN activity when parameters changing:
1. When thSAD is too low - any tr value will not help in degraining.
2. The good working value of thSAD have enough visible 'barrier' or 'step' effect - untill it reach lower noise-SAD levels it is mostly ineffective. After it is set to upper noise-SAD values it become already nearly maximum effective and increasing thSAD to higher levels mostly do nothing (useful) but may cause more details blurring.
3. After thSAD reach optimal level - the most of degrain-strength adjustment is only tr-width (value). Increasing thSAD to twice or more higher above optimal will mostly not add anything useful to degrain activity.

To the left it is placed rotated graph of different DegrainWeight() functions graphs scaled to 'possibly optimal' thSAD vertical value to show how blocks weights depend on SAD and thSAD values and with different wpow params. May be it is good to shoot a video-lection with a several minutes or more duration with attempt to describe this drawing better :) .

"What is the latest version that of MVTools that I can use with SMDegrain with no AVSI modification, withouth AVX2/512 requirement?"

In theory any builds should be backward compatible with old scripts. All new params are in the default disabled state. Also the max available version of SIMD co-processor is auto-detected.
It was funny to found the old program text around MAnalyse() functions that very ancient 'isse' common functions param was truncated to SSE or nothing only. And there were no newer functions above SSE 128bit to use more newer chips. So this truncation were never detected untill the AVX2 functions were added.

tormento
28th June 2022, 18:23
I hope it can help to understand MDegrainN activity when parameters changing
I do it manually, increasing tr and thsad at the same time, until compressibility comes to decrease less and less rapidly.

tr=3, thsad=300 -> x265 -> file size
tr=4, thsad=400 -> x265 -> file size

etc...

But it's very time consuming and I have always wondered if there is a way to do it automatically.
In theory any builds should be backward compatible with old scripts.
I remember that you sent here a version with one hardcoded parameter that could really increase speed without affecting quality in a visible manner. Would it be possible to have that version, updated?

LeXXuz
28th June 2022, 18:49
"How this graph would help us to find the correct values for parameters?"

I hope it can help to understand MDegrainN activity when parameters changing:
1. When thSAD is too low - any tr value will not help in degraining.
2. The good working value of thSAD have enough visible 'barrier' or 'step' effect - untill it reach lower noise-SAD levels it is mostly ineffective. After it is set to upper noise-SAD values it become already nearly maximum effective and increasing thSAD to higher levels mostly do nothing (useful) but may cause more details blurring.
3. After thSAD reach optimal level - the most of degrain-strength adjustment is only tr-width (value). Increasing thSAD to twice or more higher above optimal will mostly not add anything useful to degrain activity.

To the left it is placed rotated graph of different DegrainWeight() functions graphs scaled to 'possibly optimal' thSAD vertical value to show how blocks weights depend on SAD and thSAD values and with different wpow params. May be it is good to shoot a video-lection with a several minutes or more duration with attempt to describe this drawing better :) .

"What is the latest version that of MVTools that I can use with SMDegrain with no AVSI modification, withouth AVX2/512 requirement?"

In theory any builds should be backward compatible with old scripts. All new params are in the default disabled state. Also the max available version of SIMD co-processor is auto-detected.
It was funny to found the old program text around MAnalyse() functions that very ancient 'isse' common functions param was truncated to SSE or nothing only. And there were no newer functions above SSE 128bit to use more newer chips. So this truncation were never detected untill the AVX2 functions were added.

These figures are ver interesting and thanks for the more detailed explanation.

I never paid much attention to anything else but prefiltering, tr and thSAD. Simply because I didn't understand enough how all the other parameters are connected with each other. Yes, I read the docs. But that still was way over my head at times. :o

So the very big question is how to determine the somewhat best SAD value for a source file.

Right now, much like tormento already mentioned, it's more like a lot of trial and error for me. So I was wondering if there may be any automated way to measure this somehow. It doesn't have to measure the best possible settings but something like a decent base of params to just tweak a little here and there to personal liking. Otherwise starting from scratch for every movie will be a life's work if I ever want to recode my collection. :D

DTL
28th June 2022, 20:06
" that version, updated?"

The most currently developed new feature of internal shifting for MDegrainN need at least AVX2 CPU to run faster in compare with old versions. And still have only YV12 format supported in this mode with Y-block size of 8x8. So it will not run faster at old AVX-only chip.

" always wondered if there is a way to do it automatically"

Initial estimation of the thSAD may be with MShow(showsad=true). To make it work stable I use single pair of frames search:

super = MSuper(mt=false, pel=1)
forward_vec1 = MAnalyse(super, isb = false, delta = 1, search=3, chroma=true, mt=false)
MShow(super,forward_vec1, showsad=true)


With multi-mode of MAnalyse it typically not shows SAD stable enough.

" increasing tr and thsad at the same time"

thSAD mostly control 'quality by blurring' and tr the 'amount of degraining'. So initially it is good to set as high thSAD as still not too much degrade fine details but already making degraining with relatively low tr like 3. And next increase tr to balance speed/degraining ratio. And look for the ratio of thSAD vs thSCD1 value - if thSAD > thSCD1 visibly (also if mean SAD by MShow(showsad=true) is > thSCD1) - need to start raise thSCD1 too.

Boulder
29th June 2022, 06:55
As for thSCD1 value: The current ideas it shoud be at least as great as thSAD. Default thSCD1 looks like 400, so if increasing thSAD above 400 it may required to raise thSCD1 too or it will work as internal thSAD limiter and will also throw-away blocks from processing completely because detected as scene-changed blocks and completely wrongly compensated.

Interesting - I thought that scene change detection affected the whole frame and not just a single block. If you use MShow to view the vectors, you get that impression.

DTL
29th June 2022, 08:21
Updated post:

After more looking into the source: Yes - the array 'usable_flag_arr' is one per frame entry.

The usage of thSCD1 and thSCD2 is mostly as

bool FakePlaneOfBlocks::IsSceneChange(sad_t nTh1, int nTh2) const
{
int sum = 0;
for ( int i = 0; i < nBlkCount; i++ )
sum += ( blocks[i].GetSAD() > nTh1 ) ? 1 : 0;

return ( sum > nTh2 );
}


So when there are too many blocks with SAD > thSCD1 - the total frame marked as not-usable. So thSCD1 really directly compared with block SAD but the final result is per-frame but not per-block.

So engine allow some blocks to have SAD > thSCD1 and still be in processing (only if the frame still marked as usable !). But after percentage of these blocks become > thSCD2 - the whole frame is marked as unusable and thrown away from processing.

thSCD2 (int, 130)
Threshold which sets how many blocks have to change for the frame to be considered as a scene change. It is ranged from 0 to 255, 0 meaning 0 %, 255 meaning 100 %. Default is 130 (which means 51 %).

So user must carefully look for situation when thSAD > thSCD1 - it may quickly stops any useful processing and any increasing of tr will be useless.

LeXXuz
29th June 2022, 12:53
Just throwing in some numbers...

I had:
thSAD=800, tr=12 and thSC1=default => total file size 7.72GB

now retried with:
thsad=800, tr=12 and thSCD1=600 => 6.59GB
thsad=800, tr=24 and thSCD1=600 => 5.69GB

I think tr=24 and higher thSCD1 were totally worth it. At least for this source. However, I will not go any higher than 24, speed gets too low for general use. With tr=12 I had 5.18FPS and with tr=24 it dropped to 2.91FPS including prefiltering and a modified "slower" setting of x265. That's barely still okay. But any slower would kill me with my next electrical bill. :D

Will now lower thSAD more closer to thSCD1 and see how much file size will increase, because 800 is already smoothing too much for my taste.

DTL
29th June 2022, 13:35
"thsad=800, and thSCD1=600"

I think in practical use cases thSCD1 should be not less than thSAD. Default is thSAD=thSCD1=400 as I see from documentation.

" total file size 7.72GB"

If you encode in crf mode with x264 (may be x265 too) there may be also some 'threshold effect' based of crf-value close to MDegrain activity - if you set crf as high so the MPEG encoder do not detect changed blocks - it encodes as static and no residual noise changes and output file size reduces very visibly. Same happens if after increasing thSAD and tr to such high values that residual noise is below 'crf-threshold' of MPEG encoder you also got significant filesize decrease.

So you may try to make a research of

(thSAD, tr) in mvtools + (crf) in MPEG encoder and look how output file size is changed.

So practically mvtools are pre-processor for higher-ratio MPEG compressing. As moving from MPEG4-AVC to MPEG-HEVC may give about +50% compression ratio but using denoise before MPEG4-AVC may add thousands % of compression ratio and also make image more clean and clear. I currently have about 22000Kbit/s in non-denoised documentaries in FullHD and about 4500Kbit/s after 'deep denoising' with same crf=18 x264 encoder. So additional compression ratio from denoise-preprocessing is about 488%.

"Will now lower thSAD more closer to thSCD1 "

In the 2.7.45 and older the DegrainWeight weighting functions have fixed control param of 2. In the newer versions it is wpow param of MDegrainN and may be set up to 6 and 7=equal weight. It allow to increase block weight inside thSAD without setting thSAD too high. I typically use wpow=4 now. BlockWeight=f(wpow, blockSAD) is that graph at the left rotated 90degrees at the big combined image https://i4.imageban.ru/out/2022/06/28/44eb4fb767b05f134515006c7a979dc0.png
Unfortunately in the used math functon wpow > 6 is too slow in computing so after 6 the SAD-based smooth falloff weighting is disabled and equal weighting used - so wpow=7 is the max possible degraining at given thSAD but may cause additional visual issues.

LeXXuz
29th June 2022, 22:00
Initial estimation of the thSAD may be with MShow(showsad=true). To make it work stable I use single pair of frames search:

super = MSuper(mt=false, pel=1)
forward_vec1 = MAnalyse(super, isb = false, delta = 1, search=3, chroma=true, mt=false)
MShow(super,forward_vec1, showsad=true)



Is this the average value found for a frame or the maximum?
With the source I currently have it hardly goes over 400. I use 600 now which still leaves a little noise in the picture.
Also I start to think there is more than just grain in this film that makes it compress so badly. I think I noticed some flickering and mosquito noise around edges too. Looks like the source bitrate was already chosen too low when this Blu-ray was created. :(

DTL
29th June 2022, 22:59
"Is this the average value found for a frame or the maximum?"

MShow -> showsad

Allows to show the mean (scaled to block 8x8) SAD after compensating the picture and quantity (thSCD2) of bad (thSCD1) blocks.

Mean is about average I think. May be it also good to add more statistics to MShow like ends of distribution like mean of 5..10% smallest SAD and mean of 5..10% of highest SAD.

takla
30th June 2022, 05:59
Yeah. Using what ever thSAD Mshow shows ain't gonna work. A quick test with one of my sources shows a range from ~50 to ~200 (so my default 150 was actually pretty good here).

And yes, having the statistic show some % of lowest and highest SAD would be very helpful.

thSAD NEEDS to be dynamically adjusted automatically. It should not be a fixed value. What SHOULD be a fixed value is something like thSADmax which caps the maximum.

OR you could also make it so there is a logfile that writes every frames SAD value and have MDegrain read from it. Basically 2-pass mode.

anton_foy
30th June 2022, 07:48
Yeah. Using what ever thSAD Mshow shows ain't gonna work. A quick test with one of my sources shows a range from ~50 to ~200 (so my default 150 was actually pretty good here).

And yes, having the statistic show some % of lowest and highest SAD would be very helpful.

thSAD NEEDS to be dynamically adjusted automatically. It should not be a fixed value. What SHOULD be a fixed value is something like thSADmax which caps the maximum.

OR you could also make it so there is a logfile that writes every frames SAD value and have MDegrain read from it. Basically 2-pass mode.

I use these lines below to regulate thSAD and TR dynamically with ScriptClip.
Although my material is noisy 4K sLog-2 footage so for other material the "noise detection" may be tweaked or changed to fit the purpose better:


o=last

#Prefilter:
b=fastblur(3)
P=merge(o,b,0.5).ex_levels(12,1.2,100)

pk = converttoRGB()
pl = pk.converttoPlanarRGB()
in = pl.ex_invert()

t=ScriptClip(function[in,pl,pk,p] () {

lum = in.averageR()
rgb = pk.RGBDifferenceFromPrevious()
luma = int(lum + rgb)
ttr = int(luma*0.0001)
ths = int(luma*0.0067)

TSMC(tradius=ttr,lumathresh=ths,auxclip=p)
} )

Also in this case I use mocomped TemporalSoften but you can use mdegrainN or SMDegrain instead. Note my prefiltering is a simple fastblur+levels which after months of testing prefiltering techniques surprisingly works the best (out of all the other prefiltering I tried) for my material.

takla
30th June 2022, 08:22
I use these lines below to regulate thSAD and TR dynamically with ScriptClip.
Although my material is noisy 4K sLog-2 footage so for other material the "noise detection" may be tweaked or changed to fit the purpose better:


o=last

#Prefilter:
b=fastblur(3)
P=merge(o,b,0.5).ex_levels(12,1.2,100)

pk = converttoRGB()
pl = pk.converttoPlanarRGB()
in = pl.ex_invert()

t=ScriptClip(function[in,pl,pk,p] () {

lum = in.averageR()
rgb = pk.RGBDifferenceFromPrevious()
luma = int(lum + rgb)
ttr = int(luma*0.0001)
ths = int(luma*0.0067)

TSMC(tradius=ttr,lumathresh=ths,auxclip=p)
} )

Also in this case I use mocomped TemporalSoften but you can use mdegrainN or SMDegrain instead. Note my prefiltering is a simple fastblur+levels which after months of testing prefiltering techniques surprisingly works the best (out of all the other prefiltering I tried) for my material.

That is nice and might help some people, but in this case, I want to get the exact value from Mshow. How to I accomplish this? I don't think support for that is there.

LeXXuz
30th June 2022, 09:29
"Is this the average value found for a frame or the maximum?"

MShow -> showsad

Allows to show the mean (scaled to block 8x8) SAD after compensating the picture and quantity (thSCD2) of bad (thSCD1) blocks.

Mean is about average I think. May be it also good to add more statistics to MShow like ends of distribution like mean of 5..10% smallest SAD and mean of 5..10% of highest SAD.

The second digit shows the quantity of bad blocks? What does bad blocks mean in that context?

DTL
30th June 2022, 10:15
"What does bad blocks mean in that context?"

( blocks[i].GetSAD() > nTh1 )
bad (thSCD1) blocks.

I think it is blocks with SAD > thSCD1 .

LeXXuz
8th July 2022, 12:53
I just checked most of my scripts and they are running with mvtools 2.7.44 :eek:

I have no idea why I haven't checked this more thoroughly. :rolleyes:

I already had pinterf's 2.7.45 in my library, no idea why I didn't use it.

DTL you wrote 2.7.45+ so I guess there is already never version to use?

DTL
8th July 2022, 15:25
Still no next official release like 2.7.46 from pinterf. With 2.7.45+ I mean post-2.7.45 builds I typically put at https://github.com/DTL2020/mvtools/releases .

I hope someday may be in this or next year :) it will be more or less merged to pinterf branch and after supplementing and testing finally we will see 2.7.46 or may be even 2.8 release. The number of strategic new features and processing modes continue to increase after first fork in 2021. I think to finish adding most of new features after interpolated overlap I plan to start at this week. But after reading mvtools docs one more time at this year :) I found MFlow with per-sample processing precision mode and got new idea to test it with MDegrainN frame-operation pipeline (with easy to use multi-mode). So it may be next more or less slow development feature to the MDegrainN. Also all new features added and approved need to supplement with SIMD processing functions for better speed for most or all supported colour formats and at least some commonly used block sizes and bitdepths. Currently only some formats have at least AVX2 execution in addition to very slow C-reference like only YV12 and only 8x8 block size of 8bit for UseSubShift mode of MVPlane (fully working only in MDegrainN now and planned for MAnalyse and other filters to save RAM and/or better speed at some use cases).

Typically that builds are full featured of this and https://forum.doom9.org/showthread.php?t=183517 thread described features but most of latest builds are with DX12-ME support and will not load where no DX12 installed (so no Win7 and old). So it is required separate build config to build all-win compatible executable without using DX12-ME mode of MAnalyse but using all new features of MDegrainN for example. The overlap single pass MDegrainN for colour formats are also ready to use after 06.07.22 commits but I still not make release build - you can only build yourself from latest git sources image. I plan to make new release after adding the also very strategic interpolated overlap feature to finally get solution against blockiness at some scenes with no-overlap supported hardware accelerated MAnalyse now.

Also the shader need to be fixed after final runtime subshift of block processing implementation based on old mvtools Wiener kernel - it is delayed because 12.05.22 release have not best but about good working SAD compute shader and fast rebuild of shader still not show better results and need more debug.

Some new features like single pass colour MDegrainN or MVLPF interfiltering are not depend on colour format and block size so expected to work already with all old formats. Single pass colour proc also do not require new options so compatible with old scripts directly (expected a bit better speed with same quality).

mvtools will soon be 1/5 of century aged - in January of 2024. So may we will have version 2.8.0 prepared to that celebration. Or may be final release of 2.7.46 :) .

DTL
7th March 2023, 20:59
Version for testing of (partial) fix for issue with chroma subsampled formats (both MAnalyse and MDegrainX/N) - https://github.com/DTL2020/mvtools/releases/tag/r.2.7.45-fix1 . The description in https://github.com/pinterf/mvtools/issues/59

One of my test with x264 encoding shows a bit lower output MPEG bitrate and a bit better details at 200% size comparison.

denoise script:
for YV12 source
tr=8
super=MSuper(last,chroma=true, mt=false, pel=2)
multi_vec=MAnalyse (super, multi=true, delta=tr, search=3, searchparam=2, overlap=4, chroma=true, mt=false, truemotion=false, pnew=0, pzero=0, levels=0)
MDegrainN(last,super, multi_vec, tr, thSAD=300, thSAD2=290, mt=false, thSCD1=500)

orig 2.7.45=
x264.exe --profile high --crf 18 --tff --ref 4 -b 10 --me umh --subme 9 --merange 16 --deblock -3:-3 --b-adapt 2 --psy-rd 1.0:0.7 --transfer "bt70
9" --colorprim "bt709" --colormatrix "bt709" -o out.264 src_t.avs
avs [info]: 960x540i 0:0 @ 25/1 fps (cfr)
x264 [warning]: interlace + weightp is not implemented
x264 [info]: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.1 Cache64
x264 [info]: profile High, level 3.1, 4:2:0, 8-bit
x264 [info]: frame I:5 Avg QP:14.23 size:102544
x264 [info]: frame P:203 Avg QP:17.24 size: 31718
x264 [info]: frame B:781 Avg QP:20.50 size: 6645
x264 [info]: consecutive B-frames: 1.7% 3.2% 9.1% 11.3% 8.6% 49.1% 4.2% 2.4% 2.7% 3.0% 4.4%
x264 [info]: mb I I16..4: 14.7% 66.3% 19.0%
x264 [info]: mb P I16..4: 1.8% 4.7% 1.0% P16..4: 42.6% 23.4% 19.0% 0.0% 0.0% skip: 7.4%
x264 [info]: mb B I16..4: 0.1% 0.1% 0.0% B16..8: 31.0% 7.6% 2.1% direct: 7.9% skip:51.3% L0:35.5% L1:32.5% BI:32.0%
x264 [info]: field mbs: intra: 36.6% inter:41.6% skip:31.1%
x264 [info]: 8x8 transform intra:61.4% inter:72.9%
x264 [info]: coded y,uvDC,uvAC intra: 70.9% 82.6% 65.8% inter: 29.9% 25.5% 7.7%
x264 [info]: i16 v,h,dc,p: 29% 19% 15% 36%
x264 [info]: i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 14% 12% 14% 7% 9% 10% 11% 9% 13%
x264 [info]: i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 13% 33% 7% 5% 8% 8% 9% 7% 11%
x264 [info]: i8c dc,h,v,p: 46% 27% 19% 8%
x264 [info]: ref P L0: 49.9% 28.4% 14.0% 4.8% 1.4% 1.4% 0.0% 0.0%
x264 [info]: ref B L0: 70.4% 23.7% 3.4% 1.9% 0.2% 0.2%
x264 [info]: ref B L1: 78.0% 20.4% 0.9% 0.8%
x264 [info]: kb/s:2455.20

encoded 989 frames, 1.42 fps, 2455.20 kb/s

2.7.45 fix1=
x264.exe --profile high --crf 18 --tff --ref 4 -b 10 --me umh --subme 9 --merange 16 --deblock -3:-3 --b-adapt 2 --psy-rd 1.0:0.7 --transfer "bt70
9" --colorprim "bt709" --colormatrix "bt709" -o out.264 src_t.avs
avs [info]: 960x540i 0:0 @ 25/1 fps (cfr)
x264 [warning]: interlace + weightp is not implemented
x264 [info]: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.1 Cache64
x264 [info]: profile High, level 3.1, 4:2:0, 8-bit
x264 [info]: frame I:5 Avg QP:14.14 size:102566
x264 [info]: frame P:202 Avg QP:17.24 size: 31792
x264 [info]: frame B:782 Avg QP:20.51 size: 6558
x264 [info]: consecutive B-frames: 1.4% 3.4% 9.7% 8.5% 10.6% 51.6% 4.2% 3.2% 1.8% 1.0% 4.4%
x264 [info]: mb I I16..4: 14.8% 65.9% 19.3%
x264 [info]: mb P I16..4: 1.8% 4.6% 1.1% P16..4: 42.6% 23.5% 19.1% 0.0% 0.0% skip: 7.3%
x264 [info]: mb B I16..4: 0.1% 0.1% 0.0% B16..8: 30.9% 7.5% 2.1% direct: 7.7% skip:51.6% L0:35.5% L1:32.3% BI:32.1%
x264 [info]: field mbs: intra: 36.0% inter:41.4% skip:31.1%
x264 [info]: 8x8 transform intra:61.4% inter:72.9%
x264 [info]: coded y,uvDC,uvAC intra: 71.4% 82.9% 66.0% inter: 29.7% 25.1% 7.5%
x264 [info]: i16 v,h,dc,p: 30% 20% 15% 35%
x264 [info]: i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 14% 12% 14% 7% 10% 10% 11% 9% 13%
x264 [info]: i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 13% 32% 7% 5% 8% 8% 9% 7% 11%
x264 [info]: i8c dc,h,v,p: 48% 26% 18% 7%
x264 [info]: ref P L0: 49.6% 28.6% 14.2% 4.7% 1.5% 1.4% 0.0% 0.0%
x264 [info]: ref B L0: 70.6% 23.8% 3.3% 1.9% 0.2% 0.2%
x264 [info]: ref B L1: 78.2% 20.3% 0.8% 0.7%
x264 [info]: kb/s:2439.41

encoded 989 frames, 1.42 fps, 2439.41 kb/s


Currently for best results it is recommended to use 2.7.45 and 2.7.45-fix1 in 4:4:4 mode only.

DTL
8th March 2023, 11:32
Updated fix02 - https://github.com/DTL2020/mvtools/releases/tag/r.2.7.45-fix02
Found some error in MAnalyse for 4:2:2 and added chroma shift fix to MCompensate to use in QTGMC and other MC-denoise scripts based on MCompensate.

zorr
8th March 2023, 23:08
Thanks DTL, your development of new MVTools features and fixes is impressive. Interesting that you found a bug with trymany=true as I've found sometimes trymany=false has the better quality even when it clearly shouldn't.

I haven't tested your version so far but might have some time to do some Zopti investigations. I'm mostly interested in the potential quality improvements of MAnalyse as I have a current use case for it and MCompensate.

Can you provide a list of the new parameters and perhaps a short explanation? That would help constructing appropriate Zopti scripts and make sure I don't miss anything relevant.

kedautinh12
8th March 2023, 23:13
I still don't use 2.7.46 ver of DTL cause many change in parameters will affect different result in many scripts base mvtools dependencies

DTL
8th March 2023, 23:46
"Interesting that you found a bug with trymany=true"

In my builds of post-2.7.45 in may be my own missing memory init when I add performance optimizations to MAnalyse (skipping already checked predictors positions). Somewhere around end of 2021. I not use trymany=true in that years so not found that bug. In versions 2.7.45 and before all predictors always checked so no need to fill the results vector for each predictor with some 'verybig cost' value because it will be overwritten. After optimization of skipping refining of already checked predictor - some memory were not updated and may keep better cost and result in not correct MV output.

" I'm mostly interested in the potential quality improvements of MAnalyse as I have a current use case for it and MCompensate."

Better check that approach - https://forum.doom9.org/showthread.php?p=1984140#post1984140 multi-generation MVs refining with intermediate denoising by MDegrainN. It gives most of MVs quality boost even at 2nd generation. And it also have main (and secondary) options to zopti-optimizing.

Main params of multi-generation MVs refining are thSAD of first and next MDegrainN. Secondary - may be MAnalyse for 1st and next generations. Currently I think we have too big step in quality after 1st generation and very few in 3 and next. May be better to have more slow quality gain at each generations and it may help to keep more details. So may be the thSAD for 1st MDegrainN may be reduced and the total thSAD(n) vector is subject to check for best quality.
Possible examples of thSAD(generation number) vectors:
1. Current large improvement after 1st generation (400, 200, 200, 200, 200) (result of gen2 is about good so may be used for better performance with stopping iterations after gen2)
2. Possible better quality (250, 240, 230, 220, 200) (result of gen2 lower in quality but gen5 may be better - may be used for better quality with lower performance)

"Can you provide a list of the new parameters and perhaps a short explanation?"

There were update of documentation: https://github.com/DTL2020/mvtools/blob/mvtools-pfmod/Documentation/mvtools2.html . Though still not all new params are listed - mostly about MPB-processing in MDegrainN (still in the very development and some may be removed in future). Also some features support only very few number of block size and bitdepth (other either slow in performance or even crash with error). Mostly checked is my typical used block size 8x8 and 8bit. I will try to add most of new params to March of 2023 to that documentation file soon.

Also there is significant difference already between 'very old 2.7.45' version and current post-2.7.45 builds in features list.

" That would help constructing appropriate Zopti scripts"

That may be complex task even for zopti-robot. Total number of params of MAnalyse+MDegrainN may be >50 now and quality-adjusting on per-scene basis may be >20.
If look into Interface.cpp file https://github.com/DTL2020/mvtools/blob/mvtools-pfmod/Sources/Interface.cpp
MAnalyse args[40]
c[blksize]i[blksizeV]i[levels]i[search]i[searchparam]i[pelsearch]i[isb]b[lambda]i[chroma]b[delta]i[truemotion]b[lsad]i[plevel]i[global]b[pnew]i[pzero]i[pglobal]i[overlap]i[overlapV]i
[outfile]s[dct]i[divide]i[sadx264]i[badSAD]i[badrange]i[isse]b[meander]b[temporal]b[trymany]b[multi]b[mt]b[scaleCSAD]i[optsearchoption]i[optpredictortype]i[scaleCSADfine]f
[accnum]i[UseSubShift]i[SuperCurrent]c[SearchDirMode]i[DMFlags]i

MDegrainN args[43]
ccci[thSAD]i[thSADC]i[plane]i[limit]f[limitC]f[thSCD1]i[thSCD2]i[isse]b[planar]b[lsb]b[thsad2]i[thsadc2]i[mt]b[out16]b[wpow]i[adjSADzeromv]f[adjSADcohmv]f[thCohMV]i
[MVLPFCutoff]f[MVLPFSlope]f[MVLPFGauss]f[thMVLPFCorr]i[adjSADLPFedmv]f[UseSubShift]i[IntOvlp]i[mvmultirs]c[thFWBWmvpos]i
[MPBthSub]i[MPBthAdd]i[MPBNumIt]i[MPB_SPCsub]f[MPB_SPCadd]f[MPB_PartBlend]b[MPBthIVS]i[showIVSmask]b[mvmultivs]c[MPB_DMFlags]i[MPBchroma]i[MPBtgtTR]i[MPB_MVlth]i

+MSuper
c[hpad]i[vpad]i[pel]i[levels]i[chroma]b[sharp]i[rfilter]i[pelclip]c[isse]b[planar]b[mt]b[pelrefine]b

Also MRecalculate may be useful in some scenarios - args[25].
cc[thsad]i[smooth]i[blksize]i[blksizeV]i[search]i[searchparam]i[lambda]i[chroma]b[truemotion]b[pnew]i[overlap]i[overlapV]i[outfile]s[dct]i[divide]i[sadx264]i[isse]b[meander]b[tr]i[mt]b[scaleCSAD]i[optsearchoption]i[optpredictortype]i[DMFlags]i
total is over 100. Thats huge. I understand why people like AI Neural Nework 'auto-magic' tools like RIFE with close to no one adjusting param.

Because MDegrainN is the only and main blending engine in latest 'multi-generation' MVs refining approach - all params of MDegrainN used for the intermediate super clips processing may affect the quality of final output MAnalyse MVs in a sequence.

" I have a current use case for it and MCompensate."

If your consumer filter is MCompensate with 2frames mvclip - you can change last MAnalyse in a multi-generation chain to 2-frames mode (multi=false and set isb and delta params).

Here is drawing how is macro-function of MultiGenerations MG-MAnalyse is designed (for 3 generations of MVs refining):
https://i.ibb.co/MsmVqnc/DSC-1091sm.jpg (https://ibb.co/80H5FMr)
Standard 2.7.45 mvtools MDegrainN output of single pass MAnalyse is 'g1'. Also MAnalyse of 2.7.45 is single input only for single super-clip. With post-2.7.45 builds 2-input MAnalyse used (Ref and Current super-clips inputs).
Each last output of MDegrainN may be used as degrained output or each last output of MAnalyse may be used as mv-clip for mvtools consumer filters.
MV3 out with SuperRef and SrcCurrent may be used with next MDegrainN for g3-degrained output and so on.

I think of creation of schematic drawing of internal MDegrainN design with internal processing and where different params are going. May be sometime later and in some CAD software (it will be large enough drawing).

The 'elementary building block' of in theory infinite generations MVs refinement is 'MDegrain+Super+MAnalyse'. It have inputs of mvclip, super_ref and src. Its output is refined mvclip in current generation.
So it can be designed in function for single step:

Function RefineMV(clip mvclip, clip super_ref, clip src)
{
g_next=MDegrainN(src, super_ref, mvclip, tr, thSAD=my_thSAD, thSAD2=my_thSAD2, mt=false, wpow=4, thSCD1=my_thSCD, \
adjSADzeromv=0.5, adjSADcohmv=0.5, thCohMV=16, MVLPFGauss=0.9, thMVLPFCorr=50, adjSADLPFedmv=0.9, IntOvlp=3)

super_g_next=MSuper(g_next,chroma=true, mt=false, pel=my_pel)

return=MAnalyse(super_g_next, SuperCurrent=super_ref, multi=true, delta=tr, search=3, searchparam=2, trymany=my_trymany, \
overlap=0, chroma=true, mt=false, optSearchOption=1, truemotion=false, pnew=my_pnew, pzero=my_pzero, pglobal=my_pglobal, \
global=my_global, levels=4, DMFlags=my_DMFlags, optPredictorType=my_oPT)
}

And usage:
my_src=last
s=Super(my_src)
mv1=MAnalyse(s)
mv2=RefineMV(mv1, s, my_src)
mv3=RefineMV(mv2, s, my_src)
mv4=RefineMV(mv3, s, my_src)
and so on


Also one more param to Zopti check may be tr for each generation. May be SuperCurrent may be named simply super2 because it may be no difference if it current or refs frames to search. Still not tested this idea.

zorr
10th March 2023, 01:17
" I'm mostly interested in the potential quality improvements of MAnalyse as I have a current use case for it and MCompensate."

Better check that approach - https://forum.doom9.org/showthread.php?p=1984140#post1984140 multi-generation MVs refining with intermediate denoising by MDegrainN. It gives most of MVs quality boost even at 2nd generation. And it also have main (and secondary) options to zopti-optimizing.

Will do, thanks. Do you think this way is better than the more traditional prefiltering with another denoiser? Have you done comparisons?

Also some features support only very few number of block size and bitdepth (other either slow in performance or even crash with error). Mostly checked is my typical used block size 8x8 and 8bit.

My preliminary tests indicate that block size 32 will work much better than 8, at least in the first phase before MRecalculate. Am I out of luck if I want to use that size? Are the limitations also in the CPU implementation or just the HW accelerated version? Also I recall someone mentioned the overlap of MAnalyse is not supported in all cases?

" That would help constructing appropriate Zopti scripts"

That may be complex task even for zopti-robot. Total number of params of MAnalyse+MDegrainN may be >50 now and quality-adjusting on per-scene basis may be >20.
...
total is over 100. Thats huge. I understand why people like AI Neural Nework 'auto-magic' tools like RIFE with close to no one adjusting param.


Yes, the number of parameters is inhumane. Zopti was created pretty much because I was frustrated with MVTools and wanted an easier way to tune it. So far it has fared well - even with around 50 parameters. It's just a matter of running with a large enough population and iterations. Sometimes I restrict the number of parameters by only optimizing a subset of them and then freezing some parameters and unlocking new ones. Some paramers don't benefit much from trying all possible values, for example you can test LSAD in increments of 100 or even bigger.

" I have a current use case for it and MCompensate."

If your consumer filter is MCompensate with 2frames mvclip - you can change last MAnalyse in a multi-generation chain to 2-frames mode (multi=false and set isb and delta params).

My use case is a bit special - I have two different videos and I want to match the other one to the first one by moulding it as closely as possible to resemble the first one but still maintaining its own characteristics like colours. The second video has pretty much no noise so I think I would only need to use this multi-generation MAnalyse on the first video and get a clean MSuper clip from it before I interleave it with the second video.

I think of creation of schematic drawing of internal MDegrainN design with internal processing and where different params are going. May be sometime later and in some CAD software (it will be large enough drawing).

That would certainly be interesting.

DTL
10th March 2023, 05:00
"Do you think this way is better than the more traditional prefiltering with another denoiser? Have you done comparisons?"

The denoiser for each generation may be not only MDegrain if apply previous generation MVs to the next generation denoiser. It is new way of MAnalyse with saving from accumulation of search errors. Still very few comparisons - only with user provided result in https://forum.doom9.org/showthread.php?p=1984142#post1984142 . I typically not use prefiltering because not found it useful. So do not have working scripts for compare.

"My preliminary tests indicate that block size 32 will work much better than 8, at least in the first phase before MRecalculate. Am I out of luck if I want to use that size?"

You may try. At least it is not have SIMD optimized dismetric (SSIM, VIF, covariance) and runtime subshifting functions because too large from SSE2 and AVX2 register file so only slow C-reference. But you can use standard SAD and standard MSuper pelrefining. I not test 32 block size.

"or just the HW accelerated version? "

DX12 search also not support 32 blocksize directly. Yon can only simulate it with feeding /4 divided frame size and setting blocksize of 8 and use MScaleVect after MAnalyse to scale resulted MVs to full frame size. Also may try MRecalculate or onCPU MAnalyse for refine.

"overlap of MAnalyse is not supported in all cases?"

Yes - overlap also not supported with DX12 search modes. There currenly interpolated overlap modes in MDegrain or you can simulate overlap (like diagonal 2x) with scripting - make 1/2 blocksize diagonally shifted copy of clip and use second MAnalyse to create second MVs clip and BlockOverlap pluging to combinr 2 MDegrain clips back.

"for example you can test LSAD in increments of 100 or even bigger."

Yes - some params are float point and need either some not very fine quantization to test not infinite number of points or approaching algorithm to iteratively go to best value like dividing quantization step 2 times around currently found best value.

Full working script example with refineMVs functions now in https://forum.doom9.org/showthread.php?p=1984176#post1984176

guest
10th March 2023, 13:03
I still don't use 2.7.46 ver of DTL cause many change in parameters will affect different result in many scripts base mvtools dependencies

Yes, I gave it a try today, and it doesn't work for me :(

DTL
10th March 2023, 16:03
Unfortunately it may be not compatible with many old scripts (because of still non-fixed bugs with different block sizes and may be something else). So it is no good to 'install to common plugins folder'. Only load from current working directory for current script.

It was expected pinterf will someday port most important and useful features to more official and final 2.7.46 update. Still waiting. At the begining of 2024 it looks we will have great all planet celebration of 20 years to mvtools so may be some more official release after 2.7.45 expected before January 2024. May be even great version change to 2.8.

Current list of ideas to try still not empty: There is an idea to add more predictors to MAnalyse - to fill big gap between near predictors and global motion predictor. Add 'area' predictors of the bestMV of closest blocks from all previous search levels and median of them. So in the 'all' predictors search mode (optPredictorType=0) area predictors check may be added without refine (and with trymany=true - with all refine) and in reduced predictors mode like (optPredictorType=1) only median predictor (with trymany=true - with refine around this predictor).

Addition: New strategic idea for 202x and later: For trymany=true the AVX2/AVX512 for exhaustive (search=3) may process >1 predictors at single SIMD pass and make significant benefit to current much slower trymany=true mode of MAnalyse. It is close to optSearchOption=3 and 4 idea. But for single current source block and different predictors.

joka
13th March 2023, 08:48
I want to re-write some scrips using "multi" Variants. Is there no "multi" MSCDetection? Any alternative / Work arround?

DTL
14th March 2023, 14:43
Yes - it looks MSCD can only accept single search pair mvclip. It is really only call to FakePlaneOfBlocks::IsSceneChange() via some steps. multi is a special mode for MAnalyse and I still do not have an ideas if it possible somehow easy to convert multi-mv-clip to pair-mv-clip. Though may be some playing with frame-rate/frame number may help.

In multi mode the MAnalyse select the pair to search and output using special conversion of requested frame number in the required pair:

const int ndiv = (_multi_flag) ? _delta_max * 2 : 1;
const int nsrc = n / ndiv;
const int srd_index = n % ndiv;


If multi enabled - ndiv=_delta_max*2, if disabled (standard pair) - it is 1.

So to request required pair of frame mvs from MAnalyse in multi-mode it required to calculate correct frame number to request and it will output the correct mv frame. But in AVS scripting it may be not very easy (I still not have ideas how to do it - may be play with FrameRate and so on).

Also: MDegrainN still not dead. Completely new processing mode is in development. It is finally motion to the object-oriented moving pictures reconstruction that was expected from AI/neural networks but still no working tools released.

Algorithm (for each block):
1. For the current input pool of blocks in tr-scope - find the most equally (the same) looking block and save it to local memory (with some surrounding area to have ability to perform motion compensation in limited MVs length). Standard thSAD threshold used to separate mostly likely equal blocks from significantly changed. Possible solution - simply save total frame where the 'best' block is found. But it will require very many RAM for storage unknown number of frames (max is total number of blocks in frame to have ability to compensate any MV length, but it looks very rarely required).

2. Analyse current tr-pool of blocks to found best in current pool (+-tr from current frame).

3. Compare best found block in 2. with stored in 1. for visual difference.

3.1. If visual difference (using available dis-metrics - SAD/SSIM/VIF or partial combinations) is below threshold - replace current frame block with stored block (make 100% curing operation).
3.2. If visual difference is above threshold (scenechange, object's view too much change) - replace stored block with current (or best looking in the pool) and output current (or best looked) block.

So for enough denoised clip with first MDegrainN pass it will convert slow motion and slow changed blocks in completely non-changed (with still ability to move around more or less far) and will significantly help to downstream MPEG encoder to mark these blocks as 100% motion compensated and 'skipped'. See skip %-stats in x264 output for example.

So it is threshold-based non-linear processing for complete cut-out of the residual temporal noise over a several frames in a sequence (up to total cut-scene duration).

Something like this already used in modern MPEG encoders (like 265 and may be others) but current implementation is to be used with all possible MPEG encoders like a pre-processing (from MPEG-1 and later). So it is designed to make widely used xvid/x.264 MPEG-4ASP/AVC releases better.

anton_foy
14th March 2023, 16:41
Also: MDegrainN still not dead. Completely new processing mode is in development. It is finally motion to the object-oriented moving pictures reconstruction that was expected from AI/neural networks but still no working tools released.
Have you watched Vcmohan's neuralnet and other plugins? He told me that they could help finding temporal differences too. PM him maybe?

Edit: I think now it is called "neural" in "manyPlus" package.

DTL
14th March 2023, 19:27
" they could help finding temporal differences "

The task for AI robot denoiser is really very very simple: Using input noised frames sequence _understand_ the scene content (objects, textures, transformations, lighting), create best possible clean textures for all scene objects and simply create scene from scratch using textures and lighting and objects transformations without adding inter-frame noise.

So the main task of denoising is not looking for input noise - it is about looking for clean objects textures (real clean object's views) and simply creating output frames using restored clean textures.

The described above algorithm is some step to 'ideal AI denosier'. It have all elements of this processing: Method to create as clean and as true as possible texture of a block and to create new output frame sequence using only restored textures (if possible without significant distortions).

The main issue of 'linear' MDegrainN processing (it is sort of FIR filter now) - it can not reach non-changing output frame sequence even with large enough and slow in processing tr-value and big thSAD value because at each output frame the total tr-pool of frames advances +1 frame in the input frame sequence so it lost 1 last frame and add 1 next frame and even ideal average blending process will typically create slightly different block result even for ideally motion compensated blocks.
So to create some temporal-thresholding (non-linearity at small enough temporal differences) it is require addition of internal memory for the previous frame output block and some estimatie and resolve algorithm about keep output old block or select new. It looks like IIR filter with possibility to infinite output single and completely same block if some conditions met.

Addition:

First idea about noise measurement: The typical PSNR-type is not work well with very low noise levels still critical to MPEG encoders with high and very high compression ratios (about 1000:1).

So suggested temporal noise measurement in noise-bitrate. In noise bits per second.
Calculation:
Nnps x Ns x FPS
where:
Nnps - number of noise bits per sample
Ns - number of samples in frame (width x height)
FPS - number of frames per second.

So for the 1noise bit per each sample (very close to quantization noise) giving PSNR high above 40 dB the nosie-bitrate for FullHD is still about 50 Mbit/s and MPEG encoder can not go significantly lower in output bitrate without significant distortions. It is also remarkable this noise-bitrate is not depend on bitdepth (so equal in relative amplitude 10bit noise bitrate to 8bit is about 4 times larger). Single frame sequence like Trim(1,1).Loop() have a temporal noise bitrate of true zero.

And 1noise bit per 8bit image already look as 'visually noiseless'. But for MPEG encoder it is still very loaded with bad noise. So much higher denoise ratios required to finally put noise-bitrate good below target MPEG output bitrate (with good enough quality CRF-encoding). So much denoise ratios looks like impossible to reach with 'linear' denoise modes of MDegrainN.

Now made an encoding test: For static camera scene from documentary title with sitting and talking person taking about 10..20% of total frame samples in 1920x1080i 25fps, x264 crf=18 encoding:

After 'visually noiseless' MDegrainN denoising -
2427 Kbit/s,
mb P skip: 40.9%
mb B skip: 76.2%

After creating 1bit BW mask in MS Paint masking talking person with white and all other (about 80% frame) in black and simple scripting:

mask_clip=ImageReader("mask.bmp")
bckgr=Trim(1,1)
bckgr=Loop(bckgr,1000)

Overlay(bckgr, last, mask=mask_clip)


1383 Kbit/s
mb P skip: 85.2%
mp B skip: 93.2%


So with completely static background the number of skipped blocks in MPEG encoder is significantly higher and output bitrate is about 75% lower.

Attempt to apply internal noise-reduction of x264 --nr=600:
1647 K
mb P skip: 37.1%
mb B skip: 77.5%

So even high enough noise-reduction setting for x264 encode can not reach such high skip ratio and so low output bitrate as possible with total block-duplication for non-changed blocks of static parts of the scene.

", the number of parameters is inhumane. "

It is still not very inhumane - it is only some progress from simple denoise application to mv-search engine to more advanced tool. There possible to design control console like that for colour grading pro-work to make realtime adjustments easier (for example some Davinchi products have dedicated hardware control consoles). It is like
https://i.ibb.co/9sNgp7d/mvtools-progr01.jpg (https://ibb.co/V2t9Lsk)

flossy_cake
8th April 2023, 07:17
Is it possible to have MVTools output a single floating point value somewhere that defines the overall amount of motion in the scene? I want to use this value in a ScriptClip.

Currently I am using YDiff and/or weighted YUVDiff (like what RT_FrameDifference uses) but I'm finding at times it's not very accurate because of what's in the frame - high APL panning tends to generate higher values, low APL lower values, plus some randomness of the image contents of the frame, eg. if new bright or dark or differently shaped objects are on screen then that could result in a much higher/lower value despite the motion speed being the same.

Thanks

DTL
8th April 2023, 12:02
There is some hacky way - convert mvclip to 'frame-clip' (MStoreVect()) and pick dx,dy MVs values for analysis using samples-picking in scripting (also SAD or other dismetric is available). Or some filter redesign required to calculate required value and put to some script-readable form.

It is also way to detect dupe frames - if MStoreVect (cropped-out first line with header data) return 0% zero black frame - it mean all dx=dy=SAD=0 (frames equal).

flossy_cake
23rd April 2023, 20:35
There is some hacky way - convert mvclip to 'frame-clip' (MStoreVect()) and pick dx,dy MVs values for analysis using samples-picking in scripting (also SAD or other dismetric is available). Or some filter redesign required to calculate required value and put to some script-readable form.

It is also way to detect dupe frames - if MStoreVect (cropped-out first line with header data) return 0% zero black frame - it mean all dx=dy=SAD=0 (frames equal).

Thanks, but I couldn't figure it out. Seems to require 2 passes?

For now I'm using CFrameDiff which is ok - more consistent than YUVDiff in that it still detects motion even when APL is the same. Because of this it's not as good for detecting scenechanges - YUVDiff seems better for that imo. But for motion CFrameDiff is probably the best cheap, fast solution. Some useful thresholds seem to be 0-10=very low motion, 10-25=low motion, 25-45=normal motion, >45=high motion. It also has a fast denoising option in case noise somehow interferes with the metrics.

DTL
24th April 2023, 05:50
" require 2 passes?"

No. MAnalyse return MVs data for current stream processed. So you can request any 2 frames from current clip MV analysis at any current frame in clip processing (typically current frame and some other frame, but it may be possible to request any 2 frames from clip - not only current + other).

If you need scenechange detection - it may be not good idea with mvtools. It sort of not search MV data over scenechange at all (it try but result is very bad). The scenechange detection in mvtools is poor enough. It simply look on 'quality of MVs' data as best dismetric over found blocks and if it is very bad over most of frame - it looks like attempt to search for motion over scenechange point in time axis. So may be no great difference in mean MV with static frames of single scene or many random very bad MVs over scenechange. Also mvtools have already implemented very simple filter like MSCDetect that simply output bool flag from internal scenechange detector used by may be all other internal mvtools filters based on SAD/dismetric analysis as described (using 'global' thSCD1 and thSCD2 values).

Also if you like to implement different algorithm for scenechange detection in scripting - you can also grab SAD/dismetric for each block form pseudo-frame clip output by MStoreVect and try to make your own math analysis.

Also for scenechange detection you can try to use any full-ref image quality analysis tools with 2-frames input (like PSNR/SAD/SSIM/VIF/many_other). If the sim/dissim metric over checked pair of frames is very bad - so it looks like frames from different scenes.

If you try to detect scenechange from MV data it may be same task as currently attempt to implement in MPB detector of 'stable MV data' over time axis. But it is much more complex in compare with simple mean value. If MV data is very bad it mean MVs have and random lengths and random directions (angles). So the algorithm for detection if MVs data is very bad and unnatural for typical good intrascene search need to separate many co-directed MVs in areas from mostly random directed MVs in very noisy and low detailed areas or scenechanges. It sort of measuring noise-level in dx/dy data over total set of MVs from single frame pair search. May be even making Fourier domain transform and analyse the shape of Fourier spectrum - for random white nosie it sort of equal-energy over all valid frequencies and for natural motion it may be mostly low-frequencies energy located. But also total length of MVs must be analysed (for single scene and simple dark frame with noise the MVs typically random too). So advanced scenechange detector may be very complex and math and computing loaded and slow.

I also not understand what you need to measure in motion. The mean MV is sort of global MV vector and it close to zero length for different cases (like random noised static scene and also static clean scene). May be you need mean of MVs length in the current pairs of frames analysed ? It may show some measure of motion in a frame, but for static scene with noise it will also correlate with simple noise level if noise is comparable or more of the real scene objects contrast. So for better motion measure the MVs data may be need to be processed with sort of area-based low-pass filtering to found noise-cleaned areas mean MVs at first.

flossy_cake
24th April 2023, 18:33
May be you need mean of MVs length in the current pairs of frames analysed ?

Yes, I think so. I am just trying to get a number which describes how much motion there is between 2 frames. Bigger number = more motion, smaller number = less motion. I need the result to be accessible in an Avisynth script variable so I can make conditional decisions on it in the rest of my script - I am not sure if MVTools was designed for this. Looking at the wiki, it seems MVTools stores all the motion vector information in its own bespoke format which can only be used with other modules of the MVTools package. Or perhaps it can be output to a file on disk and then read that information back in from file in realtime.

DTL
24th April 2023, 23:20
You can simply make 2 frames equal (Trim(1,1).Loop()) and after MAnalyse put MStoreVect() and look into output clip in 2D viewer with RGB values display for each sample. Try to use some simple sample format like RGB24. After some header in the first line you will see 0,0,0 for each dx,dy,SAD because frames are equal and no motion.

Now take first (top-left) block of size set in MAnalyse and shift to 1 sample left, right, top, bottom and see how RGB data changes. The blocks scanned from left to right and from top to bottom of frame. So you can found where header data ends and simple contigous list of VECTOR data starts and where 1st block data starts. The data is of 32bit integers so takes 4x8bit values. So you collect RGB triplets from frame returned by MStoreVect in script environment and decode it into 2D array of blocks with their VECTOR structure data (dx, dy, SAD). And use dx and dy to calculate each MV length (or squared to be faster and not take square root of slow op) - Length^2 = dx^2 + dy^2. And calculate mean value of MV length over all blocks in frame (width/blocksizeH x height/blocksizeV).

The analysis data header is fixed and the w and h size of the encoded frame is selected by some algorithm. You can skip header fixed and the rest should be 3x32bit VECTOR data for all blocks. If clip sample format is RGB24 these 32bit values are shifted over RGB24 samples and if set to RGB32 - you may be (or not) lucky to get each dx, dy and SAD into RGB32 sample data or each data will have equal start shift by 8bits.

If someone can access sample data from frame (Eval ? or some other function) - he can make simple enough decoder script to get each block VECTOR data from clip produced my MStoreVect(). And make math calculations with dx,dy and SAD data.

The only helper filter for script writers may be created to make 1st line with header data fixed and start 2nd (or other line if blocks number in line is too small) line in RGB32 format from dx data of 1st block in the frame and so on, So the width of a pseudo-clip frame will be number of blocks in line x 3x32bit data (x3 RGB32). So for 1920 width clip and 8x8 block size blocks number per line is 240 and width of MStoreNiceVect will be 240x3=720 and each RGB32 4bytes samples value will keep dx, dy, SAD values for blocks (VECTOR structure for each block). And number or rows (skipping header-row(s)) will be equal to V-number of blocks. It will make script-decoder more simple.

anton_foy
7th June 2023, 15:57
request:
A "Threshold" option.
Very often denosing/degraining needs to be stronger in the darker parts (heavier nosie) and less in the brighter ones (lighter noise).
It would be incredibly benificial IMHO to have this option as a limiter of strength when setting a threshold. From default 1.0 to 0.0 or 255-0 or so.
Preferably a soft threshold like a roll-off curve rather than a hard pointy one.

This can already be achived externally but it is very slow and if made internally in mvtools I think it could be much faster in speed.

example:

bright=smdegrain(tr=3,thsad=200)
dark=smdegrain(tr=7,thsad=500)
mask=levels(32,1.0,190,0,255)
mt_merge(dark, bright, mask)

or a simpler limiting example:

original=last
dark=smdegrain(tr=7,thsad=500)
mask=levels(32,1.0,190,0,200) #merge back some denoised together with original by adding 200 on the last param for better visual appearence.
mt_merge(dark, original, mask)

By now I hope I made my idea clear.
A threshold parameter (max 1.0 min 0.0 or 255-0 to adjust how bright it should limit degraining) and a thresholdlimit/thresholdstrength parameter (max 1.0 min 0.0 to adjust strength of degrain in the thresholded areas).
Strength of degraining/denoising can be argued if to blend with the original (simplest but less visually appealing) or to somehow "choke" the strength like rgtools repair or the "limit" parameter in mvtools (although the current parameter limit=1 seems not to lower the degraining very much?).

Pinterf what do you think about this?:)

Thanks!

DTL
7th June 2023, 17:19
Short answer (long may be later):

I think you can start from moving 1 level of AVS usage lower at first: Not level of user-provided script function (SMDegrain) but level of manual script writing using plugin functions.

Most quality (per-sample level) can run only at after-MDegrainX processing. So it is not very benefitical in performance to implement user-script in plugin.

Current suggestion:

Put this idea:
bright=smdegrain(tr=3,thsad=200)
dark=smdegrain(tr=7,thsad=500)
mask=levels(32,1.0,190,0,255)
mt_merge(dark, bright, mask)

In manual script (or ask Dogway to add to SMDegrain):

MDegrainN can run at provided tr-value (if not - it can be easily fixed).

So you better in performance is simply run 1 MAnalyse and several MDegrainN and combine in several layers with masking.

Some like:

super=MSuper()
mv=MAnalyse(tr=max(my_tr1, my_tr2),..)

dg1=MDegrainN(super, mv, tr=my_tr1, thSAD=my_thSAD1)
dg2=MDegrainN(super, mv, tr=my_tr2, thSAD=my_thSAD2)

mask=MyCustonMaskFunc(...)
mt_merge(dark, dg1, dg2)



It will be better in performance because of 1 MAnalyse with max_tr only. Typically MAnalyse is most of time-taking process.

anton_foy
7th June 2023, 17:54
Short answer (long may be later):

I think you can start from moving 1 level of AVS usage lower at first: Not level of user-provided script function (SMDegrain) but level of manual script writing using plugin functions.

Most quality (per-sample level) can run only at after-MDegrainX processing. So it is not very benefitical in performance to implement user-script in plugin.

Current suggestion:

Put this idea:
bright=smdegrain(tr=3,thsad=200)
dark=smdegrain(tr=7,thsad=500)
mask=levels(32,1.0,190,0,255)
mt_merge(dark, bright, mask)

In manual script (or ask Dogway to add to SMDegrain):

MDegrainN can run at provided tr-value (if not - it can be easily fixed).

So you better in performance is simply run 1 MAnalyse and several MDegrainN and combine in several layers with masking.

Some like:

super=MSuper()
mv=MAnalyse(tr=max(my_tr1, my_tr2),..)

dg1=MDegrainN(super, mv, tr=my_tr1, thSAD=my_thSAD1)
dg2=MDegrainN(super, mv, tr=my_tr2, thSAD=my_thSAD2)

mask=MyCustonMaskFunc(...)
mt_merge(dark, dg1, dg2)



It will be better in performance because of 1 MAnalyse with max_tr only. Typically MAnalyse is most of time-taking process.

Aaah so clever! Of course this is a great idea thank you. So to implement this into mvtools internally would not be faster you think?

Edit:
I did not know this was possible:
mv=MAnalyse(tr=max(my_tr1, my_tr2),..)

Great, I think actually this will help many in retaining more of the original detail where grain/noise is not as heavy in the highlights.

DTL
7th June 2023, 20:15
"this was possible:
Quote:
mv=MAnalyse(tr=max(my_tr1, my_tr2),..)"

Well - it is at least must be possible by logic of mvtools plugins but currently may still not work as it should. But it is really very small fix and the most probable pinterf will agree it.

Current status: If tr of MAnalyse != tr of MDegrainN it may cause MVs frame request mismatch because the requesting pseudo-frame number from MDegrainN to MAnalyse is about current_frame x 2 x tr. So the logic in MAnalyse in multi=true decode required current + ref frame pair to search from N frame requested + multi-flag + tr-provided. If tr of MAnalyse and tr of MDegrainN not match - it currently looks cause not correct processing.

But as I see pinterf already add analysis_data structure to MVclip and if it have (easy to add) the MAnalyse tr-value and take it in MDegrainN - the MDegrainN can encode proper N-frame number to request if even tr-value of MAnalyse and MDegrainN not equal.

" to implement this into mvtools internally would not be faster you think?"

It will be somehow faster because of more processing with single memory read-write data. But to implement it - the completely separate processing mode in MDegrainN need to be added. To make dual-tr and dual-thSADs blocks processing and some blending/mixer based on the internal or better external mask clip provided. Also 2.7.45 MDegrainN have only separated processing functions for luma and chroma planes (so need to double number of processing functions). Or attempt to make even more complex one_for_all (templated for better performance ?) processing function of single and dual params processing depending of the current running MDegrainN mode.

It require to add lots of new control params to MDegraiN like:
1. Enable/disable new mode
2. Input mask clip (Y8 ? Y16 ?) param
3. tr2
4. thSAD_second (+Chroma)
5. thSAD2_second (+Chroma)
6.... - really many of possible MDegrainN params need to be doubled (also added in possibly ported features from my post-2.7.45 builds).

So it currently much more easier to implement it as 1 MAnalyse + 2 (or more MDegrainN) and custom mask engine + some blending engine in scripting. It is a completely new mode to test and typically only if most users will like to use it for (months ? years ? decades ?) it possibly may be put to compiled form (also with possible minimul new params or some selected params by users practic accumulated in months/years/decades of scripted form usage).

The only simple fix reqiured to run several MDegrainN with different tr-value using single MAnalyse source. It is really benefitical in performance if (!?!) AVS core will cache already requested MVs frames to 2 or more MDegrainN filters running after single MAnalyse MVs-source. But AVS cache around MAnalyse source may be one more unknown variable - it may be limited to some tr-values only and depend on Prefetch() local and/or global script settings ? I not sure how many MV-frames after MAnalyse will be cached depending on AVS core settings and may be other config params somewhere. But may be for tr=3 all required MV-frames will be cached at most of use cases.

" a simpler limiting example:
Code:
original=last
dark=smdegrain(tr=7,thsad=500)
mask=levels(32,1.0,190,0,200) #merge back some denoised together with original by adding 200 on the last param for better visual appearence.
mt_merge(dark, original, mask)"

This idea may be easier to add as new post-processing engine in addition to 'limit' current post-processing. So it may be programmed as separated module and not touch internal MDegrainN core (of any version). But it may be somehow (may be much) worse in quality in compare with dual-MDegrainN runs with different sets of params. Also may be better to add new input clip param of mask from external mask source (so user will not be limited with internal masking only). But also it may be not significantly faster (additional postprocessing pass really again read-write all frame memory) and only may save some RAM in AVS caching.

anton_foy
7th June 2023, 21:00
It require to add lots of new control params to MDegraiN like:
1. Enable/disable new mode
2. Input mask clip (Y8 ? Y16 ?) param
3. tr2
4. thSAD_second (+Chroma)
5. thSAD2_second (+Chroma)
6.... - really many of possible MDegrainN params need to be doubled (also added in possibly ported features from my post-2.7.45 builds).

Sure there could be alot of params depending on this but as I figure only "tr" would suffice. Maybe "thSAD" aswell but I do not think it is needed. But even the limiting by merging the original with mdegrain by a brightness threshold would be great. As you say, the best quality would be two different mdegrain calls merged, yet I have to try the benchmarks to see if it will be alot slower than only one mdegrain call.

Edit: and there is already mmask in mvtools, so why not lumamask :D

DTL
7th June 2023, 21:55
"Maybe "thSAD" aswell but I do not think it is needed."

It is typically still work as major protection from too bad blends (causing blurring) where transform compensation is not perfect. So at the lower-nosied medium and high code values it is expected to have both lower tr and lower thSAD - so it will save more details from typicaly possible blurring.

anton_foy
7th June 2023, 22:49
"Maybe "thSAD" aswell but I do not think it is needed."

It is typically still work as major protection from too bad blends (causing blurring) where transform compensation is not perfect. So at the lower-nosied medium and high code values it is expected to have both lower tr and lower thSAD - so it will save more details from typicaly possible blurring.

Okay fair enough :)

DTL
8th June 2023, 07:57
One more idea with possibly fastest implementation in processing and simple enough in design:

If quality of block-based weighting of current (source, full input noise and details) frame in output blending result will be acceptable - it can be added reading of simple one more input mask clip (in full-frame size or blocks number H and V size only) and simply additionally correct central/current block weight in blending weights after DegrainWeight() call and before normal_weights() call. The correction may be inverse multiplication of all ref-frames blocks between current weight after DegrainWeight() call and zero weights. So in mask clip range 255..0 may be mapped to 1.0..0 float additional multiplier to all ref-frames weights except current frame weight. (May be with additional check if current frame weight !=0). So if mask is 0 - all ref frames weight will be put to zero and norm_weights() will set current frame block only to output (non-changed input). It will make close to zero penalty to performance and keep total implementation very simple.

Also it will make MDegrainN more flexible to use in complex scripts - it someone can make mask of badly blurred areas (blocks) - this mask can be applied as additional input to fix weights of badly transform-compensated ref frames and cure these areas from blurring at next MDegrainN processing (or at final output if mask will be ready before it).

It will be close to

original=last
dark=smdegrain(tr=7,thsad=500)
mask=levels(32,1.0,190,0,200) #merge back some denoised together with original by adding 200 on the last param for better visual appearence.
mt_merge(dark, original, mask)

processing but block-based (not sample-based).

(Registered as feature number 44 in my list of post-2.7.45 build features).

anton_foy
8th June 2023, 08:21
One more idea with possibly fastest implementation in processing and simple enough in design:

If quality of block-based weighting of current (source, full input noise and details) frame in output blending result will be acceptable - it can be added reading of simple one more input mask clip (in full-frame size or blocks number H and V size only) and simply additionally correct central/current block weight in blending weights after DegrainWeight() call and before normal_weights() call. The correction may be inverse multiplication of all ref-frames blocks between current weight after DegrainWeight() call and zero weights. So in mask clip range 255..0 may be mapped to 1.0..0 float additional multiplier to all ref-frames weights except current frame weight. (May be with additional check if current frame weight !=0). So if mask is 0 - all ref frames weight will be put to zero and norm_weights() will set current frame block only to output (non-changed input). It will make close to zero penalty to performance and keep total implementation very simple.

Also it will make MDegrainN more flexible to use in complex scripts - it someone can make mask of badly blurred areas (blocks) - this mask can be applied as additional input to fix weights of badly transform-compensated ref frames and cure these areas from blurring at next MDegrainN processing (or at final output if mask will be ready before it).

It will be close to

original=last
dark=smdegrain(tr=7,thsad=500)
mask=levels(32,1.0,190,0,200) #merge back some denoised together with original by adding 200 on the last param for better visual appearence.
mt_merge(dark, original, mask)

processing but block-based (not sample-based).

(Registered as feature number 44 in my list of post-2.7.45 build features).

Great idea. So that could minimize the need for time consuming 2nd+ generation of mdegrain by instead merging it as you explain?

DTL
8th June 2023, 12:18
It is single pass MDegrainN as it run today. But it still require some external engine to generate mask clip. Simple mask may be inverted Y channel (and for best performance first downsize to H and V block numbers size). Having block-number sized mask clip also skips possible questions about sample value to use if several samples per block provided. So may be put strict requirement for mask clip to be sized of H and V blocks number. So single Y8 sample per block to use.

In the above examples the 2nd MdegrainN is not 2nd generation - is 2nd parallel running with single MVs source. But that method expected to provide better quality.

anton_foy
8th June 2023, 19:15
It is single pass MDegrainN as it run today. But it still require some external engine to generate mask clip. Simple mask may be inverted Y channel (and for best performance first downsize to H and V block numbers size). Having block-number sized mask clip also skips possible questions about sample value to use if several samples per block provided. So may be put strict requirement for mask clip to be sized of H and V blocks number. So single Y8 sample per block to use.

In the above examples the 2nd MdegrainN is not 2nd generation - is 2nd parallel running with single MVs source. But that method expected to provide better quality.

Yes I see but still gains better quality and you agree the blending/merging is a great feature to implement?
Yet it can even be 2 mdegrain calls stacked to get 2nd generation while a brighter is only using 1st gen to use for the brights?

DTL
9th June 2023, 04:55
"Yes I see but still gains better quality and you agree the blending/merging is a great feature to implement?"

I agree it can be useful feature to implement.

"Yet it can even be 2 mdegrain calls stacked to get 2nd generation while a brighter is only using 1st gen to use for the brights?"

Yes - we can serialize 2 mdegrains with single MV source and different params and use 1st and last output as inputs to some weighted mixer. There are many ways to implement required processing and it is better to test first in easy to design scripting form the good or better in quality.

Fjord
13th September 2023, 15:50
@DTL: Thanks for your development work on MVTools!

Will your multi-generation MV approach work with the existing v2.7.45 MVTools? Or are new processing and/or parameters in your v2.7.46_xxx work-in-progress essential for multi-generation MVs to work?

Your "RefineMV()" function includes new parameters in calls to MDegrainN() and MAnalyse() - such as wpow, adjSADzeromv, adjSADcohmv, ... I can see the variable types in interface.cpp on github, and mention of some of them in your new_features_list.ods spreadsheet, but I haven't yet found any description of these new parameters (purpose, valid values, default value). Do you have some basic description for your new parameters somewhere that I have missed?

I have only tried your latest release v2.7.46_e.02.zip (dated 20230811), with understanding this only contains "compatible" changes to v2.7.45 version. Apparently _e.02 does not include the new parameters used in your multi-generation MV approach, since I get avisynth script errors like "MAnalyse does not have a named argument "optSearchOption".

I have 2k 10-bit YUV422 source videos (high-noise/grain film scans), where BlkSize 32 and 64 are actually useful. But from reading your posts I understand you have only implemented 8-bit operations with 8x8 Blksize. Is that correct? If so I need to stay with MVTools v2.7.45. (and that is why I ask if multi-generation MV approach will work with pinterf's release.) My application uses MCompensate() where refined MVs might help.

DTL
13th September 2023, 17:52
"Will your multi-generation MV approach work with the existing v2.7.45 MVTools? "

Possibly not because it is based on MAnalyse with separated inputs for current and ref clips (frames).

In august 2023 I made some special builds tagged as 2.7.46-e.xx - they are based on the latest sources from the pinterf repository (with some commits after 2.7.45 release) and included very few of new and important features. Latest is e.02 - https://github.com/DTL2020/mvtools/releases . So expected to be stable close to 2.7.45 release and have some few possibly not critical to stability features. It has SuperCurrent input for MAnalyse so can be used in multi-generation approach as described.

"Or are new processing and/or parameters in your v2.7.46_xxx work-in-progress essential for multi-generation MVs to work?"

Most important feature is the dual-input MAnalyse filter. Other features of post-2.7.45 builds may add to quality (like MVLPF processing) but not act as the key component of the multi-generation refining idea.

"Your "RefineMV()" function includes new parameters in calls to MDegrainN() and MAnalyse() - such as wpow, adjSADzeromv, adjSADcohmv, ... I can see the variable types in interface.cpp on github, and mention of some of them in your new_features_list.ods spreadsheet, but I haven't yet found any description of these new parameters (purpose, valid values, default value). Do you have some basic description for your new parameters somewhere that I have missed?"

I made some update of HTML documentation but it still not include all latest features added - https://github.com/DTL2020/mvtools/blob/mvtools-pfmod/Documentation/mvtools2.html . Also typically every new added param described in the release description where it was added. So one way to found at least short description is to look into every release description also some extended description sometime added in the posts in the thread with new releases announce - https://forum.doom9.org/showthread.php?t=183517

"I have only tried your latest release v2.7.46_e.02.zip (dated 20230811), with understanding this only contains "compatible" changes to v2.7.45 version. Apparently _e.02 does not include the new parameters used in your multi-generation MV approach, since I get avisynth script errors like "MAnalyse does not have a named argument "optSearchOption"."

You can skip all new params except supercurrent clip for MAnalyse.

"only implemented 8-bit operations with 8x8 Blksize. "

Some of the many new features have only implementation or SIMD faster implementation or were tested with 8x8 block size and 8bit. To display all new features and compatibility with different blocksize/bitdepth combinations someone needs to build a table of current state.
The only required for multi-generation approach feature of dual-input MAnalyse (added SuperCurrent clip input) expected to be compatible with any blocksize/bitdepth.

Expected smallest working RefineMV() function with e.02 build is

Function RefineMV(clip mvclip, clip super_ref, clip src)
{
g_next=MDegrainN(src, super_ref, mvclip, tr, thSAD=my_thSAD, thSAD2=my_thSAD2, mt=false, thSCD1=my_thSCD)

super_g_next=MSuper(g_next,chroma=true, mt=false, pel=my_pel)

return=MAnalyse(super_g_next, SuperCurrent=super_ref, multi=true, delta=tr, search=3, searchparam=2, trymany=my_trymany, \
overlap=0, chroma=true, mt=false, truemotion=false, pnew=my_pnew, pzero=my_pzero, pglobal=my_pglobal, global=my_global)
}

And usage:
my_src=last
s=Super(my_src)
mv1=MAnalyse(s)
mv2=RefineMV(mv1, s, my_src)
and so on


"(high-noise/grain film scans), where BlkSize 32 and 64 are actually useful"

I think 'large' blocksizes really works better on film scans because typically they are not only grainy but also very soft. So blocksize 8x8 have too few details to use in good search. And the higher the filmscan resolution the more softer the digital result (and larger blocksize recommended). But for refining of motion after first search stages with large blocksize - the refining MVs with MRecalculate to lower blocksize may be recommended.

Fjord
14th September 2023, 10:16
Thanks DTL for the detailed reply. I will look at your revised MVTools2.html and file history for info on new features and parameters.

Thanks for the minimal multi-generation MV script, for your v2.7.46_e.02 (20230811) release. I will give it a try.

DTL
14th September 2023, 10:24
"and file history for info on new features and parameters."

It looks I was lazy to put description in single history file - so only available in github releases description (in each version release). https://github.com/DTL2020/mvtools/releases . Will try to collect descriptions from each release in single history file later.

In the script example my_* params are script 'globals' - I found them useful when adjusting MAnalsye for degraining. Also overlap may be set to > 0 for better quality (and even lower performance). I left overlap=0 from my newer versions where I use interpolated overlap in MDegrainN. Really best quality is with full 'real' 4x overlap in MAnalyse (when overlap = bloksize/2).

With high quality settings like trymany=true and overlap=4 (and blksize default of 8x8) even 2 generatins of MVs (single RefineMV call) takes about 10 days of processing 2 hours FullHD film at i5-9600K CPU. And onCPU MAnalyse gives better quality in compare with hardware from GTX1060 card.

Also remember the MAnalyse in refining stages with partially degrained one of 2 input clips gives lower SAD values so the last MDegrainN (or even each next RefineMV call if several present) need to have lower thSAD values for MDegrainN to keep from more blurring. Here the new Auto-thSAD feature for MDegrainN expected to make good help. See example in https://forum.doom9.org/showthread.php?p=1990642#post1990642

Fjord
15th September 2023, 08:32
@DTL - I copied all your release descriptions into a Word document for my own reference. I sent you a PM with a link to it.

DTL
15th September 2023, 11:55
I added file to github.

Current research question for multi-generation MVs refining (at least using MDegrainN only - not with external denoisers as prefilters):

Is usage of several generations with slow increasing of denoise params produces better MVs in comparison with simple 2 stages with full power denoise params ?

It requires lots of test runs and checks for quality.

Example pseudo-scripts:
1. 2 stages full power denoise in each:

my_src=last
s=Super(my_src)
mv1=MAnalyse(s)
mv2=RefineMV(mv1, s, my_src) // tr=12, thSAD_a=1.3 for MAnalyse/MDegrainN in RefineMV()
final_denoise=MDegrainN(my_src, s, mv2,..) // tr=12, thSAD_a=1.3 for MDegrainN in last output denoise



2. example of several stages with slow incresing of denoise params in refining stages

my_src=last
s=Super(my_src)
mv1=MAnalyse(s)
mv2=RefineMV(mv1, s, my_src) // tr=1, thSAD_a=0.9 for MAnalyse/MDegrainN in RefineMV()
mv3=RefineMV(mv2, s, my_src) // tr=3, thSAD_a=0.9 for MAnalyse/MDegrainN in RefineMV()
mv4=RefineMV(mv3, s, my_src) // tr=6, thSAD_a=1.0 for MAnalyse/MDegrainN in RefineMV()
mv5=RefineMV(mv4, s, my_src) // tr=12, thSAD_a=1.3 for MAnalyse/MDegrainN in RefineMV()
final_denoise=MDegrainN(my_src, s, mv5,..) // tr=12, thSAD_a=1.3 for MDegrainN in last output denoise


better to supplement RefineMV() script with user-provided arguments of tr and thSAD* (_a) params.

Current idea for many generations refining - the first generations of internal degrain with low degrain params (low tr and low thSAD) may lower degrade/blur details so may save more MVs from errors in first stages and provide more correct intermediate denoised clip for next stages of MAnalyse. But this idea check may require lots of test runs.

tormento
5th October 2023, 09:22
I added file to github.
Would you please keep on releasing AVX version too?

My PC is quite old and can't deal with AVX2. :p

DTL
5th October 2023, 15:07
Here is next release build of possbly stable and compatible -e.xx branch - https://github.com/DTL2020/mvtools/releases/tag/r.2.7.46-e.03 . Also merged partial fix for unbiased division when work with subsampled colour formats (from Fix02 release of Mar 08 2023). Included SSE2, AVX and AVX2 targeted builds.

tormento
5th October 2023, 16:30
Here is next release build
Thank you!

Could you release AVX DirectX12 build too?

DTL
5th October 2023, 20:17
I found that branch builds looks like cause process memory corruption and it cause crash in random modules (like ffms2 or AVS core and so on). Will try to found and fix source of the bug.

tormento
6th October 2023, 14:01
I found that branch builds looks like cause process memory corruption and it cause crash in random modules (like ffms2 or AVS core and so on). Will try to found and fix source of the bug.
Never had a problem with previous preview version.

How to reproduce?

DTL
23rd January 2024, 23:22
It looks like we finally have 20-years of MVtools. The first release dated from 0.1-0.6 - 24.01.2004 - 01.04.2004 by Manao. First versions of MotionVectors (Motion.dll).

Still lots of ideas to implement waiting for developers.

FranceBB
24th January 2024, 00:12
Oh! It's 20 years already! You're right!
Happy 20th Birthday MVTools!! :D

https://i.imgur.com/0XyxBBJ.png

MVTools has come a long way and it's used pretty much everywhere and it's the core behind so so so many things, be it for linear interpolation or temporal degrain or quite literally any use of Motion Compensation vectors.
A big fat thank you to everyone who worked on this including Manao, Fizick, Tsp, TSchniede, DTL, Pinterf and of course to the wider open source community! :D

pinterf
3rd May 2024, 11:28
Here is a 2024 version of the good old basic mvtools2 and its DePan companions.

Download mvtools2 2.7.46 (classic), DePan and DePanEstimate
https://github.com/pinterf/mvtools/releases/tag/2.7.46

Package contains builds with several C++ compiler flavours. I did not experienced reproducible speed differences with my usual qtgmc script, but YMMV.

Change log (MvTools)

2.7.46 (20240503) *
Recheck and fix build processes for various compilers
(Visual Studio MSVC v143, v141_xp; Intel C++ Compiler 2024.1 ICX, 19.2 ICL; ClangCL; gcc mingw64)
Fix (#56): bug in Cross search
(unreleased 2.7.46 (20230208) test build in #58)
Fix (#58): MFlowFPS memory leak
Fix (#49): lsad 0 caused division-by-zero crash
Optimization: MDegrain1-6 8 bit: Add avx2 code path (already was in code but disabled, now go live)
Optimization: MDegrainN 10-16 bits: add SSE4.1 code path (was: C only)
Optimization: VerticalBicubic interpolation SSE4.1 version besides SSE2
Fix: MRestoreVect was trying to create unaligned frame (crash)
https://forum.doom9.org/showthread.php?p=1955944#post1955944
(#48) Project files/solution: Intel C++ Compiler 2021 (icx) and 19.2 (icl classic) support on Windows
source: pull avstp 1.04 helper files and reapply earlier patches
Source internals: MDegrain: for block size of 4, read exactly 4 bytes instead of 8. (in extreme cases it would read past a valid memory area)
Source internals: Stop using _mm256_zeroupper in avx2, compilers do that automatically.
Affected LLVM builds, because it unoptimizedly saved and restored all ymm registers (slow!)
https://stackoverflow.com/questions/68736527/do-i-need-to-use-mm256-zeroupper-in-2021

Change log (DePan and DePanEstimate)

Moved to Visual Studio 2022, v141_xp and v143 toolset, Intel Compiler ICX 2024.1 and ICL build support

Depan 2.14

Fix: "DepanScenes" plane parameter for YUY2 clips did not work

DepanEstimate 2.11

Throw an error if memory allocation fails


To preempt any questions: this is like the previous 2.7.45 mvtools2 with some fixes. It does not include any new features from DTL’s fork

Boulder
3rd May 2024, 11:35
Optimization: MDegrainN 10-16 bits: add SSE4.1 code path (was: C only)


With this optimization, is it now preferred to use MDegrainN instead of MDegrain1 or 2?

pinterf
3rd May 2024, 12:36
Not really, probably the degraining process itself is not the part of mvtools where the specially written SIMD routines help, especially not for small block sizes. As a power user you'll probably try each DLL which is the best for your processor and use case.
And note that when you pass the same values for thSAD and thSAD2 (and thSADC and thSADC2) then MDegrainN calls the original MDegrain1 or 2 or 3, etc... so there is no MDegrainN call at all.

DTL
3rd May 2024, 15:30
Heh - with all new features added in end of April (+2 new filters for mvtools) I think to make version numbers more separate: Make next release 2.8.0 tagged instead of planned 2.7.46-a.30. As in x.Y.z system the Y-advancing mean something (significantly) new added.

Boulder
3rd May 2024, 15:58
Are the two ICL builds meant only for specific CPUs? I was looking to do some comparison between the builds and they refused work on my system (5950X), "Script error: There is no function named 'msuper'" is what I got.

DTL
3rd May 2024, 16:18
The (partial) fix for unbiased shift-division at UV blocks fetching with chroma-subsampled formats (https://github.com/pinterf/mvtools/issues/59) is not planned to addition to next versions ?

pinterf
3rd May 2024, 17:29
Are the two ICL builds meant only for specific CPUs? I was looking to do some comparison between the builds and they refused work on my system (5950X), "Script error: There is no function named 'msuper'" is what I got.
If don't have SSE4.2 they won't work. See the notes txt.

DTL
3rd May 2024, 17:40
AMD 5950X listed as having up to AVX2 https://www.techpowerup.com/cpu-specs/ryzen-9-5950x.c2364 and including SSE 4.2.

It looks I found - ICL builds require intel libmmd.dll. Asd-g include it with some builds.

And also svml_dispmd.dll - they are somewhere in the redistributabe of intel compiler ?

With these (old) versions from 202x years ICL build is working at Core 2 Duo E7500 CPU (no AVX even) - https://drive.google.com/file/d/1eDZ3Zukk6wzaN-vUirvrovYmevcxTMrk/view?usp=sharing . But it may be better to add .dlls from new (?) intel compiler.

Also svml_dispmd.dll and libmmd.dll required to load ICX_LLVM build. But it crash VirtualDub with script of:

LoadPlugin("ffms2.dll")
LoadPlugin("mvtools2.dll")
FFMpegSource2("52.avi")

AssumeBFF()

ConvertToYV12(interlaced=true)

SeparateFields()
tr = 6 # Temporal radius
thCommonSAD=600

super = MSuper (pel=2, chroma=true, levels=0, hpad=64, vpad=64)
multi_vec = MAnalyse (super, multi=true, overlap=0, overlapV=0, blksize=8, search=3, searchparam=2, delta=tr, chroma=true, mt=false, levels=0)

mvlpf=MDegrainN(super, multi_vec, tr, thSAD=thCommonSAD, thSAD2=thCommonSAD-1, mt=false)
last = mvlpf

Weave()

Prefetch(2)


Either intel .dlls are old or not applicable to ICX at all or other reason.

pinterf
3rd May 2024, 17:40
The (partial) fix for unbiased shift-division at UV blocks fetching with chroma-subsampled formats (https://github.com/pinterf/mvtools/issues/59) is not planned to addition to next versions ?
I checked the open issues but did not find exact and quick code replacement for #59 (given the time frame I wanted to deal with this release).

Actually I didn't even plan this "next version" but the latest issue could be solved like changing a "+" sign to "-". Then I realized that I still had un-uploaded former commits, so I wanted to do a cleanup. Then it turned out that my Intel compiler does not work and there is an Intel 2024 compiler instead of 2021. Downloaded, fixed the old and new warnings and build errors, the XP build did not built either. And then came the documents and change logs and re-tests for all compilers.

So the "oh it's only one character" change turned into a nine-hour process :)

DTL
3rd May 2024, 18:17
I checked the open issues but did not find exact and quick code replacement for #59 (given the time frame I wanted to deal with this release).


This commit - https://github.com/DTL2020/mvtools/commit/fa7ccc48f0d0a588e2b9e3ec957f8e6d47cef1ef

pinterf
3rd May 2024, 18:21
This commit - https://github.com/DTL2020/mvtools/commit/fa7ccc48f0d0a588e2b9e3ec957f8e6d47cef1ef
Thanks, this will fit in the weekend I hope

pinterf
4th May 2024, 08:19
This commit - https://github.com/DTL2020/mvtools/commit/fa7ccc48f0d0a588e2b9e3ec957f8e6d47cef1ef
Thought this direct link works, but when I add your branch as a remote, I can see a totally different commit under this title, and on that day, with a different commit ID:
https://github.com/DTL2020/mvtools/commit/bfff0f0664fde574e507b4910c3bc3c44d1758cb
I thought I can cherry-pick it but I rather copy-paste the differences unless we figure out what happened with the history of your repo.

DTL
4th May 2024, 11:25
I am not understand how github is working and only use web-interface of it (once github-desktop lost one of my commmit so I stop using even this way). So it is better to make copy-paste. There is a few places to change and all changes are equal:
At GetPointer() call we need to add +1 to dx and dy MV coordinates bias before >>LogRatioUV shift-division if LogRatioUV > 0. This makes quantization error distribution symmetrical and decrease max abs error to factor of 2.

if (nLogxRatioUV_super == 1) blx++; // add bias for integer division for 4:2:x formats
if (nLogyRatioUV_super == 1) bly++; // add bias for integer division for 4:2:x formats

Complete fix of this issue requires bigger mvtools redesign - make pel*2 UV super clip part and use real /2 coordinate fetching without any error. It is equal to internal conversion of input 4:2:x to 4:4:4.
For pel=4 it requires to design either pel=8 for UV planes or use runtime sub-shifting of block with pel=8 granularity.

Run-time subshifting is much slower for MAnalyse searches but faster for MDegrain (only single shifted block required).

pinterf
4th May 2024, 13:46
I am not understand how github is working and only use web-interface of it (once github-desktop lost one of my commmit so I stop using even this way). So it is better to make copy-paste. There is a few places to change and all changes are equal:
At GetPointer() call we need to add +1 to dx and dy MV coordinates bias before >>LogRatioUV shift-division if LogRatioUV > 0. This makes quantization error distribution symmetrical and decrease max abs error to factor of 2.

if (nLogxRatioUV_super == 1) blx++; // add bias for integer division for 4:2:x formats
if (nLogyRatioUV_super == 1) bly++; // add bias for integer division for 4:2:x formats

Complete fix of this issue requires bigger mvtools redesign - make pel*2 UV super clip part and use real /2 coordinate fetching without any error. It is equal to internal conversion of input 4:2:x to 4:4:4.
For pel=4 it requires to design either pel=8 for UV planes or use runtime sub-shifting of block with pel=8 granularity.

Run-time subshifting is much slower for MAnalyse searches but faster for MDegrain (only single shifted block required).
Visual Studio Community 2022 perfectly integrated git, now with quite a few 'advanced' options are supported, I recommend it.

These changes intend to fix a chroma shift. Does it work indepentenly of the original chroma placement, e.g. top-left or center?

FranceBB
4th May 2024, 14:50
Thank you for the SSE4.1 assemblies, they work like a charm on Windows XP.


ConvertBits(10)

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)
MDegrain2(super,bv1,fv1,bv2,fv2,thSADC=200, thSAD=200)


SSE4.1

AVSMeter 3.0.4.0 (x86), (c) Groucho2004, 2012-2020
AviSynth+ 3.7.3 (r4066, master, i386) (3.7.3.0)

Number of frames: 501
Length (hh:mm:ss.ms): 00:00:16.717
Frame width: 848
Frame height: 480
Framerate: 29.970 (30000/1001)
Colorspace: YUV420P10
Audio channels: 2
Audio bits/sample: 32 (Float)
Audio sample rate: 48000
Audio samples: 802401

Frames processed: 501 (0 - 500)
FPS (min | max | average): 5.856 | 21.34 | 13.31
Process memory usage (max): 438 MiB
Thread count: 26
CPU usage (average): 62.9%

Time (elapsed): 00:00:37.636



Plain C

AVSMeter 3.0.4.0 (x86), (c) Groucho2004, 2012-2020
AviSynth+ 3.7.3 (r4066, master, i386) (3.7.3.0)

Number of frames: 501
Length (hh:mm:ss.ms): 00:00:16.717
Frame width: 848
Frame height: 480
Framerate: 29.970 (30000/1001)
Colorspace: YUV420P10
Audio channels: 2
Audio bits/sample: 32 (Float)
Audio sample rate: 48000
Audio samples: 802401

Frames processed: 501 (0 - 500)
FPS (min | max | average): 3.335 | 12.27 | 8.005
Process memory usage (max): 439 MiB
Thread count: 26
CPU usage (average): 54.2%

Time (elapsed): 00:01:02.584


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

pinterf
4th May 2024, 15:54
Thank you for the SSE4.1 assemblies
Are you sure with these performance numbers? Did you compare 2.7.45 and 46? Was it surely both example at 10 bits in the tests? Mdegrain2 was not changed unless I forgot about something I have done in the past theee years :). MdegrainN was affected, when thSAD and thSAD2 is different.

DTL
4th May 2024, 16:25
"These changes intend to fix a chroma shift. Does it work indepentenly of the original chroma placement, e.g. top-left or center?I am not sure - it is subject to testing. Currently I am not see in the design of mvtools any respect of chroma-placement. It may simply 'work from 2004 year as is'."

Typically with any noised sources the MV-jitter is much larger in the comparison of differences of sub-sample chroma-placement and after applying MDegrain total jitter of both luma and chroma planes is also much larger. So users may notice only large-areas 'stable' chroma-shift reported in that issue originally.

"Are you sure with these performance numbers? Did you compare 2.7.45 and 46? Was it surely both example at 10 bits in the tests? Mdegrain2 was not changed unless I forgot about something I have done in the past theee years . MdegrainN was affected, when thSAD and thSAD2 is different."

Each build/version of the compiler can create significant differences in the executable performance at some hosts. Also when compiled with some limits of max-SIMD valid. So if even sources do not change - the relative performance of 2.7.45 old builds and all new builds may be different. CPU usage reported is also very different.

Also do you add intel .dlls to run ICL/ICX builds ? I still don't know why got crashed with ICX build and think it requires proper intel .dlls to be used (from build environment). ICX_LLVM build is expected to be fastest at least at intel-CPU hosts.

"Visual Studio Community 2022 perfectly integrated git, now with quite a few 'advanced' options are supported, I recommend it"

After I updated VS2019 from some 'old' to some 'new' version I got lots of compile errors in Microsoft-CPP text for DX12-ME part of mvtools. A natural error was found in Microsoft DX samples working with 'old' VS2019 and stop working with 'new' VS2019. So I need to add new fixes to DX12 MAnalyse to get it compiled with 'new' VS2019. So I am afraid the migration to VS2022 may open even more errors to fix. Now I have working DX12 builds for me.

FranceBB
4th May 2024, 19:19
Are you sure with these performance numbers?

Well, both 10bit, one with SetMaxCPU("none") and the other without it, but that's not the problem unfortunately.


Mdegrain2 was not changed unless I forgot about something I have done in the past three years :). MdegrainN was affected

I'm an idiot, when you said "MDegrainN" for some reason my brain thought you meant "MDegrain1", "MDegrain2", "MDegrain3" etc where "N" stands for "number", not the MDegrainN() function hahahahahahahahaha


Anyway new test, this time properly:

#Indexing progressive flagged as interlaced SD source
video=FFVideoSource("test.ts")
audio=FFAudioSource("test.ts")
AudioDub(video, audio)

#From SD anamorphic to SD 1.77 FF 16x9
Spline64Resize(848, 480)

#Bringing everything to 10bit
ConvertBits(10)

#Degrain
Super = MSuper(Pel=1, Chroma=true)
Vector = Super.MAnalyse(Multi=true, Delta=3, BLKSize=8, Overlap=4, Chroma=true)

MDegrainN(Super, Vector, 3, thSAD=150, thSAD2=135, thSADC=150, thSADC2=135)

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


Plain C

AVSMeter 3.0.4.0 (x86), (c) Groucho2004, 2012-2020
AviSynth+ 3.7.3 (r4066, master, i386) (3.7.3.0)

Number of frames: 501
Length (hh:mm:ss.ms): 00:00:16.717
Frame width: 848
Frame height: 480
Framerate: 29.970 (30000/1001)
Colorspace: YUV420P10
Audio channels: 2
Audio bits/sample: 32 (Float)
Audio sample rate: 48000
Audio samples: 802401

Frames processed: 501 (0 - 500)
FPS (min | max | average): 2.782 | 11.77 | 8.425
Process memory usage (max): 422 MiB
Thread count: 26
CPU usage (average): 64.2%

Time (elapsed): 00:00:59.466


SSE4.1

AVSMeter 3.0.4.0 (x86), (c) Groucho2004, 2012-2020
AviSynth+ 3.7.3 (r4066, master, i386) (3.7.3.0)

Number of frames: 501
Length (hh:mm:ss.ms): 00:00:16.717
Frame width: 848
Frame height: 480
Framerate: 29.970 (30000/1001)
Colorspace: YUV420P10
Audio channels: 2
Audio bits/sample: 32 (Float)
Audio sample rate: 48000
Audio samples: 802401

Frames processed: 501 (0 - 500)
FPS (min | max | average): 3.920 | 19.29 | 12.10
Process memory usage (max): 421 MiB
Thread count: 26
CPU usage (average): 68.7%

Time (elapsed): 00:00:41.395

amayra
21st June 2024, 22:14
does this version support VapourSynth ?

DTL
22nd June 2024, 07:13
No. VS has even more old and simple version - https://forum.doom9.org/showthread.php?t=171207

Selur
22nd June 2024, 07:18
Any plans for Vapoursynth support?

DTL
22nd June 2024, 09:12
mvtools2 is a complex software project (may be the most complex for current AVS+ software). So I see there were designed separate version for VS. It is better to ask current (if any still exist) programmers of VS version of mvtools why a separate version was designed ?

Somewhere I read about performance reasons like VS-mvtools running up to several times faster in VS-environment. It may be because of different memory management ? So VS-mvtools also may be an attempt to re-design of some old mvtools version for better performance and other new nice (programming ?) features. But it looks development of VS-version was stopped even before AVS-version.

As I see porting of mvtools2 to VS started about 2014 - a 10 years after beginning of mvtools2 design. But 201x years were already great end of all freeware video processing software (with end of home video cameras) so the porting was incomplete.

Selur
22nd June 2024, 10:36
Thanks, so I guess that is a: No :(

amayra
22nd June 2024, 21:35
it's not possible to port improvements over to vapoursynth version?

DTL
24th June 2024, 00:17
Everything is possible - but programmers required. As you see we have close to no programmers for AVS plugins in 202x years from the total planet. Sad enough. I tried to ask Asd-g for some non-free help with mvtools (like bug fixes or feature additions) but no reply.

Soloiam68
13th July 2024, 12:40
I have been using MVTools for a while with great results. However, recently I encountered some issues. I encoded a video and noticed some weird horizontal line-type blockings. It’s not banding, but when a cloudy-type object covers a wide area and moves, it looks like multiple horizontal lines of box-type patterns appear and it shows up on multiple parts of the video. It's not present in the source file and isn't coming from any other prefilters used before MDegrain3. When the video goes through MVTools and removes the grain, the issue appears. I am facing this issue recently and have tried everything to solve the problem, but nothing has worked. I also used the latest and many other versions of MVTools, but the issue persists.

My Setup:
AMD Epyc Processor; Windows 10 Server Edition 2019
AviSynth+ 3.7.3
Encoder Used: x264 (veryslow preset)

All the source, avs, test files and images are included.

Files (https://drive.google.com/file/d/17647P0pgmzSZCFe_G4Lomv1X7G6ACBgj/view)

Please someone look into the matter kindly and inform me. My request.

takla
9th October 2024, 13:34
FPS (min | max | average): 2.782 | 11.77 | 8.425
FPS (min | max | average): 3.920 | 19.29 | 12.10

Over 40% speedup? Amazing :o

Selur
9th October 2024, 15:49
@Solaima68: opened your script and can't the artifacts (I added avsfilter, to the required filters since you didn't include it), you highlighted
Here's what I see in AvsPmod:
https://i.ibb.co/7VZrWsS/grafik.png (https://ibb.co/q9cmsTD)
Here's what I see when I look at your test-output.mp4 in AvsPmod:
https://i.ibb.co/HTJm3dj/grafik.png (https://ibb.co/F4PGCVF)
neither of them seem to show the artifacts in your screenshots.
=> might be a playback issue

tormento
17th October 2024, 20:13
From MVTools documentation:

dct: using of block DCT (frequency spectrum) for blocks difference (SAD) calculation. In particular it can improve motion vector estimation at luma flicker and fades.
0 - usual spatial blocks, do not use DCT;
1 - use block DCT instead of spatial data (slow for block size 8x8 and very slow for other sizes);
2 - mixed spatial and DCT data; weight is dependent on mean frame luma difference;
3 - adaptive per-block switching from spatial to equal-weighted mixed mode (experimental, a little faster).
4 - adaptive per-block switching from spatial to mixed mode with more weight of DCT (experimental, a little faster).
added in v1.9.5.3 modes: (require sadx264 0-7, uses fastest SATD function, luma only!)
5 - SATD instead of SAD for luma
6 - same as 2 only use SATD
7 - same as 3 only use SATD
8 - same as 4 only use SATD
9 - similar to 2, use SATD and weight ranges from SAD only to equal SAD & SATD
10 - similar to 3/4,use SATD weight is on SAD, only on strong luma changes
Default = 0.

Can someone explain me some concrete cases where to change them from 0 to other values? What are the benefits and the caveats?

takla
18th October 2024, 02:35
Can someone explain me some concrete cases where to change them from 0 to other values?

Example:

Vector = Super.MAnalyse(Multi=true, Delta=3, BLKSize=8, Overlap=4, Chroma=true, dct=1)



What are the benefits
Insignificant quality enhancement. CPU cycles are much better used on a lower BLKSize & higher Delta value.

tormento
18th October 2024, 13:01
Example
Thanks for your time but I need case scenarios. Such as for this kind of noise or function, use this or that.
Insignificant quality enhancement. CPU cycles are much better used on a lower BLKSize & higher Delta value.
I disagree. I played a bit yesterday with SMDegrain, setting DCT=10, and the resulting video went from 5 GB to 4GB with no discernible difference.

takla
18th October 2024, 13:22
I disagree.
SMDegrain

And there is your problem. Use EZdenoise (https://forum.doom9.org/showthread.php?t=183192) and you'd see for yourself that what I said is true.

Thanks for your time but I need case scenarios.

No you don't.
Use

EZdenoise(BLKSize=4, Overlap=2, tr=8, Chroma=true, out16=true)
ConvertBits(10, dither=1)


For maximum quality and best efficiency of your CPU time.

tormento
18th October 2024, 19:31
Use EZdenoise
Tried with the material posted here (https://forum.doom9.org/showthread.php?p=2008439#post2008439).

Nice on light scene but the grain in the dark one is still there, dancing around.

takla
19th October 2024, 00:38
Tried with the material posted here (https://forum.doom9.org/showthread.php?p=2008439#post2008439).

Nice on light scene but the grain in the dark one is still there, dancing around.

Sorry, I can't help you further. I would, but my PC is dismantled atm.

tormento
3rd December 2024, 21:48
Did you compare 2.7.45 and 46?
The Intel_ICL_Classic and Intel_ICX_LLVM builds are not working for me.

They give me the error "MSuper not found".

MSVC and ClangCL ones work ok.

StvG
5th December 2024, 04:52
The Intel_ICL_Classic and Intel_ICX_LLVM builds are not working for me.

They give me the error "MSuper not found".

MSVC and ClangCL ones work ok.

You probably need Intel runtimes (https://www.intel.com/content/www/us/en/developer/articles/tool/oneapi-standalone-components.html) (click on left "Runtime Versions"->"Runtime Versions - Microsoft Windows* and macOS* Binary Packages" and download "Intel® oneAPI DPC++/C++ Compiler Runtime for Windows*").

tormento
5th December 2024, 11:41
You probably need

Uhm. Will try that, I run many other plugins and x265 compiled with ICC and I had no issues. Perhaps they were statically linked.

tormento
5th December 2024, 16:13
Eventually, they are not statically linked. It works with ICC runtimes.

SMDegrain (tr=9, thSAD=900, plane=4, chroma=true, LFR=false, DCTFlicker=false)

MSVC 2.471
Intel_ICL_Classic 2.581 (+4,45%)
ClangCL 2.658 (+7,57%)
Intel_ICX_LLVM 2.737 (+10,76%)

Adub
15th May 2025, 02:25
I have a clarifying question I'd like to ask about the behavior of MVTools, specifically the use of MSuper, the concept of "pel" and pixel subsampling as a method of speeding up motion search.

If I'm reading the MVTools code correctly, MSuper creates a new clip from a source clip, with the new clip containing a hierarchy of levels. The top level (index 0, if thinking of the hierarchy as an array) contains the frame data that has been interpolated from the source frame, according to the "pel" parameter. So if "pel = 2", then the top level is twice the size (twice the width, twice the height, so technically 4x) of the source frame. If "pel=4", then the top level is 4x the size (4x width, 4x height, so 16x).

Sticking with the example of "pel = 2", then the next level down in the hierarchy is the original source frame (the equivalent of pel = 1). Continuing, the next level from that is 1/2 the size of the source frame, and so on and so on until some very small fraction of the original source.

This makes sense, as this is the hierarchy that is walked when searching for motion vectors. It starts from the bottom (the smallest version of a frame) (technically there are two hierarchys, one for the current frame and one for another frame, like the previous or next frame), finds the motion vector of a block, and then works its way up the hierarchy refining that motion vector so that it is more and more accurate as we work our way up the hierarchy.

Where I'm a little confused is how MSuper seems to split up these levels of the hierarchy. You can see this if you output the super clip directly. It appears to be creating subsampled versions of each level, and stacking them on top of each other.

Using the "pel=2" example, then the top of the stack is derived from an interpolated frame that's twice the size of the source frame, where the very top contains the information for pixels at index 0, 2, 4, 6, etc. Then the next clip in the stack contains the information for pixels 1, 3, 5, 7 of the interpolated frame. This means, in theory, that the top of the stack actually contains a copy of the originally sized frame, but then the next clip in the stack contains just the interpolated pixels from the 2x upscale. So the source frame is upscaled 2x, and then subsampled into two different clips and stacked on top of each other.

Do I have this correct?

If so, then looking at the motion search code, it selects which clip to search based on the coordinates of the block it is searching for. If the coordinates are (0,0) for example, then it selects the clip at the very top of the stack, which contains the original pixels (and *NONE* of the interpolated pixels) and loads that data into a block. If the block had the coordinates (1,0) instead, then it would select the clip with the interpolated pixels.

This seams to suggest that only some blocks use interpolated pixels, instead of all blocks, as I would have originally expected.

What exactly is the purpose of this approach?

It kind of seems like MSuper interpolates all of these pixels, but then MAnalyse turns right around and inverts the process for some blocks, begging the question - if you're going to subsample, then why interpolate all of that pixel data in the first place, as you're just going to skip over it?

I hope this question makes sense. I'm really just trying to learn how MVtools is operating.

DTL
15th May 2025, 21:18
For pel >1 super clip contain upsampled version of a frame. For pel=2 2x upsampled and for pel=4 4x upsampled.
The only difference with standard upsampled frame - it is stored as separated shifted versions of a frame. It is done to make MAnalyse and MDegrain faster on old CPUs - to make sub-sample precision search it do not shifts or upsample frame for each operation but fetch shifted versions of input frame from MSuper clip (so it create large read traffic and may cause slower performance on new many-cores CPUs and narrow slow memory bus). To partially fix it at MDegrainN version was designed runtime sub-sample shifting of real size input frame block. Also available for MAnalyse. But it do not make performance of MAnalyse faster (on current non-AVX512 and slow chips) - only save RAM because you can always set pel=1 for MSuper and it create lower-sized clip.

The reason of storage of 2x or 4x upsampled frame as a set of shifted sub-planes was for more simple design of MAnalyse search as I remember. But this also cause very hard to make pel>1 search versions on SIMD because it can not simply compare upsampled version of source with integer-shifted upsampled version of ref frame. It always compare of 1x size source block with sub-sample shifted version of ref block - but sub-sample shifted is located in different part of RAM and can not be read in register file fast enough.

You can try to make same super-clip by separating 2x or 4x upsampled frame to 1x sized shifted sub-planes. It is also good example of digital interpolated frame view versions - it either

1. interleaved sub-sample shifted copies (standard upsampled frame storage) as we got from
XResize(width*2, height*2)

or
2. separated set of sub-sample shifted 1x versions of frame as we got from (as current MSuper do and store)
XResize(width, height, force=X, sub_x=-0.5)
XResize(width, height, force=X, sub_x=+0.5)
XResize(width, height, force=X, sub_y=-0.5)
XResize(width, height, force=X, sub_y=+0.5)

"Do I have this correct?"

Yes.

"This seams to suggest that only some blocks use interpolated pixels, instead of all blocks, as I would have originally expected."

Yes - for best performance it may use real input frame as (0.0f, 0.0f) sub-shifted version and create 3 more versions (for pel=2 and 2x upsample) as
0,0=src
1,0=XResize(width, height, force=X, sub_x=+0.5)
0,1=XResize(width, height, force=X, sub_y=+0.5)
1,1=XResize(width, height, force=X, sub_x=+0.5, sub_y=+0.5)

This really cause some distortions and non-equal for 0,0 and sub-shifted versions because for many source no-way of zero-distortion interpolation exist. Internally MSuper uses some sort of Spline (?) interpolation kernel (for sharp=2 and it is not equal to Lanczos with taps=2 - mostly looks like Spline or even different kernel) and it works not bad even for non-sinc conditioned sources (low ringing). But it also means it can make less sharp result for good sinc-conditioned source. This is because MSuper allows user to provide external upsized/interpolated clop for sub-shifted separation only internally. If user knows input source better and can provide better upsized version (like SincResize(taps=16) for good sinc-conditioned sources).

As I remember the sharp=2 interpolation is simple and so fast and create nice non-ringing (or at least very low ringing) result at even completely non-conditioned for sinc resizers sources. And I had an ideas to make that kernel as additional AVS resize kernel to use at some 'unknown' sources. But it may be close to Spline (?).
In sources it is called: https://github.com/pinterf/mvtools/blob/a488b095c4bdc8d81abfd952ab534c015a9d45b7/Sources/Interpolation.cpp#L1879
// so called Wiener interpolation. (sharp, similar to Lanczos ?)
// invarint simplified, 6 taps. Weights: (1, -5, 20, 20, -5, 1)/32 - added by Fizick

So can be named WienerResize(). Though its kernel weights also looks close to some weighted-sinc of low (support and kernel size) size. But only kernel for fixed 2x or 4x is available and no generic f(x) kernel function in the sources so it can not be directly applied to current AVS resize fiilter. Need to find the full f(x) equation for float x argument for that Wiener kernel (if it exist at all).

" if you're going to subsample, then why interpolate all of that pixel data in the first place, as you're just going to skip over it?"

MAnalyse with full exhaustive search always checks all sub-shifted positions in the given radius. But MDegrain (and any other motion-compensated) function only fetch the sub-position pointed by (fractional last 1 or 2 bits) motion vector. So for motion-compensation if CPU is fast and RAM (bus) is slow it is possible to compute sub-shifted position of block inside CPU (caches) instead of fetching it from slow host RAM (as designed in other branch of mvtools).

"What exactly is the purpose of this approach?"

It is both for performance and logic of motion search:

1. For performance - for 2x upsample we need to compute only +3 new sub-shifted planes and can copy source plane as 4th sub-part.
2. For motion vector search - the zero-motion and MV (0,0) mean src block equal to ref block and the SAD of src block and not_sub_shifted ref block is minimal (or = 0). So when MAnalyse make search using blocks dissimilarity metric - it is very natural to compare 1x src block with 1x ref block and get lowest SAD (or other dissimilarity metric) and produce output MV of (0,0). Also this cause the lowest possible interpolation error for zero MVs for any kind of sources (with more or less good interpolate-able). Any interpolation for natural (noised too) sources adds some error and it cause non-zero MVs to have less quality (also may have more errors). Also that (may) mean the error distribution for zero-MVs and non-zero may be not equal. I.e. probability of bad zero-MV is lower in comparison with the probability of bad non-zero MV. This also can be used somehow in the statistical averaging of MVs for denoising.

Adub
16th May 2025, 19:13
Thank you very much for the detailed response! It confirms some of my suspicions and expands my understanding of the approach.

Let me restate the method to make sure I properly understood your answer.

Specifically, there is definitely utility in both upsampling (2x or 4x) as well as sub-sampling (selecting every 2nd or 4th pixel) when conducting motion estimation. Upsampling provides more spatial resolution to conduct a search at the finest levels of a hierarchy, allowing for more accurate motion vectors. Sub-sampling provides two benefits: 1) improved performance by reducing the number of pixels considered and 2) the slight inaccuracies induced by using sub-sampling adds a small amount of "jitter" (for lack of a better term) to the motion vectors produced. This has a beneficial effect if motion vectors are averaged together, because less zero-motion vectors will exist, thereby smoothing out the resulting average.

Example from averaging three motion vectors together: without the sub-sample jitter, we might have (0 + 0 + 10) / 3 = 3.3333, but with the sub-sample jitter, we have something more like (1 + 2 + 10) = 5.3333.

I think that all makes sense to me.

With respect to the specifics of how MSuper currently creates sub-sample shifted 1x versions instead of a "normal" interleaved sub-sample - I agree, the current approach seems like a nightmare for cache locality on modern processors. Granted, this impact is reduced if one version is used more than the others, which seems to be the case. I'd be curious to see if modern processors can better handle sub-sampling with the "normal" interleaved sub-sample approach, particularly because you get the benefit of better cache locality and SIMD "gather" instructions now exist. That locality might make up for the cost of the strided sub-sampling access and still come out faster.

So would it be safe to say that a more modern approach to MSuper might be to avoid the use of sub-sample shifted 1x versions and instead use a "normal" interleaved approach instead?

DTL
17th May 2025, 00:50
" there is definitely utility in both upsampling (2x or 4x) as well as sub-sampling (selecting every 2nd or 4th pixel) when conducting motion estimation."

It is better to name interpolation for getting a sub-sample level of precision. Yes - the MSuper performs interpolation-upsampling. But there is no sub-sampling (downscaling) in MAnalyse - it simply fetches the sub-shifted blocks (see GetRefBlock() function) from super-clip. SAD (and other dissimilarity) calculation functions always run with 1x sized current and ref blocks - the only differences at 0.5 and 0.25 levels precision is that ref blocks are sub-sample coordinates shifted from original position in a frame.

For pel=2 MAnalyse simply runs +1 level of 0.5 precision search.
For pel=4 MAnalyse runs +2 levels of 0.5 and 0.25 precision search.

MRecalculate always runs only single level (really not full level search but refining only).

"Sub-sampling provides two benefits: 1) improved performance by reducing the number of pixels considered"

At MAnalyse it does not really reduce - it only allows to run 1x SAD calculation functions at any level (both reduced size initial levels and 1x and below 1x). And for motion-compensation it allows to fetch ready to use sub-shifted ref blocks instead of new calculation of shifted blocks from 1x sized plane. This makes more host RAM traffic but may be faster at slow CPUs (was faster with old CPUs). Currently we have runtime sub-sample shifting implementation in MDegrainN in other branch of 2.7.45 mvtools and it runs not any slower (it is required for pel=1 mode of MSuper when hardware ME used because hardware ME do not need interpolated clip for any pel precision).

For example with DX12-ME (or any other hardware or software ME engine) there is no sub-sample shifted/interpolated frames available (like in super-clip in mvtools) and for MVs with 0.5 or 0.25 precision consumer need to calculate the sub-shifted blocks again to do motion compensation.

"2) the slight inaccuracies induced by using sub-sampling adds a small amount of "jitter" "

Simple natural noise causes lots of random jitter in MVs (at least at the flat areas with low signal to noise ratio).

"I'd be curious to see if modern processors can better handle sub-sampling with the "normal" interleaved sub-sample approach, particularly because you get the benefit of better cache locality and SIMD "gather" instructions now exist."

There are some SIMD-accelerated exhaustive search examples (it make several MVs SAD scan at the single refine function call and selects MV with lowest SAD at the end) in second-branch of 2.7.45 mvtools - but it runs only with 1x (pel=1). But to make pel=2 or pel=4 precision it is possible simply upsize 2x or 4x input clip and run mvtools with pel=1 and make re-calculation of MVs to 1x size if needed. But the 2x or 4x upsizing also causes more host RAM traffic because of current AVS+ (and mvtools architecture). For best performance with current machines architectures it is better to do local area (or even frame) upsizing-interpolation in the CPU caches and make fine search inside CPU only without keeping an upsized-interpolated frame in main host RAM. It is the same way hardware ME engines run - they get only 1x current and ref frames and do all required sub-sample precision interpolation inside hardware units and output fine 0.25 precision MVs.

"would it be safe to say that a more modern approach to MSuper might be to avoid the use of sub-sample shifted 1x versions and instead use a "normal" interleaved approach instead?"

It will not decrease required amount of RAM to store same sized interpolated super clip. But will make SIMD functions of search design somehow easier (also will cause search of 2x vs 2x upsized blocks at pel=2 and 4x vs 4x at pel=4). Though because current RAM bus is still very slow relative to cores performance it may not make big performance benefit in multithreading execution. When 4..8..16+ threads will frequently fetch large 2x or 4x interpolated frames from main host RAM via narrow and slow bus.
May be better to run with 1x super clip always (no pel=2 and pel=4 interpolated buffers at all) and make all required interpolation inside CPU core (better inside register file of enough size like AVX512).

Adub
29th May 2025, 19:40
Got it, thanks again for your detailed answer, DTL.

I agree with you - a modern approach seems to be handling all reduction and interpolation (what MVTools calls "refining" internally) inside the CPU cache, instead of via a Super clip. It might even be possible to eliminate the use of Super entirely, although it might have some benefits with padding.

I really like the idea of handling all reduction and interpolation in a "local area", just before motion search. This would significantly minimize memory usage (particularly for larger frame sizes like 4K YUV 4:4:4), keeping as much of the pertinent pixel data in the L1 cache as possible.

I might see if I can produce some toy code to benchmark a few different approaches, as a learning exercise.

DTL
30th May 2025, 11:13
To make performance of MAnalyse somehow better we have some more SIMD-friendly algoriphm - to make (refining) search of several blocks with single SIMD search process and it valid for many blocks because for static frame areas many nearby blocks have completely zero MVs (or very slightly distorted by noise) and for large coherently moving areas (also global motion/camera pans/dolly) the MVs of the several blocks are coherent. This search may be started is all predictors for a group ob blocks also coherent (or in some not very big offset - but it will cause SIMD src block loading more complex - may be permutex2var with AVX512 can help too ?).
This will significantly improves performance of small sized and high number blocks search cases. It is partially started in implementation in the
https://github.com/DTL2020/mvtools/blob/9eedb9d0850f638fc43212fb515cf048f9b9a58f/Sources/PlaneOfBlocks.cpp#L8910 (AVX2 also available for lower blocksize and search radius)

but it works only for pel=1 in that implementation because of the sub-shifted placement in current super-clip. Also AVX512 with larger register file will allow to search more blocks or of larger size or with larger search radius.

The design idea of that implementation - start multi-block search and continue until the MVs are (enough) coherent. If MVs lost coherency to too much range (for current multi-block search implementation in SIMD) - make fallback to single block search (with unlimited possible MV length).

Selur
30th May 2025, 12:28
btw. a Vapoursynth port would still be nice :)

DTL
10th April 2026, 19:45
Some new ideas how to make search performance for pel=2 and pel=4 precision better with AVX2/AVX512:


super_p4=MSuper(pel=4, hpad=8, vpad=8)

cl4x=LanczosResize(width*4, height*4, taps=16)
super_4x=MSuper(cl4x, pel=1, hpad=32, vpad=32)

#standard pel=4 search with 16 sub planes
mv_p4=MAnalyse(super_p4, blksize=8, search=3, searchparam=4, overlap=4)
mvrf_p4=MRecalculate(super_p4, mv_p4, thSAD=0, blksize=4, search=3, searchparam=16, overlap=2)

#upscaled single plane search
mv_4x=MAnalyse(super_4x, blksize=32, search=3, searchparam=4, overlap=16)
mvrf_4x=MRecalculate(super_4x, mv_4x, thSAD=0, blksize=16, search=3, searchparam=16, overlap=8)
mvrf_4x_p4=MScaleVect(mvrf_4x, scale=4, mode=1, adjustSubPel=true)



Searching with pel=1 looks more easy to make with instructions like mpsadbw and also loading from memory a single plane expected to use much less RAM read streams. With pel=4 and separated 16 sub-shifted planes each new search position requires reading a new block from the different sub-plane. With a single 4x sized plane all rows of the area to search may be loaded with a single read stream. So the number of large strided reads is about 16 times less for pel=4 and 4 times less for pel=2. For AVX512 with the possibility to load 64 of 8bits samples in a register it is expected to be possible to make a function of 16x16 block search inside a register file with radius about 8. This will emulate 8x8 block search with pel=2. Or 4x4 block with pel=4. Also for refining with MRecalculate typically required blocksize/2 and it is the slow operation now and most wanted to be optimized with SIMD.

Performance tests also show even with standard esa search without additional SIMD optimizations some performance boost with the 4x upsized version. Also the quality of MVs is different. It is still subject to research why quality changed. Maybe some processing at pel >1 levels is not performed (or performed in a different way) and this causes quality change.

real.finder
10th April 2026, 20:35
Also the quality of MVs is different. It is still subject to research why quality changed. Maybe some processing at pel >1 levels is not performed (or performed in a different way) and this causes quality change.

maybe you should use left-top/top-left aligned, in mvtools2 manual

pelclip clip =
Optional upsampled source clip for using instead of internal subpixel interpolation (for pel>1).
Pixels at rows and colunms positions multiple to pel (0,2,4,... for pel=2) (without padding) must be original source pixels, other pixels must be interpolated.

Example for pel=2: LanczosResize(width*2,height*2,src_left=0.25, src_top=0.25).
so in your case
cl4x=LanczosResize(width*4, height*4, 0.375, 0.375 (https://forum.doom9.org/showthread.php?t=147285), taps=16)

DTL
11th April 2026, 06:26
Yes - very many things may cause more or less significant changes in MVs at the MAnalyse output. The simple LanczosResize is just a first attempt to try. The internal MSuper interpolation is separate from all other AVS+ resizers kernel (Wiener ?) and it may need some research on how external resizers can emulate it with best possible precision (in both kernel shape and position/offset).

Other possible solutions for testing:
1. Export kernel from MSuper and add a new named resizer to AVS+ core (or external filter like ResampleMT).
2. Make some script based or compiled filter more or less slow to repack sub-sample shifted parts of upsampled plane from usual MSuper output into single frame/plane and feed it again at the MSuper input to create lower sized levels.

Though it is only important if users want to attempt to simulate standard output of MAnalyse/MRecalculate as best as possible. I am still not sure if it is completely possible because of possible other changes in the processing of sub-1-sized levels (pel-leveled).

Also there expected some difference in the SIMD implementation of the esa search (may be added in the C and other search methods too): The currently implemented (all ?) stepping searches (refining small algorithms) are made with checking of penalty at each step. This causes anisotropic results (the first MVs in searching area scan order are not examined with the same conditions as last in the search area scan). This causes result dependency from scan order of all positions. This may or may not be good for some search methods. At least this is not a single way of making esa search with penalty enabled (pNew > 0). Another way of applying the penalty is to check all positions with a given searching area first and apply the penalty only to the best (lowest SAD/dissimilarity metric) MV. This may be expected from documentation algorithm description but real implementations are not completely this way designed. The SIMD massive-multithreading implementation may get more or less significant performance penalty if making application of the penalty in that way (checking SAD one by one and checking condition at each step). One of SIMD implementations uses hardware instruction to get lowest value from several inputs and it is faster (warps many comparison operations in one) but this does not allow to completely simulate the stepping search with pNew at each step. This means faster SIMD-esa search will produce also a bit different results in comparison with C-esa implementation (with single SAD computing optimization with SIMD as designed today in pinterf branch). Complete SIMD simulation of currently implemented C-esa search is also possible but will have worse performance.

Natural anisotropy esa scan order + penalty > 0 at each step can cause missing of better MVs:
Scan order from left to right:
https://github.com/pinterf/mvtools/blob/a488b095c4bdc8d81abfd952ab534c015a9d45b7/Sources/PlaneOfBlocks.cpp#L1327
So this search causes some skew to the fist scanned positions if even they produce worse SAD.

Also current esa search is really expanding and will skip better MVs with larger length from starting position with pNew>0. Depending on the scene motion this may or may not help to the quality. This expects the probability of the fast motion may be lower (more likely caused by noise distortion - with any noisy frames sequence best SAD may also be created by noise difference between current and ref frame but it will not be the real best MV).

Possible partial workaround to break spatial anisotropy is to apply pNew only to the end of each round of the expanding search.
So there may exist at least 3 different versions of esa search:
1. Old current version of the expanding search with pNew check at each step (with worst spatial anisotropy).
2. Updated version of expanding search with pNew check after each full round (or even double check: 2.1 - after sides of a square and 2.2 - after corners of a square) - with spatial skew removed.
3. Full esa search with pNew checked once at the end (most SIMD friendly and of the highest performance).

"LanczosResize(width*2,height*2,src_left=0.25, src_top=0.25)."

With this correction total search difference with internal pel>1 looks like become lower. Though Lanczos kernel anyway different from internal shifter/upsampler and some difference expected to be anyway.

Some new test build https://github.com/DTL2020/mvtools/releases/tag/post_2.7.46_808 based on r808 by pinterf with added search=8 'more isotrorpic' exhaustive search. Also replaced default esa (old search=3) search for coarse levels to this search method. pnew now applied once after full border of expanding search is checked (but MotionDistortion penalty still applied at each search position - to adjist it user need to adjust lambda param). New ExpandingSearch2 function is https://github.com/DTL2020/mvtools/blob/b9b7a241c3d28c0dfe89b0dc69f019a4e51817b1/Sources/PlaneOfBlocks.cpp#L1350

tormento
10th May 2026, 15:46
I was looking at the Super Resolution (http://www.infognition.com/super_resolution_avisynth/) plugin.

Unfortunately, source hasn't been released and the development seems to have stopped.

The interesting part is not, for me, the resize part but the high frequency recovering from the temporal part of a video.

It states: Internally this plugin uses quarter-pixel motion compensation and a fusion process to combine motion-compensated previously upsized frames with spatially resampled current frame.

Would, thus, be possible to recreate the frequency recovery part by a MVTools script?

DTL
10th May 2026, 21:01
In the good conditioned against aliasing and ringing content any frame from a scene (sequence) has the very same view of a texture. It may be shifted relative to sampling grid with camera of object motion. But interpolated (upscaled) view is about the same (if no aliasing present). It is one of the main requirement for high quality digital moving pictures - no temporal aliasing. This will keep objects views undistorded at any speed of motion. No additional details can be gathered from some frames. If it is possible it mostly means there is some aliasing present and the view of an object is not stable at the motion (so temporal aliasing present and this makes fine details flicker and other temporal defects).

The standard way with noised footage is simply denoise and pass to the 'super-resolution' engines like AI/NN with an attempt to regenerate more detailed textures from local texture libraries from the engine. The texture library _may_ be updated from different footage frames. For example if some scene has a close up shot of a talent it may record high resolution face texture and apply it to blurry frames or with small size of the head and same for any other objects from total footage. But this is much more complex processing in comparison with current mvtools abilities. And this needs to analyse lots of frames, not only a few surrounding about equal frames.

tormento
11th May 2026, 09:46
No additional details can be gathered from some frames.
I was thinking about anime, where usually a single frame is repeated at least twice for characters, while background sometimes reaches real fps. It would be nice to recover additional information to recreate missing frequencies and/or recover blocking from starved sources.

DTL
11th May 2026, 10:37
If some block is static in a sequence of frames it does not carry additional (new) information in a sequence of frames. Averaging of clean static blocks with its copies does not change output. But with real noised frames and very low contrast texture (texture contrast below or about equal to the noise contrast) MAnalyse can give many false MVs (non-zeroed) for really static blocks and it will cause bad blending at denoise stage and additionally blurs the textures. It is not an error of the algorithm but because current block + noise distortion may better match other block + noise distortion.
Possible solutions in old mvtools - increase pzero (need manual adjustment and quality check for each footage with its textures contrast and noise levels) and other 'truemotion' parameters like lambda. This is expected to decrease probability of single false non-zero MV generation for each block (pzero) and skip possible false non-zero MVs predictors from surrounding blocks (lambda). Though too much pzero and lambda values may cause distortion at real moving areas of the frame.

tormento
12th May 2026, 17:21
Have a look at this RIFE-MVTool crossover (https://github.com/n00mkrad/VapourSynth-RIFE-ncnn-Vulkan/blob/master/RIFE/docs/readme.md).

DTL
16th May 2026, 08:09
To check with AVS+ mvtools we need AVS+ version of that filter. Also export of the MVs from RIFE may be good to offload some computing from CPU but may be not great for quality:

1. I think optical flow (at least at some implementations) is not based on block motion analysis and compensation (even with overlapping workarounds to fix some block-based artifacts). The neural networks may use different ways of motion/image interpolation. So export of MVs and usage with mvtools-based motion compensation filters (MCompensate or MDegrain) may result in lower (different) quality.

2. The previous years testing of RIFE for denoise (but with +-delta source frames input in AVS+ RIFE filter) shows that (that tested versions) are not significantly better in motion analysis in comparison with MAnalyse onCPU at the complex areas (low contrast and high noise levels) or not better at all.

The request at some repository at github about RIFE development to make a special version of RIFE engine for denoising (several frames analysis and real motion compensation of reference frames to current timestamp using current frame only as objects views sources) received zero replies and was closed after several years as getting no activity. The initial design of RIFE may be mostly for fast motion interpolation for 'smooth playback' and not for precise motion compensation at complex sources for high quality denoise work.

So after someone (Asd-g ?) will make AVS+ version of this filter interface (and also compatible with AVS+ mvtools branch by MVs clip format if it has some difference from VS branch ?) it may be good to test how RIFE-MAnalyse works in performance/quality in comparison with mvtools MAnalyse.

Anyway it will be the 3rd known ME engine for mvtools in addition to onCPU MAnalyse (mvtools internal) and DX12-ME (system hardware MPEG encoder) and now we may have RIFE-based. It may be used as 3 different sources of MVs for averaging processing with new filters like MAverage for possible refining of the MVs quality from 3 or more different sources.

Selur
16th May 2026, 13:04
btw. any plans to port DX12-ME (system hardware MPEG encoder) also to Vapoursynth?

DTL
16th May 2026, 17:35
I simply do not know how to do VS interface to the filter. I still never use VS and do not know how to install and make scripts with python. To make it working with VS we simply need to add VS interface to the updated MAnalyse filter with option to use DX12. Try to ask Asd-g ? But I think he does not like to touch any software with non-free parts like DirectX for MS Windows. The all DX12 part mostly located in the 2 new functions like 'init-DX12' and 'get_frame_dx12' in the MAnalyse filter (Manalyse.cpp) and a few additions to GroupofPlanes and Planes of blocks to support onCPU SAD computing if it not come from DX12 shader (it is not perfect match onCPU SAD as I remember because of different sub-sample shifting filter/engine in ComputeShader and I can not correctly debug it).

So you better need to ask VS programmers to port that version/functions of MAnalyse to VS.