View Full Version : MVTools


Pages : 1 [2]

josey_wells
14th August 2008, 04:03
Actually I have not played around with dct settings at all :(

I should have posted one more post to get that magic 1000 which you just got. :)

josey_wells
14th August 2008, 12:43
There is an issue with MVFlowFps!

Ok, I have confirmed there is a problem.

Can someone do compares of the motion vectors produced from V1.9.6.2 and V1.9.5.7 for MVAnalyse? This will give me and idea where to start looking.

moviefan
14th August 2008, 14:07
Just a little basic question compared to current discussions: How do I efficiently use the block- and overlap size? What settings make sense for which situation? (maybe also discussing SD vs. HD)

mikeytown2
15th August 2008, 00:30
@josey_wells
Rename the 1.9.5.7 Dll from mvtools.dll to mvtoolsOLD.dll, have the 1.9.6.2 mvtools.dll as is, and then run this code. It could be a little unstable but it does work.


a = ColorBars(320,240).Trim(0,29)

KenBurnsEffect(a, startAlign=5, endAlign=5, endZoomFactor=50)
last + KenBurnsEffect(a, startZoomFactor=50, startAlign=5, endAlign=1, endZoomFactor=50)
last + KenBurnsEffect(a, startZoomFactor=50, startAlign=1, endAlign=3, endZoomFactor=50)
last + KenBurnsEffect(a, startZoomFactor=50, startAlign=3, endAlign=9, endZoomFactor=50)
last + KenBurnsEffect(a, startZoomFactor=50, startAlign=9, endAlign=7, endZoomFactor=50)
last + KenBurnsEffect(a, startZoomFactor=50, startAlign=7, endAlign=1, endZoomFactor=50)
last + KenBurnsEffect(a, startZoomFactor=50, startAlign=1, endAlign=5)

ConvertToYV12()


vectors=mvtools_MVAnalyseMulti(refframes=1, idx=1)
bw1_vec1=vectors.mvtools_MVMultiExtract(0)
fw1_vec1=vectors.mvtools_MVMultiExtract(1)
a=last.mvtools_MVFlowFps(bw1_vec1,fw1_vec1, idx=2).Subtitle("1.9.6.2").ConvertFPS("ntsc_video")
b=last.mvtools_MVShow(bw1_vec1).Subtitle("1.9.6.2 Backwards")
c=last.mvtools_MVShow(fw1_vec1).Subtitle("1.9.6.2 Forwards")

bw1_vec2=mvtoolsOLD_MVAnalyse(isb=true, idx=3)
fw1_vec2=mvtoolsOLD_MVAnalyse(isb=false, idx=4)
d=last.mvtools_MVFlowFps(bw1_vec2,fw1_vec2, idx=5).Subtitle("1.9.6.2 MVFlowFps w/ 1.9.5.7 MVAnalyse").ConvertFPS("ntsc_video")
e=last.mvtoolsOLD_MVShow(bw1_vec2).Subtitle("1.9.5.7 Backwards")
f=last.mvtoolsOLD_MVShow(fw1_vec2).Subtitle("1.9.5.7 Forwards")

g=last.mvtoolsOLD_MVFlowFps(bw1_vec2,fw1_vec2, idx=8).Subtitle("1.9.5.7").ConvertFPS("ntsc_video")
h=StackComparer(last.mvtools_MVShow(bw1_vec1),last.mvtoolsOLD_MVShow(bw1_vec2),"1.9.6.2 Backwards - 1.9.5.7 Backwards")

j=last.mvtoolsOLD_MVFlowFps(bw1_vec1,fw1_vec1, idx=10).Subtitle("1.9.5.7 MVFlowFps w/ 1.9.6.2 MVAnalyse").ConvertFPS("ntsc_video")
k=StackComparer(last.mvtools_MVShow(fw1_vec1),last.mvtoolsOLD_MVShow(fw1_vec2),"1.9.6.2 Forwards - 1.9.5.7 Forwards")


w=StackHorizontal(a,b,c)
x=StackHorizontal(d,e,f)
y=StackHorizontal(g,h)
z=StackHorizontal(j,k)
StackVertical(w,x,y,z)


Function StackComparer(clip x, clip y, string s)
{
sb1=Subtract(x,y)
sb1=Overlay(sb1.Levels(128,1,130,0,255),
\ sb1.Levels(126,1,128,0,255).PointResize(320*4,240*4).ConvertToYUY2().Invert("y").ConvertToRGB32().PointResize(320,240)
\ ,mode="add").Levels(23,1,255,0,255).Subtitle("Black pixels means less/no change")
s5=Compare(x,y)
stackhorizontal(s5,sb1).Subtitle(String(s), Align=2)
}




My bet is the problem lies with 1.9.6.2 MVFlowFps.

mikeytown2
15th August 2008, 07:58
Boulder, since you have a lot more testing than I do. What value of iDct seems to give the best denoise and detection of scene change. I normally use iDct=1 but was wondering what other experience is.

I wrote a little YUY2 test script



Function mover(clip a)
{
KenBurnsEffect(a, startZoomFactor=50, startAlign=1, endAlign=5)
}
b = ColorBars(640,480).ConvertToYUY2()
b.Trim(0,29).mover()


vectors=mvtools_MVAnalyseMulti(blksize=16, overlap=8, divide=2, refframes=1, idx=1, dct=4, truemotion=true, pel=2)
bw1_vec1=vectors.mvtools_MVMultiExtract(0)
fw1_vec1=vectors.mvtools_MVMultiExtract(1)

#~ bw1_vec1=mvtoolsOLD_MVAnalyse(isb=true, blksize=16, overlap=8, divide=2, idx=2, dct=4, truemotion=true, pel=2)
#~ fw1_vec1=mvtoolsOLD_MVAnalyse(isb=false, blksize=16, overlap=8, divide=2, idx=2, dct=4, truemotion=true, pel=2)


c=mvtoolsOLD_MVFlowFps(last, bw1_vec1, fw1_vec1, num=60000,den=1001)
b= mover(b.Trim(0,58)).AssumeFPS("ntsc_double")
Compare(c, b)
StackHorizontal(b)
StackVertical(StackHorizontal(Overlay(b,c,opacity=0.5), StackComparer(c,b,""))).Trim(2,56)

Function StackComparer(clip x, clip y, string s)
{
sb1=Subtract(x,y)
sb1=Overlay(sb1.Levels(128,1,130,0,255),
\ sb1.Levels(126,1,128,0,255).PointResize(640*4,480*4).ConvertToYUY2().Invert("y").ConvertToRGB32().PointResize(640,480)
\ ,mode="add").Levels(34,1,255,0,255).Subtitle("Black pixels means less/no change")
sb1
}


for YUY2 dct=4 is the best (PSNR 53.11), followed by dct=1 (PSNR 53.10)

This gave me the best (PSNR 53.11) results with MVFlowFps.
(blksize=16, overlap=8, divide=2, idx=1, dct=4, truemotion=true, pel=2)



EDIT:
search=3 & dct=1 gives better (PSNR 53.36) results...
baised off of my PSNR tests, I'll use
(blksize=16, overlap=8, divide=2, idx=1, dct=4, truemotion=true, pel=2, search=0)
It's what I like to call best bang for your buck (PSNR 53.12).

Going to pel=4 i get PSNR=48.62
Going to pel=1 i get PSNR=49.50

Edit2:
(blksize=16, overlap=8, divide=2, idx=1, dct=4, truemotion=true, pel=2, search=0, searchparam=0, lambda=2700, sadx264=7, pnew=9)
PSNR=53.29

Mutant_Fred
15th August 2008, 16:50
josey_wells,
As I understand, ...Multi functions is now free from thead locking. Other (non-multi) functions (MVFlowFPS, etc) is still not, right ?
In this case, we should use for these (other) functions the v.1.9.5.7 threading implementation (it works fine for most people besides Mutant_Fred).


Hi Fizick,
I don't have much time these days as I was on vacation far from my computer(and still am next week actually, just passing by;)), but I really ought to try with newest versions from Josey_Wells. Then I can tell if I still encounter same issues. I have hope that these do correct them.

Mutant_Fred

moviefan
15th August 2008, 16:55
@ mikeytown2: How do you calculate the PSNR?

Gavino
15th August 2008, 18:08
How do you calculate the PSNR?
You don't have to - the Compare filter writes it out on top of its resulting clip.

For details of the calculation, see for example here (http://en.wikipedia.org/wiki/PSNR).

moviefan
15th August 2008, 19:59
Which clips do you compare exactly? The processed (by MVTools from josey_wells) and which other one?

mikeytown2
15th August 2008, 21:14
@moviefan
I generate the clip using KenBurnsEffect(). By adjusting trim I have 2 clips, one at 30fps the other at 60fps. I then use MVTools to to bring the 30fps up to 60fps and compare the 2.

scharfis_brain
15th August 2008, 21:35
that is not a valid test.
you don't have differntial motion (several objects with different speed and trajetories moving and also showing occlusions or transparency).

just take any natural video as reference... that will be better

mikeytown2
15th August 2008, 22:25
@scharfis_brain just did a test on one of my DV clips (http://rapidshare.com/files/137612375/DV-Cam-Test.avi.html). In short my results from above almost correlate with "real" footage. I will admit that this footage isn't a car crash, in that there isn't a lot going on.

Results
33.35016: (blksize=4, overlap=2, divide=0, idx=1, dct=4, truemotion=true, pel=2, search=0, searchparam=0, lambda=2700, sadx264=7, pnew=9)
33.48795: (blksize=8, overlap=4, divide=2, idx=1, dct=4, truemotion=true, pel=4)
33.49406: (idx=1, pel=4)
33.60581: (blksize=16, overlap=8, divide=2, idx=1, dct=4, truemotion=true, pel=4)
33.98558: (blksize=8, overlap=4, divide=2, idx=1, dct=4, truemotion=true, pel=2)
34.02027: (blksize=8, overlap=4, divide=2, idx=1, dct=1, truemotion=true, pel=2, search=3, sadx264=7)
34.02353: (idx=1, dct=1)
34.03998: (idx=1)
34.04628: (idx=1, dct=4)
34.05154: (blksize=16, overlap=8, divide=2, idx=1, dct=4, truemotion=true, pel=2, search=3, searchparam=0, lambda=2700, sadx264=7, pnew=9)
34.05336: (blksize=16, overlap=8, divide=2, idx=1, dct=4, truemotion=true, pel=2)
34.07283: (blksize=16, overlap=8, divide=2, idx=1, dct=0, truemotion=true, pel=2, search=0, searchparam=0, lambda=2700, sadx264=7, pnew=9)
34.07558: (idx=1, dct=1, search=3)
34.08640: (blksize=16, overlap=8, divide=2, idx=1, dct=4, truemotion=true, pel=2, search=0, searchparam=0, lambda=2700, sadx264=7, pnew=9)
34.09980: (blksize=16, overlap=8, divide=2, idx=1, dct=1, truemotion=true, pel=2, search=3, sadx264=7) - Very SLOW


AVISource("DV-Cam-Test.avi").ConvertToYUY2(interlaced=true)
SeparateFields()
SelectEven()
BicubicResize(320,240)
b=last
SelectEven()


vectors=mvtools_MVAnalyseMulti(blksize=16, overlap=8, divide=2, idx=1, dct=4, truemotion=true, pel=4)
bw1_vec1=vectors.mvtools_MVMultiExtract(0)
fw1_vec1=vectors.mvtools_MVMultiExtract(1)

#~ bw1_vec1=mvtoolsOLD_MVAnalyse(isb=true, blksize=16, overlap=8, divide=2, idx=2, dct=4, truemotion=true, pel=2)
#~ fw1_vec1=mvtoolsOLD_MVAnalyse(isb=false, blksize=16, overlap=8, divide=2, idx=2, dct=4, truemotion=true, pel=2)


c=mvtoolsOLD_MVFlowFps(last, bw1_vec1, fw1_vec1, num=30000,den=1001)
Compare(c, b, logfile="u.txt")
StackHorizontal(b)
StackVertical(StackHorizontal(Overlay(b,c,opacity=0.5), StackComparer(c,b,"")))
Trim(2,framecount()-2)
SelectOdd()

Function StackComparer(clip x, clip y, string s)
{
sb1=Subtract(x,y)
sb1=Overlay(sb1.Levels(128,1,130,0,255),
\ sb1.Levels(126,1,128,0,255).PointResize(320*4,240*4).ConvertToYUY2().Invert("y").ConvertToRGB32().PointResize(320,240)
\ ,mode="add").Levels(34,1,255,0,255).Subtitle("Black pixels means less/no change")
sb1
}


Load the txt file into excel and do an average on the PSNR column. The odd thing is pel=4 seems to be worse then pel=2 and large blocks are better.

josey_wells
15th August 2008, 23:36
OK, here is V1.9.6.5.

http://rapidshare.com/files/137620112/MVTools_V1.9.6.5.rar.html

I found out that I broke it between V1.9.6.1 Final and V1.9.6.2 Final.

I have compared, MVFlow, MVFlowBlur, MVFlowFPS, MVFlowIter, MVDegrain, MVAnalyse, MVCompensate, etc. between this version and FZick's V1.9.5.7

This contains all the enhancements listed in the previous post. Plus the MT flag for MVAnalyseMulti, and MVDegrainX, and MVDegrainMulti. Default is true which will run functions multithreaded. If set false then will run threads singurlarly.

This one should be pretty much bulletproof. But alas I can be proven wrong.

mikeytown2
16th August 2008, 00:23
@josey_wells Bug in MVAnalyse/MVAnalyseMulti with blksize=16 and overlap!=0. So far everything else seems to be ok.

Crash report from VDub

VirtualDub crash report -- build 29958 (release)
--------------------------------------

Disassembly:
012b2360: 43 inc ebx
012b2361: 3a5c446f cmp bl, [esp+eax*2+6fh]
012b2365: 63756d arpl [ebp+6dh], si
012b2368: 656e outsb
012b236a: 7473 jz 012b23df
012b236c: 20616e and [ecx+6eh], ah
012b236f: 64205365 and fs:[ebx+65h], dl
012b2373: 7474 jz 012b23e9
012b2375: 696e67735c4d69 imul ebp, [esi+67h], 694d5c73
012b237c: 6b652043 imul esp, [ebp+20h], 43h
012b2380: 61 popad
012b2381: 7270 jc 012b23f3
012b2383: 65725c jc 012b23e2
012b2386: 44 inc esp
012b2387: 65736b jnc 012b23f5
012b238a: 746f jz 012b23fb
012b238c: 705c jo 012b23ea
012b238e: 56 push esi
012b238f: 6964656f20546f imul esp, [ebp+6fh], 6f6f5420
6f
012b2397: 6c insb
012b2398: 735c jnc 012b23f6
012b239a: 56 push esi
012b239b: 69727475616c44 imul esi, [edx+74h], 446c6175
012b23a2: 7562 jnz 012b2406
012b23a4: 2d312e382e sub eax, 2e382e31
012b23a9: 345c xor al, 5ch
012b23ab: 56 push esi
012b23ac: 69727475616c44 imul esi, [edx+74h], 446c6175
012b23b3: 7562 jnz 012b2417
012b23b5: 2e7664 jbe 012b241c
012b23b8: 6900c05bc38d imul eax, [eax], 8dc35bc0
012b23be: 7600 jbe 012b23c0
012b23c0: 53 push ebx
012b23c1: 8b442408 mov eax, [esp+08h]
012b23c5: 8b4c240c mov ecx, [esp+0ch]
012b23c9: 8b542410 mov edx, [esp+10h]
012b23cd: 8b5c2414 mov ebx, [esp+14h]
012b23d1: 0f1002 movups xmm0, [edx]
012b23d4: 0f100c1a movups xmm1, [edx+ebx]
012b23d8: 8d145a lea edx, [edx+ebx*2]
012b23db: 0f1012 movups xmm2, [edx]
012b23de: 0f101c1a movups xmm3, [edx+ebx]
012b23e2: 8d145a lea edx, [edx+ebx*2]
012b23e5: 660ff600 psadbw xmm0, [eax] <-- FAULT
012b23e9: 660ff60c08 psadbw xmm1, [eax+ecx]
012b23ee: 8d0448 lea eax, [eax+ecx*2]
012b23f1: 0f1022 movups xmm4, [edx]
012b23f4: 660ffdc1 paddw xmm0, xmm1
012b23f8: 660ff610 psadbw xmm2, [eax]
012b23fc: 660ff61c08 psadbw xmm3, [eax+ecx]
012b2401: 8d0448 lea eax, [eax+ecx*2]
012b2404: 0f102c1a movups xmm5, [edx+ebx]
012b2408: 8d145a lea edx, [edx+ebx*2]
012b240b: 660ffdd3 paddw xmm2, xmm3
012b240f: 0f1032 movups xmm6, [edx]
012b2412: 0f103c1a movups xmm7, [edx+ebx]
012b2416: 8d145a lea edx, [edx+ebx*2]
012b2419: 660ffdc2 paddw xmm0, xmm2
012b241d: 660ff620 psadbw xmm4, [eax]
012b2421: 660ff62c08 psadbw xmm5, [eax+ecx]
012b2426: 8d0448 lea eax, [eax+ecx*2]
012b2429: 0f100a movups xmm1, [edx]
012b242c: 660ffde5 paddw xmm4, xmm5
012b2430: 660ff630 psadbw xmm6, [eax]
012b2434: 660ff63c08 psadbw xmm7, [eax+ecx]
012b2439: 8d0448 lea eax, [eax+ecx*2]
012b243c: 0f10141a movups xmm2, [edx+ebx]
012b2440: 8d145a lea edx, [edx+ebx*2]
012b2443: 660ffdf7 paddw xmm6, xmm7
012b2447: 0f101a movups xmm3, [edx]
012b244a: 660ffdc4 paddw xmm0, xmm4
012b244e: 0f10241a movups xmm4, [edx+ebx]
012b2452: 8d145a lea edx, [edx+ebx*2]
012b2455: 660ffdc6 paddw xmm0, xmm6
012b2459: 660ff608 psadbw xmm1, [eax]
012b245d: 660f db 0fh
012b245f: f6 db 0f6h

Built on Aegis on Sat Aug 09 14:02:26 2008 using compiler version 1400

Windows 5.1 (Windows XP x86 build 2600) [Service Pack 3]

EAX = 01e9c918
EBX = 00000080
ECX = 00000080
EDX = 02410a98
EBP = 000003a3
ESI = 02457440
EDI = 00000800
ESP = 0238fd7c
EIP = 012b23e5
EFLAGS = 00010283
FPUCW = ffff027f
FPUTW = ffffaaaa

Crash reason: Access Violation

Crash context:
An out-of-bounds memory access (access violation) occurred in module 'mvtools'...

...reading address FFFFFFFF.

Pointer dumps:

EAX 01e9c918: 52565656 49494949 41414249 353e4141 35353535 2d2d2d2f 1f1f2a2d 151f1f1f
EDX 02410a98: 8b9b9b9b 80808080 70707280 586d7070 58585858 48484852 2e354848 2e2e2e2e
ESI 02457440: 00000004 00000003 00000010 00000010 0000000c 00000001 00000000 00000008
ESP 0238fd78: 00244cb0 02410898 012d69c4 01e9c918 00000080 02410898 00000080 00000000
0238fd98: 00000000 02e0ffff 00000000 02457440 00000000 00000000 012d5862 00000014
0238fdb8: 00000028 00000000 00000000 00000000 00000000 01b927b4 00000010 fffffff0
0238fdd8: 00000008 00000004 00000004 00000000 00000000 00007d00 0000001e 01e9f950

Thread call stack:
012b23e5: mvtools!000123e5
012d69c4: mvtools!000369c4
012d5862: mvtools!00035862
012d4411: mvtools!00034411
012d4092: mvtools!00034092
7c910202: ntdll!RtlAllocateHeap [7c900000+100a4+15e]
0130b7c4: mvtools!0006b7c4
7c910202: ntdll!RtlAllocateHeap [7c900000+100a4+15e]
013396f8: mvtools!_AvisynthPluginInit2@4 [012a0000+6c5d0+2d128]
7c910202: ntdll!RtlAllocateHeap [7c900000+100a4+15e]
013397a0: mvtools!_AvisynthPluginInit2@4 [012a0000+6c5d0+2d1d0]
7c910202: ntdll!RtlAllocateHeap [7c900000+100a4+15e]
7c80b713: kernel32!GetModuleFileNameA [7c800000+b55f+1b4]
7c910202: ntdll!RtlAllocateHeap [7c900000+100a4+15e]

-- End of report

Spuds
16th August 2008, 02:32
I can't get anything to work correctly, multi or not, with the latest build. The resulting frames are completely corrupt. I tried the core2 and p4 compiles with the same results. The lower half of each frame appears to be a composite of two different frames and the top half seems to have some form of chroma corruption.

josey_wells
16th August 2008, 02:35
This should fix.

http://rapidshare.com/files/137645849/MVTools_V1.9.6.6.rar.html

There was a problem with all YV12 frames, I only tested YUY2.

Zep
16th August 2008, 07:14
This should fix.

http://rapidshare.com/files/137645849/MVTools_V1.9.6.6.rar.html

There was a problem with all YV12 frames, I only tested YUY2.

MVFlowFps crashes instantly for me with this version with

An out-of-bounds memory access (access violation) occurred in module 'mvtools'...
...reading address 00000000.


if I comment out MVFlowFps line it runs fine. (the official release works fine)

backward_vec = video.MVAnalyse(blksize=16, truemotion=true, isb = true, chroma=true, pel=1, search=3, searchparam=1, idx=1)
forward_vec = video.MVAnalyse(blksize=16,truemotion=true,isb = false, chroma=true, pel=1, search=3, searchparam=1, idx=1)
video=video.MVFlowFps(backward_vec, forward_vec, num=4*FramerateNumerator(video),den=FramerateDenominator(video), mask=0, idx=1)

IanB
16th August 2008, 08:57
@mikeytown2,...
012b23e5: 660ff600 psadbw xmm0, [eax] <-- FAULT
...
EAX = 01e9c918 <-- This address is not Mod 16!

map1742
16th August 2008, 09:57
@josey_wells

I was just documenting a bug report for YV12 chroma corruption in 1.9.6.2 when using a filtered clip in mvanalyse but you may already fixed it in 1.9.6.6 (at least for a blksize of 8). :)

However 1.9.6.5 and 1.9.6.6 both immediately crash for me with a blksize of 16 in the same code section as @mikeytown2 above. This for both YV12 and YUY2.

On a Q6600 with 1.9.6.6 and mvdegrain3 with a blksize of 8 on my test script I am seeing 10 to 11 fps with the multi versions compared to 1.9.5.7 at 2 to 3 fps.

Thank you for your work on threading this.:thanks:

Boulder
16th August 2008, 17:06
Using the multithreaded MVTools tends to eat up quite a lot of memory (with Avisynth 2.5.8RC3). I have had to set SetMemoryMax to 384 to cope with this on my 2GB RAM computer, running two encoders simultaneously. My regular processing script takes something like 700-800MB in HC with these settings. How's the memory usage on other users computers?

Even when running two encoders, I noticed that allowing MVTools to use multithreading is more efficient than using mt=false to disable multithreading :) With one encoder and mt=true, I got ~5.2 fps - with two encoders and mt=true, I get a total of ~7.0 fps. With mt=false in the latter case, I got 6.7-6.8 fps.

josey_wells
16th August 2008, 19:00
OK here is fix for blocksize 16

http://rapidshare.com/files/137795705/MVTools_V1.9.6.7.rar.html

Hopefully last issue :)

Fizick
16th August 2008, 22:57
thanks for fast develpment!
some questions:

1. A multitude of memory fragmentation and alignment problems have been fixed.

Magnitude was fixed? How it is important?

2. A bug in YUY2 planes have been fixed.

Please be more specific, where was the bug. Your code has massive cosmetic changes (rewriting) and it is difficult to analyse and compare. Comments (marks) in changed code will be very useful. IMHO, it wold be better do not touch working code lines.

6. I have fixed several other stability problems. The worst being where a destructor was called twice after the object was detroyed.

Same question, where?

3. At more than one hundred of places delete was used where delete [] was needed.

Opps, will fix it. But they are probably all in filters (not frame) destructor, so not so important (do not use Animate with MTtools :).

4. All the filters are being updated to not ask for frames if not needed, i.e. already in cache. Filters will need testing after this because of the scope of changes. This will also prep them to become multithreaded as time permits.

dont quite understand it, but have a question. Your AnaliseMulti function calculate all "mult" stacked frames at once or needed (requsted) only?

5. I want to redo the cache mechanism for idx since I believe it can be made clearner using the STL map class.

Some time ago I wrote, that it is better (IMO) to remove idx completely and replace it with MVPrepare, to use normal Avisynth cache (may be v.2.6)

Although I doubt this will ever be officially adopted and always remain a branch.

really I am not official person.
However, due to combination of your new great lines of code with massive cosmetic changes (all those ++, etc) it is hardly to check (understand) and continue development (for me). For example, now I try implement Didee's request, based on v1.9.5.7 (and may be even older version).

But what is bad with "branch" if you and people will use it?
May be some day other developer will continue. Its open source world. :)

IanB
17th August 2008, 01:52
@Fizick,

Now you understand why a lot of open source projects only accept changes in the form of diff patches.

Diff patch submission encourages the submitter to express their idea in a tidy concise form. The more concise and tidy the quicker it gets reviewed, accepted and imported into the core source.

It stops senseless reformatting with just white space changes, that makes the job of the integrator that much harder, by playing on the pride of the submitter. Nobody wants to get a reputation for submitting patches that delete all the lines and insert all these new ones.


@josey_wells,

You have done much good work here. I would encourage you to take a few hours to review all your changes with a good source diff program (M$ windiff is reasonable) and remove all the white space and white code changes you have made so the real changes you have made can shine out.

thetoof
17th August 2008, 07:53
Woah, some awesome development was made here in a short while!
As for what happens with mvtools... imo it'd be a shame to have 2 branches, 1 "official" and 1 multi-threaded with a new concise syntax... but maybe no implementation of further development. What IanB suggested seems to be the best solution for everybody, even if it's more work for you, josey_wells, who already gave us a lot of your time. Thanks.

Anyways, on with my request: I have yet to read all the posts and understand fully the new syntax, so I was wondering if someone could post a modded version of MCBob, TempGaussMC_beta1 and TemporalDegrain since they are very ressource hungry and that the speed boost we can now have would be more than welcome.

mikeytown2
17th August 2008, 08:14
Here are the 2 MC scripts that I use, haven't used TemporalDegrain so maybe someone else can upload their mod's.
http://rapidshare.com/files/137910353/MCbob_TempGaussMC.zip.html

In my MCbob I call the dll version of Vinverse (http://bengal.missouri.edu/~kes25c/vinverse.zip), it's also the nnedi version

Leak
17th August 2008, 20:21
a good source diff program (M$ windiff is reasonable)
I'd suggest WinMerge (http://www.winmerge.org/) if I may... :)

josey_wells
17th August 2008, 23:56
Magnitude was fixed? How it is important?

I fixed several places in the code and don't want to list this all. Here is a good example.

blocks = new FakeBlockData*[nBlkCount];
for ( int j = 0, blkIdx = 0; j < nBlkY; j++ )
for ( int i = 0; i < nBlkX; i++, blkIdx++ )
blocks[blkIdx] = new FakeBlockData(i * (nBlkSizeX - nOverlapX), j * (nBlkSizeY - nOverlapY));

was replaced by

blocks = new FakeBlockData[nBlkCount];
int blkYSpace=(nBlkSizeY - nOverlapY);
int blkXSpace=(nBlkSizeX - nOverlapX);
int blkIdx=0;
for ( int j = 0; j < nBlkY; ++j ) {
int j1 = j * blkYSpace;
for ( int i = 0; i < nBlkX; ++i)
blocks[blkIdx++].Init(i * blkXSpace, j1);
}

While the first one works and is functional code. It can do up to 20000 news on DVD video and closer to 140000 on HD video. I replaced with a single new and then inited each which allocates a single block of memory for the advantage of faster access and less fragmentation.


Please be more specific, where was the bug. Your code has massive cosmetic changes (rewriting) and it is difficult to analyse and compare. Comments (marks) in changed code will be very useful. IMHO, it wold be better do not touch working code lines.

const int awidth = min(nSrcPitchYUY2>>1, (nWidth+7) & -8);

While I haven't worked it out to see whether the complement of -8 gives the correct bits the way it should be expressed is ~0x7 or ~7 depending on your preference.


Same question, where?

class MVClip : public GenericVideoFilter, public FakeGroupOfPlanes, public MVAnalysisData {
...
}

MVClip::~MVClip()
{
FakeGroupOfPlanes::~FakeGroupOfPlanes(); //v1.2.1
}

When the class derives from a base class, the destructor is called automatically. So the call in the destructor of MVClip results in a second call since the base class was destroyed first. I acutally changed fakegroupofplanes to be a pointer member which does require an explicit delete to invoke the destructor.


Opps, will fix it. But they are probably all in filters (not frame) destructor, so not so important (do not use Animate with MTtools :).

Almost all of them were in the destuctors of the filters where in the constructor new x[y] was performed and delete y was done instead of delete [] y. In most cases would not cause a problem except when possibly exiting virtualdub or loading a new script etc.

dont quite understand it, but have a question. Your AnaliseMulti function calculate all "mult" stacked frames at once or needed (requsted) only?
Some time ago I wrote, that it is better (IMO) to remove idx completely and replace it with MVPrepare, to use normal Avisynth cache (may be v.2.6)

All multi stacked frames are calculated at once one in each thread. This was how a great performance improvment could be achieved.

I haven't done anything to the cache mechanism yet. I agree that it needs an overhaul or removal but I dont't want to take on that task now. :)


However, due to combination of your new great lines of code with massive cosmetic changes (all those ++, etc) it is hardly to check (understand) and continue development (for me). For example, now I try implement Didee's request, based on v1.9.5.7 (and may be even older version).

But what is bad with "branch" if you and people will use it?
May be some day other developer will continue. Its open source world. :)

I think the code is actually easier to understand now in a lot of cases since I took out code that was repeated in every filter and created some new class functions to perform the same purpose. This resulted in smaller code which is easier to see what is really happening.

Also I see nothing wrong with white space changes. www.perforce.com has a great diff program called p4diff which is free. It can be used to diff my files against originals to see only real code changes. May modern diff programs can be used to ignore line endings and white spaces.

Also there is a multitude of changes due to the addition of threading class, semaphore class, critical section class, thread files for MVDegrain, MVAnalyseMulti as well as factoring out common code for MVDegrain into a single base class moving out common code etc.

In the end all I did was just some code consilidation, bug fixes, performance improvements, and multithreading. While it took me a long time I do not take any credit for the algorithms as all I did was make them run better, faster, and more reliably.

I would be interested in performance results.

I could also look at mulithreading some of the other functions. The impact of the functions can be evaluated by doing the following:


c=last
MVMulti=c.MVAnalyseMulti(refframes=x, ...)
c.MVShow(MVMulti.MVMultiExtract(0))

This will force MVAnalyseMulti to run and when MVFLow, MVFps, etc. are added to the script the performance hit can be evaluated as to whether mulithreading will provde performance benifit.

Fizick
18th August 2008, 16:50
const int awidth = min(nSrcPitchYUY2>>1, (nWidth+7) & -8);

IMO, this code is correct and not a bug. There was no any need to rewrite it.

Thanks, I will remove ~FakeGroupOfPlanes();
Why you did not simply remove it?

About stacked multi frames. So, even if some filter use MVExtract to extract one vector subframe, all rest unneeded multi stacked vectors will be calculated?

josey_wells
18th August 2008, 17:14
IMO, this code is correct and not a bug. There was no any need to rewrite it.

I looked up two's complement for -8 and it has the same reprensentation as ~0x7. So yes this line would actually work as originally written.

About stacked multi frames. So, even if some filter use MVExtract to extract one vector subframe, all rest unneeded multi stacked vectors will be calculated?


The first reference to MVMultiExtract will cause a full evaluation of all the requested frames in MVAnalyseMulti. Subsequent request to MVMultiExtracts will cause no extra computation since all frames have already been completed. The only way I could perform threading was to thread the computation of the frame calculations.

Fizick
18th August 2008, 17:43
Thanks for clarification!

EuropeanMan
19th August 2008, 00:21
Nerds all of you!

J/K -wonderful work done here! Can't wait to start testing! thanks to josie & fizick for sweet filters... :) Keep on rockin!

egrimisu
19th August 2008, 14:11
Where can i find the latest version of MVTools optimized for multithread?

Ranguvar
19th August 2008, 14:24
Err... download the latest package josey_wells has posted... top of this thread...

Fizick
19th August 2008, 18:48
1. I tried latest version on old Ahtlon 64, so I use classic MVAnalyse-MVDegrain2 script.
The speed is about 8 fps (blksize=16, overlap4).
But I have 10 fps with v1.9.5.7 for same script.
BTW, I recompile v1.9.6.7 with my development env (VCToolkit2003), but speed is still 8 fps.
Disabling mt=false do nothing.

2. I sent preliminary v1.10 with MVRecalculate to Didee for testing. ;)

mikeytown2
19th August 2008, 23:11
Is there any way to improve MVAnalyse? This is moving 10 px per frame, no sub pixels yet it still is giving a fairly low PSNR of 45.96


Global b = ColorBars(320,240, "YUY2").Trim(0,64)

Function ttt(clip c, int x, int y)
{
c.Overlay(b,x,y)
#~ Subtitle(String(x), Align=2)
}
BlankClip(b,64, 640,480)
F30 = Animate(0,32, "ttt", 0,120, 320,120)
F60 = Animate(0,64, "ttt", 0,120, 320,120).Trim(0,62)


vectors=F30.mvtools_MVAnalyseMulti(blksize=16, overlap=8, divide=2, idx=1, dct=4, truemotion=true, pel=2, search=0, searchparam=0, lambda=2700, sadx264=7, pnew=9)
bw1_vec1=vectors.mvtools_MVMultiExtract(0)
fw1_vec1=vectors.mvtools_MVMultiExtract(1)
F60_2=F30.mvtools_MVFlowFps(bw1_vec1, fw1_vec1, num=60000,den=1001).Trim(0,62)

Compare(F60_2, F60)
StackHorizontal(last,StackComparer(F60_2,F60, ""))
SelectOdd()

Function StackComparer(clip x, clip y, string s)
{
sb1=Subtract(x,y)
sb1=Overlay(sb1.Levels(128,1,130,0,255),
\ sb1.Levels(126,1,128,0,255).PointResize(640*4,480*4).ConvertToYUY2().Invert("y").ConvertToRGB32().PointResize(640,480)
\ ,mode="add").Levels(34,1,255,0,255).Subtitle("Black pixels means less/no change")
sb1
}


Ideally this should be able to hit close to 100

IanB
20th August 2008, 00:11
...
F30 = F60.SelectEven() # Avoid Overlay chroma subsabsampling
...

mikeytown2
20th August 2008, 00:34
Still get the same PSNR of 45.96

Global b = ColorBars(320,240, "YUY2").Trim(0,64)

Function ttt(clip c, int x, int y)
{
c.Overlay(b,x,y)
#~ Subtitle(String(x), Align=2)
}
BlankClip(b,64, 640,480)
F60 = Animate(0,64, "ttt", 0,120, 320,120).Trim(0,62)
F30 = F60.SelectEven().AssumeFPS("ntsc_video")


vectors=F30.mvtools_MVAnalyseMulti(blksize=16, overlap=8, divide=2, idx=1, dct=4, truemotion=true, pel=2, search=0, searchparam=0, lambda=2700, sadx264=7, pnew=9)
bw1_vec1=vectors.mvtools_MVMultiExtract(0)
fw1_vec1=vectors.mvtools_MVMultiExtract(1)
F60_2=F30.mvtools_MVFlowFps(bw1_vec1, fw1_vec1, num=60000,den=1001).Trim(0,62)


Compare(F60_2, F60)
StackHorizontal(last,StackComparer(F60_2,F60, ""))
SelectOdd()

#~ F60

Function StackComparer(clip x, clip y, string s)
{
sb1=Subtract(x,y)
sb1=Overlay(sb1.Levels(128,1,130,0,255),
\ sb1.Levels(126,1,128,0,255).PointResize(640*4,480*4).ConvertToYUY2().Invert("y").ConvertToRGB32().PointResize(640,480)
\ ,mode="add").Levels(34,1,255,0,255).Subtitle("Black pixels means less/no change")
sb1
}

morsa
20th August 2008, 14:05
No matter what I do or what kind of script I use, when calling MVAnalyseMulti, the scripts just exit after ~800 frames.

Image size is 1920x1080 / 1088 .I tried using 1920x540 / 544 with same results

jeffy
20th August 2008, 15:02
@morsa:
Have you tried SetMemoryMax(512) or less at the beginning of your script? Does your source file use DirectShowSource for loading?

Dark Shikari
21st August 2008, 01:52
Bug report from Kokotier:
Hello I have found a bug.
Download this steam http://rapidshare.com/files/138843307/zzzz.demuxed.zip.html
Load it (MPEG2 file) in avisynth and add those lines to the avisynth script:
source=last
MVForBack = source.MVAnalyseMulti(refframes=1, pel = 2, overlap=2, overlapv=2, sharp=1, idx = 1,blksize=16,search=3,chroma=true,global=true)
source.mvshow(MVForBack)

Look at the frame just before the scenechange, motiondetection is totaly broken.

Fizick
21st August 2008, 22:50
Is there any way to improve MVAnalyse?

Yes, I am sure. But I do not know how exactly :)

More seriously: I consider how to use blocks of different sizes.
It is knewn method (macroblocks, etc). For big features it is better to use big blocks (stable and robust motion estimation), but for small features we need in small blocks.
To do no broke and rewrite MVTools (which coded with constant block size only approach), i try to add function MVRefine for two-stage estimation.

First stage: coarse_vectors=MVAnalyse(blksize=big)
Second stage: fine_vectors=MVRefine(vectors, blksize=small, thSAD=200)
Old vectors are used as a predictors.
This way we will preserve good vectors (update their SAD only),
and replace (re-estimate) bad vectors. Old vectors are used as a predictors. Probably refining is at finest level only.

I almost finished the first beta, hope can sent it to beta-testers soon ;)

Of course, I am not sure, that results will be excited.
But it certainly will be slower. :)

Ranguvar
22nd August 2008, 00:49
Of course it'll be slower xD It's something of an AviSynth law...

but seriously, thanks for your great work :) You, josey_wells, Manao, everyone :)

josey_wells
22nd August 2008, 02:31
I tried latest version on old Ahtlon 64, so I use classic MVAnalyse-MVDegrain2 script.
The speed is about 8 fps (blksize=16, overlap4).
But I have 10 fps with v1.9.5.7 for same script.
BTW, I recompile v1.9.6.7 with my development env (VCToolkit2003), but speed is still 8 fps.
Disabling mt=false do nothing.


I had disabled the BitBlt isse routines and doing memcpy only. The isse routines have been reinstated.

I finally got the rest of what I feel was missing to the multithreaded implementation of MVTools. Here is the new version.

http://rapidshare.com/files/139139361/MVTools_V1.9.6.8.rar.html

This version does away with the MT flag to control multithreading and adds the following two parameters for MVAnalyseMulti, MVDegrainMulti, MVDegrain1, MVDegrain2, MVDegrain3:

1. PreFetch - This will prefetch x frames before starting the threads for processing(default is 1)
2. Threads - This is the maximum number of threads to run concurrently(Default is 64) i.e all threads at once.

For example with the following line
MVMulti=last.MVAnalyseMulti(refframes=2, PreFetch=2, Threads=4)

There can be at most 2*refframes*prefetch=8 threads at once, and at most 4 are running at a time.

For example with the following line
MVDegrainMulti(MVMulti, PreFetch=2, Threads=4)

There can be at most 3*prefetch=6 threads at once, and at most 4 are running at a time.

Some notes:
1. When any thread completes and more data is to be processed a new thread is immediately started
2. Any prefetch greater than 1 will cause results to be cahced and the result return if still within cache. this will be seen as incrementing by prefetch in virtualdub since the cached result is returned immediately

As an example of a script which sets the parameters on a quad core.

#motion denoise
function Denoise(clip c, int "iLevel", int "iTHSAD", int "iBlksize", int "iOverlap", int "iPel", bool "bChroma", \
bool "bTrueMotion", int "iSearch", int "iSharp", int "iDct", int "iPrefetchAnalyse", \
int "iPrefetchDegrain", int "iThreads", int "iQueuedThreads")
{
iLevel =default(iLevel, 2) #default level for degrain
iBlksize =default(iBlksize, 8) #default block size
iOverlap =default(iOverlap, iBlksize/2) #default 1/2 block size
iTHSAD =default(iTHSAD, 400) #default
iPel =default(iPel, 4) #quarter pixel
bChroma =default(bChroma, true) #use chroma
bTrueMotion =default(bTrueMotion, true) #use true motion
iSearch =default(iSearch, 2) #diamond search
iSharp =default(iSharp, 2) #6 tap sharp filter
iDct =default(iDct, 1) #use DCT for SAD
iThreads =default(iThreads, 4) #max number of threads
iQueuedThreads =default(iQueuedThreads, iThreads) #number of queuedthreads
iPrefetchAnalyse=default(iPrefetchAnalyse, LCM(2*iLevel, iQueuedThreads)/(2*iLevel))
iPrefetchDegrain=default(iPrefetchDegrain, LCM(3, iQueuedThreads)/3)

MVMulti=c.MVAnalyseMulti(refframes=iLevel, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, \
truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, Threads=iThreads, \
prefetch=iPrefetchAnalyse, idx=1)
return c.MVDegrainMulti(MVMulti, thSAD=iTHSAD, Threads=iThreads, prefetch=iPrefetchDegrain, idx=1)
}

# Computes the Greatest Common Divisor of two integers
# (Euclid's Algorithm)
function GCD(int a, int b)
{
return (b == 0) ? a : GCD(b, a % b)
}

# Computes the Least Common Multiple of two integers
function LCM(int a, int b)
{
return (a*b) / GCD(a, b)
}

This will prefetch the minimum amount of frames so that the total threads avaialbe is an integral multiple of the number of threads allowed to queued.

Hello I have found a bug.
Download this steam http://rapidshare.com/files/13884330...muxed.zip.html
Load it (MPEG2 file) in avisynth and add those lines to the avisynth script:
source=last
MVForBack = source.MVAnalyseMulti(refframes=1, pel = 2, overlap=2, overlapv=2, sharp=1, idx = 1,blksize=16,search=3,chroma=true,global=true)
source.mvshow(MVForBack)

Look at the frame just before the scenechange, motiondetection is totaly broken.

The line for show should be
source.MVShow(MVForBack.MVMultiExtract(0)) #show bac1

With this build I acheived about a 10-20% improvement and up to 80-90% improvement depending on script.

You may have to set SetMemoryMax down to a value such as 256 is memory problems arise since more prefetching cost more memory and under Win32 memory is limited to about 2GB.

Have fun!

mikeytown2
22nd August 2008, 03:27
@josey_wells
TempGaussMC_beta1 (http://home.arcor.de/dhanselmann/_stuff/?C=M;O=D) bombs with this latest build, tried all 4 dll versions.

josey_wells
22nd August 2008, 03:54
@josey_wells
TempGaussMC_beta1 (http://home.arcor.de/dhanselmann/_stuff/?C=M;O=D) bombs with this latest build, tried all 4 dll versions.

I have found the problem and it has to do with multiple MVAnalyseMulti or MVDegrain in the script.

I will post fix tomorrow.

morsa
22nd August 2008, 07:38
Could this be of any use?

http://research.microsoft.com/~larryz/ZitnickICCV05.pdf


A question: What would happen if one were analizing a wavelet decomposed image, then interpolating it and recomposing it again?
Could it give any improvements quality wise?

josey_wells
22nd August 2008, 14:57
@josey_wells
TempGaussMC_beta1 (http://home.arcor.de/dhanselmann/_stuff/?C=M;O=D) bombs with this latest build, tried all 4 dll versions.

Here is the fix. I skipped V1.9.6.9 since I consdider this a major release.

http://rapidshare.com/files/139257808/MVTools_V1.9.7.0.rar.html

I now consider all optimizations to MVAnalyseMulti and MVDegrain's completed.

If there is enough interest then I can look at multithreading some of the other functions but need a break first. I will also post complete comparisons of this code vs V1.9.5.7 soon disregarding all white space changes.

Have fun!

Adub
22nd August 2008, 16:41
If I may, but why is the "Threads" option default to 64? Why not have it default to the number of cores found or something along those lines?

Edit: And also, thank you very much for your hardwork!! By all means, take a break, you deserve it!

Edit2:

Okay, bug report from kokotier:

<kokotier> hello
<kokotier> i saw you have asnwered
<kokotier> to the mvtools thread
<Merlin7777> yes?
<kokotier> canyou tell to josey_wells than the last buid is buggy
<kokotier> http://forum.doom9.org/showthread.php?p=1172974#post1172974
<Merlin7777> Wait, did you read his reply?
<kokotier> yes but is doesnt change anything
<kokotier> motiondetection is broken
<kokotier> you can test yourself
<kokotier> dl my sample
<kokotier> and on the latest buid i have green frames with it :-
<Merlin7777> It's having trouble connecting. But didn't you post it online? Anyways, I will post and tell him that you are still having problems. Same script?
<kokotier> i cant post on doom9 sorry
<kokotier> i hve to wait more days
<Merlin7777> Yeah, I know. But are you using the same script? Or are you also encountering the bug with the suggestion he posted?
<kokotier> source=last
<kokotier> MVForBack = source.MVAnalyseMulti(refframes=1, pel = 2, overlap=2, overlapv=2, sharp=1, idx = 1,blksize=16,search=3,chroma=true,global=true)
<kokotier> source.MVShow(MVForBack.MVMultiExtract(0))
<kokotier> with the suggestion i have the same bug
<kokotier> it seems that is overlapv=2 that is buggy


Edit3:
its weird
<kokotier> with refframe=2
<kokotier> 2 frame before the scene chnge is bad
<kokotier> with refframe=3
<kokotier> 3 frame before the scene change is bad
<kokotier> and so on..


Edit 4: (man, I am really going to town on this thing.)

Kokotier, (who is in the waiting period after registering, by the way) walked me through what he is doing, and I have to agree, it is a bit odd. with Refframe=1, the frame before the scenechange is filled with motion vectors, even though there is no motion. But since it is a scenechange, it might be that way on purpose.

However, that's not the issue. As Kokotier pointed out, if you change the refframe to 2, then two frames before the scenechange is filled with motion vectors, then a "good frame", aka, no motion vectors, THEN the scenechanges. It is some odd behavior I must say. But I don't necessarily know if it is wrong. So I will let the experts decide.

morsa
22nd August 2008, 19:33
I have found that if I use the histogram equalization filter from VCmohan at the MVanalyze stage, results get improved a lot.
Does it sound logical to use histogram equalization internally Fizick?

thetoof
23rd August 2008, 17:05
If there is enough interest then I can look at multithreading some of the other functions but need a break first.

Thanks a lot! Could you also consider updating the docs? (well, you or anyone feeling like it :p)
mvflowfps would be the next function to multithread imo...

Sagekilla
23rd August 2008, 20:37
@morsa: How exactly did you use the equalization, and how much did the results improve?

Delerue
24th August 2008, 07:30
Thanks a lot! Could you also consider updating the docs? (well, you or anyone feeling like it :p)
mvflowfps would be the next function to multithread imo...

I think the same. :)

EDITED: BTW, I downloaded the last version (http://rapidshare.com/files/139257808/MVTools_V1.9.7.0.rar.html), and use it with this old script, but I got crashes all the time:


SetMtmode(1,5)
source=ffdshow_source()
SetMTMode(2)
LoadPlugin("C:\arquivos de programas\avisynth\plugins\mvtools.dll")
backward_vec = source.MVAnalyse(blksize=16, overlap=0, isb = true, pel=2, search=2, idx=1)
forward_vec = source.MVAnalyse(blksize=16, overlap=0, isb = false, pel=2, search=2, idx=1)
source.MVFlowFps(backward_vec, forward_vec, num=2*FramerateNumerator(source), \
den=FramerateDenominator(source), mask=1, idx=1)
distributor()


I tried to remove the MT lines, but it doesn't help. Also tried other CPU versions of MVTools (although I have a Core2Duo), and it doesn't help either.

egrimisu
24th August 2008, 14:42
for using the next code in multithread :
source = last
backward_vec3 = source.MVAnalyse(isb = true, delta = 3, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec2 = source.MVAnalyse(isb = true, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec1 = source.MVAnalyse(isb = true, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec1 = source.MVAnalyse(isb = false, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec2 = source.MVAnalyse(isb = false, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec3 = source.MVAnalyse(isb = false, delta = 3, pel = 2, overlap=4, sharp=1, idx = 1)
source.MVDegrain3(backward_vec1,forward_vec1,backward_vec2,forward_vec2,backward_vec3,forward_vec3,thSAD=400,idx=1)

should be called as :
source = last
backward_vec3 = source.MVAnalysemulti(isb = true, delta = 3, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec2 = source.MVAnalysemulti(isb = true, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec1 = source.MVAnalysemulti(isb = true, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec1 = source.MVAnalysemulti(isb = false, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec2 = source.MVAnalysemulti(isb = false, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec3 = source.MVAnalysemulti(isb = false, delta = 3, pel = 2, overlap=4, sharp=1, idx = 1)
source.MVDegrain3(backward_vec1,forward_vec1,backward_vec2,forward_vec2,backward_vec3,forward_vec3,thSAD=400,idx=1)

Dreassica
24th August 2008, 16:56
Using that line I'm gettting a "MVAnalysemulti has no named argument "isb"" error msg.

Sagekilla
24th August 2008, 17:03
Because that's the incorrect usage of MVAnalyseMulti. It has no "delta" or "isb" syntax anymore, since a single instance of MVAnalyseMulti is supposed to be used as so:


# Ref frames is your delta, but it looks backwards AND forwards at the same time. No need for isb=true/false
vectors = source.MVAnalyseMulti(refframes = 3)



I don't remember if vector extraction has been implemented, but it was supposed to be done as so if you want old school MVDegrain:


vectors = source.MVAnalyseMulti(refframes=1)
bvec1 = vectors.MVMultiExtract(0)
fvec1 = vectors.MVMultiExtract(1)
source.MVDegrain1(bvec1,fvec1)

egrimisu
24th August 2008, 20:06
sorry, i'm a hard head so what will be the code in the new version for the code that writen up?

mikeytown2
24th August 2008, 20:12
old


source = last
backward_vec3 = source.MVAnalyse(isb = true, delta = 3, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec2 = source.MVAnalyse(isb = true, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec1 = source.MVAnalyse(isb = true, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec1 = source.MVAnalyse(isb = false, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec2 = source.MVAnalyse(isb = false, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec3 = source.MVAnalyse(isb = false, delta = 3, pel = 2, overlap=4, sharp=1, idx = 1)
source.MVDegrain3(backward_vec1,forward_vec1,backward_vec2,forward_vec2,backward_vec3,forward_vec3,thSAD=400,idx=1)



NEW


source = last
vectors = source.MVAnalyseMulti(refframes=3, pel = 2, overlap=4, sharp=1, idx = 1)
source.MVDegrainMulti(vectors,thSAD=400,idx=1)



refframes=1 is MVDegrain1()
refframes=2 is MVDegrain2()
refframes=3 is MVDegrain3()
refframes=4 is MVDegrain4()
ect...

egrimisu
25th August 2008, 10:42
There's no need for adding delta = 3 anymore?

Sagekilla
25th August 2008, 15:11
Nope. Delta is now refframes, but refframes encompasses both delta and isb. There's no need to set as being backwards or forwards vector since it stores both in the same clip.

bairradino
25th August 2008, 15:46
@ Mikeytown2

Your codesource = last
vectors = source.MVAnalyseMulti(refframes=1, pel = 2, overlap=4, sharp=1, idx = 1)
source.MVDegrainMulti(vectors,thSAD=400,idx=1) gives the following error:
there is no function named "MVAnaliseMulti".

Underground78
25th August 2008, 15:48
@ Mikeytown2

Your codesource = last
vectors = source.MVAnalyseMulti(refframes=1, pel = 2, overlap=4, sharp=1, idx = 1)
source.MVDegrainMulti(vectors,thSAD=400,idx=1) gives the following error:
there is no function named "MVAnaliseMulti".

Are you using MVAnaliseMulti or MVAnalyseMulti ?

talen9
25th August 2008, 15:58
@bairradino: that code needs josey_wells' branch of MVTools ... the latest build is linked only several posts ago in this same page (here (http://forum.doom9.org/showthread.php?p=1173626#post1173626)).

EDIT: and Underground78's question is a valid one too :p

josey_wells
26th August 2008, 12:21
OK, here is V1.9.7.1. Changes are as follows:

1. I was getting errors sometimes on loading script on low memory computers. I have changed the way memory was allocated in constructors of MVDegrainX and MVAnalyseMulti to fix and should also reduce memory footprint.
2. Found one more delete where should be delete []
3. New intel compiler version

http://rapidshare.com/files/140221063/MVTools_V1.9.7.1.rar.html

Also, as promised here is the diff of V1.9.7.1 to Fzicks's V1.9.5.7 using WinMerge. All the code changes are highlighted with whitespace changes ignored.

http://rapidshare.com/files/140221064/MVTools_Compare.rar.html

Also, I have found that pel=2 gives a more pleasing output IMO than pel=4 which tends to oversmooth the results.

Have fun!

Boulder
26th August 2008, 12:35
If I may, but why is the "Threads" option default to 64? Why not have it default to the number of cores found or something along those lines?

Edit: And also, thank you very much for your hardwork!! By all means, take a break, you deserve it!

Edit2:

Okay, bug report from kokotier:




Edit3:



Edit 4: (man, I am really going to town on this thing.)

Kokotier, (who is in the waiting period after registering, by the way) walked me through what he is doing, and I have to agree, it is a bit odd. with Refframe=1, the frame before the scenechange is filled with motion vectors, even though there is no motion. But since it is a scenechange, it might be that way on purpose.

However, that's not the issue. As Kokotier pointed out, if you change the refframe to 2, then two frames before the scenechange is filled with motion vectors, then a "good frame", aka, no motion vectors, THEN the scenechanges. It is some odd behavior I must say. But I don't necessarily know if it is wrong. So I will let the experts decide.Is there any news on this issue regarding the latest version?

Didée
26th August 2008, 12:48
I'm not sure if this is a bug at all? From what was told, it seems to be the "typical" case of what happens when there is a scenechange that didn't trigger MVTools' scenechange detection (thSCD1,thSCD2). If a scenechange isn't detected, then it's normal to get motion vectors all over the place, since MVAnalyse bravely searches for best matches between not-correlated content.

Delerue
26th August 2008, 16:52
OK, here is V1.9.7.1. Changes are as follows:

Thanks for your hard efforts. MVTools grows a lot with your work. If you have some time, can you take a look at MVFlowFPS class? It doesn't work with old and new MVAnalyse.

BTW, you noticed any improvement using Intel Compiler over VS 2008 Compiler? And did you try MinGW (http://www.mingw.org/old/download.shtml)?

Best regards
;)

kokotier
27th August 2008, 03:51
I'm not sure if this is a bug at all? From what was told, it seems to be the "typical" case of what happens when there is a scenechange that didn't trigger MVTools' scenechange detection (thSCD1,thSCD2). If a scenechange isn't detected, then it's normal to get motion vectors all over the place, since MVAnalyse bravely searches for best matches between not-correlated content.

Hello , with overlapV disabled (=0) you dont have this "bug".
And with others mvtools you don't have this "bug".

mikeytown2
27th August 2008, 04:14
@josey_wells Confirmed bug with MVFlowFPS in V1.9.7.1. in AvsP. Vdub doesn't crash.

josey_wells
27th August 2008, 12:05
Please post a simple script and I will investigate.

I also found that there was an error in MVAnalyseMuilt where an external pelclip could not be used. I am doing PSNR tests of external vs internal scalling with pel=2 and 4.

mikeytown2
27th August 2008, 12:13
Please post a simple script and I will investigate.


This one crashes
http://forum.doom9.org/showthread.php?p=1172584#post1172584

Problem is with IC10 dll's

Delerue
27th August 2008, 14:06
Please post a simple script and I will investigate.

This one (http://forum.doom9.org/showthread.php?p=1174273#post1174273) crashes too, with any DLL version.

Fizick
27th August 2008, 17:15
Released v1.10.2.0 beta (27.08.2008)
MVAnalyse: changed LSAD threshold from hard by soft for a little more coherent motion at bad areas.
MVAnalyse: fixed old bug for (rarely used) different horizontal and vertical overlap sizes.
Added MVRecalculate function to update SAD (as requested by Didee). Change MVRecalculate by more general function which can re-estimate vectors.
Fixed possible memory leaks (thanks to josey_wells for note)
Other changes of v1.9.6-1.9.7 branch by josey_wells are still not merged - too many work to analyse new code and numerous cosmetic rewriting, so based on v1.9.5.7

I am not sure that MVRecalculate will be useful, and its parameters (and operation) may be changed. It is a beta. :)

thetoof
28th August 2008, 01:43
Quick check about idx and concern about pelclip:
To use a prefiltered clip, one must use different idx, right?
source=whatever
prefiltered=source.somedenoiser
vectors=prefiltered.mvanalysemulti(idx=1)
source.mvdegrainmulti(vectors,idx=2)
Now, about the pelclip... it is said in the doc that the same pelclip must be used with all mvtools functions.
source=whatever
ups=source.nnedi(1,true).turnright().nnedi(1,true).turnleft()
vectors=source.mvanalysemulti(settings,pelclip=ups)
source.mvdegrainmulti(vectors,pelclip=ups)
My concern is that I use the pelclip of the prefiltered clip to degrain the source clip, which seems wrong to me... so should I create another pelclip with the source and use it in the mvdegrainmulti call? But this'd go against the rule "For correct results you must use the same pelclip for all MVTools functions."
source=whatever
prefiltered=source.somedenoiser
ups=prefiltered.nnedi(1,true).turnright().nnedi(1,true).turnleft()
vectors=prefiltered.mvanalysemulti(settings,pelclip=ups,idx=1)
source.mvdegrainmulti(vectors,pelclip=ups,idx=2)

This is what I'm thinking about...
source=whatever
prefiltered=source.somedenoiser
upsource=source.nnedi(1,true).turnright().nnedi(1,true).turnleft()
upprefiltered=prefiltered.nnedi(1,true).turnright().nnedi(1,true).turnleft()
vectors=prefiltered.MVAnalyseMulti(settings,pelclip=upprefiltered,idx=1)
source.MVDegrainMulti(vectors,pelclip=upsource,idx=2)
Or maybe it is simply OK to use the same pelclip to do something on 2 different clips.....

josey_wells
28th August 2008, 02:30
This one crashes
http://forum.doom9.org/showthread.php?p=1172584#post1172584

Problem is with IC10 dll's

I have found and corrected the problem of crashing for both MVFlowFPS and MVFlowFPS2.

If I may, but why is the "Threads" option default to 64? Why not have it default to the number of cores found or something along those lines?

I have changed the default behavior to be equal to the number of processors in the system.

MVAnalyse: changed LSAD threshold from hard by soft for a little more coherent motion at bad areas.
MVAnalyse: fixed old bug for (rarely used) different horizontal and vertical overlap sizes.

Before I release I would like to roll Fizick's changes above in also. Fizick, can you please point me to the sections involvled?

Lastly, I have rewritten the entire quueing mechanism to use stl maps.

Delerue
28th August 2008, 04:56
I have found and corrected the problem of crashing for both MVFlowFPS and MVFlowFPS2.

Hmmm... In which version? The 1.9.7.1 version still crashes when using MVFlowFPS. I provided a script (that I use inside FFDShow Avisynth tab) in my last message. BTW, Fizick's last version doesn't crash.

Thanks

Boulder
28th August 2008, 06:09
josey_wells hasn't released the fixed version yet.

Zep
28th August 2008, 14:08
I have found and corrected the problem of crashing for both MVFlowFPS and MVFlowFPS2.




Awesome. I posted a few pages back about them crashing with your branch and I had to go back to the Fizick branch because of it. Now I will be able to give your branch another shot! :D

Fizick
28th August 2008, 16:06
josey_wells,
See PlaneOfBlock.cpp for LSAD and FakeGroupOfPlakes for nOverlapX (around digits 1.10.2).
Changes are commented in code and as minimal as needed.
It makes clear tracking and delimits responsibility.

As IanB noted, it would be fine, if you not simply public a huge DIFF, but mark (by approriate comment in code) all needed changes and revert all unneeded changes.
I say about i++ to ++i replacing, BitBlt to PlaneCopy renaming, and other similar things. ;)

Well, you have rewritten the entire queueing mechanism to use stl maps.
Sorry, I do not know nothing about stl maps. The only language I ever was learned was FORTRAN IV in university :). Is stl maps open source? What it doing?
How much memory usage is decreased in result?

Adub
28th August 2008, 16:42
I have changed the default behavior to be equal to the number of processors in the system.


Much appreciated.

Fizick
28th August 2008, 19:10
Just noted :
http://forum.doom9.org/showthread.php?p=1158481#post1158481
Released v1.10.2.1
MVDegrain1-3: fixed old rounding error resulted in some chroma tint (no thanks to Didee due to lack of official bugreport in MVTools forum thread :)
Made doc about pelclip more accurate (hopely).

Didée
28th August 2008, 20:08
... chroma tint (no thanks to Didee due to lack of official bugreport in MVTools forum thread :)
Sorry to contradict you, but I DID report that chroma issue: lookathis (http://forum.doom9.org/showthread.php?p=853008#post853008).
(Though, admittedly, the discussion ended without a real ending.)

Thank you very much for finally fixing it! :)


While I'm at it, thanks also for MVRecalculate. It works pretty much like what I had in mind.
The embarassing news: Without MVRecalculate, I used some sloppy calculation. With MVRecalculate, the calculation is much more exact. Compairing both, it seems the sloppy one gives more pleasing results than the accurate one ... ouch!
BTW, the point is to mix different blocksizes. Asked for two years ago (http://forum.doom9.org/showthread.php?p=737251#post737251), and now that i script it, you start to implement it ... funny. :-)

Fizick
28th August 2008, 20:52
Didée, you have wonderful memory, but you was not very hard in the bug report :)
BTW, I am not sure, that I am fixed all rounding errors. What I fixed was in degrain functions, not dependent on overlap, and do not very dependent on pel.
It is not coinside with your observations...

MVRecalculate is experimental. But I have no much time for experiments... :(

Nikos
28th August 2008, 20:54
Thanks Fizick for the new stable version.
If i want to use external subpixel interpolation clip and prefiltered clip, the below code is correct?


s = last
pre = s.mydenoise()

up_s = s.EEDI2(field=1).LanczosResize(2*width(s), 2*height(s), src_left=0.25)
up_pre = pre.EEDI2(field=1).LanczosResize(2*width(pre), 2*height(pre), src_left=0.25)


b1v = pre.MVAnalyse(isb=true, delta= 1, blksize=8, pel=2, sharp=2, pelclip=up_pre, idx=1)
f1v = pre.MVAnalyse(isb=false, delta= 1, blksize=8, pel=2, sharp=2, pelclip=up_pre, idx=1)

den = s.MVDegrain1(b1v, f1v, thSAD=350, pelclip=up_s, idx=2)

cb1 = s.MVCompensate(b1v, thSAD=400, pelclip=up_s, idx=2)
cf1 = s.MVCompensate(f1v, thSAD=400, pelclip=up_s, idx=2)

pmax = s.mt_logic(cb1, "max").mt_logic(cf1, "max")
pmin = s.mt_logic(cb1, "min").mt_logic(cf1, "min")

sharp= s.mysharpen()
sharp.mt_clamp(pmax, pmin, 0, 0, U=2, V=2)

Leak
28th August 2008, 21:07
Is stl maps open source? What it doing?

Definition of Standard Template Library (http://en.wikipedia.org/wiki/Standard_Template_Library)
STL Maps Documentation (http://www.cppreference.com/cppmap/index.html)

An implementation of the STL comes with about any C++ compiler, be it MSVC, Intel's compiler or G++.

np: Landesvatter - Fläz. (Lax)

Didée
28th August 2008, 21:16
Didée, you have wonderful memory, but you was not very hard in the bug report :)
Yeah, it's a lame excuse ... but it's the best that I have. :D


@ Nikos: From my point of view, that's spot-on correct. 'pelclip' is (should be) fix-correlated to 'idx' ... in easy words: "existing idx, existing pelclip ... new idx, new pelclip". If that isn't the case, then it's a bug.

Nikos
28th August 2008, 22:07
Thanks Didée for the answer. The idx's alone is a little confusion, the idx's with peclip's are big headache!!!

With new MVtools i think we need a small modification in TempGaussMC beta-1 :D

## MVDegrain causes a chroma shift (yes it does, with pel>1 !) We compensate by shifting chroma towards plain EDI by a small notch
## [ 1+(x-1)/(1+(x/5)^4) ] on 128-centered diff-clip (x-y) ==> [ x y - abs 2 < y x x y - abs 1 - 1 x y - abs 5 / 4 ^ + / 1 + x y - x y - abs 0.0001 + / * + ? ]
stage2 = stage2.mt_lutxy(edi,"x y - abs 2 < y x x y - abs 1 - 1 x y - abs 5 / 4 ^ + / 1 + x y - x y - abs 0.0001 + / * - ?",Y=2,U=3,V=3)

josey_wells
28th August 2008, 22:47
josey_wells,
See PlaneOfBlock.cpp for LSAD and FakeGroupOfPlakes for nOverlapX (around digits 1.10.2).
Changes are commented in code and as minimal as needed.
It makes clear tracking and delimits responsibility.

Thanks I have rolled this update as well as the rounding update into the latest build.


As IanB noted, it would be fine, if you not simply public a huge DIFF, but mark (by approriate comment in code) all needed changes and revert all unneeded changes.
I say about i++ to ++i replacing, BitBlt to PlaneCopy renaming, and other similar things. ;)

I'm sorry but at this point it doesn't make much sense to do this since so many structural changes have taken place.


Well, you have rewritten the entire queueing mechanism to use stl maps.
Sorry, I do not know nothing about stl maps. The only language I ever was learned was FORTRAN IV in university :). Is stl maps open source? What it doing?
How much memory usage is decreased in result?

Leak already answered that STL is the Standard Template Library. I was able to get rid of two classes and embed everything in MVCore.

Thanks Fizick for the new stable version.

I am hoping that this was not a slight against the version that I have been working on.

This version also contains a new thSADC parameter for MVCompensate, MFlowIter, MVFlowFPS, MVFlowFPS2. Although currently both SAD parameters are ignored in the MVFlowXXX.

Before posting the source code, I want to try something to possibly improve the MVDegrain results. Currently the total SAD is used to find the motion vectors and then the total SAD is again used to weight the Luma and Chroma planes in MVDegrain. I would like to change the MVAnalyseXXX function to store the total SAD and the SAD's for each Luma and Chroma plane in the vector data. Then use the SAD for each plane to degrain that plane instead of the total SAD.

Here it is

http://rapidshare.com/files/140895528/MVTools_V1.9.7.2.rar.html

Nikos
28th August 2008, 23:39
@ josey_wells my comment was not a slight against your version, on the contrary i appreciate your work.
The bold letters was just for distinction from your version who is in alpha stage.
With your hard work i think very soon will be stable for every day usage :)

LaTo
29th August 2008, 10:20
@ josey_wells : thanks for your hard work on MT version :)

But, I have a feature request: can you make multithreaded version for MVCompensate & MVMask ???

Like this:

OLD
b1v=last.MVanalyse(isb=true,delta=1)
b2v=last.MVanalyse(isb=true,delta=2)
b3v=last.MVanalyse(isb=true,delta=3)
f1v=last.MVanalyse(isb=false,delta=1)
f2v=last.MVanalyse(isb=false,delta=2)
f3v=last.MVanalyse(isb=false,delta=3)

b1c=last.MVcompensate(b1v)
b2c=last.MVcompensate(b2v)
b3c=last.MVcompensate(b3v)
f1c=last.MVcompensate(f1v)
f2c=last.MVcompensate(f2v)
f3c=last.MVcompensate(f3v)
comp=interleave(b1c,b2c,b3c,f1c,f2c,f3c)



NEW
vectors = last.MVanalyseMulti(refframes=3)
comp = last.MVcompensateMulti(vectors)
With the same way as MVanalyseMulti (one thread for each compensated frame).
Idem for MVmask.

It would be great :thanks:

krieger2005
29th August 2008, 11:03
Why you need a MultiCompensate? In the next step you must extract every compenstated part again (for interleave). And then you have the same as like it is now. Sorry, don't see the point yet.

LaTo
29th August 2008, 13:13
Why you need a MultiCompensate? In the next step you must extract every compenstated part again (for interleave). And then you have the same as like it is now. Sorry, don't see the point yet.
Because the old method is not multithreaded... (the interleave will be part of MultiCompensate and after use selectevery)

krieger2005
29th August 2008, 13:26
Oh... I forget always the thread-thingy..

josey_wells
29th August 2008, 14:32
OK, here is version 1.9.7.3

http://rapidshare.com/files/141048396/MVTools_V1.9.7.3.rar.html

This has all the builds in it and I believe I have fixed the problem with the IC10 builds also.

This also has the modification of of calculating the SadLuma, SadChromaU, SadChromaV and carrying that information through the vector data.

I also added a SadMode to MVDegrainXXX

SadMode=0 - Works as old method
SadMode=1 - Works with new method which may or may not be better

switch(pTS->pMVDegrainBase->SadMode) {
case 0: // total SAD
if (bLumaY) pPS->WRefF_Y[i] = std::max<int>(0, pTS->pMVDegrainBase->thSAD - blockF.GetSAD());
if (bChromaU) pPS->WRefF_U[i] = std::max<int>(0, pTS->pMVDegrainBase->thSADC - blockF.GetSAD());
if (bChromaV) pPS->WRefF_V[i] = std::max<int>(0, pTS->pMVDegrainBase->thSADC - blockF.GetSAD());
break;
case 1: // Individual SAD's
if (bLumaY) pPS->WRefF_Y[i] = std::max<int>(0, pTS->pMVDegrainBase->thSAD - blockF.GetSADLuma());
if (bChromaU) pPS->WRefF_U[i] = std::max<int>(0, pTS->pMVDegrainBase->thSADC - blockF.GetSADChromaU());
if (bChromaV) pPS->WRefF_V[i] = std::max<int>(0, pTS->pMVDegrainBase->thSADC - blockF.GetSADChromaV());
break;
}

This should be a stable build. Please report back either way and if new method is useful or not.

Fizick
29th August 2008, 15:59
josey_wells,

1. So, stl maps is internal (hidden), and license terms of stl maps is GPL-compatible?

2. Well, I see that you do not want revert the changes.
But you should mark all changes by notices even if (and especially if) changes are big.
BTW, there are also GPL terms about "prominent notices".
(Why you do not use (updated) mvtools.rc? )

3. I am not sure, that SAD's for each Luma and Chroma plane may be use useful,
but if you changed the motion data format (or MVAnalyseData structure), then you must at least increment MVANALYSIS_DATA_VERSION.
Previously I could load motion data clip of v1.9.6-1.9.7 to MVShow v.1.10.1 due to same (compatible) data format.

mikeytown2
29th August 2008, 17:17
@ josey_wells
1.9.7.3 still has some issues
Using this same test (http://forum.doom9.org/showthread.php?p=1172584#post1172584) MSVC08 has smeared/blurred output. IC10 bombs in AvsP and it only has blurred output in Vdub.

TempGaussMC()/MCBob() works in AvsP with both versions and it looks ok.

Manao
29th August 2008, 19:16
Fizick : use stlport to get a full portable stl implementation.
Fizick, josey_wells : if you keep developing together, take some time to find a svn/cvs/git server, in the long run it'll help you.

josey_wells
29th August 2008, 22:09
@ josey_wells
1.9.7.3 still has some issues
Using this same test (http://forum.doom9.org/showthread.php?p=1172584#post1172584) MSVC08 has smeared/blurred output. IC10 bombs in AvsP and it only has blurred output in Vdub.

TempGaussMC()/MCBob() works in AvsP with both versions and it looks ok.

I missed the ExtraDivide function when changing the data output so anything with divide!=0 would be in error. It has been corrected.

I have also fixed rounding errors in several placed.

Here is the MSVC08-SSE2 only version for now.

http://rapidshare.com/files/141146309/MVTools_V1.9.7.4.rar.html

Delerue
29th August 2008, 22:50
I have also fixed rounding errors in several placed.

Here is the MSVC08-SSE2 only version for now.

http://rapidshare.com/files/141146309/MVTools_V1.9.7.4.rar.html

Thanks, but MVFlowFPS performance is almost 50% slower than Fzick's last version, and it can't work well with Avisynth MT. Any idea?

Adub
29th August 2008, 23:26
How are you calling it?

josey_wells
29th August 2008, 23:48
josey_wells,

1. So, stl maps is internal (hidden), and license terms of stl maps is GPL-compatible?

2. Well, I see that you do not want revert the changes.
But you should mark all changes by notices even if (and especially if) changes are big.
BTW, there are also GPL terms about "prominent notices".
(Why you do not use (updated) mvtools.rc? )

3. I am not sure, that SAD's for each Luma and Chroma plane may be use useful,
but if you changed the motion data format (or MVAnalyseData structure), then you must at least increment MVANALYSIS_DATA_VERSION.
Previously I could load motion data clip of v1.9.6-1.9.7 to MVShow v.1.10.1 due to same (compatible) data format.

1. STL is part of the C++ standard is freely distributible in compiled executables.

2. I could possibly do that once everything stabilizes if I have time. I have been lazy updating the rc file each time.

3. I'm not sure it is useful either. Just thought to give it a try it does seem to give a lower PSNR than the old method. I only changed the vector data not the Analysis structure. It might be better to code a flag to choose old or new structure?

Here are all the builds and the source.

http://rapidshare.com/files/141165267/MVTools_V1.9.7.4_All.rar.html

Adub
30th August 2008, 00:40
Josey, make sure to take a look at Manao's post, he has a very good point.

Sagekilla
30th August 2008, 00:42
Perhaps we can start by porting over some of the changes that josey_wells made that don't require massive changes to the structure? It sounds like there's been some changes that didn't require huge blocks of code to be changed that could benefit the main branch.

I can try to do this myself, but I have very little knowledge of C++ (It's more or less limited to the very small additions to AVCMatrices I made earlier on ;)) so I might not be able to get much (if anything) done :(

Edit: Wow... don't think I could do that.

Delerue
30th August 2008, 01:52
Suggestion: add the '/MP' flag to the VS 'C/C++' -> 'Command Line' option to make sure you can compile with all the cores of the CPU. This gives a little compilation speed improvement in multi-cores systems.

BTW, I compiled the last Fizick's version with Intel Compiler and VS 2008 using all the optimizations available. I didn't notice any performance improvement, but if anyone wants to test, here's the link:

http://rapidshare.com/files/141185947/mvtools_1.10.2.1.7z.html

Terranigma
1st September 2008, 01:54
Hey, since we have a 16x2 blocksize, and pel 4, I was just wonderin' if we can get 8x2 blocksize and pel 3 implemented someday.

Sagekilla
1st September 2008, 22:06
You realize pel=1 is fullpel, pel=2 is halfpel, and pel=4 is qpel? I don't see how you could (easily) use a 1/3 of a pixel accuracy of sorts..

Terranigma
1st September 2008, 23:13
You realize pel=1 is fullpel, pel=2 is halfpel, and pel=4 is qpel? I don't see how you could (easily) use a 1/3 of a pixel accuracy of sorts..

Well for MVAnalyse, Pel 2 doubles the input resolution, pel 4 quadruples it, and pel 3 would be tripling, so pel 3 for a 720X480 source would upsize to 2160X1440. At least that what I think, but I could be wrong. :p

Boulder
3rd September 2008, 03:45
Using plane=0 or plane=2 in MVDegrainMulti causes crashing with the latest version (v1.9.7.4).

LaTo
8th September 2008, 09:37
Using plane=0 or plane=2 in MVDegrainMulti causes crashing with the latest version (v1.9.7.4).
with v1.9.7.0 too...

LaTo
8th September 2008, 10:26
I have a big issue with MVToolsMULTI v1.9.7.0/1.9.7.4 and FFT3Dgpu...
It's appears when bt>1 AND refframes>1.

Here is the script:
bt=X
ref=X

i=last
p=i.FFT3Dgpu(bt=bt)
v=p.MVAnalyseMulti(refframes=ref)
i.MVDegrainMulti(v,refframes=ref)

The results:

bt=3 & ref=3 (http://latoninf.free.fr/div/bt3ref3.png) :confused:

bt=1 & ref=3 (http://latoninf.free.fr/div/bt1ref3.png)

bt=1 & ref=1 (http://latoninf.free.fr/div/bt1ref1.png)

bt=3 & ref=1 (http://latoninf.free.fr/div/bt3ref1.png)

If I replace MVToolsMULTI by MvTools : no problem

Any ideas ???

Zep
8th September 2008, 18:57
I have a big issue with MVToolsMULTI v1.9.7.0/1.9.7.4 and FFT3Dgpu...
It's appears when bt>1 AND refframes>1.

Here is the script:
bt=X
ref=X

i=last
p=i.FFT3Dgpu(bt=bt)
v=p.MVAnalyseMulti(refframes=ref)
i.MVDegrainMulti(v,refframes=ref)

The results:

bt=3 & ref=3 (http://latoninf.free.fr/div/bt3ref3.png) :confused:

bt=1 & ref=3 (http://latoninf.free.fr/div/bt1ref3.png)

bt=1 & ref=1 (http://latoninf.free.fr/div/bt1ref1.png)

bt=3 & ref=1 (http://latoninf.free.fr/div/bt3ref1.png)

If I replace MVToolsMULTI by MvTools : no problem

Any ideas ???


just comfirmed that. exact same block problem.

josey_wells
9th September 2008, 01:28
Using plane=0 or plane=2 in MVDegrainMulti causes crashing with the latest version (v1.9.7.4).

It may be awhile before I can look at this since my main computer bit the dust.

Fizick
9th September 2008, 04:43
I remember that some (prev ?) multi-version produced not same vectors.

Fizick
11th September 2008, 18:20
i have got some access to dualcore core 2.
and i am interested in most breaking script for "old good" MVTools version, to check problems with SetMTMode(2,x).
Preferable without any other plugins (like masktools, removegrains, etc).
All my own (short) testing attempts does not show any errors (including Avisource as was reported by Terranigma).

josey_wells
11th September 2008, 19:03
It may be awhile before I can look at this since my main computer bit the dust.

I found the error for the plane setting. It will affect any plane setting where any of the chroma planes are not used. I will post new dll later today.

I remember that some (prev ?) multi-version produced not same vectors.

The versions no longer produce the same motion vectors. I have fixed more rounding problems than have been implemented in original and also changed the output format.

After new dll posting I won't be working on MVTools for quite a while if ever since it has reached stability now with regards to old functionality of all functions with multithreaded MVAnalyse and MVDegrains's.

Here it is:

http://rapidshare.com/files/144510026/MVTools-1.9.7.5.rar.html

Quark.Fusion
12th September 2008, 04:50
please add multithreaded MVCompensate to pair with MVAnalyze.

LaTo
12th September 2008, 07:47
The versions no longer produce the same motion vectors. I have fixed more rounding problems than have been implemented in original and also changed the output format.
So, which version produces the same result?

josey_wells
12th September 2008, 12:21
So, which version produces the same result?

V1.9.7.3 and above create motion data that contains SAD Luma, SAD Chroma U, and SAD Chroma V.

Fizick
12th September 2008, 19:13
josey_wells,
1. Vector values are diferent (not correspond to any my version) since v.1.9.7.2 (i am not about format here).
If it is not a problem for you, it is not a problem for me too. :)
Vectors search is not one-way task. But it should be documented (and checked).

2. It is strange to see my comments with changed (not correspondent) code :confused: and without any
your notices (under GNU GPL).
2. a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.

mikeytown2
12th September 2008, 23:58
1.9.7.5 IC10 builds bomb on MVFlowFps (http://forum.doom9.org/showthread.php?p=1172584#post1172584). I only have a conroe so I haven't tried the SSE4 dll. TempGaussMC_beta2 & MCBob don't crash in AvsP though. Vdub doesn't crash with the IC10 Builds, but the output isn't correct (blurred output, YUY2 & YV12).

MSVC08-SSE2 seems flawless, so I'll be staying away from the IC10 builds for now.

superuser
14th September 2008, 02:42
josey_wells,
1. Vector values are diferent (not correspond to any my version) since v.1.9.7.2 (i am not about format here).
If it is not a problem for you, it is not a problem for me too. :)
Vectors search is not one-way task. But it should be documented (and checked)..

which is recommended version to use at present?

LaTo
14th September 2008, 17:54
which is recommended version to use at present?
If you want compatibly with official mvtools: 1.9.7.1, else 1.9.7.5...

josey_wells
17th September 2008, 13:40
1.9.7.5 IC10 builds bomb on MVFlowFps (http://forum.doom9.org/showthread.php?p=1172584#post1172584). I only have a conroe so I haven't tried the SSE4 dll. TempGaussMC_beta2 & MCBob don't crash in AvsP though. Vdub doesn't crash with the IC10 Builds, but the output isn't correct (blurred output, YUY2 & YV12).

MSVC08-SSE2 seems flawless, so I'll be staying away from the IC10 builds for now.

This was a brand new computer that I performed the builds on. So maybe I missed something setting of the environment. I will try to reperform the builds this weekend and repost to see if it corrected the problems you see with your famous MVFlowFPS script. V1.9.7.4 with rounding fixes had very good PSNR for the script but did not completely fix all the issues.

There is no difference between V1.9.7.5 and V1.9.7.4 except for the fix for the planes issue in MVDegrainXXX which involved two lines of code that I miss copied and pasted.

Fizick
17th September 2008, 18:55
"rounding fixes" demystified.

v.1.10.2.X:

nLambda = nLambda*LSAD/(LSAD + (predictor.sad>>1))*LSAD/(LSAD + (predictor.sad>>1));
// replaced hard threshold by soft in v1.10.2 by Fizick (a liitle complex expression to avoid overflow)


v1.9.7.2-1.9.7.5:

nLambda = nLambda*(LSAD/(LSAD + (sad>>1)))*(LSAD/(LSAD + (sad>>1)));
// replaced hard threshold by soft in v1.10.2 by Fizick (a liitle complex expression to avoid overflow)


all integers, comment preserved :eek:

PSNR is always better with lambda=0

josey_wells
17th September 2008, 19:52
"rounding fixes" demystified.

v.1.10.2.X:

nLambda = nLambda*LSAD/(LSAD + (predictor.sad>>1))*LSAD/(LSAD + (predictor.sad>>1));
// replaced hard threshold by soft in v1.10.2 by Fizick (a liitle complex expression to avoid overflow)


v1.9.7.2-1.9.7.5:

nLambda = nLambda*(LSAD/(LSAD + (sad>>1)))*(LSAD/(LSAD + (sad>>1)));
// replaced hard threshold by soft in v1.10.2 by Fizick (a liitle complex expression to avoid overflow)


all integers, comment preserved :eek:

PSNR is always better with lambda=0

This is exactly why I don't want to play these games any more. The two lines of code are actually

int sad = predictor.sadLuma + predictor.sadChromaU + predictor.sadChromaV;
nLambda = nLambda*(LSAD/(LSAD + (sad>>1)))*(LSAD/(LSAD + (sad>>1)));

which shows the lambda is not zero.

A lot of the rounding error fixes where in PlaneofBlocks.cpp and Interpolation.cpp.

Because some people have found this useful, I will do new builds as promised over the weekend and then someone else can take over where I left off.

jeffy
17th September 2008, 20:39
@josey_wells: Thank you for all the improvements you brought to this library and thank you for your multithreading improvements.
MVDegrainMulti brought a really nice simplification to the MVDegrain family of functions.

@Fizick: Thank you for all the things you've done so far.

Fizick
17th September 2008, 20:53
which shows the lambda is not zero.


are you sure? ;)

check value of integer dividing expression in your added brackets

josey_wells
17th September 2008, 23:05
OK, I see rearrangement of brackets has caused a multiply by 0 since den>num. I will fix before doing build.

Fizick
19th September 2008, 20:12
I also prepare (almost finish) v1.11.4.X, currently in beta testing stage - i am afraid new bugs of new changes:

MVAnalyse: cut unused compensation memory space from vector clip (mc parameter).
Decreased internal cache size growing.
All MVFlow functions: fixed old bug with pixels for pel=4.
MVAnalyse: added rfilter parameter (smooth method).
MVBlockFps: added YUY2 and pelclip support.
Tiny stability fixes for MT.

New MVBlockFps for simple fps change (almost realtime :-).
MVAnalyse: more smooth method of frame hierarchical level reducing (like ReduceBy2) for smoothing at every level.
MVAnalyse: Added pzero parameter of zero vector cost for more coherent motion vectors (now switched ON by default, set to 0 if you need in old algo).
MVAnalyse: Decreased pelsearch internal clipping from pel to 1 (asked by somebody for speed).
MVFlowFps,MVFlowFps2, MVFlowInter: removed thSAD parameter.
All functions: Removed mmx parameter.

I also consider question to add MVAnalyseMulti (and MVDegrainMulti) functions, but without threading. Is it may be useful?

mikeytown2
19th September 2008, 20:29
MVDegrainMulti has simpler syntax IMHO when using the Degrain function. My question is if your going threw all the hassles of adding the Multi functions, why kill off threading; are the changes that big?

Glad to see that pel=4 will work correctly, and sounds like MVBlockFps will give us more toys to pay with in terms of FPS conversions.

Fizick
19th September 2008, 21:27
I suppose that StackVertical of several vector clips (and reverse operation) is not very hard hassle.

Blue_MiSfit
24th September 2008, 08:31
Is it possible to get some basic documentation thrown into these builds / releases? I forget the syntax and looking it up is proving to be a bear :)

Suggestions?

~MiSfit

Boulder
25th September 2008, 17:01
OK, I see rearrangement of brackets has caused a multiply by 0 since den>num. I will fix before doing build.Is the build released anywhere yet?

josey_wells
26th September 2008, 02:33
Sorry, I have been extremely busy.

Here are new builds on another machine with fix for brackets.

http://rapidshare.com/files/148440300/MVTools_V1.9.7.7.rar.html

maxhondur
26th September 2008, 03:06
Hi,

I have a question about MVTools, whether or not something is feasable or not. I've searched before but if I'm told to search harder that's fine too, I readily admit that MVTools is often hard for me to understand.

I have an animation dvd, DGdecode tells me it's 97% film, therefore I can avoid telecide and decimate and have a nice looking 23.97fps video. However, some parts of the video were meant to be in 29.97fps due to use of CG.

I can therefore make a video that is either 23.97fps and jerky on CG, or a 29.97fps file that doesn't take advantage of the 97% film result (and while being smooth in CG, is stuttery in all the scenes that were supposed to be the 24fps).

So, here's my convoluted question: Can I use mvtools to compare the motion vectors of the 23.97fps video to the 29.97fps video? In making a final 120fps file, I want most of the video from the 23.97fps file, but on CG scenes where the motion is jerky, I want to use parts from the 29.97fps file.

Yes, practically speaking this is a downright silly approach (vfr, anyone). But, I thought it would be cool to use MVTools in such a way nonetheless.

superuser
26th September 2008, 19:02
Sorry, I have been extremely busy.

Here are new builds on another machine with fix for brackets.

http://rapidshare.com/files/148440300/MVTools_V1.9.7.7.rar.html

Thnxs a lot. Appreciate ur efforts :thumbup:

with this changes, is r the parameters expected to work as original mvtools? if so will switch to this version for time being.

thnxs once again.

I also prepare (almost finish) v1.11.4.X, currently in beta testing stage - i am afraid new bugs of new changes:
...
...


does this build include enhancements made by Josey?

If not, in case r there plans of merging these two builds?

Appreciate efforts devoted by both of u to enhance this amazing plugin.

If you want compatibly with official mvtools: 1.9.7.1, else 1.9.7.5...

thnxs. it helps.

Fizick
27th September 2008, 05:41
does this build include enhancements made by Josey?

If not, in case r there plans of merging these two builds?


v1.11.x - no (besides memory fixes already merged to v1.10.X).
"multi" syntax will not implemented as well as internal multitreading.

My plans:
1. To release v1.11.4.2 final or may be v1.10.3 (i have some small trouble with v1.11.4).

2. I work on v2.0 alpha without idx. It (will) have rather big external and internal changes (but i try make them as small as I can :))
http://forum.doom9.org/showthread.php?t=131033
I hope v2.0 will have better performance and stability. Welcome to that thread for development discussion!
So, we will have 3 branches.

3. Then some best MT method (methods) may be considered and implemented to mvtools v2.1. I hope avisynth v2.6 will have some progress too.

Terranigma
27th September 2008, 16:48
My plans:
1. To release v1.11.4.2 final or may be v1.10.3 (i have some small trouble with v1.11.4).



What kind of trouble and how big of an issue is it?

Fizick
27th September 2008, 17:19
Terranigma, i found some small old bug with help of new v2.0. Now it is fixed (not important).
So, MVTools v1.11.4.2 final is released today.

45tripp
2nd October 2008, 18:46
don;t know if anyone else gets this,
but i get weird results with josey's last build and fft3dgpu prefitering.
basically with fft3dgpu(...,bt=1,2,or 3).mvanalysemulti(...,blksize16)


a=last
b=a.FFT3Dgpu(bt=3).MVanalyseMulti(refframes=3,blksize=16,overlap=8,idx=1)
a.MVDegrainMulti(b,refframes=3,thSAD=600,idx=2)


tripp

Sagekilla
2nd October 2008, 19:06
Dear god, how many branches do we have? Josey_wells has one, then there's the 1.11.x and 1.10.x and 2.0!

What's the difference of 1.11 and 1.10?

mikeytown2
2nd October 2008, 19:35
i get weird results with josey's last build

Don't use the IC10 Builds, use MSVC08-SSE2.

45tripp
2nd October 2008, 20:09
Don't use the IC10 Builds, use MSVC08-SSE2.

i was

yup
3rd October 2008, 07:45
Simple question:
How work thSCD1 for Mcompensate and MVMask?
Script:
AVISource("cap.avi")
source=AssumeTFF()
ConvertToYV12(source,interlaced=true)
fields=SeparateFields()
fieldsf2= fields.mt_luts(fields,mode="median",pixels="0 -2 0 -1 0 0 0 1 0 2")
fieldsf=fieldsf2.Removegrain(11)
bv1 = fieldsf.MVAnalyse(blksize=8, isb = true, truemotion=true, search=2, delta = 2, idx = 1, overlap=4, dct=0,chroma=false)
bc1 =fields.MVCompensate(bv1, idx=2, mode=1, thSAD=16000)
mlth=100
mf1=fieldsf.MVMask(fv1,kind=1,ml=mlth,Ysc=255)

My source have pulse noise.
I use prefiltered clip for vector estimating and original for compensation. For compensation if thSCD1 (default value 400) will be smaller than in real non processed clip I do not get compensated frame yes or no? And I need increase thSCD1 to 16000? I do not understand how work thSCD1 in MVMask?
Please explain.
yup.

ficofico
5th October 2008, 17:37
How can I multitreadh with mvAnalyzemulti this example script? thanks

source=last
backward_vec = source.MVAnalyse(overlap=4, isb = true, pel=4, search=3, idx=1,divide=2)
forward_vec = source.MVAnalyse(overlap=4, isb = false, pel=4, search=3, idx=1,divide=2)
source.MVFlowFps(backward_vec, forward_vec, num=2*FramerateNumerator(source), \
den=FramerateDenominator(source), idx=1)

Sagekilla
6th October 2008, 00:47
I don't think a multithreaded MVFlowFPS() is supported in the MVMulti build currently.

Fizick
6th October 2008, 06:39
What's the difference of 1.11 and 1.10?

Both should produce same results with rfilter=0, pzero=0 options (if you need it), besides pel=4 bug.
Speed may differ.

thetoof
6th October 2008, 14:57
How can I multitreadh with mvAnalyzemulti this example script? thanks]

@Sagekilla
True, but you can MT the mvanalyse calls

source=last
all_vec=source.MVAnalyseMulti(overlap=4,refframes=1, pel=4, search=3, idx=1,divide=2)
backward_vec = all_vec.MVMultiExtract(0)
forward_vec = all_vec.MVMultiExtract(1)
source.MVFlowFps(backward_vec, forward_vec, num=2*FramerateNumerator(source), \
den=FramerateDenominator(source), idx=1)

ficofico
6th October 2008, 16:04
I've download version MVTools v.1.11.4.2 but I get error " there's no function named MvAnalyzeMulti"

45tripp
6th October 2008, 17:01
they're 2 different branches.
with 1.11.4.2 use your original syntax.

or use one of josey's latest builds with the syntax thetoof gave

Nightshiver
6th October 2008, 20:27
Fizick's branch doesn't include MVanalyzemulti, which is one of the main reasons why I'm not going to download it.

Delerue
7th October 2008, 01:00
I've download version MVTools v.1.11.4.2 but I get error " there's no function named MvAnalyzeMulti"

You can download Avisynth MT version here (http://forum.doom9.org/showthread.php?t=94996) and use your script with a minor change, like this:


SetMtmode(1,5)
source=last
SetMTMode(2)
backward_vec = source.MVAnalyse(overlap=4, isb = true, pel=4, search=3, idx=1,divide=2)
forward_vec = source.MVAnalyse(overlap=4, isb = false, pel=4, search=3, idx=1,divide=2)
source.MVFlowFps(backward_vec, forward_vec, num=2*FramerateNumerator(source), \
den=FramerateDenominator(source), idx=1)
distributor()


You can try other values besides '5' in the first line. Here, I get the best result with '5'. Ah! This MT script works with Fizick's MVTools.

Fizick
7th October 2008, 07:30
Delerue,
I am wondered if "this MT script works with Fizick's MVTools" :)

Delerue
7th October 2008, 15:03
Delerue,
I am wondered if "this MT script works with Fizick's MVTools" :)

Hehehe. I mean, your build, instead of josey_wells one. I use a script very similar to this one, and it works. :)

Edited: I didn't see the 'MVAnalyseMulti', hehehe. It seems that I copied the wrong quote. Corrected. :D

Fizick
8th October 2008, 20:23
v1.11.4.3 (final again :) ) fixed small bugs

Fizick
9th October 2008, 20:32
Some user reported about crash of v1.11.4.3. v1.10.2.1 works fine.

SetMTMode(5,4)
DirectShowSource("1.grf", audio=false, fps=23.976)
SetMTMode(2)
gradfun2db()
SetMTMode(5)
crop(4,128,-2,-136)
Spline36Resize(1280,544)

SetMTMode(2)
s = last
pre = s.DegrainMedian(mode=2, limitY=4, limitUV=4)
bs = 8
ov = 4
b1v = pre.MVAnalyse(isb=true, delta= 1, blksize=bs, overlap=ov, pel=2, sharp=2, search=3, chroma=true, truemotion=true, idx=10)
f1v = pre.MVAnalyse(isb=false, delta= 1, blksize=bs, overlap=ov, pel=2, sharp=2, search=3, chroma=true, truemotion=true, idx=10)
cf1 = s.MVCompensate(f1v, mode=1, thSAD=400, idx=11)
cb1 = s.MVCompensate(b1v, mode=1, thSAD=400, idx=11)
inter = interleave(cf1, s, cb1)
SetMTMode(5)
si = 1.5
mvden = inter.FFT3Dgpu(sigma=si, sigma2=0.1, sigma3=si, sigma4=si, bt=4, plane=0, mode=1, precision=2, wintype=1, bw=32, bh=32, ow=16, oh=16)
SetMTMode(2)
den = mvden.selectevery(3,1)
den = mt_lutxy(s, den, "x 3 + y < x 3 + x 3 - y > x 3 - y ? ?", Y=3, U=2, V=2)
pmax = s.mt_logic(cb1, "max").mt_logic(cf1, "max")
pmin = s.mt_logic(cb1, "min").mt_logic(cf1, "min")
sharp = den.simple(Sstr=1.5)
mm = sharp.mt_clamp(pmax, pmin, 0, 0, U=2, V=2)
return mm

Source is a bluray disc.
VirtualDub crashes after a few thousands of frames. The whole movie is around 210000 frames. it crashes in around 60000-75000 frames.

We investigate the problem. (i hope the solution will be v.2.0 :) )
I am interested in reports.

superuser
13th October 2008, 20:28
thnxs for replying.... my fault asking and providing so later :-)

"multi" syntax will not implemented as well as internal multitreading.

so Josey's enhancement will be maintained as separate branch as of now?


My plans:
1. To release v1.11.4.2 final or may be v1.10.3 (i have some small trouble with v1.11.4).

2. I work on v2.0 alpha without idx. It (will) have rather big external and internal changes (but i try make them as small as I can :))
http://forum.doom9.org/showthread.php?t=131033
I hope v2.0 will have better performance and stability.

Tht will be great. so in long run will derivative of 2.0 will the one which will go ahead and more of enhanced?

Frankly I also do not understand the idx logic tht well and have been using as one in most of my scripts to scale down on memory usage as stated in document.



Welcome to that thread for development discussion!
So, we will have 3 branches.

sure, more of can help in trying out the enhancements there. once 2.0 is stable, after that do u plan to port over the fixes from these branches (one which u have been maintaining) to over 2.0 release version?

3. Then some best MT method (methods) may be considered and implemented to mvtools v2.1. I hope avisynth v2.6 will have some progress too.

Can not Josey's enhancement be used here?

Getting it to work with MT is also good idea though the thing is say with new releases of avisynth we need new release of MT, which I do not know internals for why. Say currently we have 2.5.8 out though for me at least one of the things holding me back to move over to 2.5.8 is lack of sort of MT for 2.5.8 (I have not checked on MT thread lately and 2.5.8 but this is the inference I had got from my last reading on 2.5.8 and MT).

Fizick
13th October 2008, 21:32
superuser,
i am sure you will be happy with v2.0 (2.1): its main function is MVSuper ! ;)

see more info about v2.0.9.0 in develoment thread.

Forgot to say: user report, that v2.0.7 works without crash with scipt http://forum.doom9.org/showthread.php?p=1193093#post1193093

fleon
15th October 2008, 03:05
Hi I posted a video that I recorded with my old old sony cybershot DSC-P32 is right here http://www.mediafire.com/download.php?zy2kzoz0klm and someone in other part of this forum suggested me that in order to fix it I should use MVDegrain3 because he tried it and he said that MVDegrain3 cleaned up the video, but he didnt give me the complete script that he used, also as I dont now too much of the tech terms that the documentation of MVtools said I could not understand much of it.

So could someone here help me out? in the other part of the forum that i asked they kinda help me out but they dont seem to know too much about that, they give me this script:

DGDecode_mpeg2source("C:\Documents and Settings\Administrator\Desktop\New Folder (2)\VTS_06_1.d2v",info=3)
backward_vec3 = MVAnalyse(isb = true, delta = 3, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec2 = MVAnalyse(isb = true, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec1 = MVAnalyse(isb = true, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec1 = MVAnalyse(isb = false, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec2 = MVAnalyse(isb = false, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec3 = MVAnalyse(isb = false, delta = 3, pel = 2, overlap=4, sharp=1, idx = 1)
MVDegrain3(backward_vec1,forward_vec1,backward_vec2,forward_vec2,backward_vec3,forward_vec3,thSAD=400,idx=1)
ColorMatrix(hints=true,interlaced=true)
TDecimate(cycleR=1)
#crop
Spline36Resize(480,272)

But I get this error http://img235.imageshack.us/img235/8718/56792763sz6.th.jpg (http://img235.imageshack.us/my.php?image=56792763sz6.jpg)http://img235.imageshack.us/images/thpix.gif (http://g.imageshack.us/thpix.php) please I just need to fix this video since if I fix this one I can fix every video recorded with my camera Thanks!

mikeytown2
15th October 2008, 04:16
wow, after reading that thread (http://forum.doom9.org/showthread.php?t=141628&page=5), I think MVTools might benefit from a dumb mode For MVDegrainX(). Something where all you do is call MVDegrain3(simple=true), and in reality it calls everything that is needed inside the function, using defaults. Basically its an alias for a function like this.


SimpleMVDegrain3()
Function SimpleMVDegrain3(clip c)
{
c
backward_vec3 = MVAnalyse(isb = true, delta = 3, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec2 = MVAnalyse(isb = true, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec1 = MVAnalyse(isb = true, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec1 = MVAnalyse(isb = false, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec2 = MVAnalyse(isb = false, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec3 = MVAnalyse(isb = false, delta = 3, pel = 2, overlap=4, sharp=1, idx = 1)
c.MVDegrain3(backward_vec1,forward_vec1,backward_vec2,forward_vec2,backward_vec3,forward_vec3,thSAD=400,idx=1)
}


fleon you were missing last.MVDegrain3(...) from your previous attempts. The code above should do what you want.

superuser
15th October 2008, 05:10
superuser,
i am sure you will be happy with v2.0 (2.1): its main function is MVSuper ! ;)

see more info about v2.0.9.0 in develoment thread.

Forgot to say: user report, that v2.0.7 works without crash with scipt http://forum.doom9.org/showthread.php?p=1193093#post1193093

:cool: I know its by chance but m happy :) hope luck brings more favors like this ... kidding ... :thanks:

Fizick
16th October 2008, 07:05
mikeytown2,
it is no need for built-in function like this, but i will add script example for mvdegrain3 to v2.0 documentation,
probably even more general like MVDegrainSimple(clip, radius, thSAD, blksize, overlap) with proper defaults and all MVanalyse included. :)

and avsi file?

fleon
16th October 2008, 07:17
wow, after reading that thread (http://forum.doom9.org/showthread.php?t=141628&page=5), I think MVTools might benefit from a dumb mode For MVDegrainX(). Something where all you do is call MVDegrain3(simple=true), and in reality it calls everything that is needed inside the function, using defaults. Basically its an alias for a function like this.


SimpleMVDegrain3()
Function SimpleMVDegrain3(clip c)
{
c
backward_vec3 = MVAnalyse(isb = true, delta = 3, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec2 = MVAnalyse(isb = true, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec1 = MVAnalyse(isb = true, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec1 = MVAnalyse(isb = false, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec2 = MVAnalyse(isb = false, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec3 = MVAnalyse(isb = false, delta = 3, pel = 2, overlap=4, sharp=1, idx = 1)
c.MVDegrain3(backward_vec1,forward_vec1,backward_vec2,forward_vec2,backward_vec3,forward_vec3,thSAD=400,idx=1)
}


fleon you were missing last.MVDegrain3(...) from your previous attempts. The code above should do what you want.

I got this error: ColorMatrix: no hints detected in stream with hints=true! (C:\Documents and Settings\Administrator\Desktop\New Folder (2)\VTS_06_1.avs, line 13) with this script:

DGDecode_mpeg2source("C:\Documents and Settings\Administrator\Desktop\New Folder (2)\VTS_06_1.d2v",info=3)
backward_vec3 = MVAnalyse(isb = true, delta = 3, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec2 = MVAnalyse(isb = true, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec1 = MVAnalyse(isb = true, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec1 = MVAnalyse(isb = false, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec2 = MVAnalyse(isb = false, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec3 = MVAnalyse(isb = false, delta = 3, pel = 2, overlap=4, sharp=1, idx = 1)
last.MVDegrain3(backward_vec1,forward_vec1,backward_vec2,forward_vec2,backward_vec3,forward_vec3,thSAD=400,idx=1)
ColorMatrix(hints=true,interlaced=true)
TDecimate(cycleR=1)
#crop
Spline36Resize(480,272)

But I puted the line of ColorMatrix below the first line and it worked, but it will be right to do that?

Fizick
16th October 2008, 07:41
fleon, yes, colormatrix with hints must be right after mpeg2source. But please do not discuss colormatrix in this thread.

Fizick
16th October 2008, 10:50
Same user reported, that new released v1.11.4.4 seems works without crashes with MT.

EDIT: No, same crashes is present.

foxyshadis
22nd October 2008, 05:36
Fizick, even better than adding it to the docs, how about adding it as MVDegrainSimple.avsi in the zip? Like masktools does with limitedsharpen. That way it's obvious and immediately usable by anyone.

Chipstra
7th November 2008, 13:17
I try to Download MVTools v2.0.11.2 http://avisynth.org.ru/mvtools/mvtools-v2.0.11.2.zip
but i got:

Not Found

The requested URL /mvtools/mvtools-v2.0.11.2.zip was not found on this server.
Apache/2.0.52 (CentOS) Server at avisynth.org.ru Port 80

cb

talen9
7th November 2008, 14:11
Confirmed.

You can still download 2.0.11.1 if you manually adapt the link, though.

Chipstra
7th November 2008, 14:26
thnx talen9

lansing
15th November 2008, 18:25
Hi, I have a poorly made animation opening from a game that was upped framerate from 15 to 30fps, by doubling every frame. Also the playback was not smooth.

I tried to make it smooth with MVFlowFps after changing the frame rate back to 15, but there are noticeable artifacts on all special effect scene changes. What can I do?

johnmeyer
15th November 2008, 18:36
I tried to make it smooth with MVFlowFps after changing the frame rate back to 15, but there are noticeable artifacts on all special effect scene changes. What can I do?Change the scene detect values?

lansing
15th November 2008, 18:45
this is the script I took from the MVtools document to double fps with MVFlowFps, but I have no idea where to put in the scene change detection value.

# assume progressive PAL 25 fps or NTSC Film 23.976 source
backward_vec = source.MVAnalyse(overlap=4, isb = true, pel=2, search=3, idx=1)
# Use block overlap, halfpixel accuracy and Exhaustive search
forward_vec = source.MVAnalyse(overlap=4, isb = false, pel=2, search=3, idx=1)
source.MVFlowFps(backward_vec, forward_vec, num=2*FramerateNumerator(source), \
den=FramerateDenominator(source), idx=1)

Fizick
15th November 2008, 18:52
I tried to make it smooth with MVFlowFps after changing the frame rate back to 15, but there are noticeable artifacts on all special effect scene changes. What can I do?

Use ThSCD1 parameter.
Also try upgrade to version 2.1 with new blend=false mode.

lansing
15th November 2008, 19:53
just tried, the scene change on my clip are basically all overlapping of fade in and fade out effects, have to set ThSCD1 to low 70 or 80 to keep out the artifacts, but on the other hand it gives up too much playback smoothness, which is what I wanted

Delerue
15th November 2008, 20:01
Use ThSCD1 parameter.
Also try upgrade to version 2.1 with new blend=false mode.

Hmmm... I never took a look at 'ThSCD1' parameter. Interesting. The 'blend=false' parameter helped, but still not perfect with all scene changes. I'm using this script here:

super = source.MVSuper(pel=2)
backward_vec = MVAnalyse(super, blksize=8, overlap=0, isb = true, search=3)
forward_vec = MVAnalyse(super, blksize=8, overlap=0, isb = false, search=3)
source.MVFlowFps(super, backward_vec, blend=false, forward_vec, num=2*FramerateNumerator(source), \
den=FramerateDenominator(source))

Sometimes, when the video isn't heavy, I set 'overlap' to 2. Any idea what's the reasonable 'ThSCD1' value should I set to avoid the jitter between scene changes?

Thanks

thetoof
14th December 2008, 08:08
This is the script I use to upscale with nnedi:

function nnedi2x(clip a) {
a.nnedi(1,true).turnright().nnedi(1,true).turnleft()
return spline36resize(a.width*2,a.height*2,-1,-1,2*a.width+.001,2*a.height+.001)}
I found the values in blue by testing with this to see which ones corrected the "registration error between original and upscaled clip due to nnedi":
interleave(source,source.nnedi2x().reduceby2())
and the values in red come from here (http://forum.doom9.org/showthread.php?p=1166238#post1166238) (though I don't really know why they are used). Any other value moved the image in at least one direction.

My question is:
When using nnedi to create the external pelclip, which values should be used to match with what mvtools does internally? And is there a difference between v1 and v2 about that?

Gavino
14th December 2008, 14:28
function nnedi2x(clip a) {
a.nnedi(1,true).turnright().nnedi(1,true).turnleft()
return spline36resize(a.width*2,a.height*2,-1,-1,2*a.width+.001,2*a.height+.001)}
I found the values in blue by testing with this to see which ones corrected the "registration error between original and upscaled clip due to nnedi":
interleave(source,source.nnedi2x().reduceby2())

However, reduceby2() also introduces a "registration error" of its own, so I think the values should be -0.5, -0.5, as you posted in the other thread. That's assuming you want nnedi2x to match the positioning of the normal xxxResize filters.

Fizick
14th December 2008, 14:39
thetoof,
you may test and tune it youself by comparing of produced super clips (by Interleave).

v1 and v2 should not differ

thetoof
14th December 2008, 20:54
However, reduceby2() also introduces a "registration error"Oh thanks, didn't notice that. You're right, -.5,-.5 does the trick when downscaling with xxxresize.

thetoof,
you may test and tune it youself by comparing of produced super clips (by Interleave).
Will do.

moviefan
16th December 2008, 20:58
Is it better to use smaller blocksize like 8 and overlap 4 for HD footage, if I want to slightly reduce and stabilize grain/noise? I have read the documentation and it says that it is more sensitive to noise with smaller sizes. What I have experienced with LaTo's MCTemporalDenoise is that the noise/grain reduction is consistent... Some areas are pretty well denoised, some show "randomly" left grain (probably because it was to heavy for the filtering). Any suggestions? The examples in the first post of LaTo's thread with "300" show a consistent increase in noise/grain reduction, not only in certain areas but overall.

LegendSeeker
23rd December 2008, 18:46
sorry, another thread post;
http://forum.doom9.org/showpost.php?p=1227151&postcount=195

R3Z
28th December 2008, 11:18
Sorry to ask something stupid, alas is it still ok to use MVCompensate with the MVanalyseMulti branch ?

For when i would like to use a different denoiser such as FFT3DGPU or even FluxSmoothST.

I couldnt see any examples of this thats all. Thanks.

thetoof
28th December 2008, 12:38
If the speed gain with mvanalysemulti is worth (for you) not benefiting from v2's improvements, yes.

Though v2 is more stable with setmtmode... but then you'd have to use an older version of avisynth :p
I'd go for setmtmode + mvtools2 if you absolutely want to multithread it in 1 script, but the choice is yours.
Other option: avs 2.5.8, mvtools2, trim, run the scripts in x different rendering passes, splice, encode

Sagekilla
6th January 2009, 02:52
Fizick, if I might ask: Why was MVFlowFPS2 removed from MVTools? I understand there was originally a bug with overlap not working properly, but if that was fixed wouldn't it be useful to use a second pair of MVs?

Fizick
6th January 2009, 21:07
Sagekilla,
What bug you talk about?
MVFlowfps2 was born when there was no overlap mode in MVTools.
And MVFlowfps in fact use alternative implementation of overlapping.
So, it is no sense to use overlap with MVFlowfps2.

It is quite possible that second pair of vectors may be useful. But IMO some more general way may be more perspective,
like making some special functions for vectors operations. In particular to get resulted vectors from two shifted pairs.
With following MVFlowFPS...
But right now I prefer to drink merlot instead of C++ coding :)

Sagekilla
7th January 2009, 05:10
Ah, I remember somewhere once I heard MVFlowfps2 couldn't use overlap because of some bug. Mix up on my part, sorry!

Would be nice to see MVFlowFPS2 again. But it is up to you, since you are the developer :) (And merlot definitely sounds better than C++ anytime)

Kaze_no_Hime
18th January 2009, 11:04
I have a problem with MVAnalyse and MVDegrain3.
When I put this line:
MVDegrain3(thSAD=400, thSADC=500, plane=4, limit=255, idx=1)
it's tells me that I have to specify a vector clip. Well the problem is that I don't know how to do it. Also how can I specify mvbw, mvfw, mvbw2, mvfw2, mvbw3 and mvfw3 in MVDegrain? Here (http://avisynth.org.ru/mvtools/mvtools.html#functions) it's written that they're a "clip".
MVDeGrain3 (clip, clip "mvbw", clip "mvfw", clip "mvbw2", clip "mvfw2", clip "mvbw3", clip "mvfw3",int "thSAD", int "thSADC", int "plane", int "limit", clip "pelclip", int "idx")
Wll I know how to specify a "int" but don't know how to with "clip".

The other problem is with MVAnalyse. Here's the line I want to put in my whole script:
MVAnalyse(blksize=8, blksizeV =4, pel=2, level =0, search=3, searchparam=2, pelsearch=2, isb=false, chroma=true, delta=2, truemotion=true, lambda=1000*8*4/64, lsad=1200*8*4/64, pnew=50, plevel=1, global=true, pzero=50, overlap=2, overlapv=2, sharp=2, rfilter=1, dct=1, divide=0, sadx264=0)
but when I put it, it gives me an error:
"Avisynth open failure:
ConvertToYV12: Image height must be multiple of 2
(LimitedFasterSharpen.avsi, line57)

And finally here's the whole my script:
DGDecode_mpeg2source("H:\for DVD\Demuxed\VideoFile.d2v",info=3)
ColorMatrix(hints=true, interlaced=true)
orig = last
telecide(guide=1, hints=true, post=1)
tfm(order=-1, mode=5, PP=1, field=1, slow=2, mChroma=true, y0=0, y1=0, scthresh=12.0, ubsco=true, micmatching=3, mmsco=false, hint=true, opt=4, cthresh=9, chroma=true, blockx=32, blocky=32, MI=64, metric=0, mthresh=5)
tdecimate(mode=1, cycleR=1, cycle=5, hybrid=3, dupThresh=1.4, vidThresh=1.4, sceneThresh=15, vidDetect=3, conCycle=1, nt=0, blockx=32, blocky=32, chroma=true, exPP=true, noblend=false, denoise=true, ssd=false, hint=true, clip2=orig, sdlim=0, opt=4)
Tdeint(mode=0, order=-1, field=-1, mthreshL=6, mthreshC=6, map=0, type=3, mtnmode=1, sharp=true, hints=true, full=true, clip2=orig, cthresh=7, blockx=32, blocky=32, chroma=false, MI=64, tryWeave=true, AP=32, APType=1, metric=0, slow=2, opt=4)
MVAnalyse(blksize=8, blksizeV =4, pel=2, level =0, search=3, searchparam=2, pelsearch=2, isb=false, chroma=true, delta=2, truemotion=true, lambda=1000*8*4/64, lsad=1200*8*4/64, pnew=50, plevel=1, global=true, pzero=50, overlap=2, overlapv=2, sharp=2, rfilter=1, dct=1, divide=0, sadx264=0)
LimitedSharpenFaster(Smode=4, ss_x=1.5, ss_y=1.5, strength=160, overshoot=1, undershoot=2, wide=true)
FastLineDarken(strength=48, luma_cap=191, threshold=4, thinning=10)

Any help and seggestions for modification in the script are welcomed.

scharfis_brain
18th January 2009, 11:13
why do you use TWO fieldmatchers (Telecide AND TFM) and also a Deinterlacer AFTER the Decimation is done? It is nonsense.

also why do you write out all possible parameters? This makes your script almost unreadable.

mvanalyse also won't do anything visible with you video. It just analyses. Read the mvtools documentation and its examples more careful.

Shorten you parameter lists.
Throw out telecide. Throw out TDeint.

Kaze_no_Hime
18th January 2009, 11:43
Ok, I've removed telecide and tdecimate from the script, because TDeint works better for now. But how can I specify the "clip" parameters for MVDegrain3?

Nephilis
25th February 2009, 16:08
In Mdegrain2 denoiser how should i reduce the denoise strenght ? should i decrease the thSAD default value or how?

Thanks..

Sagekilla
25th February 2009, 16:18
You should decrease thSAD to decrease denoising. You can try using something like Restore or Soothe to help reduce denoising a bit more too if necessary.

Nephilis
25th February 2009, 16:31
My point is denoising without removing the details. (i have 720p HD source) Also i will use thSAD value less than default and soothe after sharpen (LSF)
Thanks for your help Sagekilla..

Sagekilla
25th February 2009, 16:34
You'll probably want to do Denoise --> Soothe --> Sharpen

Nephilis
25th February 2009, 16:46
i mean so,
.
..
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)
dull=last.MDegrain2(super, backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=250)
sharp=dull.LimitedSharpenFaster()
Soothe(sharp,dull,60)

.
..

is this placement false?

Boulder
25th February 2009, 17:55
You should decrease thSAD to decrease denoising. You can try using something like Restore or Soothe to help reduce denoising a bit more too if necessary.There's also the LimitChange function in the SSETools dll, available in the official RemoveGrain package at http://www.removegrain.de.tf/

Sagekilla
25th February 2009, 20:06
This code limits sharpening against the denoised source.

dull=last.MDegrain2(super, backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=250)
sharp=dull.LimitedSharpenFaster()
Soothe(sharp,dull,60)


If you want to limit the denoising so it doesn't do too much denoising, you do it like so:

src= last
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)
dull = last.MDegrain2(super, backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=250)
soothed = Soothe(src, dull, 60)
soothed.LimitedSharpenFaster()

Didée
25th February 2009, 23:04
Soothe() is a quite simplistic function for simple context. When the advantage (and computational effort) of MVTools is taken, then Soothe() is too simple to benefit from that advantage. And worse: since Soothe() forces a TemporalSoften() on its input, it huges the complexity of the script's filterchain.
- MDegrain2(source) -> "take a bowling ball. hold it in the air!"
- MDegrain2(source).temporalsoften(1) -> "take three bowling balls. juggle!" )

When motion vector search et.al. is done anyway, then you can get a smarter kind of Soothe with less waste by
src = last
shrp = src.enhance(sharpness)

src_super = src.MSuper()
shrp_super = shrp.MSuper(levels=1)

bv2 = MAnalyse(src_super, isb=true, delta=2, overlap=4)
bv1 = MAnalyse(src_super, isb=true, delta=1, overlap=4)
fv1 = MAnalyse(src_super, isb=false, delta=1, overlap=4)
fv2 = MAnalyse(src_super, isb=false, delta=2, overlap=4)

src.MDegrain2(shrp_super, bv1,fv1,bv2,fv2,thSAD=??)

Nephilis
26th February 2009, 10:23
Sagekilla ve Didée,
Thank you for the illuminative tips..

Didée,
One more question, does that script above help the sharpen stabilization? (Because i want to avoid that sharpen filters negative effects too)

Didée
26th February 2009, 13:21
Sure. In areas with successful mocomp, it combines sharpening and averaging (i.e. sharpening and soothing "in one go"). In areas with faulty mocomp, nothing happens.
However, the exact tune of that method is pretty much source dependend. That's why I posted only a general outline, instead of a fully functional script.

---

To expand (a bit) on the topic "denoise + soothe" ...

When using a purely temporal denoiser, then the action Soothe(source,denoisedsource) is mostly flapdoodle. Perhaps it makes feel elitist because of the "different usage" of a filter, but still: flapdoodle.

It's a different story when using a purely spatial, or a spatio-temporal denoiser. In that case, Soothe() can recover detail that was removed by [the spatial part of] the denoiser.


NR = source.MDegrain2( ... )
check1 = NR.mergeluma(source,0.66) # something primitive
check2 = soothe(source,NR,keep=60) # Hey! Found something! Cool!
When compairing check1 and check2, it reveals that both are quite similar. Not identical, but very similar.

Probably I'll prepare something more in-depth for the Soothe thread.

Nephilis
26th February 2009, 14:46
Didée, herzlichen Dank :)

Floatingshed
28th February 2009, 08:44
What/where is MSuper?
Thanks.

jeffy
28th February 2009, 10:41
What/where is MSuper?
Thanks.

http://avisynth.org.ru/mvtools/mvtools2.html#version2

Betsy25
11th March 2009, 20:08
src = last
shrp = src.enhance(sharpness)

src_super = src.MSuper()
shrp_super = shrp.MSuper(levels=1)

bv2 = MAnalyse(src_super, isb=true, delta=2, overlap=4)
bv1 = MAnalyse(src_super, isb=true, delta=1, overlap=4)
fv1 = MAnalyse(src_super, isb=false, delta=1, overlap=4)
fv2 = MAnalyse(src_super, isb=false, delta=2, overlap=4)

src.MDegrain2(shrp_super, bv1,fv1,bv2,fv2,thSAD=??)
Just out of interest in trying to learn a bit more about Avisynth and MVTools2, I tried this example for a movie, but I only got some response : "I don't know what sharpness means" :(

Docholo
21st March 2009, 05:27
I have video that has lots of low detail (clouds)
that are constantly getting brighter and darker
(fireworks). When the brightness changes, mvtools
sees a whole bunch of motion vectors in these
clouds where there should be none.

The problem is that there just isn't enough detail
in these blocks to actually track real motion. Is
there a minimum bound on how little detail can
be in a block? I'd like to increase it, if possible,
so that motion vectors do not get initiated on
really blurry/low detail blocks.

Fizick
21st March 2009, 22:32
Docholo, you may try dct option

rkalwaitis
24th March 2009, 22:30
Betsy25,

I think that you need to replace enhance(sharpeness), with your desired sharpener.

Try this and see if it works.

src = last
shrp = src.msharpen()

src_super = src.MSuper()
shrp_super = shrp.MSuper(levels=1)

bv2 = MAnalyse(src_super, isb=true, delta=2, overlap=4)
bv1 = MAnalyse(src_super, isb=true, delta=1, overlap=4)
fv1 = MAnalyse(src_super, isb=false, delta=1, overlap=4)
fv2 = MAnalyse(src_super, isb=false, delta=2, overlap=4)

src.MDegrain2(shrp_super, bv1,fv1,bv2,fv2,thSAD=300)

rkalwaitis
24th March 2009, 23:10
Didee,

What sharpener do you suggest for .....
shrp=scr.enhancer

Thanks K

Didée
24th March 2009, 23:57
rkalwaitis,

which notes one shall choose to make a nice song? Which colors one shall choose to make a beautiful painting?

That's my suggestion for the sharpening to use.

Sagekilla
25th March 2009, 01:12
On that note, you have some leverage with your sharpening too. The way that script works, you can prevent a lot of normal sharpening artifacts from popping up so you can use some of the more artifact prone (but sharper) sharpeners. Also, the high quality sharpeners like LimitedSharpenFaster() tend to work worse than a dumb sharpen() in my scant testing.

Play around and learn, it's what I did ;)

Didée
25th March 2009, 03:07
Sharpening has the aspect of increasing edge steepness, and the aspect of local contrast expansion. The 2nd aspect is more prominent, and is what causes halos from oversharpening. LSF works mostly on the 1st aspect of edge steepness. This weaker aspect can easily get dimished by MDegrain. The stronger effect of contrast expansion has better chances to "survive" MDegrain.

Often it seems good to use impulse enhancement as sharpener for this kind of "sharp-MDegrain" operation. This can be carried out in many different ways, the quickest is to invert a median filter into a sharpener:

mt_adddiff(mt_makediff(removegrain(4,-1)),U=2,V=2)
That's the most basic one. A bit smarter:

strength = 1.0 # strength of sharpening

Linda = last
and = Linda.sbr()
Peter = and.removegrain(4,-1)
go = mt_makediff(and,Peter)
shopping = mt_lutxy(Linda,go,"x y 128 - abs 1 2 / ^ 2 * "+string(strength)+" * y 128 - y 128 - abs 0.001 + / * +",U=2,V=2)

interleave( Linda.subtitle("source"), shopping.subtitle("impulse sharpen") )
return(last)

# -----
function sbr(clip c) {
rg11D=mt_makediff(c,c.removegrain(11,-1))
rg11DD=mt_lutxy(rg11D,rg11D.removegrain(11,-1),"x y - x 128 - * 0 < 128 x y - abs x 128 - abs < x y - 128 + x ? ?")
c.mt_makediff(rg11DD,U=2,V=2) }

The bigger fun is to directly modify the superclip.

videoFred
25th March 2009, 09:21
which notes one shall choose to make a nice song? Which colors one shall choose to make a beautiful painting?.

Good quality paint to start with: LSF :)

I have made a small clip that shows the different steps in film restoring: http://vimeo.com/3846612

The used denoiser was MVDegrainMulti() and the basic sharpener was LimitedScharpenFaster() of cource. Please note that averaging 6 frames also removes dirt spots.

At the bottom right you will see a woman and a child. It is amazing how the womans face is recovered!

Fred.

Sagekilla
25th March 2009, 14:36
Thanks for that tidbit, Didee ;) Never knew that. Would the act of increasing edge steepness mostly, with very little local contrast enhancement (i.e, no haloing ever) be more or less the holy grail of sharpening?

Also, cheeky little script you got there.

buletti
30th March 2009, 18:53
In the upcoming AVC codecs comparison thread (http://forum.doom9.org/showthread.php?t=145087) Dark Shikari mentioned some recent x264 improvements (http://git.videolan.org/?p=x264.git;a=commit;h=2dca5f5413051a26cbba4e20f3c77ff69b694ba3)for SATD/DCT/IDCT:
Vastly faster SATD/SA8D/Hadamard_AC/SSD/DCT/IDCT

Heavily optimized for Core 2 and Nehalem, but performance should improve on all modern x86 CPUs.

16x16 SATD: +18% speed on K8(64bit), +22% on K10(32bit), +42% on Penryn(64bit), +44% on Nehalem(64bit), +50% on P4(32bit), +98% on Conroe(64bit)

Similar performance boosts in SATD-like functions (SA8D, hadamard_ac) and somewhat less in DCT/IDCT/SSD.

Overall performance boost is up to ~15% on 64-bit Conroe.

Well, since TSchniede added the x264 ME code to MVTools, I was wondering if MVTools could also benefit from these improvements.

TSchniede
3rd April 2009, 02:02
Well, since TSchniede added the x264 ME code to MVTools, I was wondering if MVTools could also benefit from these improvements.
Well since I changed the minor difference in the interface in MVTools and the few assembler files from the x264 project were only verbatim copies, "merely" using the new files should be enough. After a quick comparison between the two versions it seems as if the usually more important SAD functions didn't get changed much. The SATD functions (dct > 4 or sadx264 > 7) however look quite different, so there might be some visible improvements. Adding new functions and changes in the auto detection function are slightly more complex.

Fizick
3rd April 2009, 08:19
1. MVTools v2.4.1 is released (at 24.01.2009).
MDegrain: Changed degrain weight method to more strong, some internal rewriting, Fixed weight for hight threshold and big block size.
Fixed documenation.

2. This March I tried to update MVTools with new x264 files. As TSchniede noted, there are some structural code changes in CPU detection and others. I compiled new version (2.5) succesfully, but I have not appropriate CPU to check, so i decided not to publish it. I can send it to TSchniede for testing and updating. BTW, my code is now at Mercurial version control system (I am novice in it) :)

yup
3rd April 2009, 09:20
TSchniede & Fizick :thanks:
Today morning I try dct=5 at MAnalyse function and find that MDegrain3 work worst at this setting (do not remove grain). Change dct to deafault (0) give good degraining result.
Please explain.
yup.

TSchniede
3rd April 2009, 13:41
2. This March I tried to update MVTools with new x264 files. As TSchniede noted, there are some structural code changes in CPU detection and others. I compiled new version (2.5) succesfully, but I have not appropriate CPU to check, so i decided not to publish it.Unfortunately I don't own a a Nethalem based cpu, so I can't test those either, only the few changes that apply to Penryn.

Today morning I try dct=5 at MAnalyse function and find that MDegrain3 work worst at this setting (do not remove grain). Change dct to deafault (0) give good degraining result.
Please explain.I'm a bit out of the loop, so it could be a simple bug, but SATD is a bit sharper than SAD, so strong noise might be amplified, have you tried using a blurred or otherwise smoothed clip in the analyse?

FuPP
3rd April 2009, 17:18
Hi,

I have a problem :)

Avisynth crashes always on the same frame of my clip when I write the following :


s = mpeg2source("C:\...\film.d2v", idct=7)

s = s.crop(0,12,-0,-12)

s = s.bicubicresize(608,320,0,0.5)

super = s.msuper()
b = MAnalyse(super, isb = true, lambda=1000, blksize=16)

return MFlow(s, super, b, thSCD1=260)



<!> When I remove cropping, no more crash <!>


I think it is related to MVtools2 because it does not occur with some other functions. If I use isb=false, no more crash.


Error using MVTOOLS 2.3.1 : Access violation at 0x10126e0f

Error using MVTOOLS 2.4.1 : Access violation at 0x1012710f


Any clue ?

FuPP

Fizick
3rd April 2009, 17:54
you must post a short cut of you video to get "any clue". :)

Sagekilla
3rd April 2009, 19:20
What happens if you try BicubicResize(608, 320, 0, 0.5, 0, 12, 0, -12)?

rkalwaitis
3rd April 2009, 21:54
Fupp it worked for me with the MT version of avisynth.

However it makes the x64.exe for Megui stop working. :( Ill try virtualdub and the vfw 264codec.

Virtualdub failed handingling the script and gave me this error. Well it ran for a bit then stopped......

An out-of-bounds memory access (access violation) occurred in module 'mvtools2'...
...reading address 06FB1072...
...while running thread "Dub-I/O" (thread.cpp:163).

FuPP
3rd April 2009, 22:25
here is a short clip (http://files.filefront.com/clipvob/;13532671;/fileinfo.html)

(crash on frame 17)

@Sagekilla : same crash...

Thanks in advance,

FuPP

Fizick
4th April 2009, 08:40
Fupp, confirmed.
Thanks for bug report.

workaround is to use greater value of padding:

super = s.msuper(vpad=16)


but anyway it is a bug. I will look internals reason later.

FuPP
4th April 2009, 12:49
Thanks for your time, Fizick.

FuPP

Boulder
5th April 2009, 17:51
I get an access violation with this clip if I use MVTools v2 in TempGaussMC. It happens around frames 350-370 when saving to AVI with VDub. If I use the mt=true option to switch to the multithreaded MVTools, it works fine. MVT2 seems to be quite a bit faster :)


AVISource("test.avi")
TempGaussMC()


The TempGaussMC version is from here: http://avisynth.org/mediawiki/upload/c/c8/TempGaussMC_beta1mod.avsi

The clip: http://www.mediafire.com/?sharekey=9b19b691e7eb0ac9d2db6fb9a8902bda

Fizick
7th April 2009, 21:20
v2.4.2 (07.04.2009)
MAnalyze: Fixed valid vector range for case of padding lesser than block size, with program crash (thanks to FuPP for bug report).

FuPP
8th April 2009, 11:01
Thanks again Fizick !

FuPP

Fizick
8th April 2009, 17:49
Boulder, how about access violation with your clip for v2.4.2?

Boulder
8th April 2009, 21:23
Boulder, how about access violation with your clip for v2.4.2?Seems to work now, thanks! It seems that the time is right to move to MVTools v2 :)

actionman133
12th May 2009, 01:39
Hi,

Using this plugin to create a smooth fast-motion silent film look for my film, but having problems with high motion. Just doing early tests now, but high motion objects get a garbly outline which is distracting.

In the help file, MFlowFPS shows a thSAD option which would - if I'm thinking right - decide those distortions as bad blocks and resort to blending rather than motion estimation. However, setting a thSAD value brings an error saying 'MFlowFPS does not have a named argument "thSAD".

Not yet implemented in the program or typo in the help file?

Actually, just as I was writing this, I discovered using MRecalculate with blksize = 16 solves *most* of these problems. Which search and searchparam options would help this catch wide, fast-moving vectors?

Thanks.

EDIT: just foudn this works fine on a downconverted 720p version of the source but can't make connections with the 1080p. Could this be the blocks with 1080p are too small and lack enough detail to catch blurry motion? Any chance of implementing a 32 blksize option if that's the case?

Fizick
12th May 2009, 23:03
MFlowFPS does not have a named argument "thSAD". Documentation is wrong.

Blending threshold is controlled by thSCD1, thSCD2 parameters

swaaye
14th May 2009, 03:59
I've noticed that when using MDegrain2 with MT() as described on the MVTools2 page that there are separation lines visible between the MT segments. They aren't visible most of the time, but with the right scene, they can become painfully apparent. Because I am running with 4 threads, I see 4 separate segments in the video.

Has anyone managed to get rid of this problem? I tried setting different overlap values but that doesn't seem to help at all....

What I've been using:

MT("""
super = MSuper()
backward_vec2 = super.MAnalyse(isb = true, delta = 2, overlap=4)
backward_vec1 = super.MAnalyse(isb = true, delta = 1, overlap=4)
forward_vec1 = super.MAnalyse(isb = false, delta = 1, overlap=4)
forward_vec2 = super.MAnalyse(isb = false, delta = 2, overlap=4)
MDegrain2(super, backward_vec1,forward_vec1,backward_vec2,forward_vec2)
""",4)

shoopdabloop
14th May 2009, 04:51
I thought MVTools was incompatible with MT?

swaaye
14th May 2009, 06:07
I thought MVTools was incompatible with MT?

MVTools2:
http://avisynth.org.ru/mvtools/mvtools2.html
see examples

Gavino
14th May 2009, 10:09
I've noticed that when using MDegrain2 with MT() as described on the MVTools2 page that there are separation lines visible between the MT segments.
...
I tried setting different overlap values but that doesn't seem to help at all
Setting the overlap in MAnalyse cannot extend the scope of the analysis beyond the boundaries of the MT 'split'. Try using the overlap parameter of MT itself:

MT("""
...
""",4, overlap=4)

LaTo
14th May 2009, 10:10
I've noticed that when using MDegrain2 with MT() as described on the MVTools2 page that there are separation lines visible between the MT segments. They aren't visible most of the time, but with the right scene, they can become painfully apparent. Because I am running with 4 threads, I see 4 separate segments in the video.

Has anyone managed to get rid of this problem? I tried setting different overlap values but that doesn't seem to help at all....

What I've been using:

MT("""
super = MSuper()
backward_vec2 = super.MAnalyse(isb = true, delta = 2, overlap=4)
backward_vec1 = super.MAnalyse(isb = true, delta = 1, overlap=4)
forward_vec1 = super.MAnalyse(isb = false, delta = 1, overlap=4)
forward_vec2 = super.MAnalyse(isb = false, delta = 2, overlap=4)
MDegrain2(super, backward_vec1,forward_vec1,backward_vec2,forward_vec2)
""",4)

It's normal because MT split the video in 4... so MVTools calculate vectors with some light differences between the 4 part.
Try with truemotion=false in MDegrain, it may work better.

TSchniede
14th May 2009, 17:05
Multithreading with the MT plugin unfortunately can never create the same result as doing it only in one thread. However with enough overlap in MT it can be similar enough. The reason is simple - each thread only knows a part of the frame, so any movement which crosses those boundaries cannot be compensated. Even worse, MVTools try to guess the best candidates and finally the real motion based on calculations of the whole visible frame. This causes that there is actually a wide border with less accurate movement. I suppose higher coherency like in truemotion mode increases this effect. This makes many threads on small resolutions quite useless.

swaaye
14th May 2009, 19:25
Yeah it did occur to me that the entire problem could be caused by the frame being processed in separate segments and the results not meshing well together sometimes. Hmmm....

I've been having problems with Directshowsource and SetMTMode. That's my reason for using MT instead of SetMTMode. I've been running DirectShowSource with SetMTMode(5) and it almost always works fine, but with a recent HD 1080p VC1 source I've run into an issue with the frame order getting messed up. The final encode will have moments where the video will reverse for a frame or two. Solved it by switching to fft3dgpu and running without any threading...

Gavino, yes I was referring to MT's overlap setting not MAnalyse's.

Comatose
14th May 2009, 21:39
That "video will reverse" issue seems more like something inflicted by DirectShowSource rather than a specific filter. Try using a different source filter, or DSS with seekzero=true.

BigDid
14th May 2009, 23:34
I've noticed that when using MDegrain2 with MT() as described on the MVTools2 page that there are separation lines visible between the MT segments.
Hi,

Yes, MT splits 1 frame and induce the 1 or more separation lines for filters that are not written to MT a single frame;

For these kind of filters I use Setmtmode(2,0) so it uses 2 or more consecutive frames to MT, Wiki page:
http://avisynth.org/mediawiki/MT_support_page

Did

Adub
15th May 2009, 22:38
No, for a quad core you can just say SetMTmode(2). The first number is not the number of threads, it's the number of the mode.

Arshad07
19th May 2009, 10:52
Does MVtools works with directshowsource? 'Cause everytime i close the previewer window, my megui crashes. :(

ash925
19th May 2009, 11:15
Does MVtools works with directshowsource? 'Cause everytime i close the previewer window, my megui crashes. :(
Yes, it does and no crashes for me.

Adub
22nd May 2009, 19:29
I can confirm.

adrianmak
12th June 2009, 01:31
any x64 version ?

buletti
12th June 2009, 10:35
adrianmak: Are you in the possession of a recent Avisynth build (2.5.7+) that supports 64bit? AFIAK there was merely a single custom build 64 bit version (http://www.planetamd64.com/index.php?showtopic=5013) back in 2005 which is not available anymore (and probably extremely outdated).
So, as long as there's no 64 bit Avisynth, there's no use for 64 bit plugins..

Arshad07
12th June 2009, 10:44
@adrianmak

You can still run x86 s/ws on a x64bit OS.....thats why there's a folder called Program Files (x86) in your C:/

kemuri-_9
12th June 2009, 15:02
adrianmak: Are you in the possession of a recent Avisynth build (2.5.7+) that supports 64bit? AFIAK there was merely a single custom build 64 bit version (http://www.planetamd64.com/index.php?showtopic=5013) back in 2005 which is not available anymore (and probably extremely outdated).
So, as long as there's no 64 bit Avisynth, there's no use for 64 bit plugins..

see squid_80's site for avisynth 2.5.7 x64 and accompanying x64 plugins.
http://members.optusnet.com.au/squid_80/

Terka
5th August 2009, 13:11
Fizick,
would phase shift method(s) be helpfull in motion-estimation when added to MVtools?
Are you planning something like this in future versions?
Thank you,
Terka

Fizick
5th August 2009, 21:22
Terka,
I make several "planning" to do it. Last time - use phaseshift maximums as a predictors. But I am afraid, iy should be implemented not in MVTools block-based framework.

Terka
15th August 2009, 10:04
one question to mrecalulate.
MAnalyse has some default setting, S1.
When using MAnalyse in script, i can select my own settings, S2. Other, not directly specified settings, remains same as S1.
When using MRecalculate, i can select my own settings, S3. Other, not directly specified settings, remains same as S2?

Fizick
15th August 2009, 19:26
Terka,
good question. it is not documented.

other remains as undocumented defaults of mrecalculate, which are same values as defaults of manalyse.

Terka
19th August 2009, 21:08
thank you for reply.
One more thing, the following doesnot work with latest mvtools2
AVISource("c:\test.avi") # or MPEG2Source, DirectShowSource, some previous filter, etc
vectors = MSuper().MAnalyse(isb = true)
MShow(vectors)
:confused:

Fizick
19th August 2009, 22:10
This script is wrong. MShow need in super clip, for example:

AVISource("c:\test.avi") # or MPEG2Source, DirectShowSource, some previous filter, etc
MSuper()
vectors = MAnalyse(isb = true)
MShow(vectors)

or

AVISource("c:\test.avi") # or MPEG2Source, DirectShowSource, some previous filter, etc
super=MSuper()
vectors = MAnalyse(super, isb = true)
MShow(super,vectors)

I replace source by super to show padding and vectors at padding

Puncakes
24th August 2009, 00:24
Hi,

Is the blur I'm getting with Mdegrain3 in darker scenes expected, or have I gone wrong somewhere? I've read over the documentation and after tweaking about every option I could, I wasn't able to get a noticeable change (aside from the overall strength, thsad).

Source: http://i26.tinypic.com/24vk4l0.jpg
Default: http://i25.tinypic.com/kbzvut.jpg
Thsad200: http://i26.tinypic.com/24vk4l0.jpg

VOB Sample: http://www.mediafire.com/?ij2jznzjugy

My script is:

DGDecode_mpeg2source("VTS_03_1.d2v")
tfm(order=0)
src = last
super = src.MSuper()
bvec3 = super.MAnalyse(isb=true, delta=3, overlap=4)
bvec2 = super.MAnalyse(isb=true, delta=2, overlap=4)
bvec1 = super.MAnalyse(isb=true, delta=1, overlap=4)
fvec1 = super.MAnalyse(isb=false, delta=1, overlap=4)
fvec2 = super.MAnalyse(isb=false, delta=2, overlap=4)
fvec3 = super.MAnalyse(isb=false, delta=3, overlap=4)
src.MDegrain3(super, bvec1, fvec1, bvec2, fvec2, bvec3, fvec3)


I'm hoping I've missed something that can be corrected, since mdegrain is the only filter I've tested that can remove so much noise/grain with so little blur and artifacts (on the brighter scenes at least).

onesloth
24th August 2009, 01:43
Is the blur I'm getting with Mdegrain3 in darker scenes expected, or have I gone wrong somewhere?

It seemed to me MDegrain2 and 3 got noticeably blurry with 2.4.0.
I don't have 2.3.1 so I haven't done any AB comparisons, though.

Fizick
24th August 2009, 17:07
2.4.0 beta (09.01.2009 by Fizick)
MDegrain: Changed degrain weight method to more strong...

Approx:
Old: (thSAD-blockSAD)/thSAD.
new: (thSAD*thSAD - blockSAD*blockSAD)/(thSAD*thSAD + blockSAD*blockSAD)

Assume thSAD=400,
Example 1. current SAD=100, old strength = 0.75, new strength = 0.87.
Example 2. current SAD=200, old strength = 0.5, new strength = 0.60.
Example 3. current SAD=300, old strength = 0.25, new strength = 0.28.
Example 4. current SAD=400, old strength = 0, new strength = 0.


blurring usually indicates wrong vector search...

Didée
24th August 2009, 17:45
Ah - thanks for posting the new formula. I ever wondered since it was implemented - - but not enough to start digging through the source code ... ;)

blurring usually indicates wrong vector search...... and/but: at least part of the story is that same-SAD-everywhere is not very smart: In "flat" areas like sky, skin, nebula etc., SAD usually is rather low, and even ~relatively~ small SAD can mean a big error. In contrast to high-detail / high-contrast areas, where SAD usually is rather big. Really, SAD for "edge-areas" and "non-edge-areas" are like two different worlds ...

Official question: What about taking into account local complexity when evaluating SAD? Aren't there any proven concepts out there for that?

Sagekilla
24th August 2009, 20:06
This probably is computationally unfeasible, but how's about how well a region can be compressed? For a given block, run it through your favorite lossless compressor and calculate the % of the original file size. Flat areas would probably give something like (general numbers here) 200 bytes compressed vs 2000 bytes uncomp'd, so it's complexity score would be 0.1.

Like I said, that's probably way too slow to be practical but there's probably a way to do something similar and much faster.

Fizick
24th August 2009, 20:43
Didée,
suprisingly, about week ago i found your manifesto about local complexity hidden in non-official mvtools thread ;)
http://forum.doom9.org/showthread.php?p=1305680#post1305680

If anyone has ideas that s/he thinks that would bring a worthwhile improvement, then:
MAKE IT, and SHOW THE PROOF.
Until then, I'll resort to short "nope"-style answers, when indicated.
;)

My answer is - nope. SAD is SAD, and it is evaluated (and must be evaluated) in MAnalyse as is.
Postprocessing and usage of this info (in MDegrain, etc) is other story.
But rigth now I am more interested in more coorct vector field estimation. May be even with variable block size like h264. in tis case SAD may be not so big at edges.

TSchniede
25th August 2009, 19:36
This is an issue I have been thinking about myself. Right now we simply don't know if a low SAD means that the match is good or that there isn't much information anyway.
We would want some sort of metric that tells us how reliable our guess on the movement is.
I had hoped this could be an alternative approach for the movement analysis. but so far I haven't found a way to get the concept into a working algorithm. I'm not even sure it is possible to do it in a way that the produced vectors and computation time is better or at least equivalent.

Fizick
25th August 2009, 22:11
Almost similar for big best SAD - we do not know if match is wrong (local minimum instead of global) or this object was deformed.
May be we can store second (or more) best matches for every vector.
Other option may be somehow use SADs of coarser hierahical levels.
I do not have the working algo.
But i tried implement so call meander vector scan (left to right - right to left, end so on). Seems, it give more satble results for various left-right movements.

Released version 2.5.2

MSuper: separable width and height reducing with assembler iSSE optimization
MAnalyse: limit levels value

MAnalyse: Added meander parameter for blocks scan in rows from left to right and from right to left
Small optimization of YUY2 conversion

MSuper: More full size of sublevels
MAnalyse: Increased number of sublevels (for more long vectors)
MAnalyse: Replaced parameter name level by levels, changed meaning of its positive and negative values
MAnalyse: Disabled lambda for most coarse level
MAnalyse: Full search with large radius at smallest level

Note: These 2.5 changes have experimental (beta) status (now public beta), and may be removed in next versions (for example, it is hard to implement meander scan with variable block size).
Variable block size has also problem with overlap.
Insted of meander it is possible to get two vectors set for different scan directions, but it will be twice slower.

MfA
26th August 2009, 09:06
This is an issue I have been thinking about myself. Right now we simply don't know if a low SAD means that the match is good or that there isn't much information anyway.
We would want some sort of metric that tells us how reliable our guess on the movement is.
I had hoped this could be an alternative approach for the movement analysis. but so far I haven't found a way to get the concept into a working algorithm. I'm not even sure it is possible to do it in a way that the produced vectors and computation time is better or at least equivalent.
Why doesn't the smoothness constraint take care of this?

Didée
26th August 2009, 12:47
For vector search stage, I agree it's a difficult case ... a labyrinth filled with cans of worms. It's hard to predict which theoretical means really would improve, and which are only pipe dreams.

However, for vector usage stage (e.g. in MDegrain), and in reply to the "make it and show proof" - retort in #1259 (http://forum.doom9.org/showpost.php?p=1318124&postcount=1259) :

I already have given proof, long time ago. :)
It's in TempGaussMC, in the section commented with "Needed to later make MVDegrain work as expected ...the "SAD concept" doesn't fit to the realities -- so, let's tailor the realities to fit the darn concept ...".
Since SAD rating can't be modulated at the script level, it's done the reverse way: instead of rating SAD according to contrast, the contrast is altered to fit the uniformly-everywhere method.

Point is: without that effort, TGMC would not produce much usable. With it, it does. Period.

This' I consider a sufficient [practical] proof. (...for a relation so obvious that giving proof is almost superfluid.)


And BTW, this is pretty similar to the concept I once had proposed for "static-detection" in deinterlacing/bobbing. It's been decades that all deinterlacers only used primitive hard-thresholding for static detection: if a pixel differs by more than "x", it's not static.
At some point I was annoyed enough by that insufficient concept, and build the adaptive thresholding system found in MCBob. It worked better, which was expected, and in the meantime is known as TMM() plugin function.

And it's really the same idea: areas with strong signal need a different treatment than those with weak signal.

Nobody would expect the very poor people to pay the same taxes as the very rich. So, why should pixels?

Boulder
26th September 2009, 20:45
I get an access violation with Avisynth 2.5.8 and the latest MVTools2 version with this script (VDub sometimes crashes, pointing to mvtools2.dll):


MPEG2Source("bamse.d2v")
Crop(16,4,-16,-4,true)
interleave(last,MCTemporalDenoise(chroma=true,flat=true))
AddBorders(0,0,16,8)


If I comment out the cropping and AddBorders, it works fine.

MCTemporalDenoise is the latest one (v1.3.0.0) from this thread: http://forum.doom9.org/showthread.php?t=139766

Fizick
26th September 2009, 21:06
Boulder,
I do not support MCTemporalDenoise. I need in simple script to reproduce crash, as well as short sample video.
Anyway, how about older MVTools versions?

Boulder
26th September 2009, 22:47
I'll get you a sample in the next few days, and also try to reproduce it with a simple script.

Version 2.5.2 does crash, v2.4.7 does not. I couldn't find the two versions between those on your site.

Fizick
26th September 2009, 23:57
I now added also v2.5.0 and 2.5.1 to my site.

Fizick
27th September 2009, 07:58
Some problem with SetMTMode(2) of MVTools v2.5.3 was reported by MAG79.
It seems, that temporal predictor mode is not compatible with multi-threading.

I released v2.5.4 - temporal problem is NOT resolved, but I set default temporal=false according to doc (it was wrongly =true in v2.5.3)

Boulder
27th September 2009, 09:46
Here's a sample file: http://www.mediafire.com/?sharekey=9b19b691e7eb0ac9d2db6fb9a8902bda

The highest MVTools2 version which works is v2.4.7. The 2.5 branch doesn't work with the script above and the sample clip. I'll post a link to this discussion in the MCTemporalDenoise thread, maybe LaTo has some ideas. The MCTemporalDenoise function uses MVTools2 function quite a lot so the problem could lie anywhere.

LaTo
27th September 2009, 15:14
The crash occurs when hpad=0 & vpad=0 & chroma=true in MSuper... (tested only with v2.5.4)

I don't know why but:
2.5.0 (01.08.2009 by Fizick)

* MSuper: More full size of sublevels
Maybe it is the problem...

Search all "hpad=0,vpad=0" in the script and delete them if you want to use v2.5.x with MCTD but it is sub-optimal (speed-wise)

LaTo
27th September 2009, 18:27
I have checked a bit the source: all modifications in MVSuper.h (2.4.7->2.5.0) is about vpad/hpad and chroma :D

Fizick
28th September 2009, 20:03
Boulder, LaTo:
try v2.5.5

Anyway, padding=0 is not a very good. And I wil try improve padding handling in next version(s)

Boulder
28th September 2009, 20:38
Works fine, thanks :)

LaTo
29th September 2009, 15:52
Great! ;)

thewebchat
19th October 2009, 16:16
I see that we are now at 2.5.8 of MVTools. Is the 2.5 branch still considered experimental, or is it generally safe to use?

Fizick
26th October 2009, 19:05
v2.5.8.1 it is rather safe ;)

"temporal" is the experimental feature, not compatible with SetMTMode (by one user report)

thewebchat
26th October 2009, 19:57
Actually, I do not remember reading anything about the "temporal" option in this thread, and the description of it on avisynth.org.ru is fairly limited. Could you explain what the goal of the "temporal" option is? Regardless, I will upgrade to 2.5.8.1 and test it later, since you have confirmed that it is stable.

Redsandro
31st October 2009, 14:34
I was wondering if anyone is interested in bringing rolling shutter compensation to MVTools, or if something similar has already been attempted?

Example, so bad it cannot be repaired but it illustrates the problem perfectly:
http://www.youtube.com/watch?v=0qC0_nIUq9s

Excellent article illustrating the problem with CMOS sensors and the rolling shutter effect:
http://dvxuser.com/jason/CMOS-CCD/

Right now afaik the only available solution is using Rolling Shutter compensation option in Gunnar Thalin's DeShaker (http://www.guthspot.se/video/deshaker.htm) plugin for VirtualDub (http://www.virtualdub.org/).
However the compensation is linear in nature (skew). It is very awesome, saves a lot of footage, but only half-descent for footage more complicated (speed changes, moving people etc) than just steady static pans.

Chia-Kai Liang's article on rolling shutter compensation:
http://mpac.ee.ntu.edu.tw/Exhibition/rolling-shutter.php
Curved compensation can be better than linear compensation for nonsteady pans (speed changes within frame), but this implementation is commercial, hardware only and thus not available. Just food for thoughts. This curvy compensation is imo theoretically superior to DeShaker's compensation for incalculating horizontal speed changes within the frame, but not vertical speed changes.

TheFoundy working on a commercial motion compensated rolling shutter node for Nuke 6.
http://www.thefoundry.co.uk/blog.aspx#rollingshutter
They compensate motion from different moving objects. I think they themselves were inspired by watching failing divx movies or even MVTools itself. ;)

In my imagination, a combination of the compensation from the DeShaker model, temporally motion compensated for objects moving independent from the camera and maybe spatially compensated for camera movement speed changes within one frame, is superior to all, and doable with the way MVTools detects motion and MFlow can realisticly (un)distort images. Not literally, but it seems like a lot of the work has already been done.

johnmeyer
31st October 2009, 17:06
As a first approximation, if there was a way to apply a ramp function to the MFlowInter function's time parameter, and then apply this increasingly ramped correction top to bottom (or bottom to top) to each scan line, it might provide a first approximation to a solution.

Terka
31st October 2009, 20:24
deshaker has some technique for correcting it.

Redsandro
31st October 2009, 21:04
I think I mentioned that.

TSchniede
3rd November 2009, 16:57
I'm not sure this problem can be "solved" without some sort of pattern recognition (either in the frame or the motion). The equivalent of temporal softener on the movement MIGHT help. A somewhat specific approach could be to take the common movement of each row and then compensate to somewhere closer to their vertical neighbors or the whole frame. I'm afraid this will introduce compensation artifacts. And because the angles are inherently different from frame to frame (sort of the definition of skew and wobble), the blocks SAD will be less than perfect and false positives might be far more common than usual.

Redsandro
17th November 2009, 17:45
Is it possible to calculate the integral from the motion vectors?
So that for example on frame 10 you have the vectors relative to frame 1 in stead of the previous one?

johnmeyer
19th November 2009, 08:39
I get a crash when using the following script. If I disable SetMTMode, I don't get the crash. Since there has been some discussion about crashes wtih SetMTMode with version 2.5.9, I tried 2.4.7, but it also crashed.

I monitored the MEMusage and VM Size reported by Windows Task Manager (I'm running WinXP Pro SP3), and it crept up slowly for about two minutes. Than about ten seconds before the crash, these numbers quadrupled in a few seconds, eventually consuming all available memory (I have 6 gigs, although only a portion of that is available with my XP 32-bit).

This script sometimes works fine, and other times it crashes. I am feeding it from frameserved video out of Vegas Pro 7.0d.

It always works if I disable the SetMTMode.

My computer is an Intel i7 3.2GHz (stock clocking). 8 core. It is very stable and I regularly render with all 8 cores maxed out.

I did try to change memory usage with the SetMemoryMax command, but that didn't seem to eliminate the crashes.

# Despot script for Shindig
loadplugin("C:\Program Files\AviSynth 2.5\plugins\MVTools\mvtools2.dll")
loadplugin("C:\Program Files\AviSynth 2.5\plugins\RemoveDirtSSE2.dll")
loadplugin("c:\Program Files\AviSynth 2.5\plugins\TIVTC.dll")

#SetMemoryMax(768
SetMTMode(5)
Avisource("M:\frameserver.avi").ConvertToYV12(interlaced=true)
SetMTMode(2,0)

KillAudio()
AssumeBFF()
tfm(mode=1,pp=6,field=-1,display=false)
tdecimate(mode=0)
source=assumefps(23.976)

despotted=RemoveDirtMC(source,33,false)

final=MDegrain2i2(despotted,2,0)

#stackhorizontal (source,final)
return final


#--------------------------------------------------------
function MDegrain2i2(clip source, int "overlap", int "dct")
{
overlap=default(overlap,0) # overlap value (0 to 4 for blksize=8)
dct=default(dct,0) # use dct=1 for clip with light flicker
super = MSuper(source,pel=2, sharp=1)
backward_vec2 = MAnalyse(super, isb = true, delta = 2, overlap=overlap, dct=dct)
backward_vec1 = MAnalyse(super, isb = true, delta = 1, overlap=overlap, dct=dct)
forward_vec1 = MAnalyse(super, isb = false, delta = 1, overlap=overlap, dct=dct)
forward_vec2 = MAnalyse(super, isb = false, delta = 2, overlap=overlap, dct=dct)
source.MDegrain2(super, backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=400)
}

function RemoveDirt(clip input, int limit, bool _grey)
{
clensed=input.Clense(grey=_grey, cache=4)
alt=input.RemoveGrain(2)
# return RestoreMotionBlocks(clensed,input,alternative=alt,pthreshold=4,cthreshold=6, gmthreshold=40,dist=1,dmode=2,debug=false,noise=limit,noisy=12,grey=_grey,show=true)
return RestoreMotionBlocks(clensed,input,alternative=alt,pthreshold=6,cthreshold=8, gmthreshold=40,dist=3,tolerance= 12,dmode=2,debug=false,noise=limit,noisy=12,grey=_grey,show=false)
}

function RemoveDirtMC(clip,int "limit", bool "_grey")
{
_grey=default(_grey, false)
limit = default(limit,6)
i=MSuper(clip,pel=2)
bvec = MAnalyse(i,isb=false, blksize=8, delta=1, truemotion=true)
fvec = MAnalyse(i,isb=true, blksize=8, delta=1, truemotion=true)
backw = MFlow(clip,i,bvec)
forw = MFlow(clip,i,fvec)
clp=interleave(forw,clip,backw)
clp=clp.RemoveDirt(limit,_grey)
clp=clp.SelectEvery(3,1)
return clp
}

Didée
19th November 2009, 13:30
Purely from the guts, I suspect clense could be the culprit. Clense works recursive: temporal median of previous/current/next, where "previous" is not the original source frame, but the already-clensed frame from one step before. This already-clensed frame is stored in a filter-private cache slot. (That's what the avsrecursion.dll is needed for.)
I could imagine that this workflow is not reliably compatible with MT.

If no other/better ideas come up, you might try to (temporarily) replace the line

> clensed=input.Clense(grey=_grey, cache=4)

with

> clensed = input.MedianBlurT(0,0,0,1).merge(input,0.5).MedianBlurT(0,0,0,1)

Result is not exactly the same, but surely similar enough that you won't see noticeable difference in the end. It's also a good bit slower. However, it removes the possibly problematic recusive-ness from Clense out of the script, and the end result remains being perfectly usable. If you still get those crashes, then the problem is somewhere else. If the crashes disappear, then Clense is nailed.

johnmeyer
20th November 2009, 01:18
Didée,

Your advice was correct. Replacing Clens with MedianBlurT stopped the crashing. However, it was about half the speed of the crashing code, but still twice as fast as doing the script without SetMTMode.

I'm going to experiment with other plugins to replace what Clens is doing. Your blur idea is good, but after doing a lot of A/B testing on video processed with the original script and video processed with your fix, the original script does a slightly better job. In other words, you were absolutely correct that the differences would be subtle, but I hate to give an inch on quality, if I can help it.

Many thanks.

[Edit] Spoke too soon. It still crashes. Will have to look elsewhere. It sure isn't consistent as to when it crashes.

[Edit2]It's only been a few minutes since I made my edit and no one has yet responded so I thought I'd post some more info. The biggest change in stability is changing the "overlap" parameter that is ultimately used by MAnalyse. If I use this calling function (in the script I posted above):

final=MDegrain2i2(despotted,0,0)

I can sometimes get through encoding a three hour video without a crash. However, if I instead use this call:

final=MDegrain2i2(despotted,2,0)

I usually get a crash within the first few minutes of operation.

So, I am suspecting MVTools2 and the overlap function in particular.

tedkunich
20th November 2009, 20:08
So, I am suspecting MVTools2 and the overlap function in particular.

I too had crashes with MVTools - I believe the later builds resolved my problems (but I have not been processing much of late)

Also, try the kill audio before the setmtmode - I seem to recall SET identifying that audio was not properly handled (could be wrong).

T

johnmeyer
20th November 2009, 20:23
Interesting about the killaudio command. After I read your post I search for SetMTMode and Killaudio in this forum and found a few other posts which, like yours, suggested that it may be a problem, but nothing definitive.

I went ahead and made the change in the script. I don't have any video to process today, but when I do, I'll see what happens. Thanks!

runforlife
10th January 2010, 01:18
Hi everyone!

1) Yushko Frame Rate Converter - doublerate frame rate converter with strong artifact detection and scene change detection. Its based on "MVTools" and "MaskTools". In order to run the YFRC script, you have to have "MaskTools.dll" and "mvtools.dll".

2) "Hello World"
Ok, lets try to apply YFRC on some test clip. To do it you need:
a) any *.AVI clip with properties: Frame rate 25p, Frame Size 720x576, Color Space YV12;
b) download and copy "mvtools.dll" and "masktools.dll" to the directories "C:\Program Files\AviSynth 2.5\plugins\MvTools2\" and "C:\Program Files\AviSynth 2.5\plugins\";
c) download and copy "Yushko_09dd_01mm_2010yy.avsi" or newer to the directory "C:\Program Files\AviSynth 2.5\plugins\";
d) create *.avs file near your *.avi file with content like this:
AVISource("720x576x25p.avi").YFRC()

Links:
Download from:http://videomontazh.com.ua/avisynth/YFRC/09dd_01mm_2010yyyy/
Example clip, 24p->48p, x264 30MB: http://videomontazh.com.ua/avisynth/YFRC/09dd_01mm_2010yyyy/YFRC_09dd_01mm_2010yyyy.mp4

Delerue
5th February 2010, 17:42
Hi everyone!

1) Yushko Frame Rate Converter - doublerate frame rate converter with strong artifact detection and scene change detection. [...]

Hi! I did some tests with Yushko script vs pure MVTools. The MVTools script was this:


setMTMode(2,3)
source=AVISource("test.avi")
LoadPlugin("C:\Program Files (x86)\AviSynth 2.5\plugins\mvtools2.dll")
super = source.MSuper(pel=2)
backward_vec = MAnalyse(super, blksize=8, dct=1, overlap=4, isb = true, search=3)
forward_vec = MAnalyse(super, blksize=8, dct=1, overlap=4, isb = false, search=3)
source.MFlowFps(super, ThSCD1=350, blend=false, backward_vec, forward_vec, \
num=2*FramerateNumerator(source), den=FramerateDenominator(source))
distributor()


First test Yushko seems to be better:

Yushko:
http://img.photobucket.com/albums/v256/Delerue/00Yushko.jpg

MVTools:
http://img.photobucket.com/albums/v256/Delerue/01MVTools.jpg

Same thing here:

Yushko:
http://img.photobucket.com/albums/v256/Delerue/02Yushko.jpg

MVTools:
http://img.photobucket.com/albums/v256/Delerue/03MVTools.jpg

And here:

Yushko:
http://img.photobucket.com/albums/v256/Delerue/04Yushko.jpg

MVTools:
http://img.photobucket.com/albums/v256/Delerue/05MVTools.jpg

But there are some problems with Yushko. Sometimes it just skips a frame that has too much artifact, repeating the last frame, which causes a very annoying stutter. This behavior also brings another problem that we can see here:

Yushko:
http://img.photobucket.com/albums/v256/Delerue/06Yushko.jpg

MVTools:
http://img.photobucket.com/albums/v256/Delerue/07MVTools.jpg

Notice that with Yushko we can't see the frame with the lighting, because it probably judged the lighting as an artifact or scene change, skipping that frame.

Finally, in this scenario (that occurs a lot of times in the beginning of this movie) MVTools seems to predict better than Yushko:

Yushko:
http://img.photobucket.com/albums/v256/Delerue/08Yushko.jpg

MVTools:
http://img.photobucket.com/albums/v256/Delerue/09MVTools.jpg

The sample I used can be downloaded here (http://www.mediafire.com/file/ugymtqzkjyn/test.avi). Maybe Fizick could merge part of the code of Yushko work, using the best parts and avoiding the bad ones. What you think? Thanks for sharing your information. :)

Redsandro
5th February 2010, 23:31
Thanks. I didn't even know Yushko. Can you provide a link? The first google result on yushko framerate is this very page. :P
It's unfortunate that once again the better party depends on the shot.

But here's a question I've had for a while now:

How come frame doubling/quadrupling gives artifacts so often? The chip in my Samsung 100 Hz HDTV or my folks' Philips 100Hz HDTV converts or interpolates 25 fps footage to 100fps footage on the fly, in real time (ok there's a tiny 2 frame delay, you can hear it when you listen to the unshifted audio output), and there are almost never artifacts. (And when there are, it's totally different from the MVFlow kinda distortions you see in solutions we know. It's like a block of motion is misplaced or skipped.) It does it's work so good and fast I would like to see that behaviour in an AviSynth plugin. And I cannot believe a single chip from a €600 TV is faster than my quad core.

Didée
6th February 2010, 00:31
I don't own such a TV personally, but one of my mates has a Samsung with 100Hz Truemotion (or however it's called). Per system settings it is configurable to weak/normal/strong. What I can say is: overall it is pretty much okay. But I do see artifacts regularly. And in scenes where I know that MVTools would produce artifacts, on the Samsung it is simply so that it is not smooth in those scenes, but gives just the "normal 25fps judder". So, guess what's happening ... the biggest trick is to reckognize where things get difficult, and just do "nothing" in those cases. Simple as that. Not any magic.

Redsandro
6th February 2010, 00:35
I guess there are many different quality chips because the (brand new) one I have is awesome at it. And indeed, very occasionally, it skips a macroblock (not the entire frame), but apart from that it actually is like magic imo. Or if you call Mvtools solutions magic, this is just voodoo.

Delerue
8th February 2010, 21:05
But I do see artifacts regularly. And in scenes where I know that MVTools would produce artifacts, on the Samsung it is simply so that it is not smooth in those scenes, but gives just the "normal 25fps judder".

Exactly! And I think that this behavior (turning on/off the 'smoother' constantly) is very bad and bothers a lot, specially with long pans. I've tested at least six models/manufacturers and I can tell you that MFlowFPS is better than all of them. But, of course, there's a lot of things to improve in MFlowFPS, as we can see in the SS above.

um3k
15th February 2010, 21:50
I was wondering if anyone is interested in bringing rolling shutter compensation to MVTools, or if something similar has already been attempted?


Something like this, perhaps?

# RollAway filter by um3k/Justin Phillips
# Reduces rolling shutter artifacts on video from CMOS-chipped camcorders/DSLRS
# "Amount" is the same as that used for DeShaker. The formula can be found here:
# http://www.guthspot.se/video/deshaker.htm#rolling shutter setting
# "Segh" is the height of the segments the image is split into. It should be an even number, and a dividend of the clip height.
# This script is compatible with SetMTMode.
# Use SetMemoryMax in your script to increase speed. Set it to a fairly high number that is reasonable for you computer's capabilities.
#
# Alpha 1

function RollAway_alpha1(clip c, float amount, int segh)
{
Assert(IsInt(segh/c.height), "'segh' must be a dividend of clip height")
ctime = amount/2
segs = c.height/segh
den = segs-1
num = den
super = c.MSuper()
fv = MAnalyse(super, blksize=8, isb = false, overlap=4)
bv = MAnalyse(super, blksize=8, isb = true, overlap=4)
DeRoll(c, super, fv, bv, ctime, den, segh)
}

function DeRoll(clip c, clip super, clip fv, clip bv, float ctime, int den, int segh, int "segn", clip "stack")
{
stackh = Defined(stack) ? stack.height
\ : 0
segn = Defined(segn) ? segn+1
\ : 0
num = abs(den-segn*2)
fclp = c.MFlow(super, fv, time=ctime*num/den).Crop(0, segn*segh, -0, segh).SelectEvery(1, 1)
bclp = c.MFlow(super, bv, time=ctime*num/den).Crop(0, segn*segh, -0, segh).SelectEvery(1, -1)
nseg = stackh > c.height/2 ? bclp
\ : fclp
stack = Defined(stack) ? StackVertical(stack, nseg)
\ : nseg
segn = segn return stack.height == c.height ? stack
\ : DeRoll(c, super, fv, bv, ctime, den, segh, segn, stack)
}

It isn't exactly fast, but it works. Sometimes. And I can't guarantee any semblance of stability.

The lower "segh" is set, the slower the filter will be, but the results will show less seam artifacts.

hydra3333
15th February 2010, 22:56
Any chance of before and after images/snippets ?

Redsandro
16th February 2010, 00:51
Wow, not tried it yet but I really really like that there's a shutter compensation attemt in AviSynth with MVtools.
I cannot wait to try it! But I must :P

Gavino
16th February 2010, 13:12
function RollAway_alpha1(clip c, float amount, int segh)
{
Assert(IsInt(segh/c.height), "'segh' must be a dividend of clip height")
Since segh and c.height are both ints, segh/c.height will always satisfy IsInt(). You want
Assert(segh%c.height == 0, ...)

um3k
16th February 2010, 15:30
Since segh and c.height are both ints, segh/c.height will always satisfy IsInt(). You want
Assert(segh%c.height == 0, ...)

Thanks, I was wondering why that wasn't working...fortunately a different error stepped in to prevent an endless loop.

Gavino
16th February 2010, 17:29
Actually, looking at this again,
"'segh' must be a dividend of clip height"
the required condition is:
Assert(c.height%segh == 0, ...)

um3k
16th February 2010, 18:23
Thanks, again. :)

um3k
17th February 2010, 23:16
Ok, I've run in to a little problem. The filter has a tendency to undercorrect fast motion--and I suspect the cause is MFlow's limitation of any vector over 127 being thrown out. Whether it happens depends on the resolution of the video and what "pel" value one is using. I need to find a workaround. If I use pel=1, it fixes it on lower resolutions, but also causes jaggies. I tried using MRecalculate, but as I expected, it did not help. I thought about trying MFlowInter, but it only seems able to generate an in-between frame, and I want to simply warp the current frame toward its neighbors. Any suggestions? I'd really like to make this work, one way or another.

EDIT: I tried MFlowInter, not only did it add undesirable frame blending, but it also did not fix the problem.

hydra3333
25th February 2010, 10:56
This question more properly resides here under the MVtools thread, I think.
Just wondering, some people seem to use the DePanEstimate function last updated January 27 2008, whilst the more recent version of MVtools2 last updated 8.11.2009 suggests using the newer MSuper/MAnalyse/MDePan.

Would it be fair to guess that the newer MSuper/MAnalyse/MDePan functions would incorporate more recent updates and motion detection approaches than the older DePanEstimate functions and maybe some other things like multithreading ?

XhmikosR
1st March 2010, 17:23
I just got a crash using AviSynth 2.5.8 SEt's MT mod and VirtualDub points to mvtools2.dll.

SetMTMode(5,4)
DGDecode_mpeg2source("MyCapture.d2v", info=3)
ColorMatrix(hints=true, interlaced=true, threads=4)
SetMTMode(2)
TempGaussMC_beta2(EdiMode="EEDI2")
SelectEven()
crop(12,0,-12,-4)
Spline36Resize(640,480)

VirtualDub crash report -- build 32809 (release)
--------------------------------------

Disassembly:
02f64660: 660f6fda movdqa xmm3, xmm2
02f64664: 660f61da punpcklwd xmm3, xmm2
02f64668: 660f70d300 pshufd xmm2, xmm3, 00h
02f6466d: 660f6eda movd xmm3, edx
02f64671: 8b5520 mov edx, [ebp+20h]
02f64674: 660f6fe3 movdqa xmm4, xmm3
02f64678: 660f61e3 punpcklwd xmm4, xmm3
02f6467c: 53 push ebx
02f6467d: 660f70dc00 pshufd xmm3, xmm4, 00h
02f64682: 660f6ee0 movd xmm4, eax
02f64686: 56 push esi
02f64687: 8b7510 mov esi, [ebp+10h]
02f6468a: 660f6fec movdqa xmm5, xmm4
02f6468e: 57 push edi
02f6468f: 8b7d08 mov edi, [ebp+08h]
02f64692: 660f61ec punpcklwd xmm5, xmm4
02f64696: 660fefc0 pxor xmm0, xmm0
02f6469a: 660f70e500 pshufd xmm4, xmm5, 00h
02f6469f: c744240c100000 mov dword ptr [esp+0ch], 00000010
00
02f646a7: 2bd1 sub edx, ecx
02f646a9: 2bf1 sub esi, ecx
02f646ab: 8bc1 mov eax, ecx
02f646ad: 2bf9 sub edi, ecx
02f646af: bb02000000 mov ebx, 00000002
02f646b4: eb0a jmp 02f646c0
02f646b6: 8da42400000000 lea esp, [esp+00]
02f646bd: 8d4900 lea ecx, [ecx+00h]
02f646c0: f30f7e2c02 movq xmm5, [edx+eax]
02f646c5: f30f7e30 movq xmm6, [eax]
02f646c9: 660f60e8 punpcklbw xmm5, xmm0
02f646cd: 660fd5ec pmullw xmm5, xmm4
02f646d1: 660ffde9 paddw xmm5, xmm1
02f646d5: 660f60f0 punpcklbw xmm6, xmm0
02f646d9: 660fd5f3 pmullw xmm6, xmm3
02f646dd: 660ffdf5 paddw xmm6, xmm5
02f646e1: f30f7e2c06 movq xmm5, [esi+eax] <-- FAULT
02f646e6: 660f60e8 punpcklbw xmm5, xmm0
02f646ea: 660fd5ea pmullw xmm5, xmm2
02f646ee: 660ffdee paddw xmm5, xmm6
02f646f2: 660f71d508 psrlw xmm5, 08h
02f646f7: 660f67e8 packuswb xmm5, xmm0
02f646fb: 660fd62c07 movq [edi+eax], xmm5
02f64700: 83c008 add eax, 08h
02f64703: 83eb01 sub ebx, 01h
02f64706: 75b8 jnz 02f646c0
02f64708: 8b7d08 mov edi, [ebp+08h]
02f6470b: 8b7510 mov esi, [ebp+10h]
02f6470e: 8b5520 mov edx, [ebp+20h]
02f64711: 037d0c add edi, [ebp+0ch]
02f64714: 037514 add esi, [ebp+14h]
02f64717: 035524 add edx, [ebp+24h]
02f6471a: 034d1c add ecx, [ebp+1ch]
02f6471d: 836c240c01 sub dword ptr [esp+0ch], 01h
02f64722: 897d08 mov [ebp+08h], edi
02f64725: 897510 mov [ebp+10h], esi
02f64728: 895520 mov [ebp+20h], edx
02f6472b: 0f8576ffffff jnz 02f646a7
02f64731: 5f pop edi
02f64732: 5e pop esi
02f64733: 5b pop ebx
02f64734: 8be5 mov esp, ebp
02f64736: 5d pop ebp
02f64737: c3 ret
02f64738: cc int 3
02f64739: cc int 3
02f6473a: cc int 3
02f6473b: cc int 3
02f6473c: cc int 3
02f6473d: cc int 3
02f6473e: cc int 3
02f6473f: cc int 3
02f64740: 55 push ebp
02f64741: 8bec mov ebp, esp
02f64743: 83e4f0 and esp, 0f0h
02f64746: 51 push ecx
02f64747: 0fbf4d28 movsx ecx, word ptr [ebp+28h]
02f6474b: 0fbf552c movsx edx, word ptr [ebp+2ch]
02f6474f: b880000000 mov eax, 00000080
02f64754: 660f6ec8 movd xmm1, eax
02f64758: 0fbf4530 movsx eax, word ptr [ebp+30h]
02f6475c: 660f6fd1 movdqa xmm2, xmm1

Built on Aegis on Sat Feb 20 22:12:08 2010 using compiler version 1400

Windows 6.1 (Windows Vista x86 build 7600) []

EAX = 1be01728
EBX = 00000002
ECX = 1be01728
EDX = ff3a0000
EBP = 0addf1c8
ESI = e41fe8d8
EDI = ec207af0
ESP = 0addf1b0
EIP = 02f646e1
EFLAGS = 00010287
FPUCW = 027f
FPUTW = ffff

Crash reason: Access Violation

Crash context:
An out-of-bounds memory access (access violation) occurred in module 'mvtools2'...

...reading address 00000000.

Pointer dumps:

EAX 1be01728: 393b3b3b 39393938 8d7b5938 9190918f 93919091 95949592 91919190 91919091
ECX 1be01728: 393b3b3b 39393938 8d7b5938 9190918f 93919091 95949592 91919190 91919091
ESP 0addf1b0: 07f5e8e8 07fb4628 07f5e838 00000010 00000000 00000248 00000000 02f62cbd
0addf1d0: 08009218 00000010 00000000 000002e0 1be01728 000002e0 1b1a1728 000002e0
0addf1f0: 00000058 00000054 00000054 00000004 0288f968 00000001 00000000 000000fe
0addf210: 000002e0 010102e0 00000000 00000000 00000000 1be01728 000002e0 00000001
EBP 0addf1c8: 00000000 02f62cbd 08009218 00000010 00000000 000002e0 1be01728 000002e0
0addf1e8: 1b1a1728 000002e0 00000058 00000054 00000054 00000004 0288f968 00000001
0addf208: 00000000 000000fe 000002e0 010102e0 00000000 00000000 00000000 1be01728
0addf228: 000002e0 00000001 1b1a1728 00000054 00000001 00000000 000002e0 00000170

Thread call stack:
02f646e1: mvtools2!_AvisynthPluginInit2@4 [02f50000+6740+dfa1]
10009559: AviSynth!avs_release_value [10000000+75d0+1f89]
1000adb7: AviSynth!avs_release_value [10000000+75d0+37e7]
1005417a: AviSynth!DllGetClassObject [10000000+da50+4672a]
02ec9f71: mt_masktools!_AvisynthPluginInit2@4 [02e90000+2cd60+d211]
10009559: AviSynth!avs_release_value [10000000+75d0+1f89]
1000adb7: AviSynth!avs_release_value [10000000+75d0+37e7]
1005417a: AviSynth!DllGetClassObject [10000000+da50+4672a]
10009559: AviSynth!avs_release_value [10000000+75d0+1f89]
1000adb7: AviSynth!avs_release_value [10000000+75d0+37e7]
02ec3e38: mt_masktools!_AvisynthPluginInit2@4 [02e90000+2cd60+70d8]
02ec199d: mt_masktools!_AvisynthPluginInit2@4 [02e90000+2cd60+4c3d]
02ec1a3c: mt_masktools!_AvisynthPluginInit2@4 [02e90000+2cd60+4cdc]
10009559: AviSynth!avs_release_value [10000000+75d0+1f89]
1000adb7: AviSynth!avs_release_value [10000000+75d0+37e7]
02ec9f71: mt_masktools!_AvisynthPluginInit2@4 [02e90000+2cd60+d211]
02ec78c8: mt_masktools!_AvisynthPluginInit2@4 [02e90000+2cd60+ab68]
02ec31f1: mt_masktools!_AvisynthPluginInit2@4 [02e90000+2cd60+6491]
02ebbfc1: mt_masktools!0002bfc1
02ed1bea: mt_masktools!_AvisynthPluginInit2@4 [02e90000+2cd60+14e8a]
10009559: AviSynth!avs_release_value [10000000+75d0+1f89]
1000adb7: AviSynth!avs_release_value [10000000+75d0+37e7]
02ec6f88: mt_masktools!_AvisynthPluginInit2@4 [02e90000+2cd60+a228]
02ec9e10: mt_masktools!_AvisynthPluginInit2@4 [02e90000+2cd60+d0b0]
02ec199d: mt_masktools!_AvisynthPluginInit2@4 [02e90000+2cd60+4c3d]
02ec1a3c: mt_masktools!_AvisynthPluginInit2@4 [02e90000+2cd60+4cdc]
10009559: AviSynth!avs_release_value [10000000+75d0+1f89]
1000adb7: AviSynth!avs_release_value [10000000+75d0+37e7]
02ec7d68: mt_masktools!_AvisynthPluginInit2@4 [02e90000+2cd60+b008]
02ebc377: mt_masktools!0002c377
02ec3f70: mt_masktools!_AvisynthPluginInit2@4 [02e90000+2cd60+7210]
10009559: AviSynth!avs_release_value [10000000+75d0+1f89]
1000adb7: AviSynth!avs_release_value [10000000+75d0+37e7]
02ec1bc1: mt_masktools!_AvisynthPluginInit2@4 [02e90000+2cd60+4e61]
02f61b93: mvtools2!_AvisynthPluginInit2@4 [02f50000+6740+b453]
02ec9e10: mt_masktools!_AvisynthPluginInit2@4 [02e90000+2cd60+d0b0]
02ec199d: mt_masktools!_AvisynthPluginInit2@4 [02e90000+2cd60+4c3d]
02ec1a3c: mt_masktools!_AvisynthPluginInit2@4 [02e90000+2cd60+4cdc]
10009559: AviSynth!avs_release_value [10000000+75d0+1f89]
1000adb7: AviSynth!avs_release_value [10000000+75d0+37e7]
02ec78c8: mt_masktools!_AvisynthPluginInit2@4 [02e90000+2cd60+ab68]
10009559: AviSynth!avs_release_value [10000000+75d0+1f89]
1000adb7: AviSynth!avs_release_value [10000000+75d0+37e7]
7c3416b3: MSVCR71!__crtLCMapStringA [7c340000+13ae+305]
100372e6: AviSynth!DllGetClassObject [10000000+da50+29896]
10009559: AviSynth!avs_release_value [10000000+75d0+1f89]
1000adb7: AviSynth!avs_release_value [10000000+75d0+37e7]
1006492e: AviSynth!DllGetClassObject [10000000+da50+56ede]
771e2149: ntdll!RtlAllocateHeap [77190000+5209d+ac]
10009559: AviSynth!avs_release_value [10000000+75d0+1f89]
1000adb7: AviSynth!avs_release_value [10000000+75d0+37e7]
1003bd40: AviSynth!DllGetClassObject [10000000+da50+2e2f0]
10009559: AviSynth!avs_release_value [10000000+75d0+1f89]
1000adb7: AviSynth!avs_release_value [10000000+75d0+37e7]
7c3416b8: MSVCR71!__crtLCMapStringA [7c340000+13ae+30a]
1006492e: AviSynth!DllGetClassObject [10000000+da50+56ede]
7c3416b8: MSVCR71!__crtLCMapStringA [7c340000+13ae+30a]
10009559: AviSynth!avs_release_value [10000000+75d0+1f89]
1000adb7: AviSynth!avs_release_value [10000000+75d0+37e7]
1000464d: AviSynth!0000464d
1005533b: AviSynth!DllGetClassObject [10000000+da50+478eb]
10005337: AviSynth!00005337
10005407: AviSynth!00005407
1005627b: AviSynth!DllGetClassObject [10000000+da50+4882b]
771d5e6c: ntdll!NtWaitForSingleObject [77190000+45e60+c]
754a179c: KERNELBASE!WaitForSingleObjectEx [754a0000+1730+6c]
754a17c4: KERNELBASE!WaitForSingleObjectEx [754a0000+1730+94]
10009559: AviSynth!avs_release_value [10000000+75d0+1f89]
1000adb7: AviSynth!avs_release_value [10000000+75d0+37e7]
1000e2cd: AviSynth!DllGetClassObject [10000000+da50+87d]
76b71194: kernel32!BaseThreadInitThunk [76b20000+51182+12]
771eb3f5: ntdll!RtlInitializeExceptionChain [77190000+5b392+63]
771eb3c8: ntdll!RtlInitializeExceptionChain [77190000+5b392+36]

-- End of report

Fizick, is there anything I can do to help you pinpoint this problem?

TSchniede
4th March 2010, 19:37
I suppose this is quite obvious, but unfortunately the best and fastest way to fix any bug is to replicate it. This involves finding the simplest test case that triggers it.

1) which filters are needed / is it dependent on a specific input video (or source filter) / does it depend on specific options in the filters? (this helps pinpoint which filter / which part of a filter is responsible)
2) how fast does it occur? (first frame / <1000 frames / >50000)
3) is it always on the same frame (+-10 frames)?
4) Is there a relationship with other system components - like maxed out CPU load or network traffic?
5) And since you mentioned MT - is there a difference on the amount of threads used?
I suppose it never occurs single-threaded?

Terka
2nd June 2010, 15:42
Fizick, do you have some plans about mvtools - to add some new features/improvements?
There is no update on your pages for 6months.

kypec
2nd June 2010, 20:25
Hasn't been mvtools replaced with mvtools2? I thought so but I might be very wrong. I'm just a noob regarding any external plugins and scripts...

Fizick
2nd June 2010, 20:57
i do not like the limitation of vector length to 64 (for pel=2).

Terka
3rd June 2010, 09:09
yes, was replaced. i ment mvtools as 'filter name' regardless of a version. so the question was in fact about mvtools version2.

pbristow
4th June 2010, 16:32
I have a suggestion for you guys (Terka, Fizick, et al.) to think about...

We have the function MMask, which can convert MVTools2's vector data into a "normal" clip, where, using kind=5, colours (in U,V) represent motion vectors (in X,Y). Could we have a function that does the inverse of this, i.e. turns the "kind=5" colourmap back into a vector clip (such as produced by MAnalyse), suitable for driving MCompenstae, Mflow, etc.?

This would then open the door to manipulating vector data using various avisynth functions, and applying the results to the source clip. For example, to obtain a map of the *acceleration* over three frames, you could do:

MotionMap = MMask(Source, Vectors, kind=5)
AccelMap = Subtract(MotionMap, MotionMap.DeleteFrame(0))

... and then use that data, via the new function (called, perhaps, "MUnmask"?) to create a parabolic, rather than linear, interpolation of the motion between frames n-1 and n+1. Take things one step futher, and you've got cubic interpolation, and so on.

You could also apply a combination of masks and blurs to a motion map before using it in compensation, to create an effect similar to varying the mvtools "lamda" factor (vector coherence) across the frame, depending on detected content. I.e., you could enforce higher vector coherence (strong "blur" of U & V data) where regular textures/patterns are detected, but reduce it where an edge is detected between two separately moving objects. Lots of possibilities open up for more precise, or more creative, motion manipulation! =:o}

Interested?

(Hmmm... Should I putting this in development?)

Gavino
4th June 2010, 17:52
For example, to obtain a map of the *acceleration* over three frames, you could do:
MotionMap = MMask(Source, Vectors, kind=5)
AccelMap = Subtract(MotionMap, MotionMap.DeleteFrame(0))
Don't you have to subtract the value at two different positions in order to compensate for the movement between frames?

Boulder
4th June 2010, 18:14
Edit: never mind, I got it..MDepan must be returned in order to create a log file.

Terka
4th June 2010, 18:36
MVtools are esencial avisynth plugin. So every development of them is big plus. I think the vectors modifying could be useful.
There aslo exists some 'requests' about what new feature(s) to have, Didee posted some here in forum. Maybee he could have something to say.
Also there are some papers over internet about phase correlation etc.

Boulder
4th June 2010, 19:59
A bug report: if I use range=1 in MDepan, the debug text (with info=true) is only displayed in the first frame when loading the script. It disappears when seeking to the next frame.

tormento
14th June 2010, 19:06
One question: is MDegrain3 more precise and stronger or only stronger in removing noise?

I'd like to use as a standard avs part a very light grain removal part to increase compressibility without remove too much details. I am thinking about a thSAD=200 or so with the usual motion compensated denoise script of the documentation.

Do you think that the thSAD number is too high or low? I read in the documentation that a too low number could cause "staggered denoising" but what is a too low number for that parameter? As I want remove grain only, do you think I should use a different thSADC for chroma?

And, returning to my first question, as far as PRECISION and DETAILS are concerned, is it better to use MDegrain3 or MDegrain2?

Didée
14th June 2010, 20:05
In that sense, there is no "precision" in MDegrainX. The "precision" is in MAnalyse.

Before we had MVTools, the problem was that the dumb PC could not distinguish between noise and detail.

Now that we have MVTools, the problem is that the dumb PC still can't distinguish between noise and detail.

What has changed is that, due to motion compensation, the likelyhood to catch more noise than detail has become bigger. But the basic problem hasn't changed. Good old TemporalSoften uses differences between single pixels to make its decisions. Shiny new MVTools uses differences between single pixels, summed up over 8x8 blocks, to make its decisions.

The method as a whole has become more robust, but the mechanism of making decisions is still the same.
("Hey! Now there is weighting, too!" -- [bored:] "ttempsmooth!")

*.mp4 guy
14th June 2010, 22:00
What has changed is that, due to motion compensation, the likelyhood to catch more noise than detail has become bigger. But the basic problem hasn't changed. Good old TemporalSoften uses differences between single pixels to make its decisions. Shiny new MVTools uses differences between single pixels, summed up over 8x8 blocks, to make its decisions.

With dct=5, you get usably fast satd, instead of very fast sad, which can give a nice boost to perceived (and probably actual) quality of denoising. Anyway, "Doing It Right" with "intelligent" metrics would be ridiculously slow, were talking orders of magnitude worse then tnlmeans.

Also, "its just differences of blocks of pixels instead of singly pixels" rather misses the point. VQ is just quantizing blocks of pixels instead of single pixels, but the coding gain is ridiculous. And its ridiculous because working on blocks of pixels is not comparable to working on single pixels. When dealing with blocks, even if your metric is incredibly simple, you are matching features whenever you do a block search, you can't do block matching without getting some feature detection. This combined with the higher signal correlation between frames as opposed to pixels within a frame are why mvtools is so good. The high correlation allows for fast metrics and lazy pixel grouping to work very well, thereby enabling a "fast" implementation. You can actually apply the same methodology to pixels within a frame (which is basically what tnlmeans does) but because correlation is so much lower, you have to have much more granular pixel grouping to get usable results, and to get truly good result you would probably need a much better metric then sad or sse as well.

tormento
14th June 2010, 22:06
Guys, your knowledge is fascinating but is it better, precision related, Degrain2 or Degrain3? ;)

Didée, you told precision is in MAnalyse. Do you think that using Degrain3, as far as precision is concerned, is similar do Degrain2 if the same MAnalyse process is used? If positive, does Degrain3 removes only more noise?

I thought that thSAD was the only parameter that decided the amount of noise (let me say that) to be removed. You overwhelmed me.

Didée
14th June 2010, 23:14
mp4guy - hey, of course I have exaggerated a bit, wasn't that obvious? I just wanted to make the point that the algorithms still aren't "seeing" anything. And, even with (inherently) better feature correlation, turing's machine still will not tell apart whether any given difference is due to a change in a detail's reprentation from one frame to the next, or because of noise, or because of something else. It's just a difference.
In particular, any "weak" detail that is "hidden" below the noise (signal amplitude of detail is same - or even lower - than the noise level) by chance might survive, or by chance will get filtered away. Dice game.
When dealing with blocks, even if your metric is incredibly simple, you are matching features whenever you do a block search, you can't do block matching without getting some feature detection. Sure. The best part is when there is a more or less feature-less something (sky, wall, whatever), and the motion engine still is detecting "features" and compensates them. Everybody loves floating walls.


tormento: MDegrain3 removes more noise. MDegrain2 keeps more detail. That's basically it.


If you guys insist, I'll dig out my Babylon-5 samples once more. SAD fights a losing battle there. And SATD won't do better.

*.mp4 guy
15th June 2010, 04:30
mp4guy - hey, of course I have exaggerated a bit, wasn't that obvious?
Yes, but I wasn't sure where the exaggeration ended.
I just wanted to make the point that the algorithms still aren't "seeing" anything. And, even with (inherently) better feature correlation, turing's machine still will not tell apart whether any given difference is due to a change in a detail's reprentation from one frame to the next, or because of noise, or because of something else. It's just a difference.
In particular, any "weak" detail that is "hidden" below the noise (signal amplitude of detail is same - or even lower - than the noise level) by chance might survive, or by chance will get filtered away. Dice game.
The more correlation an algorithm can leverage, the more selective it is in removing noise. This is why compression related features almost always work well for denoising (linear transforms, motion compensation, etc.). The more correlation a given algorithm can exploit, the further down the noise floor below which details are indistinguishable from noise is pushed (on average, there will always be certain cases that break a given algorithm).
tormento: MDegrain3 removes more noise. MDegrain2 keeps more detail. That's basically it.
yep
If you guys insist, I'll dig out my Babylon-5 samples once more. SAD fights a losing battle there. And SATD won't do better. SATD essentially always does better, but I'm sure the results would still be quite bad, so no need to dig it up. That source is more difficult then it should be, If I had to take a guess I would say that there is a good chance that it is due to compression artifacts. More specifically I have seen cases where not-so-great mpeg2 compression will cause detail to become "intermittent" (similar to jumping b-frames in xvid) when this happens mvtools can almost always be relied on to remove whatever detail is left, or leave all of the noise alone, because the feature that mvtools uses to separate noise from detail has been ruined by the compression. The original R1 dvd of the matrix was a classic example of this problem.

All of that said I think we are essentially in agreement and that I am just quibbling over terminology (that I still don't agree with) but that is irrelevant to the actual point.Also, no offense was meant, there was just a certain ways your previous comment could have been read that bothered me.

tormento
15th June 2010, 06:14
Do you think that the thSAD number is too high or low? I read in the documentation that a too low number could cause "staggered denoising" but what is a too low number for that parameter? As I want remove grain only, do you think I should use a different thSADC for chroma?
I love quoting myself... Could you please stop masturbating :p and giving me some help from your heavenly highness? :)

*.mp4 guy
15th June 2010, 08:08
"Do you think that the thSAD number is too high or low?"
dunno.

"I read in the documentation that a too low number could cause "staggered denoising" but what is a too low number for that parameter?"
depends.

"As I want remove grain only, do you think I should use a different thSADC for chroma?"
dunno.

The reason thSAD is a parameter and not hardcoded, is because sometimes you have to change it to get good results. Should you use a different thSADc for chroma? Is there chroma noise? If there is do you want to remove it? Is it the same strength as the luma noise? Denoising is a preference thing anyway.Try different thSAD(c) values and use the one you like the most.

Boulder
15th June 2010, 08:24
While we have some more experts in the thread, two simple questions (which probably don't warrant a simple answer :P) : is there really any use using UMH for search method and under what circumstances could MRecalculate prove to be useful?

The reason why I ask these questions is that I have a lot of handheld shot (shaky, that is), grainy 8mm film transfer stuff to process and I want to get the stabilization process work done as well as possible. In addition to this, one long reel is filmed at an enduro race so there's a lot of movement going on pretty much all the time. From what I've been testing things, in these cases using MDepan for creating the log file to feed to Deshaker's second pass is the way to go.

*.mp4 guy
16th June 2010, 03:43
just for the record, I know absolutely nothing about deshaking video.

That said, I think the most important things to look at will be pre-denoising and adequate motion vector length (I'm not sure what resolution your source footage is, but iirc mvtools could have a restrictive maximum mv length if its really bad, or HD, or both)

Boulder
16th June 2010, 13:05
If I've understood correctly (regarding Deshaker at least), the basic idea is for the motion detection engine to lock onto the background or some other static object. Deshaker's 1st pass can be set to ignore motion of blocks falling under certain conditions, for example those blocks whose movement happens in the "wrong" direction. The great thing about MAnalyse is that the settings can be tweaked a lot and the result can be immediately seen with MShow. I was just wondering whether there are options to helping MAnalyse towards the preferred behaviour.

The problem with MDepan is that I don't know which motion vectors are ignored when the stabilization data (hor and ver pan, rotation and zoom per frame) is created (either for DepanEstimate or to a Deshaker-style log file). Fizick, would it be possible to create an MShow-like view of discarded and accepted blocks? Currently tweaking the "wrong" and "range" parameters is practically impossible. Also, what does "range" actually do? Is the parameter coupled with "wrong"?

videoFred
17th June 2010, 07:45
If I've understood correctly (regarding Deshaker at least), the basic idea is for the motion detection engine to lock onto the background or some other static object.

I have made a depan version of this, you can select any region for motion detection:

# film stabilizing script by videoFred.
# Version 06/2010
#====================================================================================


# specify the source clip here with full path name

film="C:\Documents and Settings\Eigenaar\Mijn documenten\films\Dirk\videofred_002.avi"




#GENERAL PARAMETERS
#--------------------------------------------------------------------------------------------
result="result2" # specify the wanted output here
# result1= stabilized/cropped/resized clip
# result2= comparison original vs not cropped stabilized clip


trim_begin=0 # trim frames at the beginning
# useful to skip fast to a certain scene




#SIZE, CROP AND BORDERS PARAMETERS
#--------------------------------------------------------------------------------------------
CLeft=20 CTop=20 CRight=20 CBottom=20 #crop values after Depan and before final resizing

W=720 H=576 #final size after cropping



#STABILIZING PARAMETERS
#--------------------------------------------------------------------------------------------
maxstabH=20
maxstabV=20 #maximum values for the stabilizer (in pixels) 20 is a good start value

est_left=40 est_top=40 est_right=40 est_bottom=40 # crop values for special Estimate clip
# the stabilizer will use this region only

est_cont=1.0 # contrast value for special Estimate clip
# change this if the stabilizer wont work



# END VARIABLES, BEGIN SCRIPT
#=============================================================================================


# NEEDED PLUGINS
#------------------------------------------
Loadplugin("Depan.dll")
LoadPlugin("DepanEstimate.dll")
LoadPlugin("MT_Masktools.dll")




source1= Avisource(film).trim(trim_begin,0).converttoYV12()




#STABILIZING
#..............................................................................................
stab_reference= source1.crop(est_left,est_top,-est_right,-est_bottom).tweak(cont=est_cont)\
.MT_binarize(threshold=80).greyscale().invert()

mdata=DePanEstimate(stab_reference,trust=1.0,dxmax=maxstabH,dymax=maxstabV)
stab=DePanStabilize(source1,data=mdata,cutoff=0.5,dxmax=maxstabH,dymax=maxstabV,method=1,mirror=15)
stab2= stab.crop(CLeft,CTop,-CRight,-CBottom).Lanczos4Resize(W,H)
stab3=DePanStabilize(source1,data=mdata,cutoff=0.5,dxmax=maxstabH,dymax=maxstabV,method=1,info=true)

WS= width(stab)
HS= height(stab)
stab4= stab3.addborders(10,10,10,10,$B1B1B1).Lanczos4Resize(WS,HS)

result1=stab2




#SPECIAL SERVICE CLIP FOR COMPARISON
#................................................................................................
service_clip= overlay(source1,stab_reference,x=est_left,y=est_top)\
.addborders(2,2,2,2,$FFFFFF).Lanczos4Resize(WS,HS)




#SPECIAL COMPARISON CLIP FOR TESTING THE STABILIZER
#.......................................................................................................
result2= stackhorizontal(subtitle(service_clip,"baseclip for stabilizer -only the B/W clip is used",\
size=32,align=2),subtitle(stab4,"test stabilizer: dx=horizontal, dy=vertical",size=32,align=5))


Eval(result)

With this script, it is possible to 'lock' DepanEstimate() to a certain region of the clip.
Only this information will be used for DepanStabilize().

Result2 will show you all the needed information.



Fred.

Boulder
17th June 2010, 10:54
The problem is that the region changes in each scene, sometimes during the scene :) With 4.5hrs of material to process, I'm trying to automate things as much as possible (even to the extent that I've butchered your restoring script a bit and turned it into a bloated function ;) )

videoFred
17th June 2010, 11:29
The problem is that the region changes in each scene, sometimes during the scene :)

Ah! Yes, I know about this problem. Depan fails here...



With 4.5hrs of material to process, I'm trying to automate things as much as possible (even to the extent that I've butchered your restoring script a bit and turned it into a bloated function ;) )

Cool! Show me! :p

Fred.

Boulder
17th June 2010, 11:49
Cool! Show me! :pSure, after I've cleaned it up a little :) Even after that I know I'll be embarrassed to post it, but let's see if someone could enhance it further. For some reason I've never been able to get the Eval blocks work correctly with boolean operators.

videoFred
17th June 2010, 11:58
Sure, after I've cleaned it up a little :)

Very good. When you are ready, please post it in the 'Power of Avisynth' thread.

Thank you in advance Boulder!

Fred.

Gavino
17th June 2010, 12:08
For some reason I've never been able to get the Eval blocks work correctly with boolean operators.
You might find it easier to use GScript instead.

Boulder
17th June 2010, 13:50
Very good. When you are ready, please post it in the 'Power of Avisynth' thread.No problem. If I have the time to go through the script, I'll post it tonight. IIRC it is actually based on johnmeyer's modification, but it is quite easy to replace stuff if you wish to do so for your own use.

I'll also post one difficult scene to stabilize, unless DepanStabilize manages to fix it. For now I've had to edit the Deshaker log file from MDepan manually to avoid sudden jumps in the stabilized video.

You might find it easier to use GScript instead.

Thanks, that looks very useful!

Boulder
17th June 2010, 20:17
By the way, what are the correct resizing parameters for creating a pelclip (both luma and chroma since I'm using YV12) for pel=4?

For pel=2 it's (width*2,height*2,src_left=0.25, src_top=0.25) for luma and (width*2,height*2,src_left=0.5, src_top=0.5) for chroma but should all the parameters be doubled for pel=4?

Gavino
17th June 2010, 20:41
By the way, what are the correct resizing parameters for creating a pelclip (both luma and chroma since I'm using YV12) for pel=4?
(width*4,height*4,src_left=0.375, src_top=0.375) for luma and (width*4,height*4,src_left=0.75, src_top=0.75) for chroma.

Vitaliy Gorbatenko
18th June 2010, 08:17
Help properly configure MVTools that there were no ghosts and sailing parts of the image with the brightness variations. For this sample http://www.mediafire.com/?mrdkatnmyqd
And if it possible - keep thSAD = 400 and limit = 255. sample.avs included.

foxyshadis
19th June 2010, 01:08
Boulder, if you have a good script, I'll test it on the BD of Blade Runner. They butchered that: there's so much gate weave throughout the film that I can't watch it until I fix it. Either the camera was wobbling the entire time, or no one bothered to lock down the telecine.

Boulder
19th June 2010, 09:45
This is what I've been using as my latest attempt:

AVISource("w:\nimeton 1.avi",pixel_type="YUY2")
block_size=16
block_size_recalc=8
lambda= 100*block_size*block_size/64
lambda_recalc= 100*block_size_recalc*block_size_recalc/64
lsad= 400*block_size*block_size/64
Crop(16,16,-16,-16,true).ConverttoYV12()
Unflicker()
cleaned=DegrainMedian()
pelclipluma=Spline64Resize(width*4,height*4,src_left=0.375, src_top=0.375)
pelclipchroma=Spline64Resize(width*4,height*4,src_left=0.75, src_top=0.75)
pelclip=pelclipluma.MergeChroma(pelclipchroma)
supaclip=MSuper(pel=4,rfilter=4,pelclip=pelclip)
supacliprecalc=MSuper(cleaned,pel=4,rfilter=4,pelclip=pelclip,levels=1)
vec=Manalyse(supaclip,truemotion=false,global=true,blksize=block_size,overlap=block_size/2,
\dct=5,search=5,searchparam=8,lambda=lambda,lsad=lsad,plevel=0,pnew=25,badsad=400,temporal=true) # temporal=false if SetMTMode is called
vecrecalc=MRecalculate(supacliprecalc,vec,truemotion=false,blksize=block_size_recalc,overlap=block_size_recalc/2,
\dct=5,search=5,searchparam=8,lambda=lambda_recalc,pnew=25,thsad=100)
MDepan(last,vecrecalc,error=80,thscd1=625,thscd2=160,info=true,wrong=3,zoom=false,range=0,log="w:\deshaker\nimeton 1.log")

function Unflicker (clip o)
{
screen = mt_lutf(o,o,mode="average",yexpr="x",U=1,V=1) #.greyscale
screenTS = screen.temporalsoften(1,9,0,9,2).merge(screen,0.249).temporalsoften(2,5,0,5,2)
calmed = o.mt_makediff(mt_makediff(screen,screenTS),U=2,V=2)
deflk = o.Deflicker()
masky = o.mt_lut("x 32 < x 16 - 16 * x 204 > 255 204 x - abs 255 30 / * - 255 ? ?").removegrain(11,-1)

return o.mt_merge(calmed,masky,U=2,V=2)
}

Lots of things borrowed or stolen from other scripts, particularly Didée's :) MAnalyse and MRecalculate are probably overkill (using both of them and their settings) but I don't care at this point as this 4.5 hrs of Super-8 video is a one-time thing only.

I've used the script to create a log file to feed to Deshaker and run the 2nd pass there with only ConverttoRGB24(matrix="pc.601") in the script. I noticed that limiting correction to 2 percent will eliminate most shakiness coming from handheld camera movements (not to mention that some scenes have been shot by a 60-70 -year-old person). It could be that even 1 percent is enough for your purposes. Unflicker is for removing the slight flickering in the source material.

Deshaker 2nd pass settings that I've used:
http://img6.imageshack.us/img6/6271/deshaker3.th.jpg (http://img6.imageshack.us/i/deshaker3.jpg/)

If you or anyone else has any suggestions to improve things, please let me know :)

Oh, one more bug report to Fizick: if I try to set pel=2 in the MSuper statement that is then fed to MRecalculate, VDub crashes after advancing one frame. This occurs if the MSuper clip that is fed to MAnalyse uses pel=4.

johnmeyer
19th June 2010, 18:21
I've done two projects in the past months which involved 16+ hours of 8mm, Super8, and 16mm. The more recent project was 8+ hours. So, I know what it is like to try to get through a lot of film.

You might want to consider some alternative workflows if you want to do more deshaking.

First, if you Google my name (John Meyer is my real name) and Deshaker, you will find both a Deshaker guide I wrote, as well as a script I wrote which automates the Deshaker process from within the editing program, Sony Vegas. Another person has taken my script, added a UI that mimics Deshaker, and created a DLL version of the script. If you have Vegas, or if you are doing this for a living and therefore can charge off the purchase of Vegas, you will find this permits a workflow that completely gets around the scene change problem (although Deshaker does have a scene change flag) and also permits you to do really advanced motion stabilization that would either be impossible with depan, or which would just take too much time.

The short version of what I do is to first run an AVISynth scene detection script on my film capture. This gives me frame numbers for the scene changes. This isn't perfect, but it is good enough, and if I miss a few scene changes it doesn't matter much. I then use these numbers to automatically (one click) cut the film in Vegas into individual scenes. Then, the Deshaker script is run on each individual scene, something that can be done in batch mode, so you just click once and walk away for a few hours. The stabilized footage is added to each scene in Vegas as a "take." This means that if the stabilization screws up (which does happen), you just press a button to return to the original.

Now, what I have found with VideoFred's script is that the depan works amazingly well for gate weave and simple camera shake. True, it does force you to zoom in to hide the resulting stabilization black borders, whereas Deshaker has the ability to synthesize new borders. However, as long as you are doing small corrections, you don't have to zoom in much, and the compromise is IMHO not bad.

So, my new workflow is to do a quick scrub through the film, and find scenes that I think need the "heavy duty" stabilization. I then only run Deshaker on that. Then, when that is finished, I frame serve the result into VideoFred's script.

None of this may be useful if you don't use Vegas, but perhaps it gives you some ideas for an alternate workflow. The idea of trying to do anything with AVISynth that has to be changed scene-by-scene sounds too painful to contemplate, especially when dealing with many hours of material.

hydra3333
20th June 2010, 03:03
Thanks John.

Fizick
24th June 2010, 21:48
Oh, one more bug report to Fizick: if I try to set pel=2 in the MSuper statement that is then fed to MRecalculate, VDub crashes after advancing one frame. This occurs if the MSuper clip that is fed to MAnalyse uses pel=4.

Confirmed. I released fixed version 2.5.10.1 with working MRecalculate for different pels
(also fixed info in MDepan)

Boulder
24th June 2010, 22:37
Thank you :)

Lyle_JP
19th August 2010, 15:49
Any chance for a 64-bit version of 2.5.10.1? 2.5.10.0 seems to be the newest one I can find. Thanks.

Delerue
19th August 2010, 17:05
Any chance for a 64-bit version of 2.5.10.1? 2.5.10.0 seems to be the newest one I can find. Thanks.

Would be nice, indeed. :)

Vitaliy Gorbatenko
24th August 2010, 04:29
Is it possible to make option lsad adaptive to the brightness of the video? The lower the brightness of the less lsad. A clip with a strong brightness fluctuations not help dct = 5 and even dct = 2. What to do?

cobo
9th September 2010, 00:04
Could someone please upload copies MVtoolsMulti v1.9.71 and v.1.9.7.5 somewhere? They're no longer available at the links posted earlier in this thread. I'd like to see if either produce better results than v1.9.7.0 for something I'm trying to do.

runforlife
17th January 2011, 14:36
My Experimental mvtools2 extreme edition - fails.

Boulder
17th January 2011, 16:18
Could someone please explain me what is the actual difference between using dct=0 and dct=5? I have understood that dct=5 is better for finding motion in dark areas of the frame but is this true?

Vitaliy Gorbatenko
17th January 2011, 18:08
Not dark. It's useful when parts of video images change brightness. For example - in the screen there is a candle flame in the wind.

Boulder
17th January 2011, 18:11
In general, is it useful to use dct=5 if I just have the extra time to spare - or is there some cons to using it?

Didée
17th January 2011, 18:44
"In general"? Well, in general, you can 100% rely on this quote from TGMC.avs:

[DCT mode] ... various modes may help, or may harm.
:):)


Regarding metrics, it's rather simple: DCT=0 is SAD (Sum of absolute differences), DCT=5 is SSD (Sum of squared differences). Essentially, this means that "differences caused by a few single pixels" have more relatve weight with DCT=5. (Or sort of that, oh well.)

In practice, it depends. For denoising tasks, you'll probably find that more detail is preserved with DCT=5, with only a small reduction of noise/flicker removal.

But in last instance, it's always a "you win here, you lose there" game. Overall, DCT=5 is very likely to be judged "better quality". If you examine closely, I'm sure you will find spots where DCT=0 looks better than DCT=5. (More pronounced with MFlowFPS than with MDegrain, probably).

Now, lets say you are doubling the processing time, and in the end many frames look better, but some frames look worse than before. This you would judge ... how?

tormento
17th January 2011, 19:13
mvtools 2.5.11.1 extreme edition
x64 version? Any?

Boulder
17th January 2011, 20:38
"In general"? Well, in general, you can 100% rely on this quote from TGMC.avs:


:):)

Hehe, I think I had that one coming :)

Regarding metrics, it's rather simple: DCT=0 is SAD (Sum of absolute differences), DCT=5 is SSD (Sum of squared differences). Essentially, this means that "differences caused by a few single pixels" have more relatve weight with DCT=5. (Or sort of that, oh well.)

In practice, it depends. For denoising tasks, you'll probably find that more detail is preserved with DCT=5, with only a small reduction of noise/flicker removal.

But in last instance, it's always a "you win here, you lose there" game. Overall, DCT=5 is very likely to be judged "better quality". If you examine closely, I'm sure you will find spots where DCT=0 looks better than DCT=5. (More pronounced with MFlowFPS than with MDegrain, probably).

Now, lets say you are doubling the processing time, and in the end many frames look better, but some frames look worse than before. This you would judge ... how?

I tried interleaving two MCTemporalDenoise calls with very light settings and dct=0/5. I couldn't tell much of a difference, maybe slightly stronger removal of noise in flat areas in dct=0. Also some more mosquito noise was preserved EDIT:with dct=5. Subtracting the results showed distinct edges so I guess that dct=5 denoises the edge area less. In this case it's not good as the source is rather low quality and I need the edge denoising as well.

*.mp4 guy
17th January 2011, 20:50
Regarding metrics, it's rather simple: DCT=0 is SAD (Sum of absolute differences), DCT=5 is SSD (Sum of squared differences).

from mvtools documentation "[dct=]5 - SATD instead of SAD for luma"

SATD stands for sum of hadamard transformed differences. SATD is superior to SAD both by metrics (in video codecs) and visually. SATD allows mvtools to better track motion when there are rapidly changing levels of brightness.

Didée
17th January 2011, 20:54
Ya sure, edges likely will get less denoising, too. Obviously, in edge areas the differences (after compensation) are bigger than in flat areas. Consequentially, the sum-of-squares gets even bigger. The bigger the sum, the less the denoising.


Somewhat related, let me mention TGMC .... from its goal of filtering, TGMC is mainly interested in processing edges, and has (basically) only little interest in processing "flat" areas.

Quite possible that there's another funny quote to find in the script. :D ;)


Edit - OUCH! It's SATD?

... browsing html ...

Darn, it is. Mea culpa. :o

runforlife
18th January 2011, 00:21
x64 version? Any?
Only 32 bit, experimental build. I do not know how to compile x64.

P. S. Source code inside.

frustum
18th January 2011, 18:08
Hi! Please check my experimental edition of "mvtools 2.5.11.1 extreme edition (http://www.videomontazh.com.ua/index.php/en/component/content/article/4-frontpage/17-vypuwen-novyj-mvtools-25111-extrmere-edition-specialnaja-redakcija-dlja-yushko-frame-rate-converter-i-yushko-bad-frame-recovery.html)":
1) «mvtools2 EE» + «Yushko Frame Rate Converter» - 2X frame rate converter without blending interpolated frames;


runforlife, perhaps you should start a thread dedicated to your version of the tools.

Anyway, I grabbed your stuff and gave it a try. I haven't spent a lot of time on it yet, but I noticed that often, as the scene is panning left/right/up/down, the edges of the image are often blurred/distorted. If you want a snapshot of what it looks like, I can provide that. If you want a short video that you can run through yfrc for testing/debugging, I can provide that too. Just tell me how many frames you want, the format, and (if lossy), the file size.

Your EE has added a new function for doing frame interpolation/repair. Are there any other changes to your flavor of mvtools other than the new subroutine?

runforlife
21st January 2011, 19:26
Anyway, I grabbed your stuff and gave it a try. I haven't spent a lot of time on it yet, but I noticed that often, as the scene is panning left/right/up/down, the edges of the image are often blurred/distorted.
I know this bug. There is no easy way to fix it fast.

aegisofrime
24th January 2011, 13:01
@Runforlife:

Just to clarify, is the following function supposed to be YFRC()?

# Fast REAL-TIME 2X Frame Rate up to 1080p!
#AVISource("test.avi")
ox = last.width()
oy = last.height()
ASSumeFrameBased()
ConvertToYV12(last).Crop(Ox-Round(Ox/32)*32, \
Oy-Round(Oy/32)*32, 0, 0)
super = MSuper(pel=1, hpad=0, vpad=0, chroma=true)
fw1_vec116 = MAnalyse(super, blksize=32, isb = false, \
chroma=false, search=1, searchparam=0, dct=0)
MSimpleFlowFps(super, fw1_vec116, num=0, den=0, \
blend=false, mask=0)
# pel=1,2; searchparam=0,1,2,3; blksize=8,16,32

Because if I were to just call YFRC(), it says there is no function like that.

runforlife
25th January 2011, 01:48
I found that MSimpleFlowFps = MFlow. My mvtools2 - fails! I created the new MFlow!!! The project is closed!

jpsdr
25th January 2011, 09:28
Any chance for a 64-bit version of 2.5.10.1? 2.5.10.0 seems to be the newest one I can find. Thanks.

Where have you found 64bit version of 2.5.10.0 ?
:thanks:

jpsdr
29th January 2011, 09:12
Are you sure it's the 2.5.10.0 ??

-Vit-
19th March 2011, 03:47
Found a crash bug in MVTools regarding padding. It occurs in MCompensate but may affect other functions. It is triggered when the overlap is not the default blocksize/2 (and might occur in other cases too, e.g. with unusual source heights). It was affecting QTGMC in its faster presets, where overlap is blocksize/4.

Problem: The MCompensate code assumes there is a certain amount of padding around the "Super" clip, but the hpad and vpad settings default to 8, which may not be enough

Scripted workaround: in any MSuper calls these are the minimum values for hpad and vpad. Values lower than this (including the default 8) are prone to crash:
hpadMin = Width() - (Int((Width() - overlap ) / (blksize - overlap )) * (blksize - overlap ) + overlap )
vpadMin = Height() - (Int((Height() - overlapV) / (blksizeV - overlapV)) * (blksizeV - overlapV) + overlapV)
super = c.MSuper( hpad=hpadMin, vpad=vpadMin, blksize=blksize, overlap=..... )

Usually these two minimum values are the same and in many cases they are zero, which is why the problem is rare. You can work out the specific values for a given clip (watch out for that Int conversion though). For example, in the case of 720x480, blocksize=32, overlap=8 both these values work out to be 16, greater than the default 8 (and hence the crash).

The specific C++ code problem is in MVCompensate.cpp in the sections dealing with the "uncovered regions". It assumes that the bitblts for the bottom & right uncovered regions in the destination can have their input starting right at the edge of the source clip, at the beginning of the padding. So the padding needs to be at least as wide/high as the "uncovered regions". There seem to be similar chunks of code in other functions, but I didn't investigate too closely to see if the problem would also affect them.

I don't have time to fix the plugin. It really needs a look over the entire code to make sure the problem doesn't impact elsewhere...

Fizick
19th March 2011, 18:36
I will look to it.

May be to add to MAnalyse the check :
(hpad < hpadMin) ? ThrowError ("Please increase hpad in MSuper to at least %d", hpadMin)


But I can not get any crash for any pad & overlap. Please simple sample script & clip & system.

-Vit-
19th March 2011, 22:32
Here's a sample (http://www.mediafire.com/?1aj2c36wn6jyajn) specifically designed to trigger the problem (720x480 YV12 FF/Huffy in AVI). The script below crashes immediately in MCompensate. The exact method of crash depends on Avisynth version (black screen, unhandled exception etc.), but all versions fail around frame 2 or 3. MVTools version used was v2.5.11.1

c = FFVideoSource("yourfolder\MVToolsTest.avi")
super = c.MSuper()
bVec1 = super.MAnalyse( isb=true, blksize=32, overlap=8 )
ediSuper = c.MSuper( levels=1 ) # Fix crash by setting hpad=16, vpad=16
c.MCompensate( ediSuper, bVec1 ) # Crash

Fizick
20th March 2011, 12:24
crash with levels=1 is confirmed.

OK. Consider the case with too small padding. How to fill the bottom area non-covered by compensated blocks? :
1. by original source pixels
2. by pixels from reference frame
3. by padding of compensated frame
4. by ?

-Vit-
20th March 2011, 15:27
Option 1 seems reasonable (blended into the overlap of the blocks above?).
Or three less good suggestions:
- Repeat the bottom edge of the blocks above (in the output)
- Use a constant color
- Don't have a non-covered section at all, use one extra row of blocks with extra overlap (would need complex changes everywhere, so probably not feasible)

Fizick
20th March 2011, 20:10
Released v2.5.11.2 with non-covered border implemented as option 1 or 2, according to scbehavior.

pbristow
21st March 2011, 17:17
Hey Fizick, just a note to say thanks for adding the new vertical and horizontal search modes. (I never did get around to posting my own version of that, did I? But anyway, now I can throw my crude hack away and use your official version.)

Thanks! :)

Fizick
21st March 2011, 17:55
pbristow (Null Null ?), you are welcome to report your method and achievements with these search modes.

-Vit-
21st March 2011, 23:15
Thanks for the quick fix Fizick.

When I was looking at the changes I noticed another minor bug in MVCompensate.cpp. In the destructor you are deleting the incorrect array elements of the pLoop array used for the recursion mode. I don't think many will be using that mode, but worth noting...

um3k
22nd March 2011, 22:14
Would it be possible to create a modified version of MFlow to correct rolling shutter artifacts?

I know conceptually how it would work, I just don't have the programming know-how to put it together. It's a pretty simple concept.

The method would simply be to vary the interpolated time time within a single frame. The user-supplied time percentage divided by two would be used for the top line of the frame, and would be linearly interpolated downward to 0 at the middle of the frame, then to its negative at the bottom of the frame (necessitating both forward and backwards vectors). Here is a visual representation:

Time=100

Line Time
1 50.0
2 38.89
3 27.78
4 16.67
5 5.56
6 -5.56
7 -16.67
8 -27.78
9 -38.89
10 -50.0


There is an old thread discussing a script version of this function here: http://forum.doom9.org/showthread.php?p=1392643

I would gladly take a shot at coding this myself, but I can't even manage to get the unmodified MVTools code to compile in Visual Studio Express.

Thanks for your time.

johnmeyer
22nd March 2011, 22:20
This was discussed before in this thread, starting here:

http://forum.doom9.org/showthread.php?p=1339646#post1339646

um3k
22nd March 2011, 22:26
Thanks, I was already aware of that, having participated in that discussion. But seeing as a year later nothing has come of it (other than my crashtastic script), I decided to mention it again in hopes someone would be willing to make an attempt at it. IANAP, but it seems like it would be a fairly simple task for someone who knows what they are doing.

johnmeyer
22nd March 2011, 22:36
Oops, I forgot that it was you ... didn't you claim (what you refer to above as your "catastrophic script") to have something that worked?

RollAway filter by um3k/Justin Phillips
(http://forum.doom9.org/showthread.php?p=1374487#post1374487)

Redsandro
22nd March 2011, 23:00
Did someone say rolling shutter? :devil:

I remember, I kickstarted the discussion and I remember you had a script. I've never came around trying it out because I've swapped Windows for Linux for most of my work somewhere along the road and didn't try to get AviSynth working in Linux yet.

There are a lot of possibilities in the 'free/libre' world that is AviSynth that can compete with commercial filters, but on the rolling shutter compensation front, commercial parties are having the upper hand. Have you seen that movement independent intra frame shutter compensation by TheFoundry? Pretty nice! And my gut sais motion detection and -compensation can do exactly that.

But IAN really AP either and I applaude any such attempt. :)

um3k
23rd March 2011, 02:33
The script works, but it is extremely inefficient and completely unusable for higher than SD resolutions. It has to render each frame dozens or even hundreds of times, eating memory and wasting CPU cycles. Implementing what I suggested directly in MVTools could easily increase the performance 100-fold. It's really a no-brainer, just wish I could convince someone to spend a few hours on it.

Redsandro
23rd March 2011, 05:25
I am too unaware of how exactly MVTools works (even though I read the html a bunch of times) so I only use internal functions for simple stuff like frame rate conversion. But I can see the abstract.

We need something that exaggerates the horizontal part of the vector by (+0.5 * $amount) percent at clip.ymin and by (-0.5 * $amount) percent at clip.ymax, interpolating from -0.5 to +0.5, while starting these horizontal vectors at the end of the original vectors so that the correct part gets compensated.

Anyone who can answer: Is it possible to manipulate MVtools' vector data within a custom function like this in one go?

This new vector image needs to be applied to MFlow or PixelFlow (or I forgot the name) and we would have a start for movement independent compensation, although I can see new issues arise where a car driving behind a streetlight leaves compensation artifacts on the streetlight the same way framerate conversion shows a jagged grid where footage is complicated.

pbristow
26th March 2011, 00:38
1. Fizick said: "pbristow (Null Null ?), you are welcome to report your method and achievements with these search modes."
I'd love to, just as soon as I get a chance to track down that folder full of de-anaglyphed 3D stuff I did a year ago on teh harddrive of the machine that died a while later... Unfortunately, priority has to go to a clean-up and editing job that is already a year overdue... :\

2. I spotted a documentation error, in http://avisynth.org.ru/mvtools/mvtools2.html , regarding blocksize. In the descripton of MAnalyse, it says blocksize can only be 4, 8 or 16; yet in an example later on we have blocksize=32. I've tried a run today using blocksize=32, and it seems to work, so what are the actual constraints? Larger blocksizes are very useful with HD content, especially if they can be coupled with higher maximum vector lengths.
(N.B. this section is also unclear regarding the interaction between horizontal and vertical blocksize.)

3. Regarding rolling shutter correction: It occurs to me this would be a good application of a tool I suggested a while back: If we had a way to convert the "normal" clips produced by Mshow, where U and V encode the horizontal and vertical components, back into the clip type produce by MAnalyse, then manipulating the vectors for a task like this would be easy to do. Something like an MTlut operation could be used to convert each frame of full-length vectors into a frame where the vectors are progressively shortened, or lengthened, from top to bottom. Convert that back to MAnalyse format and feed it into MFlow or MCompensate, and... Bob's your uncle! :)

With that method, rather than requiring a specific addition to the features of MVtools for each new weird shutter type we discover, people would be able to write or adapt their own shutter compensation scripts to suit whatever camera type they're faced with.
(Regarding weird "shutter" types: Now that shutters are actually virtual, being side effects of scanning systems rather than actual moving shutters, they can get very weird and comples. I've just discovered a clip that appears to have been shot in 1080i using a camera that, rather than scanning each field from top to bottom, scans several *segments* of the screen in parallel... with alternate fields scanned in opposite directions! On relatively still scenes, it looks fine; but when the camera pans horizontally, one field develops a horrible wavy distortion from top to bottom, and the other field gets an equal and *opposite* distortion! When woven, horizontal strips of the picture get huge combing effects, with the strips in between having little or none. I'll see if I can put up a short section and/or some screen shots for y'all...)

Fizick
26th March 2011, 00:46
unrolling may be implemented, but no so easy. top part of frame must be interpolated with previous frame, and bottom part of frame must be imterpolated with next frame. so, new function is needed (without stackvertical)

Fizick
26th March 2011, 00:51
about block =32, this text is correct:
http://avisynth.org.ru/mvtools/mvtools2-rus.html
Learn Russian ! :)

Redsandro
26th March 2011, 01:38
unrolling may be implemented, but no so easy. top part of frame must be interpolated with previous frame, and bottom part of frame must be imterpolated with next frame.

That would be nice for the god of shutter compensation, but 'simply' basing on the previous frame would already be a great improvement to existing lolsolutions. If you're talking about reasonable camera's, there is in fact shutter going on so the bottom line would only be marginally more timed towards the next frame than the previous frame. Basing the compensated vector on both frames would similarly only be marginally better than basing it on only the previous frame.

Horizontal movement in the top row is exactly as far from the previous frame as horizontal movement in the bottom row.

I've just discovered a clip that appears to have been shot in 1080i using a camera that, rather than scanning each field from top to bottom, scans several *segments* of the screen in parallel... with alternate fields scanned in opposite directions! :scared:
We need to identify and blacklist that camera immediately!

pbristow
26th March 2011, 01:58
Here are those examples. First a still using "ShowFiveVersions": The top row shows three consecutive fields (converted to frames via Bob() and then shrunk), and the bottom row shows the differences between them. (Script is as follows: )


DirectShowSource("01hd.wmv").crop(384,64,-384,-64)
AssumeBFF
Bob().ReduceBy2.ReduceBy2

n0 = last
n1 = n0.deleteframe(0)
n2 = n1.deleteframe(0)
ShowFiveVersions( n0, subtract(n1, n0), n1, subtract(n2, n1), n2 )

Notice how the sides of the doorframe are warped one way, then the other.
http://storageserver.co.uk/files/2190/Still_ShowFive.JPG.html

As you can see the movement between fields is not equal. It looks as if a camera designed for 1080i60 operation has been adapted to attempt a fake 1080p30 output, by simply scanning the two fields as quickly and as close together as possible, using some segmented scanning scheme that is presumably optimised for speed... But it really doesn't work!

And a sample clip that includes the above 3 frames: If you step through the frames you'll see that the trunk of the potted tree, and even the pot, are warping back and forth.
http://storageserver.co.uk/files/2191/01hd.wmv.bob.ShowWeirdness.V2b.avi.html

I succesfully got rid of this problem by using MVTools to create new frames in between the original fields, then throwing away the originals using SelectOdd. The resulting frames average the two warp patterns out, delivering stable straight verticals, and a smooth 60fps flow (albeit with some ghosting and artifacts, but it's a lot more watchable).


DirectShowSource("01hd.wmv").crop(384,64,-384,-64)
AssumeTFF
Bob().ReduceBy2

Return last.MVDouble().SelectOdd


And my MVDouble helper function is as follows:

function MVDouble(Clip, "PFC", bool "IsPlanar", "bs", "olap", "precision", "sharpness", "matchmethod",\
"badSADth", "badSADrange", int "lamfactor", int "ml", bool "blend", bool "debug", "diag_sw")
{
Prefiltered = Default(PFC, Clip.blur(1.0))
IsPlanar = Default(IsPlanar, false)
bs = Default(bs, 16) # (Default blocksize in MAnalyse is 8)
olap = Default(olap, bs/2)
precision=Default(precision, 2) # (The MVTools default is 2)
sharpness = Default(sharpness, 2) # (The MVTools default is 2)
matchmethod = Default(matchmethod, 0) # (The MVTools default is 0 (SAD). Try also 5 (SATD).
badSADth = Default(badSADth, 10000) # (The MVTools default is 10000 (off). Lower threshold = likelier
# to reject best local match, and search further afield.)
badSADrange = Default(badSADrange, 24) # (The MVTools default is 24 pixels)
lamfactor = Default(lamfactor, 1000)
lam = lamfactor*bs*bs/64
ml = Default(ml, 100)
blend = Default(blend, false) #
debug = Default(debug, false)
diag_sw = Default(diag_sw, false) #

Super = Clip.MSuper(planar=IsPlanar, levels=1, hpad=bs, vpad=bs, pel=precision, sharp=sharpness) # one level is enough for MCompensate
SuperFilt = Prefiltered.MSuper(planar=IsPlanar, hpad=bs, vpad=bs, pel=precision, sharp=sharpness) # all levels for MAnalyse

# Obtain vectors (with overlap):
BackwardVectors1 = MAnalyse(SuperFilt, isb = true, blksize=bs, levels=0, lambda=lam, overlap=olap,\
dct=matchmethod, badSAD=badSADth, badrange=badSADrange)
ForwardVectors1 = MAnalyse(SuperFilt, isb = false, blksize=bs, levels=0, lambda=lam, overlap=olap, \
dct=matchmethod, badSAD=badSADth, badrange=badSADrange)

# Next step: Interpolation of new frames.
Plus50 = MFlowInter(Clip, Super, BackwardVectors1, ForwardVectors1, 50, planar=IsPlanar, ml=ml, blend=blend)
Diag = MShow (SuperFilt.levels(0,1,255,0,191), BackwardVectors1, scale=1, planar=IsPlanar, showsad=false).crop(bs,bs,width(Clip),Height(clip) )
Diag2 = Interleave(Diag, Plus50.levels(0,1,255,0,191) )
Diag3 = Average( Diag2, 0.333, Diag2, 0.333, Diag2.DuplicateFrame(0), 0.333 )
Interp = diag_sw ? Diag3 : debug ? Diag3 : Interleave(Clip, Plus50)

return(Interp)
}

pbristow
26th March 2011, 02:37
about block =32, this text is correct:
http://avisynth.org.ru/mvtools/mvtools2-rus.html
Learn Russian ! :)

Hmmm...


blksize: Размер блока (горизонтальный). Возможны только значения 4, 8, 16, 32 (по умолчанию 8). БОльшие блоки менее чувствительны к шумам, и обрабатываются быстрее, но более грубы.



Transliterates to me as:
blksize: Pass me a Snowcat (rohypnolTailbHbiN). Borzemoi Tokyo 3Hayfever 4, 8, 16, 32 (no y'Momma No 8). SOnbwne Snowcat mehee 4y'BACTERIAL 'K Why, Mom(?) 'N' orthopaedic 6pack(of)CATpee(!!!) Ho sonny raspberry6pack.

Did I get anywhere close? I look forward to the official translation. :)

I'm curious about the odd restrictions on blksizeV, though. Why not allow any power of two up to the value of blksize? For that matter, why can't blksizeV be greater than blksize (implied blksizeH?) Is this to do with optimising the blocksize for SSE instructions, or something? :confused:

yup
26th March 2011, 08:44
blksize: Размер блока (горизонтальный). Возможны только значения 4, 8, 16, 32 (по умолчанию 8). БОльшие блоки менее чувствительны к шумам, и обрабатываются быстрее, но более грубы.
blksize block size (horizontal). Possible only value 4,8,16,32 (default 8). Big blocks less sensitive to noise, and calculating faster, but more rough.
yup.
Fizick is teacher (it is not joke).

Fizick
26th March 2011, 13:20
Thanks for the quick fix Fizick.

When I was looking at the changes I noticed another minor bug in MVCompensate.cpp. In the destructor you are deleting the incorrect array elements of the pLoop array used for the recursion mode. I don't think many will be using that mode, but worth noting...

got it. 1,2,3 instead of 0, 1,2

Fizick
26th March 2011, 13:30
English doc is fixed

pbristow
26th March 2011, 23:35
English doc is fixed

Thanks! :)

SubJunk
28th March 2011, 01:50
I wonder if there is any better way to detect scene-changes. I've tried to tweak thSCD1 and thSCD2 in different ways but can't find values that work for all videos.
I don't have any ideas on better logic to use but maybe someone else does?

johnmeyer
28th March 2011, 06:09
I wonder if there is any better way to detect scene-changes. I've tried to tweak thSCD1 and thSCD2 in different ways but can't find values that work for all videos.
I don't have any ideas on better logic to use but maybe someone else does?

I wrote this code six months ago, and I've used it a few times since. It should get you started towards creating something that will work for you. I only look at even fields in order to somewhat speed processing, and also to remove the need to worry about whether the source video is interlaced or progressive.

#Script to find scene changes

Loadplugin("C:\Program Files\AviSynth 2.5\plugins\MVTools\mvtools2.dll")

filename = "e:\scenes.txt"
BlockChangeThresh = 500 # Increase to reduce number of scenes detected
Num_blocks_changed = 145 # Increase to reduce number of scenes detected

source=AVISource("e:\frameserver.avi").killaudio()

source_fields=source.separatefields().selecteven().convertTOYV12(interlaced=false)
source_super = source_fields.MSuper(pel=2, sharp=0)

#Use really large blocksize to speed processing. Accuracy isn't important for this function
backward_vec = MAnalyse(source_super,isb = true, delta = 1, blksize=16,search=0)

SceneChange = MSCDetection (source_fields, backward_vec,thSCD1=BlockChangeThresh,thSCD2=Num_blocks_changed)

#Uncomment following line for troubleshooting. It puts the scene change threshold numbers on the screen.
#ScriptClip(source_fields,"Subtitle(String(AverageLuma(SceneChange ) ),align=5)")

#This line writes frame numbers to file. These can be imported into Vegas or other editor
WriteFileIf(source_fields,filename, "(AverageLuma(SceneChange)>30)" , "current_frame+1", flush=false)

SubJunk
29th March 2011, 06:12
Thanks a lot, johnmeyer. It looks like a helpful script. Actually I was meaning a method of scene-detection that would work without having to configure it for each video.
The reason is that MFlowFps leaves ugly artifacts if it doesn't detect the scene-change, but then even at the default values for MVTools2 - which are quite weak - frames in action scenes are detected as scene-changes.
Are there any other plugins that are better at detecting scene and camera-changes or is this it?

johnmeyer
29th March 2011, 18:26
In my experience, MVTools2 does an amazingly good job at scene detection, and I am not aware of anything else that is better (I guess you could try Depan, but I don't expect an improvement).

The big problem in your request is wanting to have it work "without having to configure it for each video." I am not aware of anything in AVISynth (or in video editing in general) that can be used in a "set and forget" fashion. Video can be so completely different from one source to the next, that any universal approach to almost any video problem is almost always going to disappoint. In this particular case -- scene detection -- the problem is that some video has lots of motion, and some has little motion; some video is really dark, and some is well exposed; some video is noisy, and other video is pristine; some video is high contrast, other video has almost no contrast at all; some scene changes are abrupt, with nothing in common with the previous scene; other scene changes are jump cuts, or other similar transition where very little changes. You have to adjust the parameters and the approach for each of these circumstances.

Didée
29th March 2011, 18:47
In my experience, MVTools2 does miss scenechanges regularly. The problem is that it's hard-threshold-driven by SAD. Make thSAD small enough, and MAnalyse will drop out in high-contrast scenes. Make thSAD big enough to be safe for high-contrast scenes, and MAnalyse will miss *lots and lots* of scenechanges in low-contrast scenes.

Albeit using only old-school pixel differences, SCSelect() is (mostly) more robust against this problem. Why? Because it uses relative measurements. (Or second-order, if you like.) - It's not judging the pixel differences as such, but the ratio between consecutive pixel differences.

For MVTools/MAnalyse, it would be favourable if there were some measurement of frame complexity, and the scenechange thresholds would be evaluated in relation to that.

SubJunk
29th March 2011, 21:26
Oh Fizick hear our prayers to include a method similar to SCSelect() for use in MVTools :)

Fizick
29th March 2011, 22:14
1. Small correction: MAnalyse does not contain any thSAD parameter. it always find some "best" vectors.
thSCD1, thSCD2 are in client functions like MCompensate.

2. thscd2 constant (50%) is not very good. as well as its normalization for different block sizes and overlaps.

relative SAD is interesting, but not self-start.
How to (fast) calculate the frame complexity? May be at coarse levels.

Fizick
29th March 2011, 22:15
some relative method is included in depan

Fizick
30th March 2011, 15:38
may be to add some additional processing for doubtful frames only (with mean thsad near thscd1 or some other)

SubJunk
1st April 2011, 23:45
I'm willing to help test a new method if you would like :)

frustum
2nd April 2011, 04:38
Here is my script for scene detection. It uses mvtools at its heart, although there is an option to use a simple heuristic as well.

#===============================================================================
# a script to detect and log scene changes
#===============================================================================

# user defined parameters

# movie to process

film = "C:\Users\Jim\Videos\8mm\cinepost\original\14.avi"

# file to save the cut info to

file_out = "cuts.txt"

# scheme:
# 1 uses a fast scene change metric
# 2 uses MVtools

scheme = 2

# some scene transitions trigger the scene change logic more than once.
# this controls how long to stop looking for new scene chagnes once a
# new scene has been identified.

global min_scene_size = 5

# trim_front says how many frames to chop off the start of each scene
# trim_end says how many frames to chop off the end of each scene

global trim_front = 0
global trim_end = 0

#===============================================================================

# plumbing
lib_path = "c:\Users\Jim\Videos\8mm\Film_Restoring_v2\Script_and_Plugins\"
LoadPlugin(lib_path + "dlls/MVTools.dll")
LoadPlugin(lib_path + "dlls/MVTools2.dll")

# check parameters
Assert(scheme == 1 || scheme == 2, "Error: scheme must be 1 or 2")
Assert(min_scene_size > 0, "Error: min_scene_size is unreasonably small")

# counts which scene we are on
global scene_num = 1

# markers to the start and end of the previously detected scene
global prev_scene_start = 0
global prev_scene_end = 0

source = DirectShowSource(film).converttoYV12() \
. assumefps(150) # make it run fast

# Detect the scene changes.
#
# Ysc is the value to set the Y plane to when a scene change is detected
#
# thSCD1 (int): threshold which decides whether a block has changed
# between the previous frame and the current one. 400 is the
# default; read the mvtools2 docs, as it is complicated.
#
# thSCD2 (int): 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 % ).
#
sc_vectors = source.MSuper().MAnalyse(isb = false)
# Ysc, thSCD1, thSCD2)
sc_mask = MSCDetection(source, sc_vectors, 255, 400, 130)

# pick which approach we are going to use
c1 = (scheme == 1) ? source : sc_mask

# start log file
c2 = WriteFileStart(c1, file_out, """ "### scene change list ###" + chr(10) + \
"### source:" + film """)

# decide if there is a new scene
c3 = FrameEvaluate(c2, """

# detect new scene
global newscene = (current_frame < prev_scene_end + min_scene_size) ? false \
: (scheme == 1) ? (YDifferenceFromPrevious>40) \
: (AverageLuma>250)

# remember where scene started for subsequent filtering.
# this probably doesn't work well if not accesing the clip linearly.
prev_scene_start = newscene ? prev_scene_end+1 : prev_scene_start
prev_scene_end = newscene ? current_frame : prev_scene_end

# bump scene counter on each scene change
scene_num = (newscene && (current_frame > 0)) ? scene_num+1 : scene_num
""")

# log scene changes
c4 = WriteFileIf(c3, file_out, "newscene", \
""""scene"""", "scene_num-1", """" = orig.trim("""", "prev_scene_start + trim_front", """","""", "prev_scene_end - trim_end", """")"""")

# log scene changes at end of film
c5 = WriteFileIf(c4, file_out, "current_frame==framecount-1", \
""""scene"""", "scene_num", """" = orig.trim("""", "prev_scene_end + 1 + trim_front", """","""", "framecount - trim_end", """")"""")

# I don't know how switch to displaying only the source and still do the
# traversal of the auxiliary chain. So I merge them with all weighting
# on the source clip. If the weight is changed to 0.0, the merge filter
# optimizes away any access to c5 and the scene detection will fail.
c6 = merge(source, c5, 0.0001).ShowFrameNumber(size=12, x=10, y=40)

c7 = ScriptClip(c6, """subtitle("scene #"+string(scene_num))""")
c7


I've used this on the films I am restoring, and I have added a couple features at the request of Fred. To use this you'd have to change the path to the film you are working on and you'd have to change the path to where your DLLs live (I don't have my dlls autoloaded; I always load them explicitly)

"min_scene_size" says that if there is a scene change detected, ignore any new scene changes for that many frames. This helps prevent multi-frame discontinuities from being detected as separate one or two frame scenes. "trim_front" and "trim_end" are set to 0, but you can set them to some positive value to chop off the first few and/or last few frames of a scene to avoid cruft that is often found at scene changes.

It has to run from start to finish, no random seeking around, to count scenes properly. It produces an output file that looks like this:

### scene change list ###
### source:C:\Users\Jim\Videos\8mm\cinepost\original\14.avi
scene1 = orig.trim(1,163)
scene2 = orig.trim(164,178)
scene3 = orig.trim(179,493)
scene4 = orig.trim(494,716)
scene5 = orig.trim(717,905)
scene6 = orig.trim(906,988)
scene7 = orig.trim(989,1196)
scene8 = orig.trim(1197,1935)
scene9 = orig.trim(1936,2385)
scene10 = orig.trim(2386,2571)
scene11 = orig.trim(2572,2886)
scene12 = orig.trim(2887,3297)
scene13 = orig.trim(3298,3445)
scene14 = orig.trim(3446,3498)
scene15 = orig.trim(3499,3723)
scene16 = orig.trim(3724,3910)
scene17 = orig.trim(3911,4060)
scene18 = orig.trim(4061,4147)

I manually copy it into my film restoring script. After that, I manually run through the film and review all the scene changes. It misses some and it sometimes has false positives, but it is still less work than doing it all manually. In my flow, this review work is less than 5% of the total time I spend on each film, so it really isn't that big of a burden. Unless the scene detection is nearly 100% accurate, I'd still do the manual review.

After that, I then restore each scene using fred's script, with parameters tuned for each scene. I've wrapped it up in a function to make it easier to process.

final = scene1.restore_film(param1a, param2a, param3a, etc) + \
scene2.restore_film(param1, param2b, param3c, etc) + ...

However, as avisynth essentially inlines everything, the script causes avisynth to be unstable and I find I have to restart frequently.

Gavino
2nd April 2011, 10:36
Interesting script, frustum - nice work.
It produces an output file that looks like this:
...
scene1 = orig.trim(1,163)
...
Are you intentionally omitting frame 0? I think prev_scene_end should be initialised to -1, not 0.
Note that it does not need to be global (nor any of the other variables).

# log scene changes at end of film
c5 = WriteFileIf(c4, file_out, "current_frame==framecount-1", \
..., "framecount - trim_end", """")"""")
Should be framecount-1-trim_end.
You could also use WriteFileEnd instead of WriteFileIf(..., "current_frame==framecount-1", ...)

# I don't know how switch to displaying only the source and still do the
# traversal of the auxiliary chain. So I merge them with all weighting
# on the source clip. If the weight is changed to 0.0, the merge filter
# optimizes away any access to c5 and the scene detection will fail.
c6 = merge(source, c5, 0.0001).ShowFrameNumber(size=12, x=10, y=40)
An alternative could be
c6 = ConditionalFilter(c5, source, source, "1", "=", "1").ShowFrameNumber(...)

johnmeyer
2nd April 2011, 16:39
Great script Frustum! I posted my mvtools2 scene detection script (see a few posts earlier in this thread), and it uses similar metrics. I also have a script I did not post that uses the seemingly simpler approach of using both averageluma and one of the ydiff AVISynth functions. What I found in comparing both of these is that the AVISynth functions, much to my surprise, ended up being slower on my 8-core i7 CPU than the MVTools2 version. Also, I ended up with a lot of false positives with the AVISynth functions, whereas MVTools2 seldom gave me a false positive.

The MVTools2 script did miss scene changes, however, especially with low contrast scenes. This is important to me because, like you, I use my scene detection script not only with video but with my film transfers (using the Workprinter and my own film transfer devices).

A lot of old amateur film has low contrast.

One trick to improve the MVTools2 scene detection that I didn't include in my sample script that I posted (but which you might want to add) is to create a super-high contrast clip and use the scene detection on that. VideoFred does something similar in one or two places in his film restoration script. I highly recommend you try doing this. Just a simple:

colorYUV(autogain=true)

statement is often enough to make the difference between missing a lot of scene transitions, and nailing almost all of them.

SubJunk
2nd April 2011, 20:59
One trick to improve the MVTools2 scene detection that I didn't include in my sample script that I posted (but which you might want to add) is to create a super-high contrast clip and use the scene detection on that.Good idea

Jeremy Duncan
4th April 2011, 10:55
may be to add some additional processing for doubtful frames only (with mean thsad near thscd1 or some other)

That's the problem, you hit it on the head.
The thsad1 is wrong.
The thsad1 size is either too small or big; why is it wrong, because the pixel difference is variable.

Basically mvtools2 works as a motion compensator, all but thsad1 which doesn't work because the pixel difference changes in complex scene to basic scene.

If thsad1 has a additional processing of pelsearch/radius it could work.

How?

The pelsearch acts as a function and this function holds the thsad1, the thsad1 has a sad value thsad2 can read.

Then something checks to see if thsad2 runs thsad1 in the pelsearch function.
true= thsad1 was used, false=thsad1 was not used.

This way the pelsearch value is used with thsad1.
If multiple pelseach functions were made then one could be made for a small pixel change and one for a large pixel change: pelsearch_1(radius=1, thsad1=400), pelsearch_2(radius=finest level, thsad1=300)

SubJunk
4th April 2011, 12:02
Would it be difficult to support different blocksizes, so we could do something like MAnalyse(blksize=12)?

SubJunk
5th April 2011, 11:54
Also why is MFinest commented out, and could it be available in the next version? Some people make custom builds to uncomment it because they find it useful for pel > 1

Jeremy Duncan
5th April 2011, 20:47
One trick to improve the MVTools2 scene detection that I didn't include in my sample script that I posted (but which you might want to add) is to create a super-high contrast clip and use the scene detection on that. VideoFred does something similar in one or two places in his film restoration script. I highly recommend you try doing this. Just a simple:

colorYUV(autogain=true)

Here is how I added that code to my code. Is this the correct way? :confused:

code removed and edited code posted below in a different post.

SubJunk
5th April 2011, 22:11
You would want to add it to the super clip instead of the main clip, Jeremy :)

johnmeyer
5th April 2011, 22:19
You would want to add it to the super clip instead of the main clip, Jeremy :)Yes, the way the script is written, you will end up with a high contrast clip as the result. Instead, you simply want to use that high contrast clip as the basis for the vectors, but then apply those vectors to the original-contrast video.

Also, I wonder why you are using ChangeFPS. I assume you understand that this will either add duplicate frames, or delete good frames. This is usually not what you want. If you are trying to remove telecine, use IVTC instead. If you merely want to change playback speed, use AssumeFPS. AssumeFPS will not add or delete any frames.

Jeremy Duncan
5th April 2011, 22:49
So this is the correct way to use that code? I added it to the super line. I also added converttoyv12 to the mflowfps line to change the clip to yv12, is this necessary to get regular color back again?

code removed, edited and posted in another post below.


I add changefps to my code because of the way ffdshow works.
For 23.976 fps source video, ffdshow code using info() shows the frame rate in the osd to be some other frame rate. So I have to use changefps as Leak made assumefps not to work in ffdshow avisynth tab.

When I use Convertfps(23.976) I get a smear ghost trail artifact, so I use changefps to set the framerate to the actual frame rate the source is at.

I told the ffdshow developers this but they are ignoring me. :rolleyes:

johnmeyer
5th April 2011, 23:33
Put AssumeFPS(23.976) as the last statement (you can keep the first one as well, if you want).

Also, I have not had any reason to use the Distributor() function which, as I understand it, is supposed to fix potential mult-thread problems. Are you certain that you need it? Is there a reason you are using SetMTMode (3,4) instead of SetMTMode (5,4)? Also, I don't think that you need the second setmtmode(2) statement.

Finally, almost all of my 150+ AVISynth scripts use SetMTMode(5,0) as the statement prior to reading the source, and SetMTMode(2) after the source has been read. However, I have not used ffdshow, so perhaps you need to do things differently when reading with that.

frustum
6th April 2011, 05:03
Gavino, thanks for the code review. I wrote it a few months ago and forget the details; it is just a simple utility to save some manual work, but I manually review all the transitions anyway.

As I recall, I couldn't get WriteEnd to work, so I added the conditional write testing for the final frame explicitly and it worked, so I stopped trying to figure out why WriteEnd didn't work for me. Hmm, vaguely, perhaps it was something like the variables were not valid at the time WriteEnd was evaluated.

globals: avisynth scripting has the weirdest semantics that I have a hard time understanding. Some of it has to be that way because of the dataflow plumbing that drives the logic of it, but a lot of it just seems like poor original choices that could never be fixed because of concerns with backwards compatibility.

Gavino
6th April 2011, 17:16
Gavino, thanks for the code review. I wrote it a few months ago and forget the details; it is just a simple utility to save some manual work, but I manually review all the transitions anyway.
I've just tried out your script, and to get the first and last frame numbers right, you definitely need the corrections I posted.
As I recall, I couldn't get WriteEnd to work, so I added the conditional write testing for the final frame explicitly and it worked, so I stopped trying to figure out why WriteEnd didn't work for me. Hmm, vaguely, perhaps it was something like the variables were not valid at the time WriteEnd was evaluated.
Yes, since WriteFileEnd (unlike WriteFile) does not set 'last' to be the input clip before evaluating the expressions, you would have needed to replace "framecount" by "c4.framecount". However, it still would not have given the right result so I was wrong to suggest using it. Since the expressions are evaluated at compile-time (and only the file writing is postponed to script unload time), it would print the initial values of the variables (scene, etc) instead of their final values. Hence WriteFileEnd, contrary to what you might hope, cannot be used to obtain the final values of variables set in a run-time script. (And as I've said in the past, I think the interface to WriteFileStart and WriteFileEnd is badly designed.)
globals: avisynth scripting has the weirdest semantics that I have a hard time understanding. Some of it has to be that way because of the dataflow plumbing that drives the logic of it, but a lot of it just seems like poor original choices that could never be fixed because of concerns with backwards compatibility.
The semantics of run-time scripts are complex and there are serious deficiencies in its approach to variable name binding (easier seen in hindsight, of course). GRunT extends the semantics (in a backwards compatible way) to arrive at something I think is much more usable and useful. However, the question of globals v non-globals is more simple - run-time scripts run at the same scope level as the 'outer' script, so globals are never necessary to communciate between them.

Gavino
6th April 2011, 18:37
Also, I wonder why you are using ChangeFPS. I assume you understand ...
Hmm, I don't think you can assume that at all...

I add changefps to my code because of the way ffdshow works.
For 23.976 fps source video, ffdshow code using info() shows the frame rate in the osd to be some other frame rate. So I have to use changefps as Leak made assumefps not to work in ffdshow avisynth tab.

I told the ffdshow developers this but they are ignoring me. :rolleyes:
The reason AssumeFPS does not work within ffdshow is that you are not allowed to change the clip duration. You can change frame rate only by changing the frame count, and that's what MFlowFPS (or MBlockFPS) does.

The only reason you might want in addition to put ChangeFPS at the start of your frame doubling script is to smooth access to the cache (particularly when running multi-threaded), by doing a null change with linear=true. But then you should write it as
video = ffdshow_source()
video = video.ChangeFPS(video, linear=true)
rather than putting the actual source rate in. Then you don't have to change it for every new source file that has a different rate from the last one you used, or have different versions for PAL, NTSC, etc. That's just crazy.

Also, I don't see the point of testing for GetMTMode(false) > 0. It is useless as a check on whether you are running on a multithreaded Avisynth, as the command itself (and the earlier uses of SetMTMode) would produce an error on a vanilla Avisynth.

Jeremy Duncan
6th April 2011, 20:24
Hi Gavino,

I tried your code:

video = ffdshow_source()
B = video.ChangeFPS(video, linear=true)
b.info()


on this clip: link (http://www.mediafire.com/?3jvt2k2mu25fydo). The osd with info() shows the clip as 23.970, but it's actually 23.976. So I have to actually set the real frame rate and can't just type Video in changefps.

Gavino
6th April 2011, 20:46
The osd with info() shows the clip as 23.970, but it's actually 23.976.
That's probably just a rounding difference between two different calculations of the same thing, or in the display of the value.
Can you really tell the difference between them anyway (about 1 in 4000)?

Jeremy Duncan
6th April 2011, 22:43
In a different test video, the video is 23.976 frames per second. If I set the frame rate to 23.955, then when I frame step using my frame doubler code, the arm of the person walking by the bon fire is doubled, but if I set the frame rate to 23.976 the arm is not doubled.

ffdshow using info() shows the video to be 23.955 frames per second.


link to clip from the 2011 movie Red Riding Hood. (it's from a trailer I got online) (http://www.mediafire.com/?7bba5kc82wcmio5)


setmtmode(5,0)
SetMemoryMax(512)
video=ffdshow_source().changefps(29.976, linear=true)
A = video.autolevels()
B = video
setmtmode(2)
SetMemoryMax(512)
super_1 = A.MSuper(pel=2, hpad=12, vpad=12, rfilter=2, isse=true)
super_2 = B.MSuper(pel=2, hpad=12, vpad=12, rfilter=1, isse=true)
backward_vec = MAnalyse(super_1, isb=true, blksize=16, levels=2, search=2, searchparam=1, isse=true, sadx264=7, lambda=200, dct=10)
forward_vec = MAnalyse(super_1, isb=false, blksize=16, levels=2, search=1, searchparam=1, isse=true, sadx264=7, lambda=200, dct=10)
backward_vec_1 = MRecalculate(super_1, backward_vec, blksize=8, search=2, searchparam=1, dct=10)
forward_vec_1 = MRecalculate(super_1, forward_vec, blksize=8, search=1, searchparam=1, dct=10)
B.MFlowFps(super_2, backward_vec_1, forward_vec_1, num=FramerateNumerator(A)*2, den=FramerateDenominator(A)*1, thscd1=350, thscd2=100, ml=100)
distributor()


setmtmode(5,0)
SetMemoryMax(512)
video=ffdshow_source().changefps(29.976, linear=true)
A = video.autolevels()
B = video
setmtmode(2)
SetMemoryMax(512)
super_1 = A.MSuper(pel=2, hpad=12, vpad=12, rfilter=2, isse=true)
super_2 = B.MSuper(pel=2, hpad=12, vpad=12, rfilter=1, isse=true)
backward_vec = MAnalyse(super_1, isb=true, blksize=16, levels=2, search=2, searchparam=1, isse=true, sadx264=7, lambda=200, dct=10)
forward_vec = MAnalyse(super_1, isb=false, blksize=16, levels=2, search=1, searchparam=1, isse=true, sadx264=7, lambda=200, dct=10)
backward_vec_1 = MRecalculate(super_1, backward_vec, blksize=8, search=2, searchparam=1, dct=10)
forward_vec_1 = MRecalculate(super_1, forward_vec, blksize=8, search=1, searchparam=1, dct=10)
B.MBlockFps(super_2, backward_vec_1, forward_vec_1, num=FramerateNumerator(A)*2, den=FramerateDenominator(A)*1,thscd1=350, thscd2=100, mode=3, thres=30)
distributor()

Gavino
7th April 2011, 00:05
In a different test video, the video is 23.976 frames per second. If I set the frame rate to 23.955, then when I frame step using my frame doubler code, the arm of the person walking by the bon fire is doubled, but if I set the frame rate to 23.976 the arm is not doubled.

ffdshow using info() shows the video to be 23.955 frames per second.

link to clip from the 2011 movie Red Riding Hood. (it's from a trailer I got online) (http://www.mediafire.com/?7bba5kc82wcmio5)
When I play that clip (in WMP), ffdshow using info() reports 23.976 (2997/125).
MediaInfo confirms rate as 23.976 too.

Jeremy Duncan
7th April 2011, 00:17
your right, in wmp it's 23.976, but in mpc-hc it's 23.955. I don't know what to do now.
Edit,

What's stranger yet is I tried this clip in wmp: link (http://www.mediafire.com/?3jvt2k2mu25fydo) and the info() osd shows it to be 23.970, but mediainfo link (http://www.videohelp.com/tools/MediaInfo) shows it to be 23.976.

setarip_old
7th April 2011, 01:18
@Jeremy Duncan

Hi! What's stranger yet is I tried this clip in wmp: link and the info() osd shows it to be 23.970, but mediainfo link shows it to be 23.976.

Look again, carefully - Are you sure it didn't indicate it to be 29.970fps?

Jeremy Duncan
7th April 2011, 02:09
http://thumbnails27.imagebam.com/12688/00b1bd126871549.jpg (http://www.imagebam.com/image/00b1bd126871549)

Click the picture. This is using wmp11.


video = ffdshow_source()
B = video.ChangeFPS(video, linear=true)
b.info()

setarip_old
7th April 2011, 02:29
@Jeremy Duncan

I would have believed you if you just said, "I'm sure" ;>}

SubJunk
7th April 2011, 03:13
It is actually 23.976fps, regardless of what certain tools report. In that case it looks like the framerate is being truncated to 4 digits (2397) so that is why it displays like that.
Like I have said to you before many times, 23.970 is not a valid framerate for anything, if something is actually at that framerate it is a weird mistake. Plus I have that video you used to test and I know it is 23.976fps.

Jeremy Duncan
7th April 2011, 04:20
Hi Subjunk,

I'm not asking if the video is 23.970. We all know that that is not the framerate of the video. I even posted a link to sw that shows the framerate of the video so you or they could use it to double check.

WMP shows the frame rate of red riding hood properly, but not the montage video that I took the screenshot of them dancing from. Either it's wmp that's at fault, or it's ffdshow. But all this is off topic anyway and not really important as I can just type the real framerate in changefps.

Gavino
7th April 2011, 11:31
I can just type the real framerate in changefps.
By itself, your mvtools code produces exactly two frames for each input frame it gets, adding the extra one by interpolating between each input frame. No matter what rate ffdshow 'thinks' the framerate is, if you use a different rate in changefps, that will add or delete frames in the input stream to mvtools, throwing the motion analysis off and giving a jerkier result.

So it seems to me you actually need the changefps to do nothing (other than buffering the frames), and the only way to ensure that is to use
video = video.changefps(video, linear=true).

Didée
7th April 2011, 12:19
BTW, if you're aiming at just *doubling* the framerate, there's no need to juggle with FrameRateNumerator() and FrameRateDenominator().

In MFlowFPS and MBlockFPS, if you set either num=0 or den=0, it will automatically double the input framerate.

Jeremy Duncan
7th April 2011, 13:36
Gavino,

I tried with your code and the one I used where I input the actual framerate in changefps and frame stepped and honestly I could not see any jerkiness either way. This was with the dancing video. Tomorrow maybe I'll try the red riding hood video with the bon fine scene.
I know what jerky video looks like too, I saw it before in red riding hood, but I didn't see it in the dancing video.

Didée,

Before when I set num and den like this: num=FramerateNumerator(A)*2, den=FramerateDenominator(A)*1 and set changefps to use the actual frame rate the cpu cores on my Intel E6600 was very unevenly used.

Then I used your advice and setup num and den to be 1 and 0, and deleted the changefps code, but the cores were still slightly enevenly used.

Then I added the changefps code and set the actual frame rate in changefps, and the cores were practically evenly used across both cores.

For some reason using num and den and changefps this way balances the cpu load evenly.

:thanks: to you both for helping me.


setmtmode(5,0)
SetMemoryMax(512)
video=ffdshow_source().changefps(23.976, linear=true)
A = video.autolevels()
B = video
setmtmode(2)
SetMemoryMax(512)
super_1 = A.MSuper(pel=2, hpad=12, vpad=12, rfilter=2, isse=true)
super_2 = B.MSuper(pel=2, hpad=12, vpad=12, rfilter=1, isse=true)
backward_vec = MAnalyse(super_1, isb=true, blksize=16, levels=2, search=2, searchparam=1, isse=true, sadx264=7, lambda=200, dct=10)
forward_vec = MAnalyse(super_1, isb=false, blksize=16, levels=2, search=1, searchparam=1, isse=true, sadx264=7, lambda=200, dct=10)
backward_vec_1 = MRecalculate(super_1, backward_vec, blksize=8, search=2, searchparam=1, dct=10)
forward_vec_1 = MRecalculate(super_1, forward_vec, blksize=8, search=1, searchparam=1, dct=10)
B.MFlowFps(super_2, backward_vec_1, forward_vec_1, num=0, den=1, thscd1=350, thscd2=100, ml=100)
distributor()



setmtmode(5,0)
SetMemoryMax(512)
video=ffdshow_source().changefps(23.976, linear=true)
A = video.autolevels()
B = video
setmtmode(2)
SetMemoryMax(512)
super_1 = A.MSuper(pel=2, hpad=12, vpad=12, rfilter=2, isse=true)
super_2 = B.MSuper(pel=2, hpad=12, vpad=12, rfilter=1, isse=true)
backward_vec = MAnalyse(super_1, isb=true, blksize=16, levels=2, search=2, searchparam=1, isse=true, sadx264=7, lambda=200, dct=10)
forward_vec = MAnalyse(super_1, isb=false, blksize=16, levels=2, search=1, searchparam=1, isse=true, sadx264=7, lambda=200, dct=10)
backward_vec_1 = MRecalculate(super_1, backward_vec, blksize=8, search=2, searchparam=1, dct=10)
forward_vec_1 = MRecalculate(super_1, forward_vec, blksize=8, search=1, searchparam=1, dct=10)
B.MBlockFps(super_2, backward_vec_1, forward_vec_1, num=0, den=1,thscd1=350, thscd2=100, mode=3, thres=30)
distributor()

Didée
7th April 2011, 14:33
In the past, I've experienced issues very similar to the ones you have mentioned. However, for the most part, your solutions do not work for me.

first off: my ffdshow-Avisynth-scripts happen to start with
SetMemoryMax(600)
ffdshow_source()
changefps(last,last,true)
which in essence is the same as your recommendation.

- when I put "Distributor()" as the last line in ffdshow/Avisynth, then my player will crash immediately when loading a video. Always, without exception. For me, MT works only without Distributor().

- I found that in ffdshow/Avisynth, SetMTmode() often does not work well for me. On a few videos it works good, but on the majority of videos it works bad (i.e.: unusable) for me. For ffdshow, I had to switch to MT().

- multithreading works only efficiently if the source is decoded directly by ffdshow. When decoding is done e.g. by an MS decoder and ffdshow is in the chain only as a post-processor, multithreading becomes problematic.

- for some reason, it seems that multithreading in ffdshow never uses more than 4 threads for me. When I set threads = 6 or 8, the CPU graph shows only 4 cores get loaded.


Can't tell if such behaviour is "typical" or rather "unique". Just wanted to point out the possibility that your elaborate postings about how to do this-or-that in ffdshow might cause problems for many users. Small differences in a system's multimedia setup can cause substantial differences in the behaviour! - And consequently, what works for you, might not work at all for other users.

In any case, I'd say that "multithreading in ffdshow->Avisynth" is an odd thing.

Gavino
7th April 2011, 15:01
I tried with your code and the one I used where I input the actual framerate in changefps and frame stepped and honestly I could not see any jerkiness either way.
In the examples you've given, the difference in framerates was small, so relatively few frames would be affected (eg 1 in 4000 in one of the cases). So you won't always notice a difference using 'your' code, but where there is any visible difference, I would expect my code to be the one with better results, and it also has the advantage you don't have to change it for each new source.
For some reason using num and den and changefps this way balances the cpu load evenly.
The two ways of using num and den are completely equivalent, so don't affect anything but readability and ease of writing. Using changefps with linear=true is what balances the cpu load, but this has nothing to do with changing the rate from what ffdshow reports. I think that's the point that is confusing you - you don't want to really change the fps at that point, it's just a trick to use the buffering feature of the changefps filter.

Jeremy Duncan
7th April 2011, 20:51
Gavino,

This is the code now:

setmtmode(5,0)
SetMemoryMax(512)
video=ffdshow_source().changefps(ffdshow_source(), linear=true)
A = video.autolevels()
B = video
setmtmode(2)
SetMemoryMax(512)
super_1 = A.MSuper(pel=2, hpad=12, vpad=12, rfilter=2, isse=true)
super_2 = B.MSuper(pel=2, hpad=12, vpad=12, rfilter=1, isse=true)
backward_vec = MAnalyse(super_1, isb=true, blksize=16, levels=2, search=2, searchparam=1, isse=true, sadx264=7, lambda=200, dct=10)
forward_vec = MAnalyse(super_1, isb=false, blksize=16, levels=2, search=1, searchparam=1, isse=true, sadx264=7, lambda=200, dct=10)
backward_vec_1 = MRecalculate(super_1, backward_vec, blksize=8, search=2, searchparam=1, dct=10)
forward_vec_1 = MRecalculate(super_1, forward_vec, blksize=8, search=1, searchparam=1, dct=10)
B.MBlockFps(super_2, backward_vec_1, forward_vec_1, num=0, den=1,thscd1=350, thscd2=100, mode=3, thres=30)
distributor()

:thanks:

Didée,

If your having problems then a problem solving step would be elimination process. Try my method and see if it fixes those problems you mentioned.

Didée
7th April 2011, 21:48
If your having problems then a problem solving step would be elimination process. Try my method and see if it fixes those problems you mentioned.
I've tried a plentitude of different setups. More exactly, I've tried all setups that I can only think of.

The conclusion is what I've written in my previous post. Perhaps you need to read it more closely.

In case it was too much text -- the ultimative points are in the first sentence and in the penultimate sentence. I repeat:

your solutions do not work for me.
and
what works for you, might not work at all for other users.

travolter
8th April 2011, 10:59
@jeremy

About these new scripts, ones working OK in some computers and not in others.. I start to think that all is related about how different CPUs do the processing and expecially the MT thing.

I have here a Q9550 and usually I have to modify settings in your scripts because my cpu seems "bottlenecked" while cpu monitor is not showing 100% usage (?)

What cpu are u using?

Jeremy Duncan
9th April 2011, 01:10
I don't know the right cpu for this. I have a Intel E6600 and it seems to run fine when I play standard definition dvd's. On some scenes it stutters and slows down to a crawl though, so I don't really know the cpu to use.

I have ddr2 as well, if I had ddr3 ram it would be better. And if my videocard which is a ATI 4670 had ddr5 ram it would be better, right now it has ddr2 I think.
In other words the ram speed plays a part in the performance of the pc ability. Other things like that.

Didée,

I wonder if you got the realtime ffdshow with avisynth going or not? Did you manage to get it going?

Didée
9th April 2011, 09:07
Sure, I use framerate doubling quite frequently. Just that I need to use MT() for that, because SetMTmode doesn't play nice for me in ffdshow.

My script basically looks like this: (some #'ed processing lines removed)
SetMemoryMax(600)
ffdshow_source()
changefps(last,last,true)

MUL = 0 # 1 #
BLK = (width<1000) ? 16 : 32
ME1 = (width<1300) ? 5 : 4
ME2 = (width<1300) ? 4 : 2
DCT = (width<1300) ? 5 : 0
LEV = (width<1300) ? 3 : 2

MT("""
sup = MSuper(hpad=16, vpad=16, pel=1, levels=LEV, rfilter=3, isse=true)
bv = MAnalyse(sup,blksize=BLK, levels=LEV, search=ME1, searchparam=ME2, isb=true, plevel=0, dct=DCT)
fv = MAnalyse(sup,blksize=BLK, levels=LEV, search=ME1, searchparam=ME2, isb=false, plevel=0, dct=DCT)
MBlockFps(sup, bv, fv, num=60*MUL, den=1, mode=1)
""",4,32)
You see, quite primitive settings. But it does the job good enough, and it never hits THE WALL.

SubJunk
10th April 2011, 13:08
That reminds me Didee, I have reverted the blend=false change you suggested in InterFrame because of the scene change detection problems. I found that with blend=false a lot of action scenes weren't interpolating, and of course weakening the values just means that the blend=false hardly ever gets used anyway.

Check out this sample video made with the new InterFrame (which is mostly a MVTools2 script, so this is relevant to the topic), I think it is pretty cool :) The new version adds GPU-acceleration as well as increased quality.
Original (http://www.spirton.com/uploads/InterFrame/20110410-Sample-Original.mkv) - InterFrame (default settings) (http://www.spirton.com/uploads/InterFrame/20110410-Sample-InterFrame.mkv)

PelPix
26th April 2011, 02:13
Hey guys. I've been using MVtools for a while now to interpolate frames for motion blur in game videos. My current script is simply
super = MSuper()
backward_vec = MAnalyse(super, overlap=4,isb = true, search=3)
forward_vec = MAnalyse(super, overlap=4, isb = false, search=3)
MFlowFps(super, backward_vec, forward_vec, num=768, den=1)
TemporalSoften(6,255,255,0,2).selectevery(32,1)

I'm interpolating 768 frames out of 144. At that incredible level, I know I will never be able to remove the blocky artifacts from the output altogether, but do you have any tips on lessening them that I might not have already found out?

Keep in mind that my source footage is raw captures from the output of a game engine. There is no compression or distortion of any kind, so nothing needs to be included to counteract that.

SubJunk
26th April 2011, 02:49
You can use a higher value for ml in MFlowFps to reduce the artifacts, which weakens the mask but with other values it won't matter much. Try using ml=10000 which basically disables it, then if you need a stronger mask try lowering the value until you're happy.
Another thing is to grab the custom build of MVTools from the SVP, or you can get it from the guide in my signature. It lets you use ml=0 (whereas it is locked to greater than 0 in the official version).
Also in the custom build there is a better mask called sadml which is a good replacement for ml. It offers similar advantages with less artifacts. Have a look at InterFrame to get an idea of how to use the custom build, or just ask questions here and I'm happy to help :)

PelPix
26th April 2011, 04:48
Alright. I actually tried InterFrame directly, but found that it actually put more weight on the original frames than the interpolated ones when using it for motion blur, which obviously isn't correct.
I just disabled the mask. It looks wonderful. I guess motion blur is too low-frequency to need a mask at all, huh? It's blurring some one-pixel lines that can't be blurred though, so I'll continue tweaking it.

PelPix
26th April 2011, 04:57
Double posted

SubJunk
26th April 2011, 05:03
Yeah it's not made with motion blur in mind, but hopefully there are some tips in there that translate to your script :)

SubJunk
2nd May 2011, 23:30
Hopefully someone can help me with this question :)

Is there a way to make MVTools2 get vectors from a smaller source and apply them to a bigger source?
For example, if I have a 1920x1080 video, and I want MVTools2 to do all its work on a downsized version of it (say 1280x720), and then at the final step (MFlowFPS) scale it to the 1920x1080 size again?

In other words, the main source wouldn't be resized at any stage, only the motion information.

When I try the obvious thing of just creating the super clip from a resized source while keeping the input the same resolution, I get the error "inconsistent source and vector frame size", but I'm not a pro at AviSynth scripting so I wonder if anyone has a way to do it?

Didée
2nd May 2011, 23:48
There once was the "MVIncrease" filter for this purpose, but IIRC it's not supported anymore. It did only a strictly 2x increase anyway.

What about (blocksize=32, overlap=0, pel=1) -- not fast enough?

SubJunk
3rd May 2011, 00:14
Thanks for the reply :)
The reason I want it isn't because of speed (it is irrelevant because I encode), but because of the quality.
blksize=16 on 720p content is a great setting for most content IMO, while blksize=16 on 1080p content is worse, as is blksize=32 on 1080p content.
It didn't matter much to me before because I mostly watched 720p content, but now I am mostly watching 1080p content so I would like the same interpolation benefits I had with 720p content but with the resolution increase.

pbristow
3rd May 2011, 20:43
So ideally you want a blocksize somewhere between 16 and 32, such as 24, but that's not available with MVTools2 as it stands.

What overlap setting are you using? You may be able to approximate the effect of a blocksize of 24, by using 32 with a larger overlap. (e.g. blocksize=24 with overlap=4 has the same inter-block spacing as blocksize=32 with overlap=12 (spacing is 20)) A fairly large overlap is advisable when using large blocks anyway, to avoid any large gaps appearing between blocks that diverge from each other.

SubJunk
4th May 2011, 02:19
Hi pbristow, thanks for the ideas :)
I tried them and it seems it doesn't work like that; the overlap didn't seem to bring it close to it.
I compared blksize=16, overlap=4 with blksize=32, overlap=20 and blksize=32, overlap=16 but it seems that overlap doesn't have much effect when using blksize=32.

Attached are examples.
The first one is the 720p clip (resized to 1080p afterwards for this comparison) using blksize=16 and overlap=4.
The second one is 1080p using blksize=32 and overlap=20.

So the second one is just like an average of 2 frames, while the first is fairly accurate at merging the panning parts.

pbristow
4th May 2011, 09:42
OK, that's weird... The features it's failing to track seem big enough that a 32x32 block should be able to lock onto them OK. That belt-pouch next to the tail, for example, should be no trouble at all.

Does this problem occur throughout the movie, or only on certain scenes? (High speed action, for example?) The problem may be with the limitation of vector lengths, rather than anything to do with block sizes. With a 50% wider & taller frame showing the same action, all the movement vectors will be 50% longer in pixel terms, so in regions of fast movement they may be just too long for mvtools2 to handle.

Some other things to check:

0. First, double-check whether the 1080p source contains all clean progressive frames, or if it's actually a 1080i30 encode of a 24fps original that's being mis-read as 1080p, as that would lead to blended frames like the one I'm seeing above.

1. Are you definitely using the latest version of mvtools2? The 32 blocksize option is pretty new, and I don't know if the older version would abort when you set blocksize=32, or just default to a smaller size, or something. If you have an older version sitting in your plugins directory, that could be overriding the newer one...?

2. Check that your script is handling the two cases exactly the same way (is it exactly the same script running with a different input file?)

3. Consider whether any other mvtools parameters need scaling to match the larger block size you're setting, or the larger feature size of the source.

Hope this helps. :)

-Vit-
4th May 2011, 17:07
Is there a way to make MVTools2 get vectors from a smaller source and apply them to a bigger source?
I have a little plugin for this. It's going to be used in a later version of QTGMC for optimization. It hasn't been tested much:

Download MScaleVectors 0.1 (http://www.mediafire.com/?is3pnyqdv5pyz6d)

It lets you use motion vectors on a different sized clip than they were analyzed on. Clip sizes must be related by powers of 2.

Example

scale = 2 # 2, 4 or 8. How much to downscale the clip for analysis (and then how much upscale the resultant vectors)
pad = 16 # Padding used in full-scale super clip, must be divisible by scale (downscaled padding needed in downscaled super clip)

clip = YourSource( "Your\Video" )
clipScaled = clip.BicubicResize( clip.Width()/scale, clip.Height()/scale )

superScaled = clipScaled.MSuper( pel=2, hpad=pad/scale,vpad=pad/scale )
bVecScaled = superScaled.MAnalyse( blksize=8, isb=true ) # Blocksize can't go > 32 after scaling
fVecScaled = superScaled.MAnalyse( blksize=8, isb=false )

bVec = bVecScaled.MScaleVectors( scale ) # Increase blocksize for vectors
fVec = fVecScaled.MScaleVectors( scale )

super = clip.MSuper( pel=2, hpad=pad,vpad=pad )
clip.MFlowFPS( super, bVec, fVec, den=0 )


Other Documentation

INFO

Plugin that scales MVTools motion vectors / blocksize. Main purpose is to allow vectors to be used on a differently
sized clip than they were analyzed from.

For example
- Use MAnalyze on a half-sized clip at block size 16
- Use this plugin to scale the vectors by 2 to block size 32
- Use resulting vectors for MFlowFPS, MDegrain,... on the full sized frame.
Saves doing the MAnalyze on the full size frame, which may be faster and saves memory (good for multi-threading).

Note that you need a super clip for each frame size. The padding (hpad, vpad) on each super clip must be
manually scaled to match the vector scaling. See the example below.

Similar functionality was available in MVTools through the function MVIncrease, but it was removed.


SYNTAX

MScaleVectors( int Vectors, float Scale, int Mode )

Returns a new motion vectors clip

Vectors :
Motion vectors returned from MAnalyse
[No default]

Scale :
Mode = 0,1: Scale is the amount to up/downscale blocksize, only valid values are 2,4 or 8. Blocksize cannot drop below 4 or exceed 32
Mode = 2: Scale is (floating point) amount to scale the vectors, blocksize is unaffected. Only the range 0.0 to 1.0 is currently safe
[Default Scale = 2 (for default Mode=0)]

Mode :
Method of scaling:
Mode = 0: Increase the blocksize by 2, 4 or 8 (see above)
Mode = 1: Decrease the blocksize by 2, 4 or 8
Mode = 2: Blocksize is not scaled, only vectors themselves
[Default Mode = 0]

Mode 0 allows you to MAnalyse at a smaller size, then process (MDeGrain, MFlowFPS, whatever) at full size
Mode 1 allows you to MAnalyse at full size, but have some subsequent processes run at a smaller size
Mode 2 is for esoteric uses

SubJunk
5th May 2011, 02:24
Great idea Vit, thanks a lot! I'll check it out soon :)

SubJunk
5th May 2011, 10:39
Should these 2 scripts produce the same output (except the first with less definition than the second because of the resize)?
They produce different results and I'm trying to see why, I'm sure I'm missing something very obvious :)

Input = video
Input.BicubicResize(Input.Width()/2, Input.Height()/2)
Super = MSuper(Input, hpad=8, vpad=8, rfilter=4)
backward = MAnalyse(Super, blksize=16, searchparam=4, plevel=0, isb=true , badSAD=2000, overlap=4, search=3, dct=5, pelsearch=3)
forward = MAnalyse(Super, blksize=16, searchparam=4, plevel=0, isb=false, badSAD=2000, overlap=4, search=3, dct=5, pelsearch=3)
backward = MRecalculate(Super, backward, blksize=8, searchparam=1, overlap=2, search=3, dct=5)
forward = MRecalculate(Super, forward, blksize=8, searchparam=1, overlap=2, search=3, dct=5)
MFlowFps(Input, Super, Backward, Forward, num=48000, den=1001, ml=10000)
Spline36Resize(Input.Width()*2, Input.Height()*2)

Input = video
InputScaled = Input.BicubicResize(Input.Width()/2, Input.Height()/2)
Super = MSuper(InputScaled, hpad=8, vpad=8, rfilter=4)
backward = MAnalyse(Super, blksize=16, searchparam=4, plevel=0, isb=true , badSAD=2000, overlap=4, search=3, dct=5, pelsearch=3)
forward = MAnalyse(Super, blksize=16, searchparam=4, plevel=0, isb=false, badSAD=2000, overlap=4, search=3, dct=5, pelsearch=3)
backward = MRecalculate(Super, backward, blksize=8, searchparam=1, overlap=2, search=3, dct=5)
forward = MRecalculate(Super, forward, blksize=8, searchparam=1, overlap=2, search=3, dct=5)
BackwardFull = backward.MScaleVectors(2)
ForwardFull = forward.MScaleVectors(2)
SuperFull = MSuper(Input, hpad=16, vpad=16, rfilter=4)
MFlowFps(Input, SuperFull, BackwardFull, ForwardFull, num=48000, den=1001, ml=10000)

-Vit-
5th May 2011, 11:52
I'm missing something very obvious :)
The first script ignores the downsize. Should be something like:

Input = video
Input = Input.BicubicResize(Input.Width()/2, Input.Height()/2)
...

SubJunk
5th May 2011, 12:48
Duh ;)

Edit: After fixing that error the results are still different, is there another mistake?

-Vit-
5th May 2011, 14:16
I tested those scripts, corrected, no problems. How are the results different?

SubJunk
5th May 2011, 23:57
I tested those scripts, corrected, no problems. How are the results different?They are mostly the same but there are slight differences. I wonder if hpad and vpad are being used properly, since it seems to occur more frequently at edges.

Example attached.

Edit: Removed attachments since there are newer ones in my next post

-Vit-
6th May 2011, 01:30
Haven't looked at your images because they're still pending. But after looking at the edges on some examples I'm beginning to wonder if hpad/vpad aren't causing problems themselves. Because explicitly setting them both to 0 removes several major edge artefacts for both versions of the script above. As the MScaleVector version is clearer the problems are more obvious on that version. Try setting hpad/vpad to 0 and see if you're still getting a difference (in fact do hpad/vpad do anything useful for this example?).

SubJunk
6th May 2011, 02:26
Try setting hpad/vpad to 0 and see if you're still getting a differenceIt doesn't seem to be the hpad/vpad settings after all. :s

Here are screenshots of the 2 scripts with hpad/vpad=0:
First (http://www.spirton.com/uploads/60FPS/test-20110506-1.jpg) - Second (http://www.spirton.com/uploads/60FPS/test-20110506-2.jpg)

The scripts used in those screenshots are much simpler than before in order to rule out as many variables as possible:

Input = video
InputScaled = Input.BicubicResize(Input.Width/2, Input.Height/2)
Super = MSuper(InputScaled, hpad=0, vpad=0)
backward = MAnalyse(Super, isb=true)
forward = MAnalyse(Super, isb=false)
BackwardFull = backward.MScaleVectors(2)
ForwardFull = forward.MScaleVectors(2)
SuperFull = MSuper(Input, hpad=0, vpad=0)
MFlowFps(Input, SuperFull, BackwardFull, ForwardFull, num=48000, den=1001)

Input = video
Input = Input.BicubicResize(Input.Width/2, Input.Height/2)
Super = MSuper(Input, hpad=0, vpad=0)
backward = MAnalyse(Super, isb=true)
forward = MAnalyse(Super, isb=false)
MFlowFps(Input, Super, Backward, Forward, num=48000, den=1001)
Spline36Resize(Input.Width*2, Input.Height*2)

-Vit-
6th May 2011, 03:23
This is either a question for Fizick, or you will have to wait until I have time to go through the MVTools2 source code in detail. I'm busy with other things atm. The plugin scales the block size, overlap, padding and the vectors themselves. Would expect that to work, and it broadly does [I have a version of QTGMC that uses it successfully]. Your differences are on fast/complex motion - without some detailed code knowledge it's hard to say if this is what to expect or not [the motion vector interpolation might correctly be different between these scripts].

However, I did just notice that I didn't scale the SAD per-block (need to check the MVTools2 source to see if it is internally scaled, but I would guess it isn't) but I found no difference when I changed it. My test case was simpler, so you might want to try. So here's a version of MScaleVectors that scales the block SAD too:

Download MScaleVectors 0.11 (http://www.mediafire.com/?ephn3xlvba8u28b)

SubJunk
6th May 2011, 06:14
This is either a question for Fizick, or you will have to wait until I have time to go through the MVTools2 source code in detail. I'm busy with other things atm. The plugin scales the block size, overlap, padding and the vectors themselves. Would expect that to work, and it broadly does [I have a version of QTGMC that uses it successfully]. Your differences are on fast/complex motion - without some detailed code knowledge it's hard to say if this is what to expect or not [the motion vector interpolation might correctly be different between these scripts].

However, I did just notice that I didn't scale the SAD per-block (need to check the MVTools2 source to see if it is internally scaled, but I would guess it isn't) but I found no difference when I changed it. My test case was simpler, so you might want to try. So here's a version of MScaleVectors that scales the block SAD too:

Download MScaleVectors 0.11 (http://www.mediafire.com/?ephn3xlvba8u28b)You're right that both scripts are mostly the same, there is probably little practical difference between them. It seems in my short tests that neither one produces superior interpolation to the other; for every area that is better in the first script there is another that is worse.

For the record, I tried again with MScaleVectors 0.11 and the 2 scripts still produce different results.

Thanks a lot for the plugin, it's really cool :)

pbristow
9th May 2011, 22:10
Hey -Vit-, does MScaleVectors allow one to negate/reverse the original vectors, i.e. multiply them by -1? If not, could that be added?

That would get us halfway toward using MVTools for extrapolation, as opposed to interpolation. (See this post by Didee: http://forum.doom9.org/showthread.php?p=1498840#post1498840)

E.g. to extrapolate Frame N+1 from the previous two frames, you would take the backward vectors that run from frame N to N-1, and negate them before feeding them MFlowInterp as forward vectors (the appropriate flags would need to be set, I think, to allow them to be seen as forward vectors. I tried swapping the vector clips around when calling MFlowInterp once, and it complained). For the other (backward) set of vectors, give MFlowInterp a set of zero vectors (i.e. indicating no movement), all with a confidence rating of zero (i.e. "don't trust these at all"). We'd need a new function to create such a null vector set, which should be dead easy to produce. MFlowInterp should then shift the blocks of Frame N forward in the same direction, by the same amount, as they moved when coming from N-1 to their positions in N.

-Vit-
10th May 2011, 00:37
Hey -Vit-, does MScaleVectors allow one to negate/reverse the original vectors, i.e. multiply them by -1? If not, could that be added?
It almost does. That's one of the "esoteric uses" of mode 2. I nearly replied to the other thread, but....
I haven't actually finished mode=2 yet, hence the comment in the docs about "Only the range 0.0 to 1.0 is currently safe". Using scale <0 or >1 in mode 2 works sometimes and crashes sometimes, because when you reverse or lengthen the vectors you need to ensure they don't point outside the frame. I will add that code later. I only posted the plugin because it already had the block size scaling that SubJunk wanted.

Basic extrapolation:
- Calculate backward vectors (bVec) from Frame-1 to Frame-0
- fVec = bVec.MScaleVectors(Scale=-1.0, Mode=2)
- MCompensate Frame-1 using fVec to get approximation of unknown Frame-2 (only need one set of vectors for MCompensate)

There are a few more vector tools I might add, when I find the time:
- Converting a set of vectors (b3,b2,b1,f1,f2,f3) to an ordinary clip, which can be saved and reused. This would be useful for a *very* slow script I'm working on that needs to operate in several passes.
- Statistics on vectors for a frame (faster than analysing MMask clips)
- Combining vectors (V' = A.V1 + B.V2), could be useful combined with above
- Relating sequential vectors (by pixel), i.e. what is the motion of the target of this pixel, next frame? Feels useful...
- etc.

pbristow
10th May 2011, 01:52
when you reverse or lengthen the vectors you need to ensure they don't point outside the frame.

Actually, that's exactly the case that interests me. If the *full length* vector points outside the frame, that doesn't mean the vector isn't useful, as you may only want to interpolate to a point in time, say, 50% of the way between frame N and frame N+1, based on previous motion in frames N-1 and N. The case that interests me especially at the moment is rate-doubling a scene where a person falls out of shot between two frames. With current MVtools methods, the frame created in between the last appearance of the falling body and the first frame where it's absent has a kind of shrivelled, distorted & faded version of the falling body left in the place where it was last seen. Now, some distortion of the body probably can't be avoided; but what matters is that it should *not* appear frozen space, but continue to fall along its original trajectory.

I'd suggest that you allow switching between two or more strategies for "beyond the frame" vectors, e.g.:
1. Zero them, and give them zero confidence ratings (the "no tolerance" option! )
2. Truncate them to the edge of the frame, and give them low confidence ratings (the "right direction, wrong speed" option);
3. Let them point to where they naturally would (i.e. don't modify them because of the frame boundary), and calculate confidence ratings as you would for any other vector (the "this is the truth, whether you can handle it or not" option. :) ).

The idea with option 2 is to avoid any problems if whatever filter the vectors are passed on to (e.g., MFlowInterp or MCompensate) can't cope with any vector that points beyond the frame: You can still at least indicate that the object/block keeps moving in that general direction, even if the rate of movement is reduced.

Option 3 will only be useful if the following filter will accept vectors regardless of where they point, and then handle them appropriately... Which I *hope* MFlowInterp does, or at least can be made to with a slight modification. :)

Jeremy Duncan
13th May 2011, 10:03
What would be cool is if there was a MSCDetection built into mflowfps or mblockfps so the thscd could be tweaked on a single colored screen. So the MSCDetection would be off by default and could be activated by a parameter. I find having the thscd1 and thscd2 properly calibrated to be very important to frame doubling code.

SubJunk
6th June 2011, 04:48
I wonder if it would be possible for the hpad and vpad parameters to be used without causing warping on the edges.
Hpad and vpad are cool and they work, but the tradeoff is that the borders are sometimes "pulled" in and the only way to stop that is to set hpad and vpad to 0.
example (http://imageshack.us/photo/my-images/101/borders.jpg/)

Didée
6th June 2011, 10:48
the tradeoff is that the borders are sometimes "pulled" in and the only way to stop that is to set hpad and vpad to 0.
That's basically the reason why padding is used in the first place ... to have "something" beyond the borders.

If you don't like, you don't use. That easy. No need to change anything.

SubJunk
6th June 2011, 10:52
I'm referring to the black streaks that come in from the edges, most notably on the right side of the example image.

Didée
6th June 2011, 11:42
Yes sure. The framing of the source is so that the very-rightmost pixel column is halfway shaded to black. So that's what padding creates.

If the very borders are not clean, then padding is evil. Either you make sure that the borders are clean, or you don't use padding. That simple.

I mean, I don't quite see what you actually want to suggest here. The padding does exactly what it's meant to do. If the image data is not suited, that's another problem.

SubJunk
6th June 2011, 22:32
Ah I see, so you're saying the source is under-cropped. I think you're right. DeathTheSheep made that example and I should have checked more thoroughly.

Dogway
29th June 2011, 08:12
How can I create a mask with mmask using all the vectors mdegrain3 needs?
My purpose is to use a spatial denoiser where mdegrain 3 is not denoising.

Didée
29th June 2011, 10:05
Here's the brief answer to your brief question. :)


The slow+long way.

o = last
spat = o.SpatialNR()

sup = o.msuper()

bv3 = sup.manalyse( ... )
bv2 = ...
bv1 = ...
fv1 = ...
fv2 = ...
fv3 = ...

SADbv3 = o.MMask(bv3,kind=1, ... )
SADbv2 = o.MMask(bv2,kind=1, ... )
SADbv1 = o.MMask(bv1,kind=1, ... )
SADfv1 = o.MMask(fv1,kind=1, ... )
SADfv2 = o.MMask(fv2,kind=1, ... )
SADfv3 = o.MMask(fv3,kind=1, ... )

SAD6 = Average(SADbv3,1./6,SADbv2,1./6,SADbv1,1./6,SADfv1,1./6,SADfv2,1./6,SADfv3,1./6)

MDG3 = o.MDegrain3(sup,bv1,fv1, ... )

MDG3.mt_merge(spat,SAD6,U=3,V=3)


The faster+shorter way.

o = last
spat = o.SpatialNR()

sup = o.msuper()

bv3 = sup.manalyse(...
bv2 = ...
bv1 = ...
fv1 = ...
fv2 = ...
fv3 = ...

spat.MDegrain3(sup,bv1,fv1, ...)
In this 2nd script, spatial denoising has a little more overall weight. Most probably this is tolerable. If not, it can be compensated e.g. like so:

o = last
spat = o.SpatialNR()

enh = o.mt_adddiff(mt_makediff(o,spat,U=3,V=3),U=3,V=3).merge(o,0.75)

sup = o.msuper()
sup2 = enh.msuper(levels=1)

bv3 = sup.manalyse(...
bv2 = ...
bv1 = ...
fv1 = ...
fv2 = ...
fv3 = ...

spat.MDegrain3(sup2,bv1,fv1, ...)

Any of these script variants can be modified to do the motion search on the "spat" clip. Depending on the kind & strength of the source's noise, this could be beneficial.

Dogway
29th June 2011, 10:16
Quite straight forward! Thanks for "reading" me, you know I meant "where mdegrain3 is not targeting to denoise".
I got a bit paranoid when I saw the mask, not sure if it was going to work in mt_merge, but people used that way so...

I didn't quite understand your third example, but the fist one is what I had in mind. Thanky thanks again.

Didée
29th June 2011, 10:45
The extreme cases for th 2nd script:

1) A block has high SAD in all 6 wing frames (no motion match at all)
==> 100% spatial NR + 0% temporal NR

2) A block has zero SAD in all 6 wing frames (totally perfect match)
==> 14.3% spatial NR + 85.7% temporal NR (1/7 + 6/7)


In script #3, the wing frames are sharpened by the inverse of the spatial denoiser, to compensate for the residual spatial denoising. (25% sharpening was used as an estimated average. The mentioned 14% are an unrealistic corner case, the compensated blocks will always have a non-zero SAD.)

StainlessS
17th July 2011, 13:14
MVTools v2.5.11.2

Other MVTools functions return planar YUY2 when given them
as source, however MFlowInter returns Interleaved, surely not right.

Is this a bug or am I doing something stupid ?

ColorBars().ConvertToYUY2()
Interleaved2planar() # Planar YUY2
super=Last.MSuper(planar=true)
bv = super.MAnalyse(isb = true, truemotion=true,delta = 2)
fv = super.MAnalyse(isb = false, truemotion=true,delta = 2)
Last.MFlowInter(super,bv,fv,planar=true,time=50.0,ml=70.0) # This returns Interleaved YUY2 ??????
#Mshow(super,fv,planar=true) # This returns Planar YUY2
Planar2Interleaved() # Required for Mshow, PROBLEM for MFlowInter
return last

Mini-Me
22nd July 2011, 23:00
I've come across some suboptimal behavior regarding global motion estimation: I'm using MVTools and Depan to match the height of two analog captures. In between scenes, I have some fades to black, and there are several seconds of frames that consist solely of a black screen with a bright white timestamp. The problem is, when most of the picture fades away, the motion estimation goes haywire, and the "matched" clip has the timestamp jumping all over the place. Frames with an average luma below 16 are especially bad.

From my understanding, the issue involves the way the global motion estimation works: The black blocks are totally dominating the global motion estimation, so the ones with the timestamp - the ones that matter - are just being ignored. The thing is, practically ANY vector would be acceptable for the black blocks, yet MVTools is treating these blocks as though its particular choice of vector is actually important.

If a block has a large number of viable motion vectors (e.g. similar SAD), is there a way to reduce its influence on global motion estimation? Or, the average luma of a block is in the superblack range (or perhaps extremely close to the average luma value for the frame), is there a way to reduce its influence on global estimation?

StainlessS
29th July 2011, 01:56
Can someone please verify if the post 2 previous to this is a bug,
the example given is not supposed to do anything exciting or even sensible,
only to show whether the correct colorspace is returned.

cretindesalpes
10th September 2011, 13:47
Yes I confirm this bug (a typo in the variable init). I fixed it in MVTools 2.5.12.0 from my Dither package, along with a few other additions.

Dogway
15th September 2011, 09:30
1.A few questions here, Im trying to implement a subpixel interpolated clip for the pelclip option of msuper in a function. As I read on the mvtools examples and the interframe thread the most common way to do this is using EEDI2 as follows:
EEDI2(field=1).Spline36Resize(pel*last.width, pel*last.height, src_left=pel*0.125)
It looks ok tho, but eedi2 is a bit old and not very optimized for MT. Im not very fond on the behind the scenes behaviour but is it possible to do this using instead nnedi3?
I tried using nnedi3(field=1) but results are quite different, I read that it is not the analog behaviour of EEDI2(field=1), and it should be nnedi3_rpow2() (?). So if I then were to use nnedi3_rpow2 how do I fix the plane placement mismatch?


2.Another issue is about the internal masking of mdegrain.
I used the suggested code by Didée a few times but, it doesn't match with the mdegrain counterpart with same parameters. Could it be the weightings are not even?

blksize=8
overlap=4
asuper=MSuper(pel=2,sharp=2,hpad=blksize, vpad=blksize,chroma=true)
b3v = MAnalyse(asuper, isb=true, delta=3, blksize=blksize, overlap=overlap,chroma=true)
b2v = MAnalyse(asuper, isb=true, delta=2, blksize=blksize, overlap=overlap,chroma=true)
b1v = MAnalyse(asuper, isb=true, delta=1, blksize=blksize, overlap=overlap,chroma=true)
f1v = MAnalyse(asuper, delta=1, blksize=blksize, overlap=overlap,chroma=true)
f2v = MAnalyse(asuper, delta=2, blksize=blksize, overlap=overlap,chroma=true)
f3v = MAnalyse(asuper, delta=3, blksize=blksize, overlap=overlap,chroma=true)
SADbv3 = MMask(b3v,kind=1)
SADbv2 = MMask(b2v,kind=1)
SADbv1 = MMask(b1v,kind=1)
SADfv1 = MMask(f1v,kind=1)
SADfv2 = MMask(f2v,kind=1)
SADfv3 = MMask(f3v,kind=1)
SAD6 = average(SADbv3,1./6,SADbv2,1./6,SADbv1,1./6,SADfv1,1./6,SADfv2,1./6,SADfv3,1./6)
mt_merge(mdegrain3(asuper, b1v, f1v, b2v, f2v, b3v, f3v,plane=0),last,sad6)
http://img36.imageshack.us/img36/3317/mmask.th.png (http://img36.imageshack.us/img36/3317/mmask.png) http://img714.imageshack.us/img714/7264/mdegrain.th.png (http://img714.imageshack.us/img714/7264/mdegrain.png)

3.Also I have been long wondering about Depan. It looks like DepanStabilize is for global motion (shaking) of the overall frame. But then what is Depan() for? Can I with Depan() stabilize local shaking? if so would it be better to use MDepan instead of DepanEstimate for mdata, as it uses local blocks for the motion estimation? I should also note that both filters (depan, and depanstabilize) renders the frame with a slight tint of green.

4.And a bit offtopic but what is Eval() useful for (in a simple scenario)? I don't quite understand the documentation. Normally I find that I want to set a string (that outputs a clip) into a variable , so my variable doesn't store a clip, but only some letters. The problem comes when I want to use that code and take it out from the string so I can reuse it and link it to another code/functions. Is this possible?

Gavino
15th September 2011, 10:31
Im trying to implement a subpixel interpolated clip for the pelclip option of msuper in a function. As I read on the mvtools examples and the interframe thread the most common way to do this is using EEDI2 as follows:
EEDI2(field=1).Spline36Resize(pel*last.width, pel*last.height, src_left=pel*0.125)
It looks ok tho, but eedi2 is a bit old and not very optimized for MT. Im not very fond on the behind the scenes behaviour but is it possible to do this using instead nnedi3?
I tried using nnedi3(field=1) but results are quite different, I read that it is not the analog behaviour of EEDI2(field=1), and it should be nnedi3_rpow2() (?). So if I then were to use nnedi3_rpow2 how do I fix the plane placement mismatch?
With nnedi3, you have to add dh=true.
However, it is simpler to use nnedi3_rpow2 - this does both the vertical and horizontal resizing in one call and also shifts chroma correctly:
nnedi3_rpow2(rfactor=pel)

The code you quoted is correct only for pel=2.
For pel=4, the offset is incorrect (should be 0.375) and in any case you would have to use EEDI2 twice, not once.

what is Eval() useful for (in a simple scenario)? I don't quite understand the documentation. Normally I find that I want to set a string (that outputs a clip) into a variable , so my variable doesn't store a clip, but only some letters. The problem comes when I want to use that code and take it out from the string so I can reuse it and link it to another code/functions. Is this possible?
Eval takes a string and 'executes' it as an Avisynth command, so if your variable v contains "Blur(0.5)", then Eval(v) will call Blur(0.5). It is useful when you need to build up a command dynamically or execute an arbitrary command (eg passed in as a function parameter).

Didée
15th September 2011, 10:32
I used the suggested code by Didée a few times but, it doesn't match with the mdegrain counterpart with same parameters. Could it be the weightings are not even?

In short: the suggested code is correct, but you are not doing what you originally asked for.

A few posts above, you had asked about using a spatial denoiser in those places where MDegrain does not denoise. But in the script you posted now, you're not using any spatial denoising. Instead, you're merging the original base clip via the SAD6 mask. Now, with this SAD6 masking, you're weighting-in the not-denoised original in those places where MDegrain already had reduced its processing strength. This is equivalent to squaring the normalized SAD weighting - in places where a simple MDegrain would achieve 40% denoising, you will now get only 16% denoising (0.4*0.4=0.16).

The obvious question is: What do you want to do, after all?

Dogway
15th September 2011, 11:12
@Didée: I guess I only want the mask mvtools uses, so I can use it in masktools for whatever task. I'm not sure to understand your reasoning. My intention was always to get the mask from the original/unprocessed clip, spatially denoise the (original) clip, and merge over the temporal denoised (original) clip. Does it make a difference which one do I merge over?. Its basically the first example of your post.

Thanks Gavino, those shift numbers are mysteries to me. I will test nnedi3_rpow2 results, but Im almost all over, speed is a plus. So for example cshift=spline64 is ok right?

I see, looks like eval() doesn't solve my main issue. I will look for more uses in functions. What I normally face up is something like:

var = blur(0.5)
var.sharpen()

Here var is storing a clip, and that hits performance so it would be good to convert clip variables into strings that can be reused.

Gavino
15th September 2011, 11:28
Thanks Gavino, those shift numbers are mysteries to me. I will test nnedi3_rpow2 results, but Im almost all over, speed is a plus. So for example cshift=spline64 is ok right?
When creating a 'pel' clip, you don't want to use cshift with nnedi3_rpow2, since you need to keep the original pixel at (0,0).

I see, looks like eval() doesn't solve my main issue. I will look for more uses in functions. What I normally face up is something like:

var = blur(0.5)
var.sharpen()

Here var is storing a clip, and that hits performance so it would be good to convert clip variables into strings that can be reused.
I don't understand your problem - there is no performance hit when using clip variables (blur is only called once).

Dogway
15th September 2011, 11:33
But wouldnt it be detrimental if I had 50 or more clip variables? isn't it like storing clips in framebuffer?

Didée, I think I understand now. mdegrain is already using vectors for denoising, and I'm applying again a mask over merging back the original clip, reducing the effect in the grey mask areas. My original intention was to mdegrain with no mask/vectors, because these would be used as a mask in masktools...

StainlessS
15th September 2011, 11:48
Yes I confirm this bug (a typo in the variable init). I fixed it in MVTools 2.5.12.0 from my Dither package, along with a few other additions.

Thanks for your confirmation, will snatch a copy of your Dither.
:thanks:

Gavino
15th September 2011, 12:03
But wouldnt it be detrimental if I had 50 or more clip variables? isn't it like storing clips in framebuffer?
No, only a 'pointer' to an object representing the clip is stored, not the actual frames, which are fetched only on demand by later filters.

Fizick
19th September 2011, 17:54
MVTools v2.5.11.2

Other MVTools functions return planar YUY2 when given them
as source, however MFlowInter returns Interleaved, surely not right.

Is this a bug or am I doing something stupid ?



Its a bug ( (a typo in the variable init - thanks cretindesalpes).
Fixed today in v2.5.11.3

Dogway
12th October 2011, 17:46
What's the deal with pel=2 and assumeframebased()? I read people use it for more speed but documentation only states it is necessary when feeding field based material.

This is equivalent to squaring the normalized SAD weighting - in places where a simple MDegrain would achieve 40% denoising, you will now get only 16% denoising (0.4*0.4=0.16)

Then couldn't you just revert the effect? At the mask level, where mdegrain is going to denoise 40%, that is value 102 in the mask, I would get 16% of denoising. So by modifying the mask and converting value 102 to 40.8 I can get back to 40% of denoising

sad6.mt_lut("x x 255 / *")

In theory I mean, because mdegrain denoising is limited to the internal mask that is already passed, so we can not get back the denoising we have just lost. What could be done is make the internal mask a more flexible element where masktools can work with, or in the other hand by now find a correlation of the above code and try to match in the internal mask creation (through thSAD, lambda, etc)

Dragonshadow
27th October 2011, 23:52
Is there a way to increase the performance of this, or is my flow entirely wrong? :


AVISource("intermediary.avi", audio=false)

ConvertToYV12()

super = MSuper(pel=4)
backward_vectors = MAnalyse(super, search = 3, isb = true, lsad = 1500, lambda=1500, truemotion=true)
forward_vectors = MAnalyse(super, search = 3, isb = false, lsad = 1500, lambda=1500, truemotion=true)
MFlowBlur(super, backward_vectors, forward_vectors, blur=200, prec=1)

super2 = MSuper(pel=4)
backward_vectors2 = MAnalyse(super2, search = 3, isb = true, lsad = 1500, lambda=1500, truemotion=true)
forward_vectors2 = MAnalyse(super2, search = 3, isb = false, lsad = 1500, lambda=1500, truemotion=true)
MFlowFPS(super2, backward_vectors2, forward_vectors2, num=30000, den=1001)


I'm using it to take a 60p source, add motion estimated blur, and smoothly reduce the framerate to 29.97. Problem is even on my i7 I only render at about 0.14 fps (Rendering as x264 with medium preset, crf 18, high profile unrestricted). This makes a 20 minute video take upwards of a day and a half to render, and that's unacceptable.

It may be worthy to note I'm using MeGUI 2050 x86, and if my script looks funny, that's because I barely understand what I'm doing with it.

Redsandro
28th October 2011, 00:33
I experienced similar slow times, but I thought that was pretty normal. After all, compensating is a slow process and MflowBlur creates "many copies of partially compensated pixels at intermediate time moments in some blurring interval around current frame".

gyth
28th October 2011, 02:56
You aren't interpolating any frames, so use SelectEven instead of MFlowFPS.

Dragonshadow
28th October 2011, 08:04
You aren't interpolating any frames, so use SelectEven instead of MFlowFPS.

Wouldn't that end up with a worse quality, since I'm not blending the blended frames together? (Or are you saying decimate it first, THEN blur? That wouldn't make sense either)

Also, how would I selecteven to 29.97 from 60p? It's literally 60fps, not 59.94.

Redsandro
28th October 2011, 17:04
Playback 30fps at 99,9% speed? Reflowing the entire video will definitely throw away valuable information per frame, and flow predictions aren't perfect.

Dragonshadow
28th October 2011, 17:25
Playback 30fps at 99,9% speed? Reflowing the entire video will definitely throw away valuable information per frame, and flow predictions aren't perfect.

I don't understand what you mean, throwing away information? I'm going to be uploading this to youtube, and last I recall they convert everything to 29.97. If I do it myself ahead of time then I avoid possible encoding and audio sync issues. If mflowfps isn't the best way to reduce from 60fps to 29.97fps, then what is? (Likewise, if mflowblur isn't the best way to add motion estimated blur, what is?)

Redsandro
28th October 2011, 17:49
I don't understand what you mean, throwing away information?
The frames in your original movie contain real data. If you reflow the entire video, regenerate every frame with motion vector distorted replacements of actual frames, you're throwing away real information and replacing it with an error-prone substitute.

To convert 24 fps cinema movies to 25 fps DVD's, the studio's just play the movies 4% faster instead of messing with the frames. To go from 30 fps to 29.97, you could to the same and go 1% slower in stead of regenerating the frames.

I'm going to be uploading this to youtube, and last I recall they convert everything to 29.97.

Not sure, but I thought youtube converts everything above 30fps to 29,97 fps. You could just SelectEven() and upload to youtube as private video to see if the result is indeed clean 30fps.

StainlessS
28th October 2011, 19:00
Small point but 30FPS to 29.97FPS is a reduction of 0.1% not 1.0%.

gyth
28th October 2011, 19:17
If mflowfps isn't the best way to reduce from 60fps to 29.97fps, then what is?
SelectEven()
AssumeFPS("ntsc_video", sync_audio=true)

(Likewise, if mflowblur isn't the best way to add motion estimated blur, what is?)
It is probably the best way. But are you sure you want motion blur?
Be sure to try with/without to make sure it is an effect you want.

Redsandro
28th October 2011, 20:20
Small point but 30FPS to 29.97FPS is a reduction of 0.1% not 1.0%.

:D

That's probably a good point.

SelectEven()
AssumeFPS("ntsc_video", sync_audio=true)

That's it. That's how they do it in Hollywood. ;)

are you sure you want motion blur?
Be sure to try with/without to make sure it is an effect you want.

Indeed. Without, you get a more cinema-like shutter effect which is actually kinda popular amongst cinematographers. I remember HDV camera's were hip when they supported 25p instead of 50i, because of the shutter effect.

Dragonshadow
31st October 2011, 10:57
What exactly is the "temporal" flag actually used for with MAnalyse? I'm not sure if I need it or not for blending, and it's the only thing stopping me from going multi-threaded.

Right now I'm trying to figure out what's causing my audio to be out of sync no matter what I do. I'm using megui so the audio is encoded with nero aac encoder before the video is encoded.

Boulder
3rd November 2011, 17:44
Does MDegrainx require levels=0 in MSuper or will levels=1 do?

Didée
3rd November 2011, 17:55
Mdegrain does not require any specific levels in Msuper. But MAnalyse does.

Therefore

- if you use the same 'super' clip for both MAnalyse and MDegrain, then you need all levels. (Or as much as you want to be used in MAnalyse.)

- if you use separate 'super' clips for MAnalyse and MDegrain, then you need all (or as much as...) levels for the super clip of MAnalyse, but can use minimal levels (1) for the super clip of MDegrain.

Boulder
5th November 2011, 17:15
A small bug noticed: MShow doesn't support 32-pixel blocks. It shows only green borders around the video.

Boulder
5th November 2011, 17:54
Seems more like there is something wrong with 32-pixel blocks.

Using this script:
DGSource("2001.dgi")
Crop(0,112,-0,-112,true)

prefilt=FFT3DFilter(sigma=3,bt=3)
superanalyse=MSuper(prefilt,pel=1)
supermdg=MSuper(pel=1,levels=1)
fv1=MAnalyse(superanalyse,blksize=32,dct=5,isb=false,delta=1)
bv1=MAnalyse(superanalyse,blksize=32,dct=5,isb=true,delta=1)

MDegrain1(supermdg,bv1,fv1,thsad=200)

I get this result: http://img97.imageshack.us/img97/4966/2001blocksize32.th.png (http://imageshack.us/photo/my-images/97/2001blocksize32.png/)

The next frame is overlaid there. If I use blksize=16, there's no problem. The issue occurs at scene changes only.

cretindesalpes
6th November 2011, 11:38
Indeed, it looks like the SATD calculation (at least dct=5 and 6, maybe the other SATD modes too) goes totally wrong when blksize=32. I'll take a closer look at this issue soon.

Boulder
6th November 2011, 17:30
While testing various settings, I noticed that I have to use the same pel for the super clips used in MAnalyse and MDegrain (otherwise I only get a crash). Is this intentional?

cretindesalpes
6th November 2011, 19:34
Vectors must have been generated with the same pel setting as the superclip used in the utility functions (MDegrain, MCompensate, etc). Anyway it should definitely output an error message instead of crashing in case of inconsistency.

cretindesalpes
9th November 2011, 23:37
Seems more like there is something wrong with 32-pixel blocks. Using this script:
[...]
fv1=MAnalyse(superanalyse,blksize=32,dct=5,isb=false,delta=1)

There was no implementation for SATD with blksize > 16, the blocks were all evaluated to SAD = 0. I added an approximation in the modified MVTools 2.5.13.1 from the Dither package (http://forum.doom9.org/showthread.php?p=1386559#post1386559). I also added pel consistency checks in the functions using a superclip and one or more motion vector clips.

Boulder
10th November 2011, 05:05
Thanks, I'll test the new build.

Boulder
11th November 2011, 04:38
The new build seems to work fine, thanks :)

Do you have any plans to improve MVTools further, like making it possible to use blocksize 24? -Vit- created the plugin which could be used to scale vectors but it would be nice to have native support for something between sizes 16 and 32.

ajp_anton
11th November 2011, 18:20
I'm trying to use the motion blur effect in this plugin to convert 60fps video game footage into Youtube-friendly 30fps.
But I'm not really satisfied with the result. No matter how short I make the "time interval", the high-detailed slow-moving background gets totally blurred.

There doesn't seem to be anything wrong with the motion vectors. Is it possible to skip all vectors that are shorter than some threshold? That way I can blur any fast-moving objects, while keeping the detailed background. Or is this possible somehow with MMask?

-Vit-
11th November 2011, 19:47
QTGMC will do that kind of motion blur for you (without doing any other processing):

QTGMC( "Slower", InputType=1, fpsDivisor=2, \
ShutterBlur=2, ShutterAngleSrc=0, ShutterAngleOut=90, SBlurLimit=6, \
TR0=0, TR1=0, TR2=0, Rep0=0, Rep2=0, SMode=0, SLMode=0, Sbb=0, NoiseProcess=0, SourceMatch=0, Lossless=0 )

1st line selects motion analysis quality, sets progressive input and reduces to 1/2 rate (SelectEven equivalent)
2nd line is the motion blur settings. Game source likely has no blur so ShutterAngleSrc = 0, ShutterAngleOut sets output blur level (0-360), SBlurLimit does what you want, will not blur regions moving slower than this value pixels per frame
3rd line switches off everything else in QTGMC

___

Or if you want to do it yourself use MMask, basic idea below (assuming you will add a SelectEven() before or after):

clip=last
... # Calculate super clips, vectors fVec1, bVec1...
blurClip = MFlowBlur( ... )

BlurLimit = 6 # Blocks moving less than BlurLimit pixels per frame will not be blurred
motionMask = MMask( clip, bVec1, kind=0, ml=BlurLimit )
output = mt_merge( clip, blurClip, motionMask, U=3,V=3 )

gyth
11th November 2011, 20:09
Have you tried just SelectEven()? Many people prefer the cinematic shuttering to soap-opera smoothness.

super = MSuper()
backward_vectors = MAnalyse(super, isb = true)
forward_vectors = MAnalyse(super, isb = false)
blurred=MFlowBlur(super, backward_vectors, forward_vectors, blur=45).SelectEven()

shuttered=SelectEven()

mask=MMask(forward_vectors, kind=0, ml=10)
overlay(blurred,shuttered,mask=mask)

P.S. Which video game? Older games sometimes have blinking effects which can be more complicated to deal with.

-Vit-
11th November 2011, 21:06
That's exactly what the QTGMC line and the manual code above does (I assumed a pre or post SelectEven in the manual approach).

ajp_anton
12th November 2011, 05:52
I've already tried merging the blurred and non-blurred images with a MMask(kind=0,...) mask, and didn't like the results.

An object moving over a non-moving background will be surrounded by zeroes in the mask. The object will be blurred within the object itself (where the mask is non-zero), but its movement over the static background won't be blurred.

(The video game is Super Smash Bros Melee. It looks horrible after a simple SelectEven because it's a very fast-moving game. Many people have liked the motion blur I've been using, but others including myself hate how it completely destroys the detailed slow-moving backgrounds)

-Vit-
12th November 2011, 07:29
Perhaps combine forward and backward masks. And also the backwards mask from the previous frame and the forward mask from the next frame...? [It's the non-intuitive way round...]
Or do a MFlowBlur on the mask itself!

gyth
12th November 2011, 07:48
c = last

# blur == amount of blur, percentage
# 200 - fully open shutter (doubled because of SelectEven)
# 0 - no blur (ie SelectEven)
blur = 50

# motion == what blurs
# 0 - everything blurred
# small values - small motion treated as static
# large values - only high motion treated as moving
# 255 - nothing blurred (ie SelectEven)
motion = 10

super = MSuper(c)
b_vec = MAnalyse(super, isb = true)
f_vec = MAnalyse(super, isb = false)
blurd = MFlowBlur(c, super, b_vec, f_vec, blur=blur)

# hopefully looking forward and backwards will help the problem
# you were having with occlusion
fmask = MMask(c, f_vec, kind=0, ml=motion)
bmask = MMask(c, b_vec, kind=0, ml=motion)
mask = mt_logic(fmask, bmask, mode="or", U=3, V=3)

output = mt_merge(c, blurd, mask, U=3, V=3)

output.SelectEven()

ajp_anton
12th November 2011, 14:23
Combining masks doesn't work if the object moves more than its size for each frame, because then the object's mask will still be completely surrounded by zero-motion.
But also blurring the mask sounds very interesting! Will try that soon. Thanks.

gyth
12th November 2011, 18:14
Here is another option, blending to cause ghosting.
# http://ajpanton.se/ssbm/ajp_anton/TAS/
ffvideosource("DrMario_AR_13.08.mp4")

c = last.assumefps("ntsc_double")

# blur == amount of blur, percentage
# 200 - fully open shutter (doubled because of SelectEven)
# 0 - no blur (ie SelectEven)
blur = 50

# motion == what blurs
# 0 - everything blurred
# small values - small motion treated as static
# large values - only high motion treated as moving
# 255 - nothing blurred (ie SelectEven)
motion = 10

super = MSuper(c.blur(1.5))
b_vec = MAnalyse(super, isb = true)
f_vec = MAnalyse(super, isb = false)
#blurd = MFlowBlur(c, super, b_vec, f_vec, blur=blur)

blur2 = convertfps("ntsc_quad").SelectOdd()

fmask = MMask(c, f_vec, kind=0, ml=motion).trim(1,0)
bmask = MMask(c, b_vec, kind=0, ml=motion)
mask = mt_logic(fmask, bmask, mode="or", U=3, V=3)

output = mt_merge(c, blur2, mask, U=3, V=3)

output.SelectEven()
test (http://www.mediafire.com/?3u7t10s1eu8t26s) = stackhorizontal(c, output.selecteven.changefps(60))

cretindesalpes
14th November 2011, 23:27
Do you have any plans to improve MVTools further, like making it possible to use blocksize 24?
Adding blksize=24 looks a bit complicated for now. There are zillions of lines of code to write or adapt, this would be a pretty long task. I'm currently trying to make MVTools natively multithreaded, at least the MAnalyse part, and haven't done any significant progress so far by lack of time. However I am now more familiar with the code and know more accurately what to do and how. I also almost finished writing something allowing to safely load and save the vector clips. It will be useful to test filters quickly: generate the vectors once for a given clip, then reload them during the filtering pass for quick access. The downside is the size of the vector file which is really huge, like a lossless clip.

-Vit-
15th November 2011, 01:48
I also almost finished writing something allowing to safely load and save the vector clips. It will be useful to test filters quickly: generate the vectors once for a given clip, then reload them during the filtering pass for quick access. The downside is the size of the vector file which is really huge, like a lossless clip.
I wrote a plugin for my own testing purposes to do that. It also contains my vector scaling functions, which have been extended with various esoteric modes:
MVExtras 0.21 (http://www.mediafire.com/?xf0odqsd3z0glcc)
Contains source and some instructions.

The vector storage combines as many vector clips as you want into a single encodable clip, which you then save out lossless. Read it back in as a source and you can extract the vector clips you want. Requires a lossless RGBA encoder - I only know of Lagarith. May be better to save to a custom file format, but I needed some compression and this was the quickest way. Definitely want some kind of compression for this otherwise the vector files become unusably large.

Anyway, it might be relevant to whatever you add to MVTools. You might consider adding some vector scaling functions too, they are quite useful and MVTools used to contain something similar.

cretindesalpes
15th November 2011, 08:40
I wrote a plugin for my own testing purposes to do that. It also contains my vector scaling functions
Oh! I was aware of the scaling function, but didn't know for the store/restore vectors. I'll definitely check how to integrate your modifications to mine.

Boulder
15th November 2011, 18:26
I wrote a plugin for my own testing purposes to do that. It also contains my vector scaling functions, which have been extended with various esoteric modes:
MVExtras 0.21 (http://www.mediafire.com/?xf0odqsd3z0glcc)
Contains source and some instructions.
Have you made any extensive tests with scaled vectors? I noticed that the feature tends to produce much longer vectors, I didn't do any serious comparison yet.

-Vit-
15th November 2011, 19:25
Have you made any extensive tests with scaled vectors? I noticed that the feature tends to produce much longer vectors, I didn't do any serious comparison yet.
I have tested, but not extensively (haven't had time for any serious avisynth development for months). Clearly scaled vectors analyzed from a half-sized frame will not be exactly the same as vectors measured from the full size-frame due to differences in MVAnalyze working at different blocksizes/resolutions. I find scaled vectors a little less precise, as you might expect, but I wouldn't say I've observed any artificial lengthening (the 2^ scaling is very simple in its implementation).

Can't remember which version of the vector scaling I previously released (it was not intended for release before the next QTGMC, which uses it). The version above has had a number of changes, maybe it resolves your observation.

Boulder
15th November 2011, 20:28
Here's two sample frames where you can see the difference quite clearly:

http://img38.imageshack.us/img38/5058/normal1j.png
http://img3.imageshack.us/img3/8531/scaled1.png

http://img832.imageshack.us/img832/9183/normal2k.png
http://img853.imageshack.us/img853/5264/scaled2.png

I used this script to compare:
DGSource("batman1.dgi")
clip=last
clipScaled = clip.BicubicResize( clip.Width()/2, clip.Height()/2 )
superScaled = clipScaled.MSuper( pel=2, hpad=0,vpad=0 )
bVecScaled = superScaled.MAnalyse( blksize=8, isb=true, overlap=4 )
fVecScaled = superScaled.MAnalyse( blksize=8, isb=false, overlap=4 )
bVec = bVecScaled.MScaleVectors( 2 )
fVec = fVecScaled.MScaleVectors( 2 )
supersc = clip.MSuper( pel=2, hpad=0,vpad=0 )
fvecnormal = supersc.MAnalyse(blksize=16,overlap=8,isb=false)
bvecnormal = supersc.MAnalyse(blksize=16,overlap=8,isb=true)
interleave(MShow(supersc,fvecnormal),MShow(supersc,fvec))

-Vit-
15th November 2011, 21:23
That looks like differences due to the analysis blocksize - it's mainly affecting blocks with little detail, which can be matched quite freely. More freely when the blocksize is small. You should compare the vectors before and after they were scaled - that's what the plugin does and so those clips should be equivalent. The plugin cannot guarantee that a search with a larger image/blocksize will be identical to a search with a smaller image/blocksize - that's down to the operation of MVTools. Although in practice those searches are similar enough for some purposes. Vector scaling will be used for faster QTGMC presets on HD material.

Change the last line in your script to show original vectors, then small image vectors, then scaled vectors:
interleave(MShow(supersc,fvecnormal), MShow(superScaled,fVecScaled).Spline36Resize(clip.Width(), clip.Height()), MShow(supersc,fvec))

Boulder
16th November 2011, 17:50
I did some more testing with that rather noisy HD clip and it seems that I need to lower the denoising settings quite a bit to not oversmooth the image. Regarding this (and kind of out of topic here), is there a quick way to control how much denoising is done (like a percent of full effect)? Using limit=1 in MDegrain1 is still too much in some parts of the image.

EDIT: is it ok to use the unscaled clip as the pelclip (if pel=2) in the scaled MSuper call?

Didée
16th November 2011, 21:02
If limit=1 is still too much, then you should stop doing any denoising. :D

Or, maybe, sth like the "shift-back-by-one" thingy:


source = whatever
denoised = source.denoise() # MDegrain or whatever
mt_lutxy(denoised,source,"x y < x 1 + x y > x 1 - x ? ?",U=2,V=2) # but keep chroma. Use U=V=3 to reduce chroma NR as well


In plain english: set up the denoiser, let it do what it does, then reduce all achieved differences by 1.

This way you can often achive a reduced, but still-good amount of denoising (resp. compressibility gain), but keep more of the faint shadings that make up the fidelity.

More often than not, this turns out more "efficient", compared to reduce & reduce more and evenmore the denoiser, to the point where it hardly is doing anything anymore.

-Vit-
16th November 2011, 21:04
EDIT: is it ok to use the unscaled clip as the pelclip (if pel=2) in the scaled MSuper call?
To satisfy the requirements that MVTools has for the pelclip, you would have to PointResize to get the scaled down version of your clip. Then using the original clip as pelclip should be OK and is probably a good idea. However, I haven't tested it. A couple of thoughts:
- Whilst using PointResize feels "wrong" - throwing away half the pixels for the search clip - the very fact you're then providing those missing pixels in the pelclip may well mitigate any issues.
- This will clearly retain more detail for MVTools to work with. But detail is a double-edged sword for MVTools - not enough and the motion search has nothing to grip on to, too much detail (esp. high contrast) and good SAD matches are hard to find. When using interpolation to downscale & create the subpel clip you're performing some kind of pre-filter, albeit not an especially tailored one.
- I don't know the behavior of MVTools if you don't satisfy the requirements for pelclip...?
- There might be some half-pixel shift issues in doing this, which may (or may not) have some impact of the resultant vectors. Gut feeling says the effect will be minor since any shift would affect vector source and target. Testing needed.

cretindesalpes
16th November 2011, 22:14
- I don't know the behavior of MVTools if you don't satisfy the requirements for pelclip...?
Actually the MSuper hides a small data structure in the num_audio_samples field (see SuperParams64Bits in the source code), and if the superclip is resized, some of these variables should be changed accordingly, like nHeight and probably nHPad and nVPad. So I doubt it will work as expected.

Edit: possibly I misunderstood what Boulder wanted to do, please correct me if I'm wrong.

-Vit-
16th November 2011, 22:23
Actually the MSuper hides a small data structure in the num_audio_samples field (see SuperParams64Bits in the source code), and if the superclip is resized, some of these variables should be changed accordingly, like nHeight and probably nHPad and nVPad. So I doubt it will work as expected.
Boulder is discussing the optional parameter pelclip to MSuper, not the super clip itself. You can provide your own 2x size interpolated clip instead of having MVTools interpolate it for you. When using vector scaling from a half-sized clip you have the original 2x sized clip, so it seems an ideal opportunity to provide it as pelclip. However, the MVTools documentation notes that the even pixels of pelclip must correspond exactly to the pixels of the original clip - these were the requirements I was discussing and the need for PointResize.

cretindesalpes
16th November 2011, 22:43
Oh I see. You can also resize with -0.5 for src_left and src_top.

-Vit-
16th November 2011, 23:52
Isn't that for 2x upscaling, this is downscaling your original clip to get a half-size search clip, whose pixels are untouched from the even pixels in the original.
Decimating the odd rows and columns basically.

cretindesalpes
17th November 2011, 00:08
-0.5 is for half downsizing. To upscale, it's the opposite: +0.25. I think the "untouched even pixels" requirement refers only to sampling location. I also think the same requirement applies for vector scaling in modes 1 and 2: pixel sampling locations should be preserved instead of the picture center.

-Vit-
17th November 2011, 00:17
Re: -0.5, yes, I see you what you mean to preserve sampling location. However, the MVTools docs say of pelclip:

pelclip: 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.

I read from that documentation statement that the downscaled clip must contain *exactly* the even pixels of the original clip i.e. point sampled. However, I haven't checked the source code of MVTools. Is the documentation enforcing a condition that the code does not require? ...thinking about it that statement does seem unnecessarily rigid and unlikely taken at face value...

Edit: Vector scaling mode 2 doesn't involve any resampling, it just stretches, shrinks or reverses the vectors so they point somewhere else than they were originally supposed to. So I don't think this point is relevant to that mode.

cretindesalpes
17th November 2011, 00:47
Sampling location is important because when going from one level for pel >= 1 to the next one should keep the global picture position. Anyway I think I wrote my previous statement too quickly: keeping the pixel values will ensure the SAD for a given location will remain exactly the same on the corresponding oversampled "polyphase" pictures. Anyway, Avisynth resizers (excepted GaussResize and BicubicResize for most b and c values) should have this property if the src_top and src_left parameters are set correctly.

Edit: Vector scaling mode 2Oops my bad, I meant modes 0 and 1.

-Vit-
17th November 2011, 01:23
...keeping the pixel values will ensure the SAD for a given location will remain exactly the same on the corresponding oversampled "polyphase" pictures. Anyway, Avisynth resizers (excepted GaussResize and BicubicResize for most b and c values) should have this property if the src_top and src_left parameters are set correctly.
Maybe I'm misreading this, or maybe I'm sleepy. What property are you suggesting is common to many resizers? Untouched pixels when downsizing, or some SAD property within MVTools?

cretindesalpes
17th November 2011, 01:39
No, when upsizing.

Boulder
17th November 2011, 04:39
@Didée: thanks, that seems to be what I needed :)

@cretindesalpes: so I can safely downsize 2x by BilinearResize(source.width()/2,source.height()/2,src_left=-0.5,src_top=-0.5) and use "pelclip=source" in MSuper which determines the superclip for the downscaled MAnalyse? What about chroma, does it need a different src_left and src_top for YV12?

Groucho2004
17th November 2011, 10:17
I use MDegrain(1,2) a lot and I always assumed that MAnalyse would pick the fastest option for "sadx264" if I don't specify that value (as per documentation).

However, trying some other values, it turns out that "4" (SSE2) is the fastest for my i5 2500K Sandy Bridge, about 2-3% faster than auto.

It's not a huge improvement but for such a slow filter, every fps increase is very welcome.

Gavino
17th November 2011, 11:14
What about chroma, does it need a different src_left and src_top for YV12?
-1 for src_left and src_top in YV12 chroma.

Boulder
17th November 2011, 18:25
Some more observations: using MRecalculate seems to stabilize the motion analysis quite a bit. I tried first creating vectors on the original clip with blocksize 16, downscaled them 2x and used MRecalculate with blocksize 8 and overlap 4 on them on a downscaled clip (a different superclip, of course). All other settings were identical.

Has anyone else played around with MRecalculate?

mikeyakame
26th November 2011, 10:21
Some more observations: using MRecalculate seems to stabilize the motion analysis quite a bit. I tried first creating vectors on the original clip with blocksize 16, downscaled them 2x and used MRecalculate with blocksize 8 and overlap 4 on them on a downscaled clip (a different superclip, of course). All other settings were identical.

Has anyone else played around with MRecalculate?

I've been using it for a while with mdegrain, it works quite nicely.

It's also around 70-80% faster doing Manalyze with blksize=16, and then Mrecalculate with blksize=8, compared to using Manalyze with blksize=8 directly. While it doesn't quite catch as many motion vectors this way, it softens the denoising a little bit, which I find to be just adequate.


dct = 0
blksize = 8
search = 5
ol = 4

AssumeTFF().SeparateFields()

src = last
pf = src.removegrain(11).merge(removegrain(17,1), 0.35)
sf = pf.MSuper(hpad=16, vpad=16)
super = src.MSuper(levels=1, sharp=1, hpad=16, vpad=16)

b_vec = MAnalyse(sf, isb=true, delta=2, overlap=ol*2, lsad=lsad, dct=dct, blksize=blksize*2, search=search)
f_vec = MAnalyse(sf, isb=false, delta=2, overlap=ol*2, lsad=lsad, dct=dct, blksize=blksize*2, search=search)

b_rvec = MRecalculate(super, b_vec, overlap=ol, dct=dct, blksize=blksize, search=search, thSAD=100, pnew=55)
f_rvec = MRecalculate(super, f_vec, overlap=ol, dct=dct, blksize=blksize, search=search, thSAD=100, pnew=55)

src.MDegrain1(super, b_rvec, f_rvec, thSAD=msad, limit=mlimit, limitc=mlimitc)

mt_merge(src, last, edge_mask.mt_invert(), luma=true)
weave()


This is for field-based footage, just change the delta from 2 to 1 for the back/forward vectors for frame-based material.

Boulder
26th November 2011, 19:32
Have you tested whether it's better to use prefiltering on the MAnalyse part or the MRecalculate part?

Dogway
27th November 2011, 17:27
I think you need to supply the same super to manalyse and mrecalculate, so mrecalculate can do its job and compare vectors with the clip they were crated from, and improve them if possible, otherwise there would be a mismatch.

Boulder
27th November 2011, 19:46
Nope, it's not mandatory. The docs state that you can use different filtering, you just need to create a new superclip for MRecalculate. In fact, I think that the example also contains this approach.

Dogway
27th November 2011, 20:35
...with different super clip or new parameters set (e.g. lesser block size)
one or the other, not both!!
Although in the example they use both, so documentation is not well documented : P

You have to understand the point of mrecalculate, it just needs another take on the superclip to make some evaluation. If your source is seriously damaged, providing the unprefiltered super to mrecalculate will result in mostly wrong vectors. Its safer to feed the same prefiltered super to mrecaculate and let the refined settings do the evaluation, after all you don't need mrecalculate if your source isn't bad at all.

Boulder
27th November 2011, 20:39
I wouldn't say that it's one or the other as the docs say that "Interpolated vectors of old blocks are used as predictors for new vectors".

Fizick definitely isn't a writer of clear documentation as he has many times said himself :)

Dogway
27th November 2011, 22:30
Then it would be good someone to confirm it, because I have never seen that approach. QTGMC, interframe, Killer, FizzKiller, etc all use the same processed super for manalyse and mrecalculate.

-Vit-
27th November 2011, 23:21
Documentation states that SAD is recalculated, so you should be able to change both super and settings if you have reason.

MRecalculate is not only useful for bad sources, it can help generally. Large block sizes are good for large areas moving fairly simply, they are not confused by complex / repeated patterns within the image and tend to be more stable even on fairly low contrast areas. However, they will not capture edges or small objects well, and are confused by more complex motion when large blocks change too much. Smaller blocks will capture fine motion detail, edges and more complex motion, but they more easily make mistakes. Consequently a large->small block recalculate can capture the best of both. Start with the large block attempt, then refine where the smaller blocks feel it is necessary. Smaller block recalculation uses settings that avoid changing the original vectors too much without compelling reason (balance the improvement in SAD against reduction in coherence, lambda & pnew). In such a context, and especially with a good source, I see reason to filter less (or differently) on the super for the MRecalculate - initial large block pass aims for stability, smaller block pass for detail. But as ever with MVTools, the theory sounds cleaner than the practice...

The mythical next version of QTGMC already supports multiple levels of MRecalculate as an option, I have been intending to experiment with different pre-filters for the reasons above (and also try the interesting concept that I *think* Boulder was referring to earlier: MRecalculating after scaling the vectors). I don't think there's a plugin reason not to try, whether there's any value...

Boulder
28th November 2011, 05:05
Yes, that approach is what I was experimenting with. At least by looking at MShow's output, it seems that doing the initial MAnalyse on the full-size frame and downscaling the vectors and doing MRecalculate on the downsized clip and vectors will stabilize the analysis. Of course, this is just an MVTools newbie talking. It is possible that the same would be achieved by recalculating also on a full-size frame but on HD sources (and x264 encoding), you take whatever speedup you can have.

I have built a hack-of-a-function to play around with things MVTools, and I think the next phase will be to add the possibility to preclean the full-sized frame and disable precleaning for the downscaled clip, or allow setting a different precleaning method :)

SSH4
28th November 2011, 22:31
hmm, don't find in documentation, but why i can't set blocksize 16 and overlap 12 for example, like i can made this in dfttest?

Dogway
13th January 2012, 17:09
I found something very strange. Either it is a bug or I didn't understand the behaviour.
When I process chroma with the motion vectors I got from the luma plane, sometimes chroma just smears a lot in an even conservative environment as thSAD=200 and tr=2 is. Shifting to tr=1 doesn't show this issue but I don't know, I thought luma plane was more reliable for motion vectors than the chroma planes.

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)


http://img220.imageshack.us/img220/3941/kr01.th.png (http://img220.imageshack.us/img220/3941/kr01.png)http://img13.imageshack.us/img13/849/kr02.th.png (http://img13.imageshack.us/img13/849/kr02.png)http://img585.imageshack.us/img585/4526/kr03.th.png (http://img585.imageshack.us/img585/4526/kr03.png)http://img806.imageshack.us/img806/9680/kr04.th.png (http://img806.imageshack.us/img806/9680/kr04.png)

Didée
13th January 2012, 17:48
Not sure if it's related to the problem, but you have "chroma=chroma ? ... : ..." in the MSuper() line. That should be "chroma==chroma ? ... : ...".

Gavino
13th January 2012, 18:02
Not sure if it's related to the problem, but you have "chroma=chroma ? ... : ..." in the MSuper() line. That should be "chroma==chroma ? ... : ...".
Not at all.
The first 'chroma' is the argument name in the call, the second is the variable previously defined in the script.
'chroma==chroma' is obviously always true, so makes no sense here.

Incidentally, instead of
chroma=chroma? true : (plane==0?false:true)
you could write
chroma=(chroma || plane!=0)

Didée
13th January 2012, 18:44
Aiii, yes, you're right. I got confused. Script syntax is correct.

However, if msuper is called with chroma=false, then the super clip does not contain valid chroma data. And if the super clip does not contain valid chroma data, then the subsequent MDegrain (with plane=4, i.e. with chroma processing) might become problematic, obviously.

If you want to avoid the risk that source-damaged chroma influences the motionsearch, set chroma=false in the manalyse() call. But you need to keep chroma in the super-clip.

Gavino
13th January 2012, 19:01
However, if msuper is called with chroma=false, then the super clip does not contain valid chroma data. And if the super clip does not contain valid chroma data, then the subsequent MDegrain (with plane=4, i.e. with chroma processing) might become problematic, obviously.
But if plane=4 (or any non-zero value), MSuper() is called with chroma=true.

If you want to avoid the risk that source-damaged chroma influences the motionsearch, set chroma=false in the manalyse() call. But you need to keep chroma in the super-clip.
Dogway's script does exactly that.

Didée
13th January 2012, 19:35
Hmmh. That's true, again.

Today is not my day, it seems. ^^

manolito
13th January 2012, 20:10
Hmmh. That's true, again.

Today is not my day, it seems. ^^

Friday 13th :rolleyes:

Cheers
manolito

Overdrive80
18th January 2012, 16:59
Hi, somebody could say me if i apply mmask properly???

a=last

######SPATIAL DENOISE####
b=dfttest(tbsize=1,sigma=14,lsb=true)

#####MASK####
vectors = MSuper().MAnalyse(isb = false)
msk=MMask(vectors).dfttest(tbsize=1,sigma=12)

#####BACK MERGING WITH DFTTEST####
dither_merge16_8(b,a.Dither_convert_8_to_16(),msk,luma=true).ditherpost(mode=6)

#####CONTRASHARPEN####
contrasharpening(last, a)

#####TEMPORAL DENOISE####
super=Msuper(last)

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=320,lsb=true)

#####DEBANDING####
gradfun3(smode=1,lsb_in=true,mode=0,ampo=1.2)

#####ANTIALIASING####
LSharpAAF(StrDrk=10,aatype="supaa")

Thanks in advance

cretindesalpes
20th January 2012, 12:50
Sorry no I don't think it's a proper use. I don't know exactly what you want to achieve, but I guess you want to spatially filter only areas on which the motion estimation failed. Default kind parameter value for MMask is 0, meaning that it will output grey shades based on the vector length, even if the vector is completely wrong. You should set kind=1 to use the SAD value: smallest value = good match. I recommend to set Ysc=255 (scene change = bad match), and to play with the ml and gamma parameters. Display the msk clip to finetune the values. Then, the two first Dither_merge16 arguments should be swapped: 0 = use original clip, 255 = use spatially filtered clip.

Overdrive80
20th January 2012, 13:37
Sorry no I don't think it's a proper use. I don't know exactly what you want to achieve, but I guess you want to spatially filter only areas on which the motion estimation failed. Default kind parameter value for MMask is 0, meaning that it will output grey shades based on the vector length, even if the vector is completely wrong. You should set kind=1 to use the SAD value: smallest value = good match. I recommend to set Ysc=255 (scene change = bad match), and to play with the ml and gamma parameters. Display the msk clip to finetune the values. Then, the two first Dither_merge16 arguments should be swapped: 0 = use original clip, 255 = use spatially filtered clip.

With the code I wanted to avoid that areas not affected by the mask, had a more smooth movement. Follow your recommendations although the masks that I'm a newbie. Thanks

Boulder
26th April 2012, 18:33
Some more dumb questions:

Is it generally wise to use a very high searchparam, such as 6-8 for SD sources with pel=2 and search=5? Or with any source, I'd expect that higher resolution actually needs a higher search range.

Is it useful to use MRecalculate and search=3 with a high (once again 6-8) searchparam value?

Let's say that the slowdown does not need to be considered, this is only some throwing of ideas off the top of my head. I've been trying to check the MShow output but I cannot determine which one produces better output, that's why I'd like to have some second opinions.

alexx7777
26th June 2012, 02:13
Please tell me how to be a script for doubling the frame rate (25> 50) interlaced video (TFF) using MVFlowFps2?

StainlessS
26th June 2012, 03:17
MVFlowFps2 seems to have been removed from v2 mvtools (there was a request
for comment (in v1) as to whether or not the filter was needed, but seems to have
just disappeared without further note).

The only example in v1 is for progressive however, here is the v1 example for progressive:


To change fps with MVFlowFps2:

# Assume progressive PAL 25 fps source. Lets try convert it to 50.
backward_vec = source.MVAnalyse(isb = true, truemotion=true, pel=2, idx=1, search=3)
# we use explicit idx for more fast processing and use full search
forward_vec = source.MVAnalyse(isb = false, truemotion=true, pel=2, idx=1, search=3)
cropped = source.crop(4,4,-4,-4) # by half of block size 8
backward_vec2 = cropped.MVAnalyse(isb = true, truemotion=true, pel=2, idx=2, search=3)
forward_vec2 = cropped.MVAnalyse(isb = false, truemotion=true, pel=2, idx=2, search=3)
source.MVFlowFps2(backward_vec,forward_vec,backward_vec2,forward_vec2,num=50,idx=1,idx2=2)

Doubt this helps but ...

SubJunk
26th June 2012, 06:04
The best way to make interlaced video double framerate is to use a deinterlacing script like QTGMC. It is an automatic function of that script (just don't use SelectEven() or SelectOdd() afterwards).
MVTools2 is a great way to double the framerate of progressive video, but not interlaced.

fvisagie
6th December 2012, 09:03
In the following scenario the YV12 U & V planes get swapped from FFVideoSource()'s CS_I420 to ConvertToYV12()'s CS_YV12, causing MRecalculate() to fail with "wrong pixel type":

source = "input.avi"
FFIndex(source=source, cachefile=source+".ffindex", indexmask=-1, dumpmask=0, errorhandling=3, overwrite=false)
FFVideoSource(source=source, track=-1, cache=true, cachefile=source+".ffindex", seekmode=1, rffmode=0, width=-1, height=-1, colorspace="YV12")
a = last
Assert(IsYV12(a), "Source is not YV12")
MSuper(hpad=16, vpad=16, pel=2, rfilter=4)
bvec1 = MAnalyse(isb=true, delta=1, blksize=16, overlap=8)
fvec1 = MAnalyse(isb=false, delta=1, blksize=16, overlap=8)
a.ConvertToRGB32()
# ... some filter/s requiring RGB32
ConvertToYV12()
MSuper(hpad=16, vpad=16, pel=2, rfilter=4, levels=1)
bvec1 = MRecalculate(bvec1, thSAD=400, blksize=8, overlap=4)
fvec1 = MRecalculate(fvec1, thSAD=400, blksize=8, overlap=4)
MDegrain1(a, last, bvec1, fvec1)


Discussion at http://forum.doom9.org/showthread.php?t=166603.

I raised the issue with the FFmpegSource2 developers, but their respone contained impolite language ;) and indicated that they won't address this.

I realise that various work-arounds are possible, but as a convenience - and to prevent unexpected gotchas like the one above - please consider automatically handling swapped U-V planes? Perhaps existing behaviour could be extended with a bool "pixfmtstrict" parameter.

Gavino
6th December 2012, 10:30
I raised the issue with the FFmpegSource2 developers, but their respone contained impolite language ;) and indicated that they won't address this.

I realise that various work-arounds are possible, but as a convenience - and to prevent unexpected gotchas like the one above - please consider automatically handling swapped U-V planes? Perhaps existing behaviour could be extended with a bool "pixfmtstrict" parameter.
ffms2 isn't doing anything wrong, so I can understand their response (if not their bad manners :)).
I420 and YV12 should work interchangeably for well-behaved filters - both satisfy IsYV12() and the Avisynth core API transparently takes care of getting the U and V planes from the correct place when they are requested.

As I hinted in the original thread, the problem is that MRecalculate's compatibility check for the super and vector clips compares the 'raw' pixel type, and finds I420 different from YV12:
MVAnalysisData *pAnalyseFilter = reinterpret_cast<MVAnalysisData *>(_vectors->GetVideoInfo().nchannels);
...
analysisData.pixelType = pAnalyseFilter->GetPixelType();
...
if (vi.pixel_type != analysisData.pixelType )
env->ThrowError("MRecalculate: wrong pixel type");
This is unnecessarily strict, since as long as it goes on to access the planes individually via the API (which I think it does), it can safely treat YV12 and I420 as being the same.

fvisagie
6th December 2012, 12:08
This is unnecessarily strict, since as long as it goes on to access the planes individually via the API (which I think it does), it can safely treat YV12 and I420 as being the same.

I see, so it is potentially even simpler (just removing the check) than the swapping of internal U and V pointers I had imagined. Provided the API is used as you mention.

Gavino
6th December 2012, 13:02
I see, so it is potentially even simpler (just removing the check) ...
The check can't be removed altogether - it still needs to check for compatibility, eg YUY2 would not be compatible with YV12, nor would YV24 (different sized chroma).

Normally a filter would use the API function IsSameColorspace():
bool IsSameColorspace(const VideoInfo& vi) const {
if (vi.pixel_type == pixel_type) return TRUE;
if (IsYV12() && vi.IsYV12()) return TRUE;
return FALSE;
}
However, the MRecalculate code gets the vector colorspace from a MVAnalysisData object rather than a VideoInfo object, so would have to roll its own variant of this function.

fvisagie
6th December 2012, 16:14
The check can't be removed altogether

You're quite right, of course. I often still speak too soon, however hard I try ;).

Terka
20th March 2013, 16:47
Hi Fizick, could you please implement cross-corelation to MVtools?
http://forum.doom9.org/showthread.php?p=1620594#post1620594.
Cross-corelation code is ready. Dont know how exactly each blocks are compared. IMHO a comparison routine could be replaced by other one without a huge effort?

Fizick
20th March 2013, 19:35
sort of DCT?

Terka
21st March 2013, 10:50
yes DCT.

Terka
26th March 2013, 13:04
Fizick, will you spend effort on this?

unclescoob
10th July 2013, 20:06
Hi folks,

I am currently working on denoising some DVD .VOB episodes, using MVDegrain3. These are NTSC animated episodes. The episodes are hard telecined, but I added a simple IVTC script before using this plugin.

I have read the MV Tools documentation and have a few questions about some parameters with this type of material. I've run a few test clips and they look great. But I want to ensure that I get the best out of this filter. Assistance is very much appreciated. So here goes:

1. PEL: I'm gathering that PEL=1 is for frame-based material and PEL=2 is for interlaced/telecined source. Am I correct? If so, am I correct in using Pel=1 after I IVTC?

2. blksize: I've seen alot of Didee's scripts use blksize=16 when it comes to Mdegrain. If I use a prefilter superclip (as he does), does this make a difference? Is there an advantage in using this over, say, blksize=8? The document lists various parameters as "scaled to blksize=8". Not sure if this means that 8 is my best option.

3. Truemotion- I notice that when I pick Truemotion=false, more noise (dirt) from the source is allowed through, as opposed to using Truemotion=true. Does it make a difference is I use a prefiltered superclip for my motion vector? Does it make a difference at all?

Thanks for your time

Stereodude
12th July 2013, 23:33
So I've got an odd one... If I manually load MVtools2.dll (v2.6.0.5) in my script it works multi-threaded, but if I let it auto load from the AVIsynth plugins directory it doesn't work multi-threaded, CPU usage is lower, and the script runs slower. :confused:

Auto loading Script:
LoadPlugin("DGDecodeNVx86.dll")
Import("MCTemporalDenoise.v1.4.20.avsi")

SetMemoryMax(1280)
DGSource("Video_2.dgi").trim(0,499).crop(0,18,-0,-18)
MCTemporalDenoise(settings="medium").addborders(0,18,0,18)

Auto loading Results:
AVSMeter 1.5.3 by Groucho2004
AviSynth 2.60, build:Aug 28 2012 [18:17:07]
Active MT Mode: 0

Number of frames: 500
Length (hhh:mm:ss.ms): 000:00:20.854
Frame width: 1920
Frame height: 1080
Framerate: 23.976 (24000/1001)
Colorspace: YV12

Frames processed: 500 (0 - 499)
FPS (min | max | average): 0.67 | 3.97 | 1.50
CPU usage (average): 12%
Thread count: 4
Physical Memory usage (peak): 1792 MB
Virtual Memory usage (peak): 1933 MB
Time (elapsed): 000:05:33.756


Manual loading Script:
LoadPlugin("DGDecodeNVx86.dll")
LoadPlugin("mvtools2.dll")
Import("MCTemporalDenoise.v1.4.20.avsi")

SetMemoryMax(1280)
DGSource("Video_2.dgi").trim(0,499).crop(0,18,-0,-18)
MCTemporalDenoise(settings="medium").addborders(0,18,0,18)

Manual loading Results:
AVSMeter 1.5.3 by Groucho2004
AviSynth 2.60, build:Aug 28 2012 [18:17:07]
Active MT Mode: 0

Number of frames: 500
Length (hhh:mm:ss.ms): 000:00:20.854
Frame width: 1920
Frame height: 1080
Framerate: 23.976 (24000/1001)
Colorspace: YV12

Frames processed: 500 (0 - 499)
FPS (min | max | average): 0.71 | 8.07 | 2.31
CPU usage (average): 21%
Thread count: 11
Physical Memory usage (peak): 1794 MB
Virtual Memory usage (peak): 1935 MB
Time (elapsed): 000:03:36.509

aldix
12th July 2013, 23:36
You don't have SetMTMode set or is it intentional?

Stereodude
12th July 2013, 23:57
You don't have SetMTMode set or is it intentional?Right, it's intentionally off for benchmarking purposes to illustrate that the same script behaves differently depending how/where MVtools2.dll is loaded.

On a related but off topic note, I do have concerns over the implications of multithreading MCTD in terms of the output (due to the fact that every frame isn't run through the same decision "thread").

pbristow
13th July 2013, 10:06
It sounds like you have more than one copy of MVtools2.dll on your system, and the autoloader is picking up the wrong one. Early versions of Interframe / SVP liked to install their own copy of MVTools2, if I remember correctly... I've you've tried out one of those, that copy of the dll might still be sitting around somewhere on the autoloader's search path.

Search your hard drive for instances of the dll, and rename any that aren't needed (e.g. add ".PROBABLY_A_MISTAKE!" to the end of the filename, or something :) - Make sure you add something *after* the ".dll" suffix, so that any process that's searching for dlls to load won't find it. ). Then test everything you regularly use that uses MVtools2.dll, to make sure you haven't nuked one that *is* needed. When you're happy everything works correctly, delete the renamed dlls.

Stereodude
13th July 2013, 13:49
It sounds like you have more than one copy of MVtools2.dll on your system, and the autoloader is picking up the wrong one. Early versions of Interframe / SVP liked to install their own copy of MVTools2, if I remember correctly... I've you've tried out one of those, that copy of the dll might still be sitting around somewhere on the autoloader's search path.

Search your hard drive for instances of the dll, and rename any that aren't needed (e.g. add ".PROBABLY_A_MISTAKE!" to the end of the filename, or something :) - Make sure you add something *after* the ".dll" suffix, so that any process that's searching for dlls to load won't find it. ). Then test everything you regularly use that uses MVtools2.dll, to make sure you haven't nuked one that *is* needed. When you're happy everything works correctly, delete the renamed dlls.That was my first thought and I eliminated that as a possibility before posting. There was only one other MVtools2.dll on the HD in the x64 plugin folder, but I confirmed it is loading the correct file from the non x64 AVIsynth plugin directory in addition to the obvious fact the x64 version won't work in a x86 flow. But yet when I manually load the same .dll file from another directory the results are different. :scared:

pbristow
13th July 2013, 16:24
Ahh...

In that case, the only diagnosis I can offer you is "weird s**t is happening". :scared:

Whose MT build of avisynth are you using? You could try asking them to investigate it as a possible bug. (Make sure first that you can provide a nice simple test case for them to try replicating the problem.)

unclescoob
17th July 2013, 14:53
So were my questions just completely ignored deliberately, or did I just post them in the wrong thread?

Guest
17th July 2013, 15:11
Maybe your two references to asking for "best" has caused people to shie away, per forum rule 12.

Or maybe you have too many questions in one post.

Or maybe you haven't allowed enough time for a knowledgeable person to come on the scene.

Suggesting people are intentionally ignoring you seems a stretch.

unclescoob
17th July 2013, 20:12
Ok Neuron, fair enough.

Is there anything you can assist me with in regards to at least 1 of my 3 questions?

Guest
18th July 2013, 01:00
Sorry I don't use MV tools. :(

Hopefully, our interaction may elicit some useful replies.

foxyshadis
19th July 2013, 01:31
Try using Process Explorer from Sysinternals to see exactly which DLLs are being loaded. Note that when manually loading the way you are, you're attempting to pull from the current folder (usually wherever the viewer resides, or the script) then from anywhere else on the system path, which may include some odd locations not on the main drive.

In Process Explorer, you use View->Show Lower Pane then View->Lower Pane View->DLLs to see exactly what's loaded.

unclescoob
19th July 2013, 17:18
is Pel pertaining to whether your source is interlaced, telecined and/or progressive, or does it pertain to something else? I was under the assumption that Pel=1 was used if your source is progressive, and Pel=2 if it is interlaced.

But then in the FastDegrain doc, I read that the higher the Pel, the better the motion vector. Can someone please clarify this?

Thanks

poisondeathray
19th July 2013, 17:21
is Pel pertaining to whether your source is interlaced, telecined and/or progressive, or does it pertain to something else? I was under the assumption that Pel=1 was used if your source is progressive, and Pel=2 if it is interlaced.

But then in the FastDegrain doc, I read that the higher the Pel, the better the motion vector. Can someone please clarify this?

Thanks


No, it's motion estimation accuracy


pel : it is the accuracy of the motion estimation. Value can only be 1, 2 or 4. 1 means a precision to the pixel. 2 means a precision to half a pixel, 4 means a precision to quarter a pixel, produced by spatial interpolation (more accurate but slower and not always better due to big level scale step). Default is 2 since v1.4.10.

Boulder
19th July 2013, 17:26
Please consult http://avisynth.org.ru/mvtools/mvtools2.html

Pel is not related to progressive or interlaced material. It is used to tell how accurately the motion will be estimated. At pel=1, the super clip is not scaled at all, at pel=2 it is twice as big and at pel=4 it's four times as big. A bigger value for pel is not necessarily better as there's no way to scale an image by four times and not have any errors created by the extrapolation. Unless you live in the CSI world, that is ;) Personally I would leave it at the default which is pel=2.

Basically I would leave all the values at their defaults as there's probably a reason why they are select. If you got the CPU power to spare, maybe use dct=5 and search=5 in the MAnalyse calls.

unclescoob
19th July 2013, 19:52
I understand that using dct=5 uses the SATD (sum of absolute transformed differences) instead of SAD (sum of absolute differences) for luma. In your experiences, does this improve the motion estimation accuracy in a significant manner? for instance, in fast motion with animation, does it help in preventing blurring/ghosting at quick motion in dark scenes? I'm gonna try this for myself when I get home, but it's nice to hear from others while I'm stuck at this desk.

unclescoob
19th July 2013, 19:53
Thanks PDR and Boulder for explaining PEL

Boulder
19th July 2013, 20:09
It's been quite a long time since I tested the differences, but if I recall correctly, the differences were mostly in the areas of higher contrast. I didn't test performance in the dark frames/areas much, but I think someone (was it *.mp4guy?) did some testing and found out that it helps there.

unclescoob
19th July 2013, 20:12
Splendid!

unclescoob
19th July 2013, 20:12
Oh (as columbo would ask) one more thing, please folks if you have room for just one additional question: blocksize. 8 or 16? make any difference?

Boulder
19th July 2013, 20:15
Smaller is more accurate but more affected by noise. I personally use 8 with overlap 4 for all my stuff. If I use MRecalculate after that, I use blksize 4 and overlap 2 for SD stuff and blksize 8, overlap 4 for anything higher than that.

unclescoob
19th July 2013, 20:23
I use overlap 2. But in my script it's written as 8/2 (as per the way it's in the documentation). Is adding the / even necessary?

My stuff is analog SD and I'm using Mdegrain3. I'm thinking of using blcksize 4 if that's the case, since I'm prefiltering anyway.

Boulder
19th July 2013, 20:54
Overlap 8/2 == 4 ;)

real.finder
29th July 2016, 17:11
what rfilter in MSuper do (Technical details, I know it did smoothing)? is it effect if pel = 1?

feisty2
29th July 2016, 17:27
what rfilter in MSuper do (Technical details, I know it did smoothing)? is it effect if pel = 1?

nothing

kolak
29th July 2016, 22:11
I understand that using dct=5 uses the SATD (sum of absolute transformed differences) instead of SAD (sum of absolute differences) for luma. In your experiences, does this improve the motion estimation accuracy in a significant manner? for instance, in fast motion with animation, does it help in preventing blurring/ghosting at quick motion in dark scenes? I'm gonna try this for myself when I get home, but it's nice to hear from others while I'm stuck at this desk.

My finding which I posted in VS forum.

Search 6 and 7 works the best for me, based on the dominant movement in particular source/scene. I asked if this could be dynamically changed ahead of final calculations. 5 gives very different characteristic for final frames, never as good as when correct option 6 or 7 is chosen based on scene dominant movement.
Another interesting (or not) thing is fallback method. When you try interpolate low fps sources than quite often motion adaptive method fails giving huge artefacts. Some pro solution have fallback mode, which at some threshold switches to simple frame blending for given frames. In case of fps conversion (in current world of hybrid sources, e.g. 25p mixed with 50i) this is sometimes useful option.
Other than this mvtools results are very good. I'm thinking if anything more can be done. There is something called phase correlation, is this used in mvtools? I would like to see something reliably converting 24p to 25p, which is at the moment only a dream :)

DCT hits performance a lot, but sometimes helps on fades etc.

real.finder
30th July 2016, 13:24
nothing

why it there then?

pel use resizer to upscale frame, is rfilter for the downsize to original dimension?

feisty2
30th July 2016, 13:36
why it there then?

is rfilter for the downsize to original dimension?

yeah, rfilter stands for reducing filter

real.finder
30th July 2016, 13:41
yeah, rfilter stands for reducing filter

and if pel = 1? did nothing?

feisty2
30th July 2016, 13:45
and if pel = 1? did nothing?

pel = 1 means no upscaling nor downscaling (precision by a single pixel)

DTL
10th March 2023, 13:19
Some not very fast but better answer - rfilter is used when generating smaller sized images for higher levels of search (levels=0 mean all possible levels).

It work at all pel (if levels count all or high enough). Disabling usage rfilter is for example pel=1 levels=1. So make only refine search at largest (full size) level.

The used filter may cause generating different MVs at each level (used as a predictor after interpolation at larger levels of search). So initial developers of mvtools put several different filters for reduction of size for smaller levels and also recommend to try filtering to smaller levels:
From documentation: You may also try to apply some external filter to superclip or its coarse bottom part (by appropriate crop and overlay).