View Full Version : MVTools


Pages : [1] 2

Manao
1st November 2004, 15:18
Hi everybody

Since there was no dedicated thread for the MVTools on the usage forum, I create one. It's bundled with (yet another) new version of the MVTools.

You can fetch it here : http://manao4.free.fr/MVTools-v0.9.8.zip

A lot of things have changed since the latest version, but most of the changes are internal. However, some filters'parameters were changed ( MVAnalyse, MVCompensate, MVDenoise ). Two filters were added ( Deblock and MVChangeCompensate ), some were temporarily ( MVInterpolate, MVBlur, MVConvertFPS ) or definitively removed ( EncDenoise ).

The main change for this release is that a vector stream now contains a lot of information : for each blocks, it stores the motion vector, the SAD, but also the mean luminance of the source block and of the reference block, and an approximation of the standard deviation of the source block, and the reference block itself.

That means that, by default, a mv stream already contains the result of the motion compensation ( for luminance and chrominance ). Hence, MVCompensate becomes ( in one of its mode ) a mean of extracting the compensation from the stream. And, of course, you may want to filter it and put it back into the stream, and that's the role of MVChangeCompensate. For example, to deblock the compensation, just do the following : vectors = source.MVAnalyse(isb = false, lambda = 1000)
compensation = source.MVCompensate(vectors, mode = 0)
compensation = compensation.Deblock()
vectors = vectors.MVChangeCompensate(compensation)

Now, that change has a great influence on MVDenoise. At the beginning, that filter was only compensating the previous and next frames in order to denoise. That wasn't enough, and I added a hack in order to compensate twice the frames n-2 and n+2, in order to work on 5 frames ( which allows a better denoising ). But it was slow, and the hack was creating a lot of blocking.

Now, since the compensation are stored inside the mv stream, and since you can make a mv search between frame n and n-delta easily ( I added a parameter 'delta' to MVAnalyse ), MVDenoise can take an unlimited number of mv streams as input, and will use all of them to denoise the source.

And, to avoid blocking, you can now deblock the compensations before feeding them to MVDenoise.

Finally, the 'pel' parameter is now limited to 1 or 2 only, but works for all filters.

Now, what's left to do ? The temporal interpolations will come back, but they need a lot of work to be more than left-artifacts-all-around filters. There is still room for optimisations ( when 'pel' = 2, I interpolate the source and the reference 2 times ( one when the frame is the source, the second when the frame becomes the reference ), and when MVAnalyse is used several times on the same clip, the interpolations are recomputed each times ).

Also, MVDenoise need a better algorithm in order to denoise ( Didee, I'm still waiting for your ideas ;) ). Right now, it's only merging together collocated pixels which respects the thresholds. Something better can be done, and it can be changed very easily, so any ideas are welcomed ( BTW, i take into account the mean luma of the source and reference block when doing the merging, it avoids some artifacts when luminance was changing from a frame to another, but it still leaves a slight blocking ).

I'm sure I forgot a lot of things, and that there are still slight bugs left into the code, so I'm waiting for your impressions.

Mug Funky
1st November 2004, 16:27
thankyou very much! a new toy :)

Mug Funky
3rd November 2004, 08:32
little bump here...

would it be possible to have some kind of adaptive block-replacement going for the looping MVcompensate? sort of like the I-block/P-block decisions that encoders use.

this would be good for using the mode=2 mvcompensate in a denoiser. right now i'm using a very low value of thSCD1 (about 15-ish) to prevent the picture going too wibbly, and i can certainly use masks for the rest of the artefact prevention, but it would be good to have a kind of block change detection to mimimize redunancy on long near-static scenes.

no hurry - simple scenechange detection works well. i'm seeing just how much compression gain/denoising i can get out of MVtools. my aim is around 50-60% the size of a non-denoised encode. i'm getting close :)

Manao
3rd November 2004, 09:10
That can easily be added. I'll do it. Meanwhile, you should be able to test that idea ( on luma only ) using MVdenoise :
vectors = source.MVAnalyse(isb = false)
blended = source.MVDenoise(vectors, thSAD = XXX, thMV = YYY, thT = 256)

return yv12LUTxy(blended, source, yexpr = "x 2 * y -", u=2, v=2)I didn't test it, but it should amount to the same.

Mug Funky
3rd November 2004, 10:27
right now i'm doing something similar to "forced block skipping". ie, if the difference between a looped compensate and the source is small enough, the looped compensate is used. it doesn't really remove much grain, but after encoding with xvid, the grain is somehow gone. plus it's quite fast :).

i'm just doing a test encode with it now.

also, an advantage of looped compensation to me is that i can encode difficult-to-IVTC sources at double framerate, and i don't lose denoise effectiveness from all the duplicated frames.

Manao
3rd November 2004, 10:47
I should have read your post entirely. You can't achieve denoising with MVcompensate mode 2 and intra block. The all thing behind MVDenoise is to make the strongest possible temporal denoising. MVCompensate only takes the noise from one frame to another.

If you want strong denoising, use MVdenoise, with 4 or 6 mvstreams, all deblocked through Deblock(quant = 30), and with high sad / mv / temporal threshold for MVDenoise.

Mug Funky
3rd November 2004, 14:33
i'm looking more for a compression gain, actually. the encoder seems to handle the noise pretty well. i'm thinking of I-blocks just as a way of stopping error accumulating (though masking seems to be working pretty well), while still letting through the parts that are still good (rather than forcing a scenechange).

on another note, i can't seem to get mvtools to finish a full encode - i get an access violation at about the 30000 frame mark (it varies). haven't been able to track it down, because 30000 frames is a long time to be without my computer.

plugins i'm using on my last encode to do this are:

dgdecode
tdeint
removegrain
masktools
mvtools

i don't think it's tdeint or dgdecode, as i've done a full length encode with them. it's either mvtools, or masktools (i'm not certain about removegrain, but i think i've had this crash without it).

i'm on win2k sp2, p3-733, 384 sdram.

[edit]
i'm also using VirtualDubMod as well (it's a little unstable of late), but i've had this crash in other apps as well (mencoder via AVIS, and QuEnc)

Manao
3rd November 2004, 14:36
Thank for the report, I'll check that ( this week-end ). I never tried it on long sequence, so it's more than possible than MVTools are guilty.

Mug Funky
3rd November 2004, 15:10
ah, okay. i have no idea what it could be. maybe a memory problem? i haven't explicitly looked for a corellation between how early it crashes and how big the frames are. but i seem to remember a larger framesize encode crashing much earlier (this could be imagination).

johnmeyer
8th November 2004, 07:35
I have used mvtools version 0.9.2.2 to create smooth slow motion, using this script:loadplugin("c:\Program Files\AviSynth 2.5\plugins\kerneldeint140.dll")
loadplugin("C:\Program Files\AviSynth 2.5\plugins\MVTools\mvtools.dll")

AVISource("E:\Volleyball\Volleyball (Soldedad)\Volleyball (soledad)0022.avi")
assumebff()
changespeed(4, 2, 8) #1/4 speed, using motion compensated frame interpolation (motion will stay smooth)

function changespeed(clip a, float factor, int mode, int th)
{
ord = getparity(a) ? 1 : 0
f=a.kerneldeint(order=ord, sharp=false, twoway=false, threshold=th)
e=a.separatefields.trim(1,0).weave.kerneldeint(order=1-ord, sharp=false, twoway=false, threshold=th)
interleave(f,e).assumeframebased
# converttoyuy2() # not needed if mode=2 saves extra conversion by commenting out

(mode == 0) ? changefps(framerate*factor) : (mode == 1) ? convertfps(framerate*factor) : converttoyv12().mvconvertfps(fps=framerate*factor).converttoyuy2()
assumefps(a.framerate*2,true)
separatefields()
(ord==0) ? selectevery(4,0,3) : selectevery(4,1,2)
weave()

}This worked well with this version, but I cannot get any later version to even load, much less do the slow motion. Also, in looking at the release notes for the latest version, I see that mvconvertfps() has temporarily been deleted.

Question: Is there a better way to generate slow motion using motion-estimated synthesized frames, using another AVISynth plug-in, like Depan? Also, is there any way to use later mvtools versions? With any version after 0.9.2.2 I get this error message:

AVISynth Open Failure.
Evaluate: Unrecognized exception!

Manao
8th November 2004, 13:43
The way of using the MVTools changed after v0.9.2.2. So it's normal that your script doesn't work. Moreover, temporal interpolators are disabled for version > 0.9.5, because they are being rewritten.

So I'd advise you to fetch v0.9.5, look into the documentation to see how to adapt your script to the new syntax. The main change is that you have to use two stages : one (or several) filter which analyses the clip and create a motion vectors streams, and another filter which takes the clip and one or several vectors streams and which does the actual processing.

Heini011
8th November 2004, 19:10
Hi,

little errors in the docu:

version: 0.9.5

III) Examples
...
To denoise :
...
return source.MVDenoise(backward_vectors1, backward_vectors1, forward_vectors1 ...

---
does the order of backward_vectors1, backward_vectors2 matter ?

can i use 'backward_vectors1, forward_vectors1' only ?

---
many thanks for your really great work!!

best regards.

johnmeyer
8th November 2004, 19:12
OK, I revised the script using MVTools v0.9.5. I have it working pretty well, but would REALLY appreciate any hints as to which settings -- either in the deinterlace, or in MVTools -- I should try changing in order to improve the results.

My source is interlaced NTSC DV AVI, and I plan to print back to a NTSC DV tape and view on an NTSC monitor. The test clip is a volleyball game, with the camera panning back and forth, and lots of action (inluding the ball) moving in front of the camera.

I am now getting very smooth, clear slow motion, but still sometimes get single frame "glitches," even in areas that are not moving much. I am VERY close to making this work really well.
loadplugin("c:\Program Files\AviSynth 2.5\plugins\kerneldeint140.dll")
loadplugin("C:\Program Files\AviSynth 2.5\plugins\MVTools\mvtools.dll")

AVISource("E:\Volleyball\Volleyball (Soldedad)\Volleyball (soledad)0022.avi")

assumebff()
changespeed(4, 8) #Change to 1/4 speed (slow motion)

function changespeed(clip a, float factor, int th)
{

ord = getparity(a) ? 1 : 0
f=a.kerneldeint(order=ord, sharp=false, twoway=false, threshold=th)
e=a.separatefields.trim(1,0).weave.kerneldeint(order=1-ord, sharp=false, twoway=false, threshold=th)
g=interleave(f,e).assumeframebased
h=converttoyv12(g)

vec_back = h.MVAnalyse(sx=8, sy=8, fth=20, isb=true)
vec_forw = h.MVAnalyse(sx=8, sy=8, fth=20, isb=false)
MVConvertFPS(h, vec_back, vec_forw, fps=h.framerate*factor, fbw=2, thSCD2=255, thSCD1=200)

converttoyuy2()
assumefps(a.framerate*2,true)
separatefields()
(ord==0) ? selectevery(4,0,3) : selectevery(4,1,2)
weave()
}

Manao
8th November 2004, 19:14
The documentation on my webpage is for 0.9.7 only. However, a documentation is bundled with 0.9.5 : it is made of several html documents and you ought to refer to this one when using v0.9.5. Sorry for not having made that clear in the online documentation.

Manao
8th November 2004, 19:21
johnmeyer : these filters have always been more experimental than stable. The glitches you're experiencing are due to the crudeness of the code, and I don't think you'll find settings good for the whole movie. This is why I'm rewritting these filters.

johnmeyer
8th November 2004, 19:31
Hey, I am not complaining! :)

If these are experimental, I'd love to see something you consider finished. It must be amazingly good.

Heini011
9th November 2004, 22:53
Hi Manao,

work the following 2 functions identical and if not, which does it right ??

function mvdenoise1(clip) {
backv2 = clip.MVAnalyse(isb=true, blksize=4, pel=2, lambda=1000, delta=2)
backv1 = clip.MVAnalyse(isb=true, blksize=4, pel=2, lambda=1000, delta=1)
forwv1 = clip.MVAnalyse(isb=false, blksize=4, pel=2, lambda=1000, delta=1)
forwv2 = clip.MVAnalyse(isb=false, blksize=4, pel=2, lambda=1000, delta=2)
return clip.MVDenoise(backv1, backv2, forwv1, forwv2, thT=10, thSAD=64, thMV=100, thSCD1=80)
}


function mvdenoise2(clip) {
{...}
return clip.MVDenoise(backv2, backv1, forwv1, forwv2, thT=10, thSAD=64, thMV=100, thSCD1=80)
}

thanks!

Manao
10th November 2004, 06:37
Both should work correctly. Order of the vectors streams does'nt matter anymore in MVDenoise.

Heini011
10th November 2004, 13:04
mvdenoise from MVTools 0.97 seems to be buggy: it produces much ghosting where MVTools 0.96.2 works great.

Use this code for testing purpose:

---------------------------------
MVTools 0.96.2:

function mvdenoise2(clip) {
backv = clip.MVAnalyse(isb=true, sx=4, sy=4, pel=1, lambda=1000)
forwv = clip.MVAnalyse(isb=false, sx=4, sy=4, pel=1, lambda=1000)
return clip.MVDenoise(backv, forwv, thT=100, sadT=1000, thMV=1000, thSCD1=1000)
}

---------------------------------
MVTools 0.97:

function mvdenoise2(clip) {
backv2 = clip.MVAnalyse(isb=true, blksize=4, pel=1, lambda=1000, delta=2)
backv1 = clip.MVAnalyse(isb=true, blksize=4, pel=1, lambda=1000, delta=1)
forwv1 = clip.MVAnalyse(isb=false, blksize=4, pel=1, lambda=1000, delta=1)
forwv2 = clip.MVAnalyse(isb=false, blksize=4, pel=1, lambda=1000, delta=2)
return clip.MVDenoise(backv1, backv2, forwv1, forwv2, thT=100, thSAD=1000, thMV=1000, thSCD1=1000)
}
---------------------------------

Manao
10th November 2004, 13:44
I found the bug, a new version will be online late tonight, or tomorrow. Thanks for the report.

I wonder what you're filtering, because thT = 100 is very high.

Heini011
10th November 2004, 19:40
Hi,

>I wonder what you're filtering, because thT = 100 is very high.

the code was for testing only.

my defaults for medium noisy sources:

MVAnalyse: blksize=4, pel=1, lambda=1000

MVDenoise: thT=10..12, thSAD=64, thMV=100, thSCD1=80

the 0.97 version is fast, fixing the bug would be very nice..! thanks very much!

greetings.

johnmeyer
16th November 2004, 17:21
I just completed a volleyball music video and needed to create super slow motion. I have Sony Vegas, which has a pretty good slow motion, but it doesn't use motion estimation. Even though you say your motion estimation code is crude and is being re-written, I must say that, for short clips, the results are stunning. Yes, there are glitches on some frames because of errors in the estimation, but on short clips, these often don't occur at all. I just can't get over how fabulous the slow motion looks.

If you ever decide to release another version that includes the motion estimation (I am using one of the older releases), I will be one of your first downloaders.

Again, thanks for your fabulous work.

Manao
16th November 2004, 17:29
Thanks for the kind words.

However, I'll need some time to put them back into MVTools. I think that meanwhile, I'll put back the old filters.

Concerning the previous bug, i didn't release a new version yet because there were some other modifications that needed testing before being released. I don't know yet when it'll be released, but it should be before the end of the week.

Meanwhile, Heini011, can you tell me if the bug (ghosting with mvdenoise ) is still here if you work on a greyscale video ?

Heini011
17th November 2004, 13:51
hi manao,

the problem remains even with greyscaled video and is very easy to reproduce. simply use very high thresholds. image becomes very blocky and strange even when there is no motion and even the luma on flat areas is irregular changing. very strange.

greetings.

Manao
17th November 2004, 14:01
In fact, there were two problems : one is that I stupidly substracted a value that i should have added, which led to strong blocking. The second was that ghosting seemed more important when chroma isn't filtered ( and in your case, it wasn't, since 0.9.7 didn't support chroma denoising ).

Since you described firstly your problem by ghosting, I thought you were dealing with the second issue.

Manao
20th November 2004, 00:25
New version up : MVTools v0.9.8 (http://manao4.free.fr/MVTools-v0.9.8.zip) ( the website changed, there should not be any more unavailibity )

Changelog : * Yet another little changes in the filters' syntax. The core changed a lot, in order to gain speed were it was possible. However, by default, the speed gain won't be visible, you'll need to configure correctly the analysis filter through its "idx" parameter in order to gain speed ( in the mode "pel" = 2 ).
* Bugfixes in MVDenoise, and chroma denoising in MVDenoise.
* Now, the filters down the filter's chain tell to the analysis filter is they need the compensation, so you don't have to worry about that at the analysing stage.

Heini011
20th November 2004, 21:21
Hi,

if i put mvtools_098 in my avisynth-plugin directory, virtualdobmod 1.5.4.1 is crashing just with starting the program, even when mvtools_098 is alone in this directory. i get an invalid page error within windows kernel:


VIRTUALDUBMOD verursachte einen Fehler durch eine ungültige Seite
in Modul KERNEL32.DLL bei 018f:bff8e1ad.


i have mvtools_098 in a different directory now, in avisynth plugin directory is only mpeg2dec3dg. i can open a simple script with mvtools_098 within virtualdubmod, but at closing it crashed again.

script:

----------
LoadPlugin("C:\Programme\AviSynth 2.5\plugins\MPEG2Dec3.dll")
LoadPlugin("C:\Programme\AviSynth 2.5\mvtools_098\MVTools_098.dll")

function mvdenoise2(clip) {
bw_v2=clip.MVAnalyse(isb=true, blksize=4, lambda=1000, delta=2, pel=2, idx=1)
bw_v1=clip.MVAnalyse(isb=true, blksize=4, lambda=1000, delta=1, pel=2, idx=1)
fw_v1=clip.MVAnalyse(isb=false, blksize=4, lambda=1000, delta=1, pel=2, idx=1)
fw_v2=clip.MVAnalyse(isb=false, blksize=4, lambda=1000, delta=2, pel=2, idx=1)
return clip.MVDenoise(bw_v2, bw_v1, fw_v1, fw_v2, thT=10, thSAD=64, thMV=80, thSCD1=64)
}

MPEG2Source("v.d2v",cpu=4,iDCT=7)
trim(750,120006)

mvdenoise2()

crop(4,2,712,572)
----------


error after closing it:

Oops -- VirtualDub has crashed [...]
Crash details:
An out-of-bounds memory access (access violation) occurred in module 'MVTOOLS_098'.


would you like to see the complete crashinfo.txt ?

My System:
Avisynth 2.53
Windows ME

greetings.

Manao
20th November 2004, 21:30
I'll search the bug. Thanks for the report, no need to send further information, I think I know what could go wrong ( since only putting it in the autoloading directory make vdubmod crash ).

However, I do not observe that behavior on my computer. I wonder why...

Manao
21st November 2004, 08:56
I could include overlapped motion compensation. It would need a change in vectors format, and it would slow things down, but it's possible. It's not on my to do list right now ( I'm trying to make the MVTools usable with avs 3.0 ), but i could add it once I resume the development of the filters.

For the stability of the vectors format, it could and may surely change if I add new features. I want to add 16x16 blocks for example, and I may add new values to those already computed.

Anyway, that's why I made an interface to use those vectors : I derived a class GenericMotionFilter from GenericVideoFilter, and inside, there are all the tools needed to use motion vectors. And it should ( at least I hope ) be transparent if I update the format.

However, you'd need to include a lot of files ( Fake*, GenericMotionFilter.*, MotionParameters.*, portability.h, MVCore.* MVFrame.* and MVAnalysis.* at least ).

Finally, I don't have an internal global motion estimation.

Before you try to use the motion vectors, it'd be better if i try if they can be easily used outside of the MVTools. I'll try that in the next day and report to you.

Heini011
21st November 2004, 16:08
Hi,

mvdenoise 0.98 with pel=2 works great (when it works)! the bugs from 0.97 seems to be fixed, the result is less blocky on motion than mvdenoise 0.96.2 with pel=1 and the performance is reasonable! it would be very nice, when the mvtools "loading-bug" get fixed soon!

many tanks @manao!

Manao
21st November 2004, 16:16
Heini : can you try this version :

http://manao4.free.fr/MVTools.dll

Edit : no need to try, it will surely fail, another bug was just yet discovered.

Manao
21st November 2004, 17:58
Alright, new dll, it should work this time :

http://manao4.free.fr/MVTools.dll

Fizick
21st November 2004, 18:18
Manao, i moved my post to development, sorry :)

So, i will wait a stable MV format,
and currently make other plugins. :)

Manao
21st November 2004, 18:38
Fizick : damned, i wonder all the morning why you did a croosposting, i didn't even notice that you actually moved your post :) I should've stay in bed.

Heini : a third version is up, and in addition to solving loading issue, it should also work even after several seekings in the file.

Heini011
22nd November 2004, 15:13
Hi manao,

the second one seemed to worked already, but bug-fixing is always fine ;-) many thanks!

there are still the little bugs in your documentation:

----
version: 0.9.5

and 2x:

return source.MVDenoise(backward_vectors1, backward_vectors1, forward_vectors1, forward_vectors2, tht = 10, sadt = 300)
----

an idea for mvdenoise: maybe a parameter like 'min' in deen would be useful to decreasing the thresholds for more distant neighbour frames.

greetings.

tsp
25th November 2004, 21:20
hmm I think I found a bug. When trying to call MVAnalyse from medianblurt (I will try to see how much improvement there are from using motion compensation with the temporal median blur filter) with this code:

AVSValue args1[12]=child,8,1,0,2,1,true,1000,1,true,true,1};
PClip vectors = env->Invoke("MVAnalyse",AVSValue(args1,12)).AsClip();


I get this

Unhandled exception at 0x0135b8d2 (MVTools.dll) in virtualdubmod.exe: 0xC0000005: Access violation reading location 0xbaadf015.

I don't now what's going on. If it's my code, MVTools or avisynth. It's not a IScriptEnvironment::NotFound error.

Manao
25th November 2004, 21:46
Firstly, in doubt ( since some version were buggy ), can you try the version i just put up on my website :

http://manao4.free.fr/MVTools-v0.9.8.1.zip

Secondly, can you make your source code available to me, so i can directly debug my filter with it. It'll be easier for me to start from a code which segfaults than trying to create one.

tsp
25th November 2004, 23:25
Thatsolved it thanks.

tsp
28th November 2004, 22:17
wow that really a usefull filter. I used it with my temporal-median filter and it really works wonders. I have one questian/request does the filter only use the Y-plane to calculate the motion vectors and SAD and if it does is it possible to at least use some of the chroma information to avoid really ugly artifacts like this (http://www.tsp.person.dk/who_ate_my_shoulder.jpg)

(the first row is the previous frame compensated to the center frame, center frame, and the next frame compensated to the center frame.
The next row is the previous frame without motion compensation(MC), the center frame, and next frame without MC.
Next row is the 2 previuos row subtract.
The last row is the fist row subtract from the center frame.)

The setting used to create this is
MVAnalyse(blksize=4,lambda=1000,delta=1) and
MVCompendate(thSCD1=200,thSCD2=10) )

Manao
28th November 2004, 22:25
It can be easily added. Next release will have chroma ME.

Manao
29th November 2004, 07:51
http://manao4.free.fr/MVTools-v0.9.8.4.zip

I also added a 'mode' parameter to Corrector, which, if set to 1, change the behavior of Corrector from making the mean to choosing the closest, as asked by scharfi here (http://forum.doom9.org/showthread.php?s=&threadid=82015).

The chroma ME isn't tested thoroughly, but it worked ok on the samples I tried. There's no way to disable it yet ( hence, experimental build )

Manao
19th January 2005, 20:41
http://manao4.free.fr/MVTools-v0.9.9.zip

New release, here is the changelog : * Filter added : Corrector
* Filter added : MVIncrease
* New available blocksize : 16
* New parameter in MVAnalyse : chroma
* Changes in the coreNo temporal interpolators yet.

scharfis_brain
20th January 2005, 15:11
AVISynth rejects mvtools 0.9.9 .
It says:

AVISYnth open failure
Loadplugin: Unable to load "D:\x\mvtools099.dll"

(I always rename mvtools.dll to mvtools0.version.dll)

I am using an AthlonXP with WinXP.

Mug Funky
20th January 2005, 15:52
wow, thanks for the update :)

[edit]

i seem to need stlport_vc7146.dll

Manao
20th January 2005, 19:15
To those who succeed / fail to use the version 0.9.9 : do you have WinXP SP 2 ?

Edit : I just saw Mug Funky's edit : I'll correct that tonight, it shouldn't be necessary.

Manao
20th January 2005, 22:04
Corrected : http://manao4.free.fr/MVTools-v0.9.9.1.zip

Mug Funky
21st January 2005, 04:46
cool. it works now.

[edit]

just a bit of warning: i got an access violation on frame 32 while playing back in VDM, using blksize=16. couldn't make it happen again though. possibly a problem at my end, but these kinds of problems tend to make long encodes unreliable. if there's nothing immediately wrong, then just put it down to my 5 year old computer :)

Manao
21st January 2005, 06:38
I made the mvtools run 24 hours straight with a complicated script and i didn't get any access violations :( These are very hard to found & reproduce.

However, blksize = 16 is largely untested, so I'll check here and there to see if I didn't left any obvious wrong code.

scharfis_brain
21st January 2005, 16:07
manao, could you take a look into corrector?
especially for copy&paste mistakes.
somehow the analysis clips are passed through to the output.

addtional I would like to request separated thresholds for luma and chroma.

also many thanks for the larger blocksize of 16px!
it made the motioncompensation more stable in general, but small moving objects and borders aren't as precise as they waere before with blocksise 8 or 4.

Manao
24th January 2005, 20:01
Scharfi : can you post your script ? I checked the code, and it seems i made no mistake. A script showing the issue would be of great help.

Heini011
27th January 2005, 15:00
Hi manao,

i still prefer the 0.98.5 version of your mvtools for mvdenoise. i used both on a 3 hour video and the result of the 0.98.5 version is clearly visible cleaner especially on motion parts. The 0.99.1 version works too, but the result is not as good.

script used:

LoadPlugin("C:\Programme\AviSynth 2.5\plugins\MVTools_0985.dll")

function mvdenoise2(clip) {
bw_v2=clip.MVAnalyse(isb=true, blksize=4, lambda=1000, delta=2, pel=2, idx=1)
bw_v1=clip.MVAnalyse(isb=true, blksize=4, lambda=1000, delta=1, pel=2, idx=1)
fw_v1=clip.MVAnalyse(isb=false, blksize=4, lambda=1000, delta=1, pel=2, idx=1)
fw_v2=clip.MVAnalyse(isb=false, blksize=4, lambda=1000, delta=2, pel=2, idx=1)
return clip.MVDenoise(bw_v2, bw_v1, fw_v1, fw_v2, thT=10, thSAD=64, thmv=90, thSCD1=64)
}

----------

the examples for mvdenoise in your documentation still use 2 x "forward_vectors1" and doesn't use the computed "forward_vectors2" at all.

----------

b.t.w. the following mvdenoise2() function script works imho already better than pixiedust(6..8) (!)

---
LoadPlugin("C:\Programme\AviSynth 2.5\plugins\MVTools_0985.dll")

function deblock2(vec,clip) {
comp=clip.MVCompensate(vec, mode=0).Deblock(quant=16, aOffset=5, bOffset=5)
return vec.MVChangeCompensate(comp)
}

function mvdenoise2(clip) {
bw_v2=clip.MVAnalyse(isb=true, blksize=4, lambda=1000, delta=2, pel=2, idx=1).deblock2(clip)
bw_v1=clip.MVAnalyse(isb=true, blksize=4, lambda=1000, delta=1, pel=2, idx=1).deblock2(clip)
fw_v1=clip.MVAnalyse(isb=false, blksize=4, lambda=1000, delta=1, pel=2, idx=1).deblock2(clip)
fw_v2=clip.MVAnalyse(isb=false, blksize=4, lambda=1000, delta=2, pel=2, idx=1).deblock2(clip)
return clip.MVDenoise(bw_v2, bw_v1, fw_v1, fw_v2, thT=16, thSAD=100, thmv=90, thSCD1=72)
}
---

maybe we still need some kind of adaptive thresholding and your mvdenoise is clearly the best avisynth filter at all... !

many thanks for your great work!

greetings.

Heini011
29th January 2005, 16:02
Hi!

@manao,

please test the script above with noisy film-material just after a scenechange. it seems, that mvdenoise from movtools 0.99.1 doesn't use all off the referenced frames. (maybe only the first ??)

greetings.

krieger2005
1st February 2005, 12:52
I have a problem, that MVTool can not find the right motion. Still in "no-motion" it shows me results like this (this is extremly):

http://freehost11.websamba.com/krieger2005/Vectors.JPG

This is Frame 8003 of the movie. I will show you the real Frames before and after:
Frame 8002:
http://freehost11.websamba.com/krieger2005/8002.JPG
Frame 8003:
http://freehost11.websamba.com/krieger2005/8003.JPG
Frame 8004:
http://freehost11.websamba.com/krieger2005/8004.JPG

here the script, which i used for showing the vectors:
source=last
vectors = source.MVAnalyse(isb = false, pel=2, blksize=4)
return source.MVShow(vectors)

I tried different options: set lambda very high, set blksize=16, set source=tempralsoften(3,30,30,10,2) (which cause in artefacts) or source=MedianBlur(6) (no noise, no little things), but nothing help...

A new thing i tried help:
source=FineEdge(5).Levels(20,1,80,0,255,false).inflate

v1=source.MVAnalyse(isb = false, pel=2, blksize=4)
This give me good results, but when i try to Denoise with MVDenoise, then there are no effects. If i set tht=50 the i got visible effects but it seems, that there were put from the source (which is a mask), so i got black areas...

1. What can i make that MVTools give me the right results.
2. Why MVDenoise use source (in the second example) to denoise, when i call him with an other movie (not source)? Should it not only use the vectors, which were given by source und MVAnalyse?

If you want i can give you a little example of the movie, for testing...

Didée
1st February 2005, 13:17
You did use 2 sets of vector clips? The other filters have to be provided with backward *and* forward vector clips (iirc - didn't touch that stuff for a while. Alas.)

Please post the complete related parts of the script. All generated vector clips, and the calls where they get used.

krieger2005
1st February 2005, 13:43
I guess you mean this script:
source=last
vectors = source.MVAnalyse(isb = false, pel=2, blksize=4)
return source.MVShow(vectors)

well this is the hole script. Above is something like "mpeg2source...". You are right, this is only one type of the script. I used following different usage of MVAnalyse (one every time):
vectors = source.MVAnalyse(isb = false, pel=2, blksize=4)
vectors = source.MVAnalyse(isb = true, pel=2, blksize=4)
vectors = source.MVAnalyse(isb = false, pel=2, blksize=16)
vectors = source.MVAnalyse(isb = false, pel=2, blksize=4, lambda=1000)
vectors = source.MVAnalyse(isb = false, pel=2, blksize=4, lambda=40000)
vectors = source.MVAnalyse(isb = false, pel=2, blksize=4, lambda=1000, delta=2)
vectors = source.MVAnalyse(isb = false, pel=2, blksize=4, lambda=1000, delta=4)


and some other combinations, but every time with the same result: MVTools give me this "bombed" result, where the vectors go though the people...

The problem of this movie is, that it has "part-flickering". This means, that there are parts in every frame, which go in every frame. I you look at the frame 8002 above you can see that dark area. And so it goes the hole movie... This is, i gues the problem. I put in 2 hours a sample-movie for testing... I must away

Manao
1st February 2005, 13:49
krieger2005 : The sky changed a lot between frames 8002 and 8003. That explains why the vectors are so chaotic. There's nothing you can do about it ( there could be a way, but it would be slow, so no way ( yet ? ) )

MVDenoise not only uses the vectors, but also the motion compensation stored with the vectors. This is done in order to improve the speed ( motion compensation could be computed in MVDenoise, but the data is already in the cache when the vector is computed in MVAnalyse, so it's computed there ).

You can change the motion compensation using MVChangeCompensate. You can't (yet) apply vectors to source to create a new compensation, but the code to do that is already written, so it will be available in the next release.

However, there again, it will be slow

heini011 : sorry to have taken so much time to answer. I haven't yet tested your script. However, IIRC, I changed the way the relative strength of the thresholds between 0.985 and 0.991 ( i tried to make the parameters less dependant of the blocksize ). That should explain the differences between 0.985 and 0.991 ( because the denoising is exactly the same )

The filter doesn't take into account frames that are in the other side of what is detected as a scene change. That behavior is expected, and wanted.

The filter often detects very noisy frames as scene change, so if you're handling noisy material, raise the SCD thresholds ( and prevent artifacts with thSAD / thMV / thT ).

The example in the documentation is wrong, indeed, it will be corrected.

Finally, i would recommend not to use blocksize = 4, because it slower and imho less efficient than blocksize = 8 or 16 ( vectors are too sensitive to the noise ).

Edit : krieger, i just saw your post : indeed, the vectors are wrong because of the flickering. Either deflick the clip, or don't plan to flicking areas. Anyway, there are enough thresholds in MVDenoise to prevent artifacts from appearing in such areas, so even if the vectors look like s**t, you can safely use the filter. And finally, event if it try to denoise, it will compensate for the mean luma variation it observed. I'll finally implement a flickering safe motion estimation, it won't be that hard.

krieger2005
1st February 2005, 16:53
You are right. The sky changed very hard but i used to get the vectors for "source" something like that:
source=temporalsoften(3,25,25,10,2)
vectors = source.MVAnalyse(isb = false, pel=2, blksize=4)
return source.MVShow(vectors)
Because this is a scene where is not so much motion the results are very good and the changes of the sky were compensated. But here i get still the same wrong results... However i uploaded now a sample. Maybe you use it to prove your new versions. You can get it here (http://freehost11.websamba.com/krieger2005/Sample.avi).

PS: Does someone hear about this (http://www.hs-art.com/) (hs-art restoration tool for standard PC)? I want know how good it is...


I'll finally implement a flickering safe motion estimation, it won't be that hard
Ohhh, it's welcome, because i have now two movies of that flickering style ;)

PS: The deflicker-plugin of Fizick the antiflicker of "Sorry, does not find your name" can't repair this flicker, because it is local and not global, this means it is only on parts of frames and not on the hole frame. These filters make the frames only darker or lighter but this does not help...

Heini011
1st February 2005, 18:00
Hi Manao,

how can i compute the parameters for mvdenoise 0.99x based on the 0.98x parameters ?

it seems, that pixiedust also uses blocksize=4x4. maybe blocksize=8 is a better choice for strong denoising.

greetings.

scharfis_brain
9th February 2005, 16:51
Hello Manao.

When you (hopefully) bring back mvconvertfps and mvinterpolate to us,

would it be possible to include some error checking into the internal compensation routines to avoid motion artifacts?
(cross checking of back- and forwards compensated frames to their originals)

All detected areas should then replaced with simple blending instead of the wrong motion-blocks.

That's the way, the commercial mv-enabled converters seem to work! Hard to estimate areas (clapping/shaking hands etc.) are blended, while pans and large moving objects are motion compensated.

sh0dan
10th February 2005, 22:56
I just love this filtercollection. I'd like to find the time and put in an improved MVConvertFPS. My main issues are soft block appliance and a blended frame scbehaviour and border mv-interpolation/guessing.

Manao
11th February 2005, 07:51
After playing a lot with temporal interpolation, i'd say that soft block appliance are not the way to go. It avoids artifacts, but it blurs ( that was the problem with the version that was in mvtools 0.9.5 )

Right now, I build a list of possible candidate for each pixels, and i choose the best one. More artifacts, far slower ( the choice is hard to do ), but the picture isn't blurred.

For interpolating areas that aren't interpolatable, i was more thinking of inpainting than of temporal blending. Two reasons theres : discontinuity at the border of the area if we blend ( which means a kind of inpainting is required ), and once more, blurriness.

I still have issue for choosing the good candidate, that's why nothing is released yet. But if i find some time ( which i haven't ), i'll try to work on it this week-end.

sh0dan
11th February 2005, 10:06
Could the soft appliance be weighed based upon the SAD of how good the match is on the destination frame?

A frame sequence:
[A][b][C], where [b] is the interpolated frame, each block is applied with the strength of how good frame A is matching C after mv are applied. That way quite bad MV's shouldn't affect the final result.

Perhaps this could even be combined with interpolating blocks from frame [A] into the destination blocks from frame [C], as the time gets closer to [C].

Inpaining is of course optimal, and it would exceptionally good if you'd be able to implement it. But I think it would still leave problematic areas. IMO blending isn't as bad as blocks, or distinctly wrong areas. Blending is "the way out", if no good MV's can be found.

scharfis_brain
11th February 2005, 19:12
manao:

discontinuity at the border of the area if we blend

hm.. what about doing a soft transition between mv-ed and blended areas?

Manao
11th February 2005, 19:27
hm.. what about doing a soft transition between mv-ed and blended areas?That's called inpainting :) ( well, it's a basic one, but still, it's inpainting )Perhaps this could even be combined with interpolating blocks from frame [A] into the destination blocks from frame [C], as the time gets closer to [C].
Already implemented, works quite well, when the mv is valid. Right now, I'm able to fill two kinds of areas : those pointed by mvs ( these ones are easy, and represents most of the picture ), and those that are hidden or discovered by an object ( reverting the next / previous mvs helps a lot here, but something is still missing )

I'll try to see this week-end what results give blending.

Manao
12th February 2005, 14:04
Here are some results :
http://manao4.free.fr/10.png
http://manao4.free.fr/15.png
http://manao4.free.fr/20.png
As you can see, most of the picture is fine, but artifacts are annoying. Uncompensated areas were rebuilded by a basic kind of inpainting, luckyly, they were small enough. You can notice some blurriness / fuzziness around some edges ( hand ), a badly reconstruct area ( nose ), which isn't due to inpainting but to a wrong motion compensation ( the lighting change on the nose is killing the ME ), a part of the hair ( on the top ) which doesn't move ( wrong ME, there again ), the reflect on the photo wall which was disturbed ( wrong ME, because it's blurred ), and some stray pixels ( which could be avoided / reduced by a postprocessing, undot() for example )

On the bright side, that picture was reconstructed without using reverse vectors ( i've still to tweak some threshold for them to be used correctly ), and it was done only with integer motion vectors.

On the darker side, it's slow ( due to inpainting, mostly ).

I tried blending :
http://manao4.free.fr/15-blended.png
You can see that inpainting yields better results.

scharfis_brain
12th February 2005, 14:43
Originally posted by Manao Originally posted by scharfis_brain
hm.. what about doing a soft transition between mv-ed and blended areas?That's called inpainting :)

Hmm. maybe I didn't explain that precisely enough.

I thought about creating a soft mask for missed mv-ed areas.
soft -> soft transition between mv-ed and blended areas, or blurring a hard, one bit mask after creation with a variable blurring radius.

This should handle the transition between mv-ed and blended areas, shouldn't it?

But hey! your images are looking good :)

2Bdecided
14th February 2005, 13:37
If you want some more killer mvfps clips, then I have several. They're 15fps 320x240 video clips taken with a digital still camera which I'm trying to convert to 50fps and then interlace for a PAL DVD.

If you might be interested, let me know. I'll understand if that's the last thing you want to test mvfps with though!

Cheers,
David.

scharfis_brain
14th February 2005, 16:39
I also have some videos that confuse mvtools.

They contain pulsing lumiosity changes caused by a high speed shutter slow motion camera that interferred with the 100Hz lights.
The brightness is not pulsing on the whole frame,
because the different lights are fed with 120 degrees phased electricity. (German: Drehstrom)

So manao, if you are interested...

btw. how do you search for motion?
do you look at the plain image or do you compare the egdemasks, too?

I ask this, because edgemasks are not affected by brightness changes.

maybe an additional edgemask-search could help?

Didée
15th February 2005, 09:37
What's the result like when you create the MV's just on [edgemask] ? Or perhaps on "MaskedMerge( orig, orig.edgemask, edgemask)" ?

scharfis_brain
15th February 2005, 19:04
hm.. no improovement :(

but this may be cause due to the video clip itself. It is very noisy with wavy interference lines.

Maybe far too tricky for mocomping.

krieger2005
17th February 2005, 11:19
Till now i read something about "deflicker"-Algorithms, which where described to deflicker not only temproal, like the existing deflicker-Plugins, but also spatial. The authors of such Alogorithms said, that the Motion-Compansation must be very robust to destroy such problems while can also "compensate the motion".

Why i'm writing this all? My question is, is it better to make the MVTools very robust against such spatial flicker or is it maybe better to write an external filter, which "maybe" can handle such imperfections and deliver a deflickered movie for MVTools?

What's your meaning?

Valky
24th February 2005, 13:11
Seems that this latest 0.9.9.1 did crash all my avs-scripts and I couldn't open any avs-script with any version of VD.
I removed mvtools.dll from avisynth-plugins folder and everything works great now.

Btw, I couldn't open avs-files with mpc neither. It said 'out of memory'

patxitron
24th February 2005, 23:09
Hello to all

I'm trying to get more compresibility from HDTV (1080i) source encoding it at 720p after some motion compensated grain removal (wich visualy seems to me the best filter removing grain and preserving detail).

The script was borrowed from this forum and is:


LoadPlugin("C:\Video\Avisynth\DGDecode.dll")
LoadPlugin("C:\Video\Avisynth\undot.dll")

LeeVideo()
Filtro()
Lanczos4Resize(1280, 720)


function LeeVideo() {
c=MPEG2Source("E:\test\testHDTV.d2v", idct=5)
c=c.Trim(20, 144507)
c=c.undot()
c=c.AssumeFPS(25.0)
return c
}

function efficace(clip c, bool backward, int del) {
v = c.mvanalyse(isb = backward, lambda = 1000, blksize = 16, delta = del, idx = 1, pel = 2)
d = c.mvcompensate(v, mode = 1, thscd1 = 2500, thscd2 = 170).deblock(quant = 30)
return v.mvchangecompensate(d)
}

Function Filtro(clip c) {
LoadPlugin("C:\Video\Avisynth\MVTools-v0.9.9.1\MVTools.dll")
backward_vectors2 = c.efficace(true, 2)
backward_vectors1 = c.efficace(true, 1)
forward_vectors1 = c.efficace(false, 1)
forward_vectors2 = c.efficace(false, 2)
return c.MVDenoise(backward_vectors2, backward_vectors1, forward_vectors1, forward_vectors2, tht = 10, thSAD = 300)
}

My troble begins when I try to load the script into VirtualDub in order to tune filter values. I get no image and the following message: "Avisynth read error: Avisynth: caught an access violation at 0x012e41b5, attempting to write to 0x35711000". Similar script used with regular DVD source works without trouble.

Best regards.

EDIT: With other script version (borrowed from MVtools documentation without mvchangecompensate) I get image and a well grain removal but shows a lot of macroblocks in some (very movement intensive) scenes.

kassandro
2nd March 2005, 18:18
As a first time user I need some clarification concerning the documentation. Consider the following script

input=MPEG2Source("C:\video\input.d2v", ipp=false)
vectors = MVAnalyse(input, blksize=16, lambda=0, isb=true)
MVCompensate(input, vectors)

Now I hope that a frame of the output clip is constructed by using the previous frame from the original clip and moving them with the backward motion vector to get the current frame. Is that hope justified?
Similarily

input=MPEG2Source("C:\video\input.d2v", ipp=false)
vectors = MVAnalyse(input, blksize=16, lambda=0, isb=false)
MVCompensate(input, vectors)

should do the same but with the subsequent instead of the previous original frame.

Manao
2nd March 2005, 19:07
kassandro : indeed, you're right

patxitron : i'll have a look at your script

valky : can you give an example of a script making avs crash. What is your processor ? do you have win xp sp2 ?

kassandro
2nd March 2005, 19:39
Thanks, Manao!
Thus if motion compensation would be perfect, the compensated clip would be identical with the original one.
Is the idx variable useful also pel=1, if I want backward and forward vectors?
Usually I use the previous and the subsequent frame together with the current frame for temporal cleaning. Now I want to repalce the previous frame by the forward compensated frame and the subsequent frame by the backward motion compensated frame. Motion compensation and cleaning should take place with twice the width and twice the height (qpel). That's why I use mvtools with pel=1, blksize=16 and my own fast up- and downsize routines. To me that looks like a valid concept.

If one want's more than denoising, bidirectional motion vectors would be quite useful. I mean the following. Lat b be a block in the current frame, then I want a vector v, such that v+b in the subsequent frame and -v+b in the previous frame have a low SAD. Thus for this kind of motion compensation the pixel values of the current frame are not used at all. This is important if there is big piece of dirt on this block in the current frame, which would mislead the usual backward/forward motion compensation.

Manao
2nd March 2005, 20:32
'idx' will hardly have any effects with pel = 1. It will allow not to recompute the subsampled version of each picture, but that is fast in comparison to the motion estimation.

For the rest, it demands some thinking. Your idea seems interesting, but i don't know if it will work that well ( it doesn't take into account acceleration for example )

kassandro
2nd March 2005, 20:51
Originally posted by Manao
'idx' will hardly have any effects with pel = 1. It will allow not to recompute the subsampled version of each picture, but that is fast in comparison to the motion estimation.

Good to know.


For the rest, it demands some thinking. Your idea seems interesting, but i don't know if it will work that well ( it doesn't take into account acceleration for example )
I think it only makes sense for cleaning. In my case it would also be faster, because I need only one set of motions vectors (the bidiredtional vector can be extrapolated backward and forward). Togehter with the other two motion vectors it can even be used for detecting dirt. If all three motion vectors are similar --> no big dirt. If the backward and forward vectors do not fit together or are low quality and the bidirectional one is high quality and the neighbouring blocks are ok, the block is probably very dirty.

Valky
3rd March 2005, 17:41
Originally posted by Manao
kassandro : indeed, you're right

patxitron : i'll have a look at your script

valky : can you give an example of a script making avs crash. What is your processor ? do you have win xp sp2 ?

I dont have sp 2 and will never get it either :)
My processor is Athlon 1700+

It didn't matter what avs-script I tried. Even the simple avisource("video.avi"), didn't work. All these scripts worked fine after I removed that dll from plugins directory.

paviko
12th March 2005, 23:11
@Valky
It didn't matter what avs-script I tried. Even the simple avisource("video.avi"), didn't work. I've encounter the same 2 days ago, but it wasn't MVTools. The solution was to remove unused .dll files from plugins directory. It looks like Avisynth is able to deal only with certain amount of new function names. MVTools has got a lot of function in its .dll (MVAnalyse, MVCompensate, MVDenoise, ...) so probably you've reached the limit of Avisynth.

@Manao
Hi!
MVTools is the greatest ever available plug-in (counting not only Avisynth). Congratulations and thank you so much :)
I'm shooting home, family movies with miniDV camcorder and as with most DV cams there is a problem with low-light. After gaining video big noise appears. MVDenoise is the best in removing it. There is any other filter (FFT3DFilter, Mipsmooth, Dust, Gold, ...) that can come close to the results I've got with MVDenoise.
Unfortunately I see that MVDenoise is missed in many comparision of denoisers :( I suppose it's because you have to deal with so many parameters - first MVAnalyse with it's own, then MVDenoise. The default values and example in documentation is for removing low noise, so probably most people when copying script doesn't see filter in it's full potential. The default thSad value = 200 is very low. With normal lightning and static scene I'm getting Sad value (with MVShow) around 300-400, low-light after gain it's 900-1200. So please Manao could you put in documentation 3 examples for low, medium and high strengh densoing. Or even better maybe some simple script that can imitate behaviour of other denoiser, that only line clip.XXXDenoise(strenght = 2.0) is needed:

function MotionDenoise(clip c, int strength){
strength = default(strength, 1.0)
bw3 = c.efficace(false, 3)
bw2 = c.efficace(false, 2)
bw1 = c.efficace(false, 1)
fw1 = c.efficace(true, 1)
fw2 = c.efficace(true, 2)
fw3 = c.efficace(true, 3)
return source.mvdenoise(bw3, bw2, bw1, fw1, fw2, fw3,
\ thsad = strength * 800, thmv = 200, tht = strength * 6,
\ thscd1 = strength * 800, thscd2 = 170)
}

function efficace(clip c, bool backward, int del)
{
v = c.mvanalyse(isb = backward, lambda = 1000, blksize = 16,
\ delta = del, idx = 1, pel = 2)
d = c.mvcompensate(v, mode = 1, thscd1 = 2500, thscd2 = 170).deblock(quant = 30)
return v.mvchangecompensate(d)
}

Usage:

source = avisource("filename.avi")
# deinterlace if needed
source.MotionDenoise(2.0)

Script is from your reply in thread http://forum.doom9.org/showthread.php?s=&threadid=89555.
It's a pity people ommit the best denoiser on the earth ;) We need some advertising campain :D
If someone is interested I've also posted script with some combination of denoisers in this thread http://forum.doom9.org/showthread.php?s=&threadid=90042.

I'm also using your frame rate conversion filter available in older version to convert NTSC to PAL. The results are amazing especially when I upsize video before conversion 4 times (2x2 supersampling). I've comapared results with demo version of Twixtor, Retimer (both costing around 1000$) and MotionPerfect using a bit hard video clip.
MotionPerfect is very blocky, weavy, blurred. Twixtor gives sometimes some weavy effect and is blurry but no blocks visible. Retimer has great, sharp image, but sometimes appear small artefacts when it's undecided what to do (it's doing blending, so one straight line appears as 2 line). With used clip MVConvertFPS with 2x2 SS was the best. No artefacts, blocks. Only slightly blured image, but it can be easily removed with Unfilter or LimitedSharpen (I think the same is doing Retimer which has option to Deblur). And also one thing somehow important - speed:
- MVConvertFPS with 2x2 SS and LimitedSharpen - 2 seconds one frame
- Twixtor - 8 seconds
- Retimer - 12 seconds !!!
- MotionPerfect - 0.8 second
Incredible results with MVConvertFPS. Although MotionPerfect is faster but quality is unacceptable. Twixtor and Retimer are so slow - unusable in home application. 2 seconds with MVTools is acceptable for me and it gives the best results.
The only aspect in which MVTools is worse than Twixtor or Retimer is sudden change of light. With MVTools blocks appear. Twixtor and Retimer doesn't have that. But it's really only minor problem - on my home miniDV movies sudden change of light almost doesn't occur.

Thank you very much Manao. I'm waiting impatiently for announced come back of conversion function. Hmm ... but what can you improve in allready so great image quality?

Regards

johnmeyer
13th March 2005, 01:32
paviko,

Could you post the script you use for MVConvertFPS? Here is the one I use, and it works well, but I'm always looking for better ideas. This script is used to create slow motion of NTSC 29.97 DV AVI files. This particular example will slow it down to 1/3 normal speed (the 3 in changespeed is the key setting).

loadplugin("c:\Program Files\AviSynth 2.5\plugins\kerneldeint140.dll")
loadplugin("C:\Program Files\AviSynth 2.5\plugins\MVTools\mvtools.dll") #this script REQUIRES mvtools version 0.9.6.1

AVISource("E:\My Video\MVI_0002.AVI")

assumebff()
changespeed(3, 8)

function changespeed(clip a, float factor, int th)
{
ord = getparity(a) ? 1 : 0
f=a.kerneldeint(order=ord, sharp=false, twoway=false, threshold=th)
e=a.separatefields.trim(1,0).weave.kerneldeint(order=1-ord, sharp=false, twoway=false, threshold=th)
g=interleave(f,e).assumeframebased
h=converttoyv12(g)

vec_back = h.MVAnalyse(fth=30, isb=true)
vec_forw = h.MVAnalyse(fth=30, isb=false)
MVConvertFPS(h, vec_back, vec_forw, fps=h.framerate*factor, fbw=2, thSCD2=255, thSCD1=200)
converttoyuy2()
assumefps(a.framerate*2,true)
separatefields()
(ord==0) ? selectevery(4,0,3) : selectevery(4,1,2)
weave()
}

paviko
13th March 2005, 13:27
Hi.
Your changespeed function with script that I use will look like this:


function changespeed(clip a, float factor, int "th")
{
th = default(th, 6)
ord = getparity(a) ? 1 : 0
fps = a.framerate
width = a.width
height = a.height

a = a.ConvertToYV12(interlaced = true)
a = a.TDeint(mode=1,order=ord,type=2,mthreshL=th,mthreshC=th)

a = a.lanczos4resize(width * 2,height * 2)

vec_back = a.MVAnalyse(sx=8, sy=8, fth=20, isb=true, st = 3, stp = 2)
vec_forw = a.MVAnalyse(sx=8, sy=8, fth=20, isb=false, st = 3, stp = 2)
MVConvertFPS(a, vec_back, vec_forw, fps=fps*factor, fbw = 4, sbw=0,
\ rbw=0, thSCD2=255, thSCD1=200, wf = "ramp", rl = 0, nb = 1)
LimitedSharpen(ss_x = 1, ss_y = 1, strength = 255, wide = true)
Lanczos4Resize(width,height)

converttoyuy2()
assumefps(fps * 2,true)
separatefields()
(ord==0) ? selectevery(4,0,3) : selectevery(4,1,2)
weave()
}

I'm using 0.9.5 version of MVTools for conversion. I can't found 0.9.6.1 and don't know what has been improved.
As far as I remember the idea of upsizing movie before MVConvertFPS comes from Scharfis_brain.
For slow-motion best results can be achived with high shutter speed (good lightning of the scene), so source material is sharp.

Regards

johnmeyer
13th March 2005, 17:23
Many, many thanks for that script. I'll be gone all next week, so I may not get time to do some comparisons, but when I do, I'll post back here.

rkk44
20th March 2005, 19:55
Dear Manao,

Great work on MVTools -- the basis of most of the recent explosion in quality motion compensation avisynth functions available.

Unfortunately, I am experiencing a processing time problem with V.9.9.1. When I try to run avisynth functions which require V.9.9.1 (for example: the latest MVBob or MCRemoveDust) on my Desktop (Win 2000, 2.8 GHz P4) the scripts process "die of old age" slow (MVBob, for example: >125 hrs/45 min clip). However, when I run the exact same configuration on my Laptop (Win XP, 2 GHz Celeron), the completion time is more typical (about 40 hrs for MVBob, for example).

This order is totally reversed. From past experience, with MVTools V.9.8.2, the Desktop generally turns in processing times which are 2 - 4 times superior to the Laptop. (For example, the original version of MVBob requires about 7 hrs/45 clip on my Desktop while the Laptop runs about 26 hrs.)

Lastly, I also tried replacing V.9.8.2 in my older scripts with V.9.9.1 and I still experience the dramatic slowdown in processing time on my Desktop.

Manao
20th March 2005, 20:19
That is a strange behavior. I can't think of anything that could cause such slowdown on P4 ( i've got an Athlon XP, and I didn't notice any slowdown ), except perhaps hyperthreading.

I'm puzzled, and finding what wauses such an issue will be hard without a P4 to test, which i don't have.

paviko
20th March 2005, 22:39
@rkk44
Try playing with SetMemoryMax function. When processing chain is long changing value from 64 to 256 allowed for me to speed up 2 times.

Regards

rkk44
21st March 2005, 00:44
Dear Manao and Paviko,

Thanks for the prompt feedback and help. I do not have hyperthreading so that is not the cause of the slowness with MVTools 9.9.1. However Paviko's recommendation shows a significant speed improvement.

Fortunately, I have about 700 MB of free RAM so I did a quick and dirty comparison between memorymax = 128 (my normal setting) and memorymax = 512. At 512, MVTools 9.9.1 now works, at least in Virtualdub, with good speed.

I plan on running a CCE encode during the week to confirm this, so if it works and you do not hear anything back from me by next weekend, you know the memorymax fix worked.

Mug Funky
21st March 2005, 08:13
careful with setmemorymax - CCE especially uses bucketloads of memory, so you'll want to make sure there's enough left over for it (it tends to use about 250 megs on my machine).

if you've got a gig of RAM, then i guess max 512 is fine for avisynth (damn you and your abundant memory :))

Heini011
23rd March 2005, 11:06
hi,

i tried fluxsmooth with mvtools and despite the fact, that fluxsmooth dosn't care about blockchanging, i'am very satisfied with the result. this may give some hints for a even better mvdenoise function.

the following script works great on low-noise sources and yields slightly better sharpness and compressibility results than mvdenoise!


function FluxSmoothMC(clip,int limit)
{
# rgrmode = 1
limit = default(limit,4)
# rg = RemoveGrain(clip,rgrmode)
# pref = TemporalRepair(rg, clip)
pref = clip
bvec = MVAnalyse(pref, blksize=4, lambda=1000, delta=1, pel=2, isb=true)
fvec = MVAnalyse(pref, blksize=4, lambda=1000, delta=1, pel=2, isb=false)
backw = MVCompensate(clip, bvec).Deblock(quant=15, aOffset=4, bOffset=4)
forw = MVCompensate(clip, fvec).Deblock(quant=15, aOffset=4, bOffset=4)
interleave(backw,clip,forw)
FluxSmoothST(limit,2)
SelectEvery(3,1)
return last
}


greetings.

ADLANCAS
8th May 2005, 15:53
Hi,

I can´t open Avisynth since mvtools.dll is in plugin folder. I tried all versions from 0.95.
Is there another version for P4 like MaskTools ?

Thanks,

Alexandre

Manao
8th May 2005, 15:57
There should be no need for a special P4 version for the MVTools. As for the Masktools for what matters, since v1.5.5. The issue with P4 and Masktools was due to the dll compressor I was using, and I don't use it anymore.

So perhaps the issue lies elsewhere ? Could you try to empty your plugin directory, and put only the latest MVtools in it, to see if you can open scripts only with that or not ?

scharfis_brain
8th May 2005, 16:03
Hi Manao!

Will you include the motion interpolators somewhen again?

Manao
8th May 2005, 16:05
Damned, i've been spotted :)

No, alas, i've got no plan to do so yet. Though sometimes, on an impulse, who knows ?

ADLANCAS
9th May 2005, 01:20
Manao,

There is a problem when MVTools.dll and TransAll.dll are in plugin folder. VdubMod crashes when open a simple script in this case. I tried also to open in Windows Media Player but it shows a message that says something like "not enough memory".
I used latest version from MVTolls and TransAll.
Any idea ?

Thanks,

Alexandre

Edit1: The same problem when HDRAGC.dll and TransAll.dll are in plugin folder.

Edit2: I´ll post a message in a new thread trying to get information from VCMohan(TransAll developer) and others.

krieger2005
23rd August 2005, 19:27
Hi Manao,

i have a problem with mvtools with a complex script. Well, i build a function which trim a movie by scenechanges. I looks like this:
function RUN(clip c){
c
trim(0,119+1).makeCLEAN()+
\trim(119+2,1235+1).makeCLEAN()+
\trim(1235+2,1497+1).makeCLEAN()+
...
\trim(118400+2,118565+1).makeCLEAN()+
\trim(118565+2,119260+1).makeCLEAN()+
\trim(119260+2,119924+1).makeCLEAN()+
\trim(119924+2,0).makeCLEAN()


The Function "makeCLEAN" should clean the parts of the movies. It looks till now so:
global index=0

function MakeCLEAN(clip c){
c
ScriptClip("current_frame == 0 ? last.BlindPP(cpu=2, moderate_h=17, moderate_v=32, quant=20) : last")
ScriptClip("current_frame == (framecount-1) ? RemoveGrain(17) : last")

DeFlicker(scene=255, percent=65, lag=15, border=16)

trim(2,-1)+last+trim(framecount-3,-1)

RemoveDirt(mthreshold=75, pthreshold=2, tolerance=15)

<"Some MV-Tools Calls with idx=index">
global index=index+1
trim(1,framecount-2)
}

function "Some MV-Tools Calls with idx=index"(clip c, int i){

v = c.mvanalyse(isb = backward, lambda = 1000, blksize = 16, delta = del, pel=2, idx=i)
Q = c.mvcompensate(v, mode = 1, thscd1 = 2000, thscd2 = 170, idx = i)
\.deblock(quant = 55)
return v.MVChangeCompensate(Q)
}



When i load the code i get:
"System Exception - Access Violation", pointed to the call the Evaluation of "v" in the "MV-Tools-Call Funtion".

Even the same Problem i get when using in this Function the Mask-Tools.
Maybe this Post is nonsense, but if you can help and please post. If you want i can post you the whole script.

Thanks

Manao
23rd August 2005, 20:22
Knowing the ugly mechanisms that are behind the MVTools, I can only guess that something went wrong in my filter.

Best guess to solve the issue : call mvanalyse before trimming, and trim the vectors clips. It should work better, i hope.

On a sidenote, I don't understand what you're trying to achieve there ? why separate all the scenes ?

krieger2005
23rd August 2005, 21:04
Does MVTools work correctly, if i do the analyse BEFORE the trimming and use the Results of the Analyse AFTER/IN trimming?

The trimming of scenes is simply a try of mine... The movie got some problems with the first Frame in a scene and with the last one. Also i use Fizick's Deflicker filter with "no-Scene-Change-Detection-Mode". For me the Scene-Change-Detector of the Deflicker-Filter does not work properly.

I think also that MVTools make the problem, because i used also some other filters with no problem. I thought it was a memory-problem but i looked at the task-manager while loading the script and it show me just as much memory-usage as when i use this script without trimming.
As i wrote before it's interesting, that by using Mask-Tools (i used YV12LutXY-Function) this problem appear also. So i thought it's something same in that both Function, so they make problems. I don't know.

Manao
23rd August 2005, 21:22
Masktools' filters behave properly ( at least, like the other filters ). So if they don't work with your script, i'd rather be inclined to think that it's your script faults. Perhaps something like too much allocation of filters, or something like that.

MVTools are much more dirty in that regard, since there's a global object watching over the filters and keeping track of frames. I guess that object can easily go berserk ( it was designed when I had got much insight on how to do it properly ) if there's a lot of mvanalysis calls ( by calls, i mean applying mvanalysis to a clip, which you do a lot here, since you call it after the trim ).

What i think is that if you do all the MV processing before trimming ( ie, the analysis, and the denoising ), you shouldn't have issues. Analysis before, then trimming, then denoising, i'd say it'll work, but i'm not sure. Trimming, then analysis and denoising, and it obviously doesn't seem to work in your case.

So, in an empirically way, i'd say it safer to avoid the trimming before the use of MVAnalyse. it show me just as much memory-usage as when i use this script without trimming.Well, avisynth manages to keep its internal memory at the level set by SetMemoryMax.

My filters allocate some memory too, but it's constant and not depending on trimming ( since it's done by the global object ).

krieger2005
23rd August 2005, 22:51
Ok. Thanks for your reply.

BTW: I don't think that MVTools and any other filter like MVTools can compensate a Frame in general. The best what such filter can do is to reconstruct/compensate some parts of a frame. For thoose part the temporal-cleaning is usefull. The other Part have to clean with spatial-Cleaner... i guess PixieDust make this in this way? But this was just my meaning and can be clearly false!

scharfis_brain
23rd August 2005, 23:02
pixiedust is a motion compensated temporal cleaner.
it does only have a very limited spatial infuence.

TheBashar
28th August 2005, 11:35
Hi,

Am I doing something wrong? I tried using MVDenoise on a test clip and I get some pretty major blocking. Everybody in this thread seems to have good results so I'm wondering what I'm doing wrong.

I'm using a procedure almost straight from the MVTools manual:
b2 = MVAnalyse(clip,isb=true,lambda=1000,delta=2,pel=2,idx=1)
b1 = MVAnalyse(clip,isb=true,lambda=1000,delta=1,pel=2,idx=1)
f1 = MVAnalyse(clip,isb=false,lambda=1000,delta=1,pel=2,idx=1)
f2 = MVAnalyse(clip,isb=false,lambda=1000,delta=2,pel=2,idx = 1)
MVDenoise(clip, b2, b1, f1, f2, tht=10, thsad=300)


Cheers!

EDIT: Removed pictures due to inability to reverify.

Mug Funky
28th August 2005, 16:49
i think thSAD might be a tad high for those clouds - mathematically there's not much difference between a blocky cloud and a smooth one.

you could get an idea of what you can get away with by using mvmask and setting it to SAD mode and checking out which bits are glowing.

your source is pretty clean though - mvdenoise might be overkill for it. removedirt or something similar (like a change-limited removedirt) would be fine for that, and loads faster :)

TheBashar
28th August 2005, 20:22
I am really sorry. I have to retract my previous blocking complaint. I had tons of examples where there was very bad blocking. This morning I went to get you a sample from a less abstract (than clouds) scene and to my shock almost all of the blocking was gone. The only realy blocking that remains can be tweaked by scene change thresholds.

Until I can find the crack pipe that my computer was smoking last night when it repeatedly produced the block images, I have removed the links to the screen shots I posted. I'm going to be running some Memtest and Prim95 today to see if it was a hardware problem.

Again, sorry for the mistaken post!

scharfis_brain
28th August 2005, 20:39
sometimes AVISynth behaves strangely, which is commonly blown away after a restart. So do not worry about it.

Fizick
20th November 2005, 23:59
Recently I create a little modified versions of MVTools.
See its development history at http://forum.doom9.org/showthread.php?t=102071

Main improvents:
1. "True motion" estimation.
2. motion compensation not by blocks, but by pixels (by bilinear vectors interpolation)by function MVFlow. This method is used in some other functions:
3. Motion Interpolation by MVFlowInter
4. Motion Blur by MVFlowBlur
5. Framerate conversion by MVFlowFps.
6. Updated documentation a little.

But new release 0.9.13 is still experemental, of course.

Please test and report here.
Take it from my site.

Mug Funky
21st November 2005, 09:22
hi. thought i'd reply here rather than the other thread (though not sure if it really matters).

mvflowfps2 seems to behave oddly when going from 25p to 60000/1001.

on my work computer (p4 w/ hyperthreading) it wouldn't work at all, though 50fps worked fine on the same source.

on my home machine (athlon 64 3500+) it worked fine for 60000/1001, but motion appeared ever-so jittery. i can give a sample if you like. just gotta turn it into something more uploadable...

btw, the truemotion preset is a great idea. i didn't know i wanted it until you gave it to us :). already framerate conversion rivals (surpasses?) motionperfect and twixtor.

thanks for all your work on this.

communist
21st November 2005, 20:29
4. Motion Blur by MVFlowBlur
MVFlowBlur is not working for me. I'm using the example script in the documentation.

Source = AviSource("MSample1.avi").ConvertToYV12(interlaced=true).LeakKernelbob(0,0)
backward_vectors = source.MVAnalyse(isb = true, truemotion=true)
forward_vectors = source.MVAnalyse(isb = false, truemotion=true)
return source.MVFlowBlur(backward_vectors, forward_vectors, blur=15)

Input is KernelDeinterlaced or KernelBobbed PAL DV footage. I tried with prec=1 and higher, aswell as blur values of 1 / 10 / 25 / 99 - doesnt do anything. Output looks 100% identical to the input.

Can anyone confirm this or am I'm using it wrong?

/EDiT - I've tried with v0.9.13 and v0.9.12.3 (without the truemotion=true parameter).

Fizick
21st November 2005, 22:16
Mug Funky, communist,
Thanks for your reports.

Any improvement creates a bug. :(

But it is now fixed. Try new version 0.9.13.1 !

communist
21st November 2005, 23:31
Great - works now :) However as you said with each improvement come more problems. It works when using

MVAnalyse(isb = false)

but complains when using

MVAnalyse(isb = false, truemotion=true)

MVAnalyse does not have a named argument "truemotion"

Or did you have to remove this in order to get it to work?

Fizick
21st November 2005, 23:49
Camarade, really?
Truemotion must work and works fine for me.
What version date?
22 november 2005, 0:05:13

I never wanted to release a version with a number 13 :)

communist
22nd November 2005, 00:02
Hmm yes I downloaded the latest version but I must have extracted the wrong one - sorry my fault. Truemotion parameter works now.

However there seems to be a problem with MVFlowFPS. Using 50fps material as input and setting output frame-rate to 100 in the sample script:

backward_vec = source.MVAnalyse(isb = true, truemotion=true, pel=2, idx=1)
forward_vec = source.MVAnalyse(isb = false, truemotion=true, pel=2, idx=1)
return source.MVFlowFps(backward_vec, forward_vec, num=100, den=1, ml=100, idx=1)

The filter 'resets' after frame 214 - frame 215->end seems to be frozen (shows frame 0).
When setting 400fps as output it will also crash VirtualDub when seeking to frame 422.

Fizick
22nd November 2005, 00:14
I mostly tested it with short video only.
Will try.

Fizick
22nd November 2005, 00:24
Communist,
what is your PC system config?

communist
22nd November 2005, 00:29
AMD Athlon XP2600+ (MMX/3dnow/SSE)
WinXP SP2
768MB RAM
MSI K7N2-L Delta nforce2 motherboard
GF4Ti 4200 / 160GB + 60GB IBM hdds

Is it because of insufficient RAM?

Fizick
22nd November 2005, 00:56
I have similar.
Avisyntn 2.5.6?
may be is some "problem" source ?
Try another source.

Wait reports from other users.

johnmeyer
22nd November 2005, 05:44
My test script stopped at frame 585. I am using AVISynth 2.5.6, and was using MVTools 0.9.13. Also, I was using num=120 and my video input was 29.97 fps (NTSC DV fed through kerneldeint).

Fizick
22nd November 2005, 06:41
Please check the same source clip, but trimmed before MVTools (latest version is 0.9.13.1).

source=source.trim(100,0)
MV...

What is the new "stopped" frame now? The same (by content) or with the same number?

May be some bad motion vector generated (pointed out of frame boundaries).
if som please prepare some short clip (3-5 frames) with the bad frame.

chilkari
22nd November 2005, 08:19
First of all - THANKS! I'm very very excited about the TrueMotion mods to this plugin. Now...

FlowBlur works fantastic.

However, FlowFPS and FlowFPS2 work great for about 170 frames then blow up, taking VDdub down with them. It plays fairly smoothly up to about frame 107, then jumps/skips over to 157, then skips into 170-ish -- and dies.

Several experiments:

1) Changed frame size from 352x240 to 720x480 -- no difference crashes on same frame (around 170).

2) Tried different values for SetMemoryMax() - 128, 384, 512 - no difference.

3) Trimming down to (0,30) - runs fine. Never gets into trouble.

I have an Athlon 3800 (laptop) with 1GB RAM. Using Avisynth 2.5.6 and MVTools 0.9.13.1.

I'll try to get better info tomorrow night (must go to bed now).

My source is MiniDV using DirectShowSource. Could be problem there?

Script that blows up:

setmemorymax(512)
loadplugin ("C:\MOVIE\plugins\tdeint.dll")
loadplugin ("C:\MOVIE\plugins\MVTools.0.9.13.1.dll")
loadplugin ("C:\MOVIE\plugins\ReInterpolate411.dll")
loadplugin ("C:\MOVIE\plugins\cnr2.dll")

x = DirectShowSource("c:\movie\mine\TAPE_0001.avi", fps=29.970)
\ .Trim(0,100)

clean = x.cnr2().Reinterpolate411()
deint=clean.tdeint(mode=1,type=2, mthreshL=2, mthreshC=2)
source=deint.ConvertToYV12()
backward_vec = source.MVAnalyse(isb = true, truemotion=true, pel=2, idx=1)
forward_vec = source.MVAnalyse(isb = false, truemotion=true, pel=2, idx=1)

return source
\ .MVFlowFps(backward_vec, forward_vec, num=80, den=1, ml=100, idx=1)
\ .AssumeFPS(23.976)

chilkari
22nd November 2005, 08:44
Just a little more information. I went back to 0.9.12.4, removed the truemotion arg to MVAnalyze -- same problem. Blows up at the same point.

I tried with an ImageSource instead of DirectShowSource (Completely different source -- image sequence of PNGs instead of DV) -- same problem (roughly the same frame as well).

johnmeyer
22nd November 2005, 08:47
Downloaded the latest (v0.9.13.1). Runs without stopping on a 10 second NTSC DV clip. Two problems remain:

1. Can't slow down more than 4x. Since I'm deinterlacing NTSC video, num=60 is normal speed. Any number up to num=240 works. If I use 360, it fails to provide most intermediate frames, and I get instead duplicated frames.

2. Only seems to work on second half of the clip. I am not sure whether this is a problem with the threshold setting for LeakKernelBob, a problem in MVAnalyse, or a problem in MVFlowFPS. For the first half of the clip, I get intermediate frames, but the result is not smooth. In the middle of the clip, I get a few smooth frames, then jerky frames, then a few more smooth frames. For the last 1/3 of the clip (roughly), I get very smooth motion -- what I would expect. The few seconds of slow motion at the end of the clip are truly amazing -- and I haven't yet tried tweaking (using different block sizes, etc.).

Here's the current script (which uses suggestions provided earlier in this thread):

loadplugin("c:\Program Files\AviSynth 2.5\plugins\LeakKernelDeint.dll")
loadplugin("C:\Program Files\AviSynth 2.5\plugins\MVTools\mvtools.dll")

AVISource("J:\Senior Video Tribute (do not erase)\Video\Video Highlights (JHM)\Baseball\Baseball-0013 - 000.avi")

assumebff()
changespeed(4, 5)

function changespeed(clip a, int factor, int th)
{

ord = getparity(a) ? 1 : 0
g=a.LeakKernelBob(order=ord, threshold=th)
h=converttoyv12(g)
vec_back = h.MVAnalyse(isb = true, truemotion=true, pel=2, idx=1)
vec_forw = h.MVAnalyse(isb = false, truemotion=true, pel=2, idx=1)
h.MVFlowFps(vec_back, vec_forw, num=60*factor, den=1, ml=100, idx=1)
converttoyuy2()
assumefps(60,true)
separatefields()
(ord==0) ? selectevery(4,0,3) : selectevery(4,1,2)
weave()
}

P.S. [Edit] The fps throughput reported by VirtualDub when reading this script falls to about 1/2 the fps rate at the end of the clip, where the quality is good.

P.P.S. [Edit 2] Changing the blkssize down to 4 in MVAnalyse and using search=3 makes everything work much better -- about 85% of the clip now shows correct, smooth motion. However, the remaining 15% is still "jerky."

Fizick
22nd November 2005, 21:53
I got it!
It was a bug for crazy (huge) source numerator and denominator.
But it seems, that Avisynt use exactly such crazy values of it for NTSC.
60000/1001 worked fine, but fps=59.94 was = 15712911/262144 !
This bug is fixed in new v.0.9.13.2

(now I know how to multiply _int64 values properly :) )

communist
22nd November 2005, 22:34
Great now any number works (tested with upto 1600fps). For some stuff it already works amazing for creating superslowmotion - Thanks for this great plugin :)

chilkari
22nd November 2005, 22:50
I can't wait to try this out tonight. Thanks, so much, Fizick! :D

chilkari
22nd November 2005, 22:58
Nah - couldn't wait! Snuck it in from work. It works Great! HA! I'm going to be up late tonight playing with this toy.

Mug Funky
23rd November 2005, 04:21
awesome! 60/1.001 to 50 conversions are working very nicely indeed!

we just need some kind of artefact protection now - i understand there's a fair bit worked into the filter already, but i'm getting (not surprisingly) mismatches on patterns.

for example, a camera following a person walking past a wall made of horizontal slats of wood. the slats move in unison until the person comes near it, then parts of the wall match the wrong slat in adjacent frames, causing a shear when compensated.

or a similar effect with japanese sliding doors, except vertical instead of horizontal.

hmm. i'm not sure i've explained it well. it kind of reminds me of those "magic eye" pictures where you deliberately point your eyes in the wrong direction causing slightly different patterns to overlap in your brain and give a 3d effect... except without the 3d effect :)

anyway, thanks heaps for your work on this. it's looking very, very promising.

johnmeyer
23rd November 2005, 04:59
Has anyone got a script yet that produces really awesome slow motion? Mine seems to be working fine now, but I'm still getting artifacts. Some of this can't be helped (I've used Motionperfect, so I know what to expect), but I figured there might be some additional settings in MVAnalyse or in the deinterlacer that might help (I'm using LeakKernelBob). Or, perhaps you've tried MVFlowFps2 and gotten better results (I haven't yet taken the time to figure out how to do the cropping, etc.).

Anyway, it's not that I'm lazy -- I've spent several hours "perfecting" my script (which I shared earlier) -- but I'm hoping someone else might have some ideas or insights, perhaps using some combination of frame-based motion comp and this newer pixel-based motion comp. Or maybe there are some key MVAnalyse settings that I haven't yet tried (I'm using the defaults that you get with "truemotion" set to true).

foxyshadis
23rd November 2005, 05:27
If you're going to mocomp you should really use the most advanced deinterlacer you can, which means either tdeint or mvbob (which is basically tdeint+leakkerneldeint+mvtools). I've been adapting mvbob to Motion for my own use, but it shouldn't be too terribly difficult to adapt it to mvflow. In fact since you're mocomping anyway, you could probably bastardize mvbob into doing the slowmo during the bob, eliminating the post-bob compensation, but I won't go there.

Mug Funky
23rd November 2005, 09:14
that's a pretty good idea. you'd still need the output from mvbob, but perhaps you can re-use the motion-vectors searched off the lower-quality bob?

the vectors will be lower quality, but with truemotion mode it should make no practical difference (and you can now use MVflow to make the compensation, increasing quality a fair bit, especially on rotation and zooms).

videoFred
23rd November 2005, 09:33
we just need some kind of artefact protection now - i understand there's a fair bit worked into the filter already, but i'm getting (not surprisingly) mismatches on patterns..

The same here....

But the improvement, compared with the old MVConvertFps() is already spectacular. I have already created very nice slow motion (assumeFPS(1)!!) from original 15fps source with almost no artefacts.

But I agree: sometimes artefacts, sometimes not. It depends on the scene.

Now, what can we do to improve this?
Can we make a script that detects the artefacts?
And correct them?

But of cource, if the difference between two frames is to much (fast movement) it's almost impossible to calculate correct new intermediate frames, right?
I think we need 3d software for this....

But I do not understand '60/1.001 to 50 conversions '
Please explain!

Fred.

Mug Funky
23rd November 2005, 09:53
60/1.001 is a pedantic way to say 59.94 aka NTSC. to be really specific it's 60000/1001, but i like the decimal for avisynth reasons (it'll give ints if fed ints).

i'm converting NTSC to PAL :)

[edit]

as far as detecting artefacts... tricky. perhaps do a comparison using a full compensation and then motion interpolate the resulting mask?

the problem lies in matching blocks - if you move the block to compensate the frames you get no artefact because the mismatched block will in fact look more like the area to be compensated than the true position. this only shows up when mvflow is used to compensate, and a boundary between good matches and mismatches results in a sheared picture area.

we probably need pictures to explain this properly...

the solution to this problem most probably lies in simply improving the true-motion searching involved. considering clouded's motion search (using a true-motion algo, rather than a modified version of mvtool's algo) gives the same artefacts in the same places, it looks like this'll be a hard one to crack. my thoughts are that some kind of "edge-following" is needed in the motion search, but even this will probably fail if the regular pattern has a spatial period close to the block size.

i don't know enough about motion-estimation to say more than that... and in fact all of the above is guesswork as i've never seen (nor attempted to understand) the sources for mvtools or motion.

thankfully it doesn't come up often.

videoFred
23rd November 2005, 10:25
thoughts are that some kind of "edge-following" is needed in the motion search

I was thinking of this, too.
Could extreme sharpening and do motion detection/estimation on this sharpened clip be an improvement? Or increasing contrast or something...

Or could we not seperate moving objects and background with motion masks?

Fred.

mg262
23rd November 2005, 11:16
There are "feature tracking" methods of the kind you mention out there (e.g. see here again (http://forum.doom9.org/showthread.php?t=100791)). But, I tried a rough implementation of one and it seem to miss most important features. Its very rough... 100 lines of code... but you're welcome to it if interested, Fizick.

IMO improving true motion search is tricky. (This (http://www.icce.org/authors_page/slides.pdf), on p13, looks very interesting... ) But there are still alternatives... e.g. using masks.

Fizick
23rd November 2005, 18:50
1) The motion estimation is generally incorrect task.
There are many suggested partial solutions only.

2)Generally say, some preprocesing of clip for estimation is good method.

For example, here is my crazy idea for video with regulal patterns (like building blocks wall):
Try preprocess it with my DeFreq plugin :)
Or at last some blur.

3) I have some ideas (but not inplementation) for improving MVFlowFps artefactes.
I think, it must switched to simple not-compensated (like convertfps) or to globalmotion compensated (like Depan) frames if many bad areas detected.

I also think about to add some parameter to smooth vectors more and more (to global motion limit).

May be bi-direction motion vectors would give some improvement to motion interpolation (FPS convertion).

4)Deinterlacing is other task. But I am not intersesting in it now (as well as in video standard conversion too). I am interested in motion for progressive video only.

scharfis_brain
25th November 2005, 22:22
If you're going to mocomp you should really use the most advanced deinterlacer you can, which means either tdeint or mvbob (which is basically tdeint+leakkerneldeint+mvtools). I've been adapting mvbob to Motion for my own use, but it shouldn't be too terribly difficult to adapt it to mvflow. In fact since you're mocomping anyway, you could probably bastardize mvbob into doing the slowmo during the bob, eliminating the post-bob compensation, but I won't go there.


this version of mvbob()
http://forum.gleitz.info/showpost.php?p=239437&postcount=23

does the 50 <-> 59.94 fps conversionon the fl by reusing motionvectors from deinterlacing.

Though, the version is about 2 weeks old, so it will need a rewrite, again for which I do not have any time ATM.

Fizick
27th November 2005, 23:05
v0.9.13.3 (Released 27.11.2005)
Added global motion (simple method) vector predictor to MVAnalyse.
Vector search is skipped (for speed) if good predictor was found (with SAD
Parameter scale in MVShow works properly now.
Disabled some debug and profiling info output (for speed increasing).
Changed default prec=1 (was 2) in MVFlowBlur.

Mug Funky
28th November 2005, 10:35
very slight bug... "percent" in mvflowblur seems to be double what it should be.

a shutter that's always open (like that on a CCD video camera) should be the real world equivalent of 100% in mvblur. but i need to enter 50% to get this.

i'm testing it out on "beast wars", a very old CG cartoon where there's no motion-blur whatsoever (and barely any antialiasing...), and MVflowBlur is working extremely well! it even appears to account for acceleration and angular motion, and produces (best case scenario) better motion blur than 3dsMAX's old vector-based motion blur, which is impressive indeed. i haven't used max since version 4 though... they may have improved it :)

a bonus is you can do mvblur to 50% (well, 25%) and then interpolate the framerate using the same vectors to make 25p, no blur into 50i with motion-blur. makes it look like it was shot on a video camera in CG-land :) even fast motion with loads of texture come out good most of the time. of course REALLY fast/complex motion with aliased texture (which kills corellation between the same object on different frames) can be spoiled, but i don't expect it to be perfect (twixtor's motion blur fails spectacularly if there's no blur present in the source, even on ery simple motion).

i'm very impressed indeed.

[edit]

@ fizick:
just read your reply about artefact protection. interesting idea with deFreq, but impractical IMHO. frequency-wise a brick-wall pattern is wide-band, as are most other patterns. and in any case, even if these regular patterns were perfect sines there's still be the possibility of mismatches simply because one cycle looks like another. i noticed Clouded's Motion stuff suffers the same drawbacks when warp-compensation is used. it's to do with the transition between correctly matched blocks and incorrectly matched ones.

maybe think of each matched block as a local minimum of the used comparison metric (it's still SAD, right?). on most frames the local minimum will be the global one for each block, but some frames have multiple minima and only 1 correct one. i guess the trick is using what we know about the frame and it's surrounding frames to better guess the global minimum (especially in cases where there are several blocks that match perfectly, such as diagonal sines moving to the left at a rate near the sine's period... this potentially has 8 correct matches but only 1 true one)

of course, having described the problem i still have no idea for a solution :) increasing vector coherence, lambda style is not a guaranteed solution, as it'd just shift the "fault line" around.

Fizick
28th November 2005, 19:45
Mug Funky,
1 . It is not a real bug, but I can change the blur scale, if nobody object to it.

2. Defreq must work with not-sinewave too. But there are no real solution, yes.
Human eyes often wrong too in this case.

3. I also not very happy with global motion. it is generaly better, but sometimes wrong with logo. So, i want restore zero vector predictor (in addition to global motion predictor)

2.

Fizick
2nd December 2005, 15:00
Version 1.0 (Released 29.11.2005)
I'm tired of long version numbers :). But the plugin is stil experimental :(.
Restored zero vector predictor in MVAnalyse.
Changed blur time scale in MVFlowBlur (100 is fully open shutter now) as Mug Funky requested.

Mug Funky
2nd December 2005, 15:04
thanks fizick!

what's this zero predictor thing?

1.0 release! it's a milestone :)

Fizick
2nd December 2005, 16:19
I use 1.0 simply in order to Manao start to develop version 2.0 alpha :)

zero predictor is a vector with null length (i.e.static block)

acrespo
2nd December 2005, 18:37
Recently I create a little modified versions of MVTools.
See its development history at http://forum.doom9.org/showthread.php?t=102071

Main improvents:
1. "True motion" estimation.
...


What is "true motion" estimation? I read some threads here but I don't understand.

Can I use this filter to motion estimation in anime/cartoon? I am asking because some time ago I read a comment here that it's not recommend.

Fizick
2nd December 2005, 20:44
Why do you want to motion estimation?
Interpolation is not recommended (too abrupt motion).

acrespo
2nd December 2005, 20:56
Well I tried mvbob some time ago in my animes and I have too many block artefacts. Other avisynth script to convertfps based in a mvtools function give me blocks too. For this reason I am asking if now I can use mvtools functions in anime. The creator of mvbob told me to not use in anime becaus mvtools functions are not good to anime.
I am very newbie in this subject and I don't understand exactly what motion estimation do and I am learning, and documentation is very poor to newbies like me. I don't know the difference between motion estimation and "true motion" estimation.

foxyshadis
2nd December 2005, 22:29
There is anime where mvtools can work well, mostly native 24/25/30 fps animation and cg. Bigger-budget houses like disney, pixar, and ghibli especially. Most anime however is 12 fps with gimmicks to make it look a little smoother, or 24 with motion that isn't smooth enough, which throws the motion off something severe and causes lots of those messy artifacts.

If stepping through the video it looks as if it could have been filmed, with constant natural-looking motion, it'll work, otherwise don't bother.

True-motion is motion-estimation taken down to the pixel level, as opposed to the block level that standard mvtools uses. That's the most important difference.

Fizick
2nd December 2005, 23:46
1. "true motion" is true motion estimation, it may be both pixel level and block level.
The most important, that it search not the simply most similar block, but with some coherence to neighbors. Old MVTols tryes to make it too (with lambda), but not so strong.

2. why do not try? Better to see than to read. :)

Neil Lee
10th December 2005, 20:47
Hi Manao (Fizick):

Big thanks for the MVtools, Temporal denoising with motion estimation
had only been a dream for me, Glad that I've found it in MVtools, finally.:)
I read the document, is MVdenoising only uses 3 frames (previous, current,
following) for averaging? Would it be enough for very noisy videos?

I've been using VirtualDub's temporal smoothing, very effective on static
areas, it takes up to 7 frames (3 previous, current, 3 following) and
does a time weighted averaging. Too bad it doesn't have motion estimation.
I'm not familiar with AVIsynth, don't know if it can fetch as many following
frames? (maybe a frame buffer will help? downside is output lag:)

I haven't started to use MVtools, still reading the long documentation, was
just too excited and thought maybe you would consider using more frames,
alongside with Motion(&Time) Weighted Averaging? Which performs like:

High-Motion area = Low pixel diff threshold / average less frames
Low-Motion area = High pixel diff threshold / average more frames
Static Area = Max pixel diff threshold / Max average

If you had the time, please consider it :)

Big Thanks and keep up the good work..!

Fizick
10th December 2005, 23:48
Neil Lee, welcome to the forum!
1. Thanks for your thanks!
But MVTools creator is Manao. I only add some function to it (read version history).

2. Read document up to end. You find script examples with 5 frames. And generally there is no limit.
3. Avisynth has no any temporal lag.
4. You (we) can use both internal MVDenoise, and external denoisers with some mask.
Some complex denoiser scripts were posted here (in another threads).
I have a plan to implement new internal denoiser to MVTools, but it is still under development (i.e. no any code :)).

Neil Lee
11th December 2005, 05:06
Hi Manao/Fizick, thanks for the reply

I believe the document doesn't give MVDenoise' averaging algorithm,
I mean how does it calculate the output pixels?
Is it a "flat" average or a weighted one?

for example in 3 frames situation :

A. output pixel = 33% previous + 33% current + 33% next
B. output pixel = 25% previous + 50% current + 25% next
C. output pixel = 15% previous + 70% current + 15% next

(A. has the most smoothing strength, C. has the least)

I believe Vdub's temporal smoother uses B., which is a reasonable approach, but
I'd like to have a "flexible" averaging algorithm,(and an adaptive noise threshold:),
which takes motion vectors into account, like I mentioned in the previous post,
I would prefer :

A. for static area (can erase more noise)
B. for low-motion area
C. for high-motion area (to avoid smearing artifact)

and again, if you had the time, please consider it :)

Thanks....

Mug Funky
11th December 2005, 06:27
Bigger-budget houses like disney, pixar, and ghibli especially.
well, not to split hairs, but ghibli is 12fps for the cel-painted stuff. just the motion graphics and CG sequences are 24fps. disney do a lot more 24fps, but they tend to flip between the 12fps and 24 depending on the complexity and importance of a given sequence. they'll do more full-rate stuff because they have the budget for it (ie thousands of poor fine-arts and illustration students:)).

but more identical frames makes it easier to denoise, so i'm not complaining. then all the motion-compensation is needed for is fixing registration errors.

Manao
20th December 2005, 22:07
Neil lee : it's a flat average. Note, you can emulate its behavior with a script, so you can achieve what you want with a script. It'll be slower, but it'll help to see if it's useful or not.

Isochroma
20th December 2005, 23:07
I made some tests with different numbers of reference-frames. At six, certain artifacts begin to show up, and twelve and twenty-four become unworkable unless the parameters are tweaked.

Increasing thT to 16 prevented major artifacting in the 6-frame version; in particular I'm interested in suggestions for the thT, thSAD, and thMV parameters and likely values for large numbers of reference frames?

Fizick
21st December 2005, 01:48
Isochroma,
IMHO, MVdenoise use too simple algo to twenty-for frames diameter.
Some weighting must be used.
but you can create some script and use external (not MVDenose) denoising of MV-compensated frames.

Try use search forums with "MVTools" word.
Here some good examples:
http://forum.doom9.org/showthread.php?t=90042
http://forum.doom9.org/showthread.php?t=101387

Isochroma
21st December 2005, 04:35
Thanks!

Mug Funky
21st December 2005, 08:24
i'm not sure if i'm supposed to be able to do this, but i'm running mvanalyse on a yv12 clip and mvflow on a yuy2 clip.

results are kinda... different. mostly junk on the right half of frame, and a _nearly_ good compensation on the left (some parts are green/pink where warping has taken place). some frames are good though...

should i just use yv12?

btw - for anyone doing mocomped denoise on anime, blksize=16 is a big help for pans and stuff - just make sure your thresholds for whatever denoiser you use allow for the serious warpage that you'll get around animated objects.

@ foxyshadis:
i'm having a shot at denoising "my neighbor totoro", and it's definitely not 24fps :) very pretty though, if a little grainy.

Didée
21st December 2005, 09:09
Here some good examples:
http://forum.doom9.org/showthread.php?t=90042
http://forum.doom9.org/showthread.php?t=101387
Uh-oh, the 2nd one is LTSMC ... that one was/is purely for evaluation, wouldn't dare to recommend using it.

MCNR_simple (http://forum.doom9.org/showthread.php?p=752196#post752196) (posted silently) seems quite usable, so far. (Was build starting with a Schwarzenegger-Denoiser Mug Funky had posted.) Also, it inherently has the possibility to use weighted averaging, since it optionally can use TTempSmooth internally - however in the script, TTempSmooth's parameter "strength" is fixed to "5". Must be manually reduced to get weighted averages.
From the few testing done, it seems to me that "flat" averaging, plus the offered "lowpass protection", do the best job.


@ Fizick:

Could you check (again?) chroma treatment?. When using above script, I'm almost convinced that chroma is shifted to the right by a half pel: faces against a dark background get a greyish border on their left side. When placing yv12convolution("0 1 1","1",Y=2,U=3,V=3) after the script, it looks correct again, apart from the unnecessary blurring.

Fizick
21st December 2005, 11:43
Mug Funky,
YUY2 is not implemented in mvtools (it is in "to do" list).

Didée,
What "above" script I must check for croma? MCNR_simple2 ? It is too complex for debugging.
Chroma displacement = luma displacement / 2
There is some roundings:
Ordinary rounding: 2/2 =1, 3/2 = 1, -2/2 = -1, -3/2 =-1
But probably MVTools use (fast) right bit shift:
Chroma displacement = luma displacement >> 1
In this case rounding woul be differ for negative:
3/2 = 1, but -3/2 = -2
I will look to source.

foxyshadis
21st December 2005, 12:42
@ foxyshadis:
i'm having a shot at denoising "my neighbor totoro", and it's definitely not 24fps :) very pretty though, if a little grainy.
I know, I checked a couple of my friend's DVDs after your earlier comment and confirmed it. ^^; I like your block=16 idea though. I wonder if size 32 would do any good at all if enabled?

Mug Funky
21st December 2005, 15:33
Schwarzenegger-Denoiser

damn, if that were easier to spell i'd make that the function name :)

bear in mind that denoiser was meant for some very very old, high-ISO, several-times copied anime on 16mm film.

Didée
21st December 2005, 16:08
Mug Funky: What about "bulldozer" then? Easier to spell? :)
(Just poking you - it does an awesome job for very strong cleaning!)


Fizick,
I stumbled over the default for "lambda" when "truemotion=true": 1000*blksize*blksize/64. Is that really intended? It gives
blksize=4 -> lambda=250
blksize=16 -> lambda=4000

Shouldn't it be the other way round? Using 1000*64/blksize/blksize gives
blksize=4 -> lambda=4000
blksize=16 -> lambda=250

The usual rule of thumb is "smaller blocksize, bigger lambda" ... or did you find the reverse is better for truemotion?

scharfis_brain
21st December 2005, 16:22
I have an idea for a function wrapping for lossless YUY2 motion compensation:

warning! pseudocode follows:


x=last #yuy2 video to compensate
y=x.converttoyv12()
u=x.utoy().converttoyv12().pointresize(y,width,y.height)
v=x.vtoy().converttoyv12().pointresize(y,width,y.height)
y_comp=y.mvflow(vf,vb).converttoyuy2()
u_comp=u.mvflow(vf,vb).pointresize(y,width/2,y.height).converttoyuy2()
v_comp=v.mvflow(vf,vb).pointresize(y,width/2,y.height).converttoyuy2()
comp=ytouv(u_comp, v_comp, y_comp)

It WILL be slow, of course.

Fizick
21st December 2005, 20:21
Didée,
1)Internally lambda is a SAD penalty coefficient for vector squared difference from predictor (neighbors).
cost = SAD + lambda*vdif*vdif
SAD is proportional to block area, so default lambda must be too.
2) I can not get any chroma shift.

blankclip(color=$000000,width=256,height=256)
a=addborders(96,0,0,0,color=$FFFFFF).crop(0,0,-96,0)
b=addborders(143,0,0,0,color=$FFFFFF).crop(0,0,-143,0)
interleave(a,b)
src=converttoyv12()
v=src.mvanalyse(truemotion=true)
src.mvcompensate(v).subtitle("mc")
interleave(src,last)
pointresize(width*2,height*2)

Fizick
28th December 2005, 14:03
New MVTools version 1.0.2
Corrected value of displacement in MVFlow (a little).

Fizick
30th December 2005, 00:25
Oops! new v1.0.3
Fixed bug with displacement in MVFlowInter, MVFlowFps (introduced in v1.0.2).

Backwoods
3rd January 2006, 04:13
MPEG2Source("K.d2v")
Telecide(1)
Decimate(5)
i=Trim(6100,7200)
#mdata=DePanEstimate(i)
mdata=MVDePan(i)
DePanStabilize(i,data=mdata)

I receive an access violation when replacing DePanEstimate with MVDepan. Do I have to set parameters for MVDepan?

krieger2005
3rd January 2006, 22:43
From MVTools-Documentation:

vectors = source.MVAnalyse(isb = false)
globalmotion = source.MVDepan(vectors, pixaspect=1.094, thSCD1=400)
DepanStabilize(source, data=globalmotion, cutoff=2.0, mirror=15, pixaspect=1.094)

So you must get the vectors from MVAnalyse...

wonkey_monkey
17th January 2006, 12:37
Hi,

Where can I find the latest version of MVTools? I can only find up to v0.9.9 on http://manao4.free.fr/

Thanks,
David

Sylf
17th January 2006, 22:04
Did you check the file just above v0.9.9?

WorBry
18th January 2006, 11:44
I cant find v1.0.3 either

Didée
18th January 2006, 12:15
Yes indeed. Fizick spelled some magic and made all newer versions vanish.

Hint: read here (http://forum.doom9.org/showthread.php?p=766736#post766736) and below.

WorBry
1st March 2006, 07:47
Hi Fizick,

Thanks for adding YUY2 support to MVTools v 1.2.1.

However, with my PAL YUY2 sources (Pal DV deinterlaced to 50fps HuffYuv with MVBob or EEDI2-TDeint (mode 1), and to 25fps with EEDI2-Deint (mode 0), I am now seeing some sort of frame shift after applying MVFlowBlur that did not occur when I was pre-converting the clips to YV12. The effect appears as a strip (about 4 pixels wide) shifted from the right edge of the frame to the left edge.

For the 50fps clips, I’m using:

a=avisource("C:\50fps source.avi")
backward_vectors = a.MVAnalyse(isb = true, truemotion=true, idx=1)
forward_vectors = a.MVAnalyse(isb = false, truemotion=true, idx=1)
b=a.MVFlowBlur(backward_vectors, forward_vectors, idx=1)
Return b.SelectEven()

And for the 25fps clips:

a=avisource("C:\25fps source.avi")
backward_vectors = a.MVAnalyse(isb = true, truemotion=true, idx=1)
forward_vectors = a.MVAnalyse(isb = false, truemotion=true, idx=1)
b=a.MVFlowBlur(backward_vectors, forward_vectors, idx=1)
Return b

I’m also seeing the same effect with a modification of Scharfis_Brain’s mvfps function, replacing MVConvertFPS with MVFlowFPS:

avisource("C:\50fps source.avi")
mvfpsflow(25,oversample=16,blurradius=4)
#
function mvfpsflow(clip i, float fps, int "oversample", int "blurradius")
{
oversample=default(oversample,1)
blurradius=default(blurradius,1)
j=i.temporalsoften(2,4,5,2)
forward_vec=mvanalyse(j,isb=false, truemotion=true, idx=1)
backward_vec=mvanalyse(j,isb=true, truemotion=true, idx=1)
i.MVFlowFps(backward_vec, forward_vec, num=fps*oversample, den=1, ml=200, idx=1).deblock
(oversample>1) ? last.temporalsoften(blurradius,255,255,mode=2).selectevery(oversample,0) : last
}


The source clips are 720 x 544 so it doesn’t seem to be due to some block incompatibility. It appears to be coming from the oversampled-temporal blur, because it disappears if I eliminate the last temporal soften.

The effect also occurs if I replace MVFlowFPS with MVFlowFPS2 in the above script, but, in this case, every 8th frame (0, 8, 16 etc) is unaffected.

I’ve attached a frame-shot showing the effect.

If it’s not a bug, can you suggest a remedy?

Thanks.

Fizick
1st March 2006, 15:09
Yes, it is a bug. It arised from assembler optimized YUY2 conversion routines whcih I borrowed from from Avisynth 2.6 CVS.
Bug will be fixed in next version.
Temporary (slow) workarond: add parameter "isse=false" to MVFlow...

WorBry
1st March 2006, 19:58
Thanks Fizick. Yes, the temporary workaround corrected it. Looking forward to the bug-fix in the next release.

Fizick
5th March 2006, 18:26
WorBry,
next release 1.2.2 is released today.
Only this bugfix.

WorBry
6th March 2006, 14:41
Great. Thanks alot.

AI
24th April 2006, 08:14
Idea from Motion (http://people.pwf.cam.ac.uk/mg262/posts/Motion/motion.html)
not search vectors, but summation (add):
bsz=16
forwvect1=MVAnalyse(blksize=bsz, overlap=bsz/2, isb=true, truemotion=true, delta=1, idx=1)
forwvect2=MVAnalyse(blksize=bsz, overlap=bsz/2, isb=true, truemotion=true, delta=2, idx=1)
forwvect4=MVAnalyse(blksize=bsz, overlap=bsz/2, isb=true, truemotion=true, delta=4, idx=1)

forwComp1= Last.MVFlow(forwvect1, thSCD1=500, idx=1)
forwComp2= Last.MVFlow(forwvect2, thSCD1=500, idx=1)
forwComp3= forwComp1.MVFlow(forwvect2, thSCD1=500)

forwComp4= Last.MVFlow(forwvect4, thSCD1=500, idx=1)
forwComp5= forwComp1.MVFlow(forwvect4, thSCD1=500)
forwComp6= forwComp2.MVFlow(forwvect4, thSCD1=500)
forwComp7= forwComp3.MVFlow(forwvect4, thSCD1=500)now we can use:Interleave( backcomp7, backcomp6, backcomp5,\
backcomp4, backcomp3, backcomp2, backcomp1,\
Last,\
forwcomp1, forwcomp2, forwcomp3, forwcomp4,\
forwcomp5, forwcomp6, forwcomp7)
TemporalSoften(7,16,16,mode=2)
selectevery(15,7)very good idea, for anime with background panorama (global move) and move personage foreground.
(DePan can't right find this global move)

PS Excuse me my English :(

Edit: after edit - we have smaller errors becose we have summation only 2 vectors (except vect7)
Edit2: I delete "idx=1" in several MVFlow
Edit3: I add thSCD1=500 for noise anime, and large bloks

Fizick
24th April 2006, 16:33
AI,
it was discussed here:
http://forum.doom9.org/showthread.php?p=753009#post753009

AI
24th April 2006, 19:14
I post in this thread ("usege" forum) becose this is real idea (not only theoretical)
and this idea can help save cpu time anyone too.

What somebody else think about it?

PS excuse me my bad english...

Fizick
25th April 2006, 18:47
New version 1.2.4 is released.

Implemented MVDepan for interlaced source separated by fields;
added optional MVDepan log file.

Fixed bug v.1.2.3 with info mode in MVDepan

Adub
25th April 2006, 23:55
Get is here. (http://avisynth.org.ru/mvtools/mvtools-v1.2.4.zip)

I had some trouble finding it, so I thought to make it easier for others. :)

Alain2
26th April 2006, 01:17
What somebody else think about it?
Probably a stupid question, but I don't understand the logic in what you do...

In your calcs, for instance for forwComp4, you apply the forwvect1 compensation vectors to an already well compensated frame forwComp3 (compensated with a 3-frames objects movement length), so the objects are not in the same place now, so re applying the old compensation vectors will just mess up the video, won't they ?

From what I read in Fizicks thread, I think the idea of Neil Lee is to do only delta=1 steps compensations internally and make a sum of the compensation steps.. I don't know how to script that, but I don't think that manao's script given in answer to Neil Lee does what was asked for.. (or at least I don't understand what mode=1 in mvcompensate does)

maybe something like

back2=last
back1=trim(1,0)
current=trim(2,0)
fwd1=trim(3,0)
fwd2=trim(4,0)

back2vectback=back2.MVAnalyse(blksize=bsz, overlap=bsz/2, isb=true, truemotion=true, delta=1, idx=1)
back1vectback=back1.MVAnalyse(blksize=bsz, overlap=bsz/2, isb=true, truemotion=true, delta=1, idx=2)
currentvectback=current.MVAnalyse(blksize=bsz, overlap=bsz/2, isb=true, truemotion=true, delta=1, idx=3)
currentvectfwd=current.MVAnalyse(blksize=bsz, overlap=bsz/2, isb=false, truemotion=true, delta=1, idx=3)
fwd1vectfwd=fwd1.MVAnalyse(blksize=bsz, overlap=bsz/2, isb=false, truemotion=true, delta=1, idx=4)
fwd2vectfwd=fwd2.MVAnalyse(blksize=bsz, overlap=bsz/2, isb=false, truemotion=true, delta=1, idx=5)

back1comp=current.MVFlow(currentvectback, idx=3)
back2comp=back1comp.MVFlow(back1vectback, idx=2)
back3comp=back2comp.MVFlow(back2vectback, idx=1)

fwd1comp=current.MVFlow(currentvectfwd, idx=3)
fwd2comp=fwd1comp.MVFlow(fwd1vectfwd, idx=4)
fwd3comp=fwd2comp.MVFlow(fwd2vectfwd, idx=5)

interleave( back3comp, back2comp, back1comp,
\ current,
\ fwd1comp, fwd2comp, fwd3comp )

TemporalSoften(9,16,16,mode=2)
selectevery(7,3)

AI
26th April 2006, 05:45
1) I have only one clip for MVAnalize and only one "idx" - it's very faster!
Now frame 32 of the output is made up of portions of frame 31 of the singly compensated clip.
But frame 31 of the singly compensated clip is itself made up of portions of frame 30 of the source. So we have indirectly used (only) frame 30 of the source to mimic frame 32 of it. This
allows us to apply motion compensated temporal denoise with radii larger than 1.

2) forwComp3=forwComp1.MVFlow(forwvect2, idx=1)
forwComp1 - compensated frame from (n+3) (i.e. "similar", for ideal exactly frame(n))

forwComp1= compensated from "similar" frame (n+1),
but "similar" (n+1) is already compensated from ((n+1)+2),
i.e. we have compensate from frame (n+3)

PS I nearly assurance that you don't understand my very bad English :(

Alain2
27th April 2006, 23:58
hum, I tried the modified version you gave without the temporalsoften + selectevery, and it appears that forwcomp1,2,and 4 are the only working ones, 3=2, 5,6,7=4 ; I think this is because you use idx=1, and try to apply on and different source than "last"

AI
28th April 2006, 05:46
You are right.... I don't know why... :(
Fizick may be know?

PS I Edit my post for correct this error (or bug).

PPS I found bug in manual in Examples: realy forward search with isb=true, but in manual with isb=false
(I edit my post again)

Fizick
28th April 2006, 12:16
AI,
You are not the first man who notes this "isb bug" :)
http://forum.doom9.org/showthread.php?p=618889#post618889

forward compensation is from prev to current frame,
backward compensation is from next to current

Chainmax
31st May 2006, 21:01
I am trying to make encodes out of some digicam videoclips with the following script:

AVISource("X:\wherever\somedigicamclip.avi",audio=true)

TimeStretch(tempo=(100.0*14.985)/15)

AssumeFPS(14.985, 1)

ConvertToYV12()

Levels(0,1.1,255,16,235)

FFT3DFilter(sigma=6,plane=3,bw=32,bh=32,bt=3,ow=16,oh=16)

Crop(0,2,320,238,align=true)

DeGrainMedian()

EEDI2().TurnRight().EEDI2().TurnLeft()

Tweak(sat=1.2)

vf=last.mvanalyse(isb=false,blksize=4,pel=2,search=3,truemotion=true)
vb=last.mvanalyse(isb=true,blksize=4,pel=2,search=3,truemotion=true)

Lanczos4Resize(656,448)

LimitedSharpenFaster()

MVFlowFPS(vb,vf,num=30000,den=1001)

c=last

GrainU=c.UtoY().AddGrain(2,0,0)
GrainV=c.VtoY().AddGrain(2,0,0)
Return ytouv(GrainU,GrainV).MergeLuma(c).AddGrain(10,0,0).AddBorders(24,16,24,16)

and I keep getting an access violation error pointing at the MVFlowFPS line. Switching from Avisynth v2.56 (without using the TimeStretch feature, of course) to v2.57b3 and upgrading MVTools to v1.2.4 didn't help. What could be the cause? Also, why do I have to use num=30000,den=1001 instead of just num=2997,den=100 in MVFlowFPS for NTSC framerates?

Fizick
31st May 2006, 21:54
Chainmax,
please simplify your script to minimal one, that still produces the access violation.

num=30000,den=1001 are the only correct (precise) values. Use search to find more info.

Chainmax
31st May 2006, 22:29
Will do.

[edit]Using this script:

AVISource("X:\wherever\somedigicamclip.avi",audio=false)

vf=last.mvanalyse(isb=false,blksize=4,pel=2,search=3,truemotion=true)
vb=last.mvanalyse(isb=true,blksize=4,pel=2,search=3,truemotion=true)

MVFlowFPS(vb,vf,num=30000,den=1001)

using Avisynth v2.56- I'll try v2.57b3 again.

[edit2]Still not working.

Fizick
1st June 2006, 00:05
Your clip and vectors parameters are not named and mixed thus.
For example, try use this:
MVFlowFPS(last,vb,vf,num=30000,den=1001)

Chainmax
1st June 2006, 00:37
What do you mean by "Your clip and vectors parameters are not named and mixed thus"?
It seems to have worked, I can now load the script and compare the source vs the results. There seems to be another issue though: on the right side of the frame, some kind of paddding appears. It appears to be a mirror image of a section of the frame.

Didée
1st June 2006, 07:56
Well, at least in your 1st example (the longer script), you're trying to apply vectors to a source of a different size: MVAnalyze() on 2x the original resolution (2xEEDI, giving 640x476), MVFlowFPS() after the LanczosResize to 656x448. That's likely to make problems.
For the 2nd (short) script, no clue. Seems to be correct.

Chainmax
1st June 2006, 16:24
Sounds logical, doesn't it :o? Putting everything at the end of the script (right before the noise addition) seems to have eliminated both the padding problem and access violation errors I got when stepping through the video in VDubMod. Thanks :).

Fizick
3rd June 2006, 20:18
My "to do":
Overlapped procesing in MVCompensate.
(Almost finished).

dirio49
9th June 2006, 14:01
LoadPlugin("DGDecode.dll")
LoadPlugin("mvtools.dll")
LoadPlugin("RemoveGrainSSE2.dll")
LoadPlugin("deblock.dll")
source=mpeg2source("VTS_01_1.d2v")
vectors = source.MVAnalyse(isb = false, lambda = 1000)
compensation = source.MVCompensate(vectors, mode = 0)
compensation = compensation.Deblock()
vectors = vectors.MVChangeCompensate(compensation)

RemoveGrain(mode=2)

ConvertToYV12()

more importaly how to get this script to work:o

thanks

Fizick
9th June 2006, 15:00
What do you really want? get this script to work or use MVFlowbur?

dirio49
9th June 2006, 16:46
use MVFlowbur.

P.S.
Sorry for the confusion:o

Chainmax
10th June 2006, 03:25
I'm currently using the following lines:

vf=last.mvanalyse(isb=false,blksize=4,pel=2,search=3,truemotion=true)
vb=last.mvanalyse(isb=true,blksize=4,pel=2,search=3,truemotion=true)
MVFlowFPS(last,vb,vf,num=30000,den=1001)

in order to convert 15fps footage to 29.97 for DVD creation. It looks fantastic on static scenes and slow pans, but on high speed shakes (read as: n00bs don't shoot good videos) all kinds of artifacting appear. Is there some way to reduce such artifacting? I can provide screenshots and/or sample clips if needed.

Fizick
10th June 2006, 05:11
dirio49,
Did you try MVFlowBlur example from MVTools documentation?

Chainmax,
There are no ideal solution. MVFlowFps2 is usually better.
May be you must firstly stabilize your video (DePan, deshaker).
Or try convert to 30fps with Depan (interleave with offset=0.5, see its doc).
Better solution: buy camcorder :)

Chainmax
10th June 2006, 06:16
Well, a Canon Elura 100 is on the "to-buy" list, so that base is covered :). Thanks for the DePanInterleave and MVFlowFPS alternatives, I'll check those out. In the meantime, could you please take a look at [link removed] and tell me if you think stabilizing could help?


[edit]Would this script:

ConvertToYV12()

FFT3DFilter(sigma=3,plane=3,bw=32,bh=32,bt=3,ow=16,oh=16)
FFT3DFilter(sigma=1,bw=32,bh=32,bt=3,ow=16,oh=16,sharpen=0.7)

HDRAGC(max_gain=16,min_gain=1.5,coef_gain=0.8,coef_sat=0.6,shift_u=5,shift_v=-18,reducer=1.0)

Crop(0,2,320,238,align=true)

DeHalo_Alpha()

EEDI2().TurnRight().EEDI2().TurnLeft()

Lanczos4Resize(656,448)

LimitedSharpenFaster(SMode=4)

forward_vec=last.mvanalyse(isb=false,blksize=4,pel=2,search=3,truemotion=true,idx=1)
backward_vec=last.mvanalyse(isb=true,blksize=4,pel=2,search=3,truemotion=true,idx=1)
cropped = last.crop(2,2,-2,-2)
backward_vec2 = cropped.MVAnalyse(isb=true,blksize=4,pel=2,search=3,truemotion=true,idx=2)
forward_vec2 = cropped.MVAnalyse(isb=false,blksize=4,pel=2,search=3,truemotion=true,idx=2)
MVFlowFPS2(last,backward_vec,forward_vec,backward_vec2,forward_vec2,num=30000,den=1001,idx=1,idx2=2)

AddGrain(10,0,0)

AddBorders(24,16,24,16)

ConvertToYUY2()

include a correct MVFlowFPS2 call?

Fizick
10th June 2006, 09:07
Chainmax,
You must try stabilize it yourself. Sorry, I have no time.

Chainmax
10th June 2006, 17:05
Oh, I will try it myself. I was just asking if you thought it would be beneficial from a theoretical point of view.

rig_veda
14th June 2006, 11:14
I'd like to address a big THANK YOU to Fizick and Manao for bringing the mvtools to where they are now!
Very impressive things can be done with motion-adaptive denoising, especially in animation, as I lately found out. It's possible to use temporal denoisers at places where I would never have believed it possible without artifacts before.

Lately the line
interleave(last.MVCompensate(MVAnalyse(isb = false, pel = 2, search = 3, truemotion=true, delta = 7, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = false, pel = 2, search = 3, truemotion=true, delta = 6, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = false, pel = 2, search = 3, truemotion=true, delta = 5, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = false, pel = 2, search = 3, truemotion=true, delta = 4, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = false, pel = 2, search = 3, truemotion=true, delta = 3, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = false, pel = 2, search = 3, truemotion=true, delta = 2, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = false, pel = 2, search = 3, truemotion=true, delta = 1, idx = 1), idx=1), last, last.MVCompensate(MVAnalyse(isb = true, pel = 2, search = 3, truemotion=true, delta = 1, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = true, pel = 2, search = 3, truemotion=true, delta = 2, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = true, pel = 2, search = 3, truemotion=true, delta = 3, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = true, pel = 2, search = 3, truemotion=true, delta = 4, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = true, pel = 2, search = 3, truemotion=true, delta = 5, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = true, pel = 2, search = 3, truemotion=true, delta = 6, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = true, pel = 2, search = 3, truemotion=true, delta = 7, idx = 1), idx=1)).TTempSmooth(maxr=7,lthresh=3,cthresh=4,strength=5).selectevery(15,7)

has more or less become my only denoiser for DVDs with low noise level. It might look like a little overkill to use 7 frames backwards and forwards, but it mostly has proven worth it if quality is more important than speed. Cause its slooow.. ^^;

On the other hand, if the movie is pretty noisy, like Ghibli's Porko Rosso, i needed to apply much more massive filtering to the static and slow motion scenes (which i defined manually via ReplaceFrames):
#denoise fast pans
ReplaceFramesSimple(last, last.FFT3DFilter(), filename="PorcoRosso_denoise_FFT3D.txt")
#TTempSmooth_middle_short - denoise slow pans
ReplaceFramesSimple(last, interleave(last.MVCompensate(MVAnalyse(isb = false, pel = 2, search = 3, truemotion=true, delta = 1, idx = 1), idx=1), last, last.MVCompensate(MVAnalyse(isb = true, pel = 2, search = 3, truemotion=true, delta = 1, idx = 1), idx=1)).TTempSmooth(maxr=1,lthresh=10,cthresh=10,strength=5).selectevery(3,1), filename="PorcoRosso_denoise_TTempSmooth_middle_short.txt")
#TTempSmooth_lite_wide - denoise intro
ReplaceFramesSimple(last, interleave(last.MVCompensate(MVAnalyse(isb = false, pel = 2, search = 3, truemotion=true, delta = 7, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = false, pel = 2, search = 3, truemotion=true, delta = 6, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = false, pel = 2, search = 3, truemotion=true, delta = 5, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = false, pel = 2, search = 3, truemotion=true, delta = 4, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = false, pel = 2, search = 3, truemotion=true, delta = 3, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = false, pel = 2, search = 3, truemotion=true, delta = 2, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = false, pel = 2, search = 3, truemotion=true, delta = 1, idx = 1), idx=1), last, last.MVCompensate(MVAnalyse(isb = true, pel = 2, search = 3, truemotion=true, delta = 1, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = true, pel = 2, search = 3, truemotion=true, delta = 2, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = true, pel = 2, search = 3, truemotion=true, delta = 3, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = true, pel = 2, search = 3, truemotion=true, delta = 4, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = true, pel = 2, search = 3, truemotion=true, delta = 5, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = true, pel = 2, search = 3, truemotion=true, delta = 6, idx = 1), idx=1), last.MVCompensate(MVAnalyse(isb = true, pel = 2, search = 3, truemotion=true, delta = 7, idx = 1), idx=1)).TTempSmooth(maxr=7,lthresh=4,cthresh=5,strength=5).selectevery(15,7), filename="PorcoRosso_denoise_TTempSmooth_lite_wide.txt")
#TTempSmooth_middle_wide - denoise still frames
ReplaceFramesSimple(last, last.TTempSmooth(maxr=7,lthresh=10,cthresh=10,strength=5), filename="PorcoRosso_denoise_TTempSmooth_middle_wide.txt")

with FFT3DFilter doing the problematic high-motion/low-contrast and fade scenes and mvcompensate+ttempsmooth doing anything else.

Motion compensation worked well in most cases where a texture with a good mount of structure was moved not too fast. Too little detail, too little contrast or to large movements kind make it difficult for the mvtools, and it also has now way of recognising a uniform change in brigthness.. But after all it's supposed to do motion compensation, not fading compensation.

Speaking of which - does anybody think something like a "fading compensation" can be done, in theory? It kind of seems to resemble mc, but with the vectors moving more or less uniformly through the YUV space.. or not? o_O

Fizick
14th June 2006, 17:25
...quality is more important than speed. Cause its slooow.. ^^;


You can easy make your "long line" more slower with new overlap mode in MVTools v.1.3 ;)

But generally temporal radius=2 is very good (and radius=1 is quite good for speed).

Fizick
14th June 2006, 17:28
Fading compensation?
Deflick the image, remember deflick correction values,
analyze and compensate motion of deflicked clip, denoise it,
and revert deflick changes?

It is not MVTools question, of course.

Chainmax
14th June 2006, 17:34
...
try convert to 30fps with Depan (interleave with offset=0.5, see its doc).

That would be with something like this:

i=last
data=DePanEstimate(i,range=1,trust=5)
f=DePan(i,data,offset=0.5)
b=DePan(i,data,offset=-0.5)
Interleave(f,i,b)
SelectEvery(...)

, right? What should I put in the SelectEvery line?

rig_veda
14th June 2006, 19:36
You can easy make your "long line" more slower with new overlap mode in MVTools v.1.3

That's definitely what I'll do when it's released. ;)

Fading compensation?
Deflick the image, remember deflick correction values,
analyze and compensate motion of deflicked clip, denoise it,
and revert deflick changes?

It is not MVTools question, of course.

Hm, I'll give that some thougt. Sounds like quite a task for my poor brain to put together. :D
The reason I asked about it was because it hit me as the next best thing to try to improve with my filter chain, but also because i was wondering whether mvtools' vector calculations (especially the truemotion concept) couldn't be (ab)used to do an area based brightness compensation. Anyway, i'm off to read deflick's manual.

Fizick
15th June 2006, 05:56
rig_veda,
double mistake :)
1) 1.3 is released.
2) defading is not implemented.

redfordxx
20th June 2006, 10:01
Is there any way to save motion vectors to file and reuse them?

Fizick
20th June 2006, 16:12
No, only save.

redfordxx
20th June 2006, 17:27
No, only save.You're saying it is possible to save motion vectors (how?), but you can't use it?
It could be good for speed up repeated processing.
R.

Fizick
20th June 2006, 20:10
Read a doc about vectors saving (outfile). It is in beta stage.
But reading is not implemented. And I have no plan to do it now.

scharfis_brain
20th June 2006, 21:33
I have a feature request :)

Is it possible to implement such a function:

function amount_of_motion_of_current_frame(clip clip, clip vectors)
{
return float
}

or even better:

function current_frame_is_part_of_fluent_sequence(clip clip, clip vectors, int some_thresholds)
{
return bool
}

I need functions that
- describe the amount of motion (length of vectors)
- return true, if a sequence of frames is consisting of individual frames (without duplicates (like 3:2 or 2:2 pulldown) or blending)

Fizick
20th June 2006, 22:57
Seems, it is not possible in Avisynth plugins.
Use mvmask with additional conditional functions.

scharfis_brain
20th June 2006, 23:36
Seems, it is not possible in Avisynth plugins.
What do you mean is not possible? returning a bool or a number?
of course it is possible, but it needs to be a function for the conditional environment.

Fizick
21st June 2006, 16:56
Do you know al least one such plugin, which return not clip but float or boolean?

krieger2005
21st June 2006, 19:41
I think Clouded made in his "Motion"-Plugin such functions.

scharfis_brain
21st June 2006, 20:50
Do you know al least one such plugin, which return not clip but float or boolean?
eg.: the functions averageluma() (see AVS documentation)
or iscombed() from neuron2's Decomb.dll

of course both functions are for the conditional environment, only.

Fizick
22nd June 2006, 21:05
Of course, I know abot averageluma.
I suggested to you use Averageluma(MVMask(...)).
But I did not know about iscombed!
Thanks for poit to it. Therefore, it is possible to implement

function amount_of_motion_of_current_frame(clip clip, clip vectors)
{
return float
}

as MVMaskConditional...

But function current_frame_is_part_of_fluent_sequence is probably not related to MVTools. Maybe to DepanScenes ?

scharfis_brain
23rd June 2006, 00:49
I think, that it will be related to mvtools, cause I even want to know whether there is motion like talking head etc.

Depan won't catch that... (doesn't it?)

anyways, implement it the way you like and I'll see, whether it works or not ;)

Fizick
23rd June 2006, 14:59
Why not simple YDifferenceFromPrevious (clip) ?

Adub
24th June 2006, 00:53
Why is it that when ever I try to use MVflowfps or MVflowfps2 I get an Evaluate:System Exception - Access violation
error.

I am using Alpha 3 and MVtools version 1.3. I thought everything had been cleared up with this in this last release.

By the Way here is my script:

DgDecode_mpeg2source("C:\Documents and Settings\Merlin\Desktop\Movies\USA Parkour\usa.parkour[1].d2v").KillAudio()
MVFlowfps2(num=25, den=1)

Thanks for any help in advance.

scharfis_brain
24th June 2006, 01:43
Rtfm ...

Adub
24th June 2006, 02:15
Okay, my apologies Scharfis_Brain. I am a little bit of a newbie when it comes to putting scripts together like this. But I did look at the manual and tried one of the sample scripts, and it works perfectly.

Again I am sorry for my ignorance. Thanks by the way. I am now learning more and more.

foxyshadis
24th June 2006, 03:54
Still, a function should throw an error ("mvflowfps2 requires an input clip and four vector clips" or something) rather than crashing and dying, so it's a worthwhile bug report.

actionman133
28th June 2006, 01:30
Hi, just wondering if someone could explain to me how MVTools' searchparam works in a practical sense with the varius search modes as the manual kinda once-overs right over it.

For example, when search = 3, it searches for vectors within the radius of searchparam... but how is searchparam measured? Is it a multiple of the block size or something?

Judging by the documentation about the other methods, it seems as though searchparam has a different influence on the other search modes...

Thanks.

Fizick
28th June 2006, 20:59
As I can read a sourcecode,
searchparam is measured in pixels (or halfpixels for pel=2).
If it is wrong, Manao will correct me. :)

Manao
28th June 2006, 21:19
It depends on the search mode :
* exhaustive : radius of the search, in pixel or half pixel, depending on the precision
* logarithmic : number of steps for the logarithmic search. the nth step of the diamond search is done by starting from a motion vector, and by checking its neighbours ( at +/- 2^(n-1) in pel/hpel for each coordinates ) to see if they are better. If one is better than the current vector, it is chosen and the process is repeated by starting from this new vector. The previous step is repeated till the vector is the best one. Then n is reduced by 1 and the process is iterated ( hence, with searchparam = 3, in pel, we first try to find the best vector recursively with a precision of -/+ 4. Once we found it, we reduce the precision to -/+ 2, then to -/+ 1 )
* nstep : the nth step consists in checking the current vector, and only four of its neighbours ( -n,0 / n,0 / 0,n / 0,-n ), to select the best one and to do the (n-1)th step from that one.

OneTime search mode shouldn't be used, and Square doesn't use searchparam.

To summarize, the larger searchparam, the better the ME should be, and the slower too. There's a threshold over which increasing search param won't help. Since there's the motion estimation is hierarchal, for example, seachparam needn't be very high for the logarithmic search ( 1 or 2 at most should be enough ) not for the exhaustive one ( 4-5 should already yields near optimal results ). I wouldn't advise nstep search.

actionman133
29th June 2006, 14:43
Thanks, Manao. That helps a little although my eyes are slightly glazed over... :D

I recently went masochistic with MVTools, doing some outrageous overnight encodes. I found that with search = 3 and searchparam of 5 yielded somewhat buggy results in high motion, but searchparam 6 fared much better, and 8 is almost perfect, even in insanely high motion scenes.

If you're curious to know my test sources, they were the final 20 minutes of Mission Impossible II and the minivan chase in Mr & Mrs Smith - the latter uses a lot of handheld camerawork and it worked very well on both of them. Each of them used MVTools to double the framerate.

Thanks for the great work so far, guys!

johnmeyer
29th June 2006, 15:58
actionman133 - I'd be interested in seeing the mvtools part of your script to see what settings worked for you.

actionman133
29th June 2006, 16:37
Johnmeyer... easier said than done... :p

I modified the original MVConv function that came with MVBob to give it more control.

Those tests were done with PAL DVDs (region 4) at 25 fps. Results were very good with searchparam = 6 for Mi-2, and were almost great for the (trickier) Smith sample where searchparam = 8.

She's a hefty beast, so I bolded the default lines to help you see them a little more easily. With the exception of searchparam, all of those presets were used.

MVConv (50, 1, searchparam = 8)

Function MVConv (clip full, int num, int den, int "blksize", int "pel", \
int "search", int "searchparam", int "idx", bool "truemotion", \
int "overlap", int "sharp", bool "show") {

LoadPlugin ("F:\Core\AVISynth Plugins\Deinterlacing\mvtools.dll")
blksize = Default (blksize, 8)
blksize = (blksize == 4) || (blksize == 8) || (blksize == 16) ? blksize : 8
pel = Default (pel, 2)
pel = (pel == 1) || (pel == 2) ? pel : 1
search = Default (search, 3)
search = (search == 1) || (search == 2) || (search == 3) ? search : 1
searchparam = Default (searchparam, 6)
idx = Default (idx, 1)
idx = (idx < 1) ? 1 : idx
overlap = Default (overlap, 2)
sharp = Default (sharp, 1)
sharp = (sharp == 0) || (sharp == 1) ? sharp : 1
show = Default (show, false)

cropped = (blksize == 4) ? full.Crop (2, 2, -6, -6) : \
(blksize == 8) ? full.Crop (4, 4, -4, -4) : \
(blksize == 16) ? full.Crop (8, 8, -8, -8) : Last

idx1 = (idx * 2) - 2
idx2 = (idx * 2) - 1

forward1 = full.MVAnalyse (blksize, pel, 0, search, searchparam, false, \
idx = idx1, truemotion = true, overlap = overlap, sharp = sharp)
backward1 = full.MVAnalyse (blksize, pel, 0, search, searchparam, true, \
idx = idx1, truemotion = true, overlap = overlap, sharp = sharp)
forward2 = cropped.MVAnalyse (blksize, pel, 0, search, searchparam, false, \
idx = idx2, truemotion = true, overlap = overlap, sharp = sharp)
backward2 = cropped.MVAnalyse (blksize, pel, 0, search, searchparam, true, \
idx = idx2, truemotion = true, overlap = overlap, sharp = sharp)

final = full.MVFlowFPS2 (backward1, forward1, backward2, forward2, \
num, den, idx = idx1, idx2 = idx2)
vectors = full.MVShow (forward1)

return (show == true) ? vectors : final

PS. Anyone tend to get worse results with MVFlowFPS when blksize = 4? In my tests, it seems as though there isn't enough information in a 4x4 block to produce an accurate vector. I find 8x8 blocks to be much more effective, likely due to the extra detail in each block, and also a little faster.

EDIT: truncated the extremely long lines of the script

Boulder
6th July 2006, 12:10
How does MVTools deal with multithreading a'la tsp's Avisynth build and its SetMTMode? I was just wondering if the idx parameter gets all confused because Avisynth requests two different frames instead of just one but MVAnalyse/MVFlow etc. has a specific idx set.

johnmeyer
6th July 2006, 16:47
actionman,

Thanks for the script. That will be very useful to me in some upcoming work I plan on doing.

Revgen
6th July 2006, 21:24
How does MVTools deal with multithreading a'la tsp's Avisynth build and its SetMTMode? I was just wondering if the idx parameter gets all confused because Avisynth requests two different frames instead of just one but MVAnalyse/MVFlow etc. has a specific idx set.

I've never had a problem with MVFlowFPS and SetMTmode. Have you asked TSP about it?

Boulder
7th July 2006, 07:03
I've not had any problems (except that using CCE and SetMTMode occasionally causes a sudden reboot), I was just wondering if multithreading has been given any thought since it will be a part of Avisynth v2.6.

tsp
7th July 2006, 13:19
Mvtools is not coded with multithreading in mind as there are many places in the code that could cause trouble with multithreading(like global motion getting estimated by two different frames at the same time making it rather random witch value will be used). But using multithreading shouldn't cause reboots by itself as the worst thing that should happend is that the application crashes

Boulder
7th July 2006, 13:36
Yep, I figured that it's probably the extra load combined with high ambient temperatures (a heat wave up here in the North) that causes the rebooting. HC doesn't cause it but it doesn't cause as high CPU load as CCE.

Nevertheless, using SetMTMode doesn't give a huge performance boost, which might be explained by the fact that MVTools isn't multithread friendly at the moment.

wiak
9th July 2006, 20:38
here is a mirror
http://nwgat.net/dl/mvtools/MVTools-v0.9.8.zip
:)

Boulder
9th July 2006, 20:58
here is a mirror
http://nwgat.net/dl/mvtools/MVTools-v0.9.8.zip
:)
Humm, the latest MVTools version is 1.3.0 (by Fizick) ;)

Fizick
14th July 2006, 18:24
Today I release new v1.4.1 (23.06.2006):
Added MVDeGrain, MVDeGrain2 denoisers.
Chanded thSCD1 default from 300 to 400.
Corrected thSAD scale in MVDenoise.
Corrected documentation about SAD.

Boulder
14th July 2006, 18:38
Thanks, I have to try the new denoisers with my next analog capture encode :)

actionman133
15th July 2006, 01:17
Today I release new v1.4.1 (23.06.2006):

Where can I download it Fizick? You're MVTools page appears to only go up to 1.3.0... :(

Fizick
15th July 2006, 08:34
oops!
updated the site.

krieger2005
15th July 2006, 13:51
Fizick! I like Results of MVDeGrain-Function. Maybe i found a problem. This simple Script does not work for me:
mpeg2source("film.d2v", cpu=2)

bv2 = MVAnalyse(last,16,2,isb = true, delta = 2, overlap=4, sharp=1, idx = 1)
bv1 = MVAnalyse(last,16,2,isb = true, delta = 1, overlap=4, sharp=1, idx = 1)
fv1 = MVAnalyse(last,16,2,isb = false, delta = 1, overlap=4, sharp=1, idx = 1)
fv2 = MVAnalyse(last,16,2,isb = false, delta = 2, overlap=4, sharp=1, idx = 1)
MVDegrain2(last,bv1,fv1,bv2,fv2,0,idx=1)
return last

The only difference to your example is the Blocksize. I found out, that the overlap MUST be half of blocksize. For blksize 16 it does not work with overlap 4 or 12 but with 8 (same Problem with all blksizes).
I don't know if this is a problem of MVDeGrain. I does not tried any other Functions with these Parameters.

Another thing. I get some strange results using MVDeGrain. Here are sample Pictures (blksize=8 and blksize=16, I mean the ringing-like Artefacts near the tree on the right):
http://img204.imageshack.us/img204/9338/blksize08yx1.th.png (http://img204.imageshack.us/my.php?image=blksize08yx1.png)http://img204.imageshack.us/img204/8923/blksize16rm6.th.png (http://img204.imageshack.us/my.php?image=blksize16rm6.png)

These artifacts are results of overlap. Setting overlap to 0 let remove the Artifacs but also the quality is not so good like with overlap. Is there any change to get rid of this artifacts?

Yet another thing. "Default thres=400." in your Documentation of MVDeGrain should be "Default thSAD=400."?

Last: Peaple in the forum use global counter for using with MVTools for the idx-Parameter. I think i can remeber of 3 different counter-names for the same thing. Maybe in the Documentations should be defined something like this, so all peaple will use then the same counter.

The Counter will be defined in a script in the Auto-Load-Directory of Avisynth, and all Scripts should use this counter and increase it, when an idx is used with this counter. What do you think about this?

Pookie
15th July 2006, 20:17
Very impressive :thanks:

http://fileserver1.jpghosting.com/images/tn_55_594e27d7b734d88a90064132a6b9e638.png (http://fileserver1.jpghosting.com/images/55_594e27d7b734d88a90064132a6b9e638.png)

Fizick
16th July 2006, 00:43
krieger2005,
It is "pre-vacation" alpha build, and I do not remember nothing.
:)
Use (or do not use) it as is.
I will look later.
Anyway, overlap=blocksize must be the best.
And what do you see on your BLACK images?

foxyshadis
16th July 2006, 02:56
Haha, you have to turn the brightness/gamma up to see it. :p It's a collection of artifacts, a lot of blocks with a gridding pattern (which changes between the two), along with a handfull of blocks full of noise surrounded by degrained one (which are the same in both).

Fizick
18th July 2006, 00:28
Fixed some bugs in v.1.4.2 and v1.4.3

Boulder
18th July 2006, 07:24
I noticed a small bug(?): if I don't give the value for thSAD in MVDeGrain2, it doesn't do anything.

MVDeGrain2(last,vbw1,vfw1,vbw2,vfw2,idx=2) doesn't denoise,
MVDeGrain2(last,vbw1,vfw1,vbw2,vfw2,idx=2,thSAD=400) does.

Didée
18th July 2006, 08:29
:) Big thanks for all the new stuff, Fizick! :)

One thing I noted is that overlapped search & compensation gives a slight color shift. The result at times appears slightly reddish or greenish. It's there with MVCompensate, and gets worse with MVDegrain/2, when overlapping is used. Anyone else noticed this?

Fizick
18th July 2006, 09:42
Didйe,
I note big color shift with overlapped MVDegrain v1.4.0,
I decreased it in v.1.4.3.
The main reason: interger number weigthing window instead of float.

Didée
18th July 2006, 10:00
Ah ... my latest tests were with v1.4.1. I'll surely check with v1.4.3., too ;)

Does the (integer<-->float) weighting thing also apply to MVCompensate, or is that not related?

Fizick
18th July 2006, 10:56
Didйe,
I will look to MVCompensate.

Boulder,
Really default thSAD=6 now. It is a bug, of course. Firstly I wanted to use normalized parameter THRES (THSAD=64*THRES)

krieger2005
19th July 2006, 13:20
I have a problem while using this small script with MVTools 1.4.3
bv2 = MVAnalyse(last,8,2,isb = true, delta = 2, overlap=0, sharp=2, idx = 1)
#a=MVFlow(last,bv2, idx=1)
a=MVCompensate(last,bv2, idx=1)
bv2 = MVChangeCompensate(bv2,a)
aShow=MVCompensate(last,bv2, mode=0, idx=1)

return interleave(aShow,a)
While "a" looks fine, "aShow" is a green-touched screen. This is not related what you use for "a": MVCompensate or MVFlow.

Fizick
19th July 2006, 21:11
thSAD and MVChangeCompensate bugs are fixed in new v.1.4.4.

Boulder
20th July 2006, 10:30
Would it be possible to add the option to disable chroma processing in MVDegrain1/2 for a small speedup? I often either deal with b/w footage or use FFT3DFilter/FFT3DGPU for chroma denoising so chroma processing is usually unnecessary.

EDIT: MVDegrain1/2 look really great on my analog material, the result is much better than with my previous MVTools-powered denoising stuff.

foxyshadis
20th July 2006, 11:42
Fizick, did you see Dide'e's improved artifact mask for mvflow in the alchemist thread?

http://forum.doom9.org/showthread.php?p=853714#post853714

I tried it out and it seems to prevent the worst of the artifacts very well, so maybe something like it could be implemented into mvflow itself?

Didée
20th July 2006, 12:09
Impossible is nothing ;)
But it's probably not all that straight-forward to do like that in the plugin. I suppose that MVFlow currently does the error checking before interpolation (by checking the vector field), or at latest (for MVFlowFPS2) during the interpolation.
Now, the method used in that script requires more work: first, the basic interpolation must have been done already. Then a 2nd interpolation is done ("helper interpolation"), and from this one some sorts of metrics can be derived, which are then used to correct the initial interpolation. In this sense, it's a multi-step operation ... or post-processing, if you wish so.

However, just in case that such "helper interpolation" operation eventually is considered: IF so, then there would be much more powerful ways of checking the result for "correctness". That edgemask-based method in fact is pretty dumb ... it's just that this is one way of how interfering from the script level is possible at all. For the more mighty ones, things like reverse-direction vectors and perhaps partial-length vectors would be needed.

foxyshadis
20th July 2006, 14:11
Drat, you can't actually use huge block sizes, I was hoping to test the idea I had earlier. (I realize that it would be entirely unoptimized.) Is there an algorithmic reason for disabling 32, 64, etc, or just speed reasons? Just curious.

btw, Degrain_mmx.asm is missing from the source archive.

Edit: Chopped out mvdegrain temporarily and larger block sizes work fine. Now I just have to figure out if they're acually useful to my project or not. ;) Oops, no, it appears they just fall back on blending. Back to the drawing board.

Fizick
20th July 2006, 18:13
Yes, I can add option chroma=false to DeGrain1/2.

I see new "alchemist" thread. It is interesting for me, but no comments yet. :)

foxyshadis,
Manao does not disable 32,64, he does not implement it. :)
And I do not see any reason to implement so huge blocks. Object detail size is usually smaller.
IMHO 16 is best for (overlapped) denoising, 8 is best for interpolation.

BTW, Degrain_mmx.asm is not missing. It is omitted. :)
MMX is not implemented yet. OLD v.1.4.0 (other algo) Degrain_mmx.asm is in "unused" subfolder.

krieger2005
20th July 2006, 21:08
Is it possible to change the Compensation Clip of the Vector-Clip, which will be derived to MVDegrain. I tried to use "MVChangeCompensate" but VDubMod closed without any comments.

Fizick
22nd July 2006, 21:58
krieger2005,
I do not understand you. probably overlap mode is not supported in
MVChangeCompensate.

Boulder,
chroma denoising may be disabled in new released MVTools 1.4.5.

krieger2005
22nd July 2006, 22:13
I wanted just use something like this:
clip1=last
clip2=<SomeFilters>
vect1a=MVAnalyse(clip2,...)
vect1a=MVChangeCompensate(vect1a,MVCompensate(clip1,vect1a))
vect1b=MVAnalyse(clip2,...)
vect1b=MVChangeCompensate(vect1b,MVCompensate(clip1,vect1b))
MVDeGrain1(clip1,vect1a,vect1b)

So in generale to make the compensation with one clip and the Denoising with an other. I tried it this way, but VDub close itself when loading a script like that above. So i asked if it is possible to make this an other way.

Fizick
23rd July 2006, 00:28
clip1=last
clip2=<SomeFilters>
vect1a=MVAnalyse(clip2,...)
vect1b=MVAnalyse(clip2,...)
MVDeGrain1(clip1,vect1a,vect1b)

Boulder
23rd July 2006, 08:41
Boulder,
chroma denoising may be disabled in new released MVTools 1.4.5.
Thanks!

:)

krieger2005
23rd July 2006, 09:01
clip1=last
clip2=<SomeFilters>
vect1a=MVAnalyse(clip2,...)
vect1b=MVAnalyse(clip2,...)
MVDeGrain1(clip1,vect1a,vect1b)
You are right. This way is possible. But then the DeGrainMethod is not that effective, because the SAD should be set much higher to overright the artefacts removed by <SomeFilters>.

For example: if you set for <SomeFilters> a filter, which increase the light (because than MVAnalyse give better motion-vectors...) but don't wont to get theses increase of Light in the result-clip, than you get on the MVDegrain-"Cleaned"-Areas still these increase of light from <somefilters>.

Fizick
23rd July 2006, 10:32
krieger2005,
different idx for MVDegrain.

Pookie
24th July 2006, 08:06
Fizick - Any plans to give MVDeGrain a "Degrid=x" setting, as in FFT3dfilter ?

Fizick
25th July 2006, 18:03
Answer is yes, but without extra parameter: :)

New v1.4.7 (25.07.2006 by Fizick)
Decreased overlap gridness in MVDeGrain1, MVDeGrain2, MVCompensate.
Added example with MVDeGrain1 for interlaced.
Decreased denoising in MVDeGrain1, MVDeGrain2.
Plane parameter in MVDeGrain1, MVDeGrain2 now works :)

Pookie
25th July 2006, 18:13
Thanks :D

Fizick
26th July 2006, 18:50
there are no reports.
It seems, it is final 1.4.x version.

Revgen
26th July 2006, 19:42
there are no reports.
It seems, it is final 1.4.x version.

Isn't there some way to make it more compatible with Dual-Core Cpu's using TSP's SetMTmode plugin. Somebody said something about idx vars being the issue.

Fizick
26th July 2006, 20:03
I have no Dual core CPU (and even hyperthreading), so can not make it.
Anybody welcomed to implement it. Source code is open.

Fizick
31st July 2006, 17:22
fixed some bug in v1.4.8

TSchniede
14th August 2006, 00:24
There seems tobe some incompatibility of MVCompensate/MVDenoise2(and colorplanes processed) with YUY2 input and overlapped blocks in mvanalyse

as soon as overlapped blocks in mvtools 1.4.8 (1.4.7 "works") are used these two functions mess up YUY2 video. The luma is set to white in vertical bars 2 pixel white, 2 pixel normal, the last 8 pixel white, the chroma plane is set to cyan, the last 4 pixel are green on most frames with the following simple script:

vec=yuy2clip.MVAnalyse(overlap=4)
yuy2clip.MVCompensate(vec)

Although yuy2clip.mvcompensate2(...,plane=0) and yuy2clip.converttoyv12().MVCompensate(vec) work as they are supposed to.

Fizick
14th August 2006, 15:48
Released MVTools new v1.4.9.
Fixes a bug in MMX optimization of overlap mode in MVDeGrain, MVCompensate for YUY2 with blksize=8 (thanks to TSchniede for report!).

Mug Funky
16th August 2006, 03:38
Drat, you can't actually use huge block sizes

you could try it with reduceby2 and mvincrease...

Heini011
16th August 2006, 15:43
Hi,

i tried the sharp bicubic and wiener subpixel interpolation methods, introduced already in mvtools 1.3. all i can say is: Thank you Fizick!

no more blurring when denoising modern dvd content ! nearly lossless filtering, a dream comes true ;-)

but why is sharp=1 not the default value in mvanalyze?

and what about quarter-pixel subsampling ? any plans for it ?

greetings.

Fizick
16th August 2006, 20:02
I wanted make sharp=1 as default.
and I already make it in version 1.5.0 beta (in preparation)
:)
and your post is the almost first positive about sharp :)

No plans for quater-pixels.

my current plans for 1.5.0 is:
1) more correct (stable) vector predictors hierarhical interpolation,
2) smooth local transition to convertFPS-like MVFlowFPS for bad vectors.

foxyshadis
16th August 2006, 20:46
For qpel, you can always simulate it yourself; just double the size of the input (lanczos or spline) and use hpel on it. Not very efficient, but it's the normal method of doing qpel internally anyway. (More efficient methods are more of a pain to do right.)

Didée
16th August 2006, 22:23
While we seem to be on the way to v1.5, a question about MVCompensate:

Currently, it seems that
Originally by MVTools
int thSCD1 : threshold which decides whether a block has changed between the previous frame and the current one. When a block has changed, it means for me that motion estimation for him isn't relevant at all. It occurs for example at scene changes. So it is one of the thresholds used to tweak the scene changes detection engine. ...

int thSCD2 : threshold which sets how many blocks have to change for the frame to be considered as a scene change.
is interpreted by MVCompensate so, that lastly only thSCD2 is used to not compensate over scenechanges. If thSCD2 is not satisfied, then all blocks are compensated. I.e. also those blocks with a SAD > thSCD1.

Shouldn't there be a mode available, where blocks with too big vector SADs are not compensated, and just the reference block is put out? (See the underlined part of the quote)
Currently, with MVCompensate it seems not possible to avoid the usual errors in those areas where no good compensation was found.

(Having to build a kind=1 MVMask, level adjusting it, then masked-merging back the original is rather slow and cumbersome, compared to MVCompensate just ignoring blocks with big SADs ;) )
___

Regarding MVFlow/FPS-style interpolation filters, perhaps I'd have an idea or two. When are consultation hours?

Fizick
17th August 2006, 20:15
Didйe,
probably you want use zero motion vector for block if the vector SAD is bad?
But zero vector has worse SAD.
Anyway, I can provide this option in v1.5.0.

MVFlowFPS brainstorm later.

I found a bug in MVCompensate with right and botom edge processing, if frame size is arbitrary (not covered by blocks entire). Will release v1.4.10 soon.

Mug Funky
18th August 2006, 03:11
i think didee means that a bad-sad block (hehe) is "intra" coded, in that it doesn't use motion compensation at all, just passes through the block on the current frame.

Fizick
18th August 2006, 16:52
Released new MVTools v1.4.10 (18.08.2006):
Corrected right and bottom borders processing in MVCompensate for arbitrary frame sizes.
Changed defaults in MVAnalyse: pel=2, truemotion=true, sharp=2.

Probably it is the the reaaly last 1.4.x :)

krieger2005
22nd August 2006, 11:45
How can i get a mask, which show which parts of the image where not processed by MVDeGrain or other MVTools, because the thSAD is exceeded. I mean, i can use a simple "Diff" of "previos" and "after"-frame, but the "diff"-Function show the difference and not what was processed by MVDeGrain.

Didée
22nd August 2006, 12:06
@ krieger: erhm ... MVMask ?

MVMask:
kind=1 allows to build a mask of the SAD (sum of absolute differences) values instead of the vectors' length. It can be useful to find problem areas with bad motion estimation. (Internal factor blocksize*blocksize/4 is used for normalization of scale ml.)
Of course, this means combining several MVMask's, one for each temporal compensation (backward-1 + backward-2 + ... + forward-27)

For having full fine control, one has to do everything on one's own, instead of using pre-made filters, anyways ... like instant soup vs. self-cooked. Instant is not bad, but self-made is better. ;)

krieger2005
22nd August 2006, 12:15
And how to "emulate" the SAD-option, since it is based on a Block and not on a Pixel?

EDIT:
Oh... Sorry does not read your post carefull enough... I will see how to make it. Thanks

Didée
22nd August 2006, 12:53
It depends. Basically, this SAD-thingy IS a per-block value, not a per-pixel value: SAD is calculated for each vector, and since each vector is related to a block, so is SAD. And that is what MVMask spits out.

It might get more complicated for block-overlapped search & compensation (not sure if MVMask takes the overlapping into respect?), and even more for those interpolated-per-pixel FlowXYZ functions ...

Personally, I don't care much about SAD ... on one end, rather small SADs might already provide unacceptable errors ("flat" areas), while on the other end, rather big SADs still might be quite okay (high contrast areas, big noise, ...).

Fizick
22nd August 2006, 19:22
More long "to do" list for v1.5 or above (some cleaning):
3) remove compensation from vector stream,
so remove MVDenoise, and mode=0,2 from MVCompensate,
4) remove"idx" hell. I think about implementing
MVXXX(... , doubled=DoubledClip) syntax to all functions instead of idx.
doubledClip must be prepared as doubledClip=AlmostLanczosResize(width*2)
AlmostLanczos may be true LanczosResize or BilinearResize (it would be easy to use),
but now MVTools use a little different pixels upsampled positions:
direct copy of original (to even), and interpolated to odd (latest repeated)
we need some workaround.
(MVTools code must be updated too)
So we will get no "callback" hack in MVTools.
5) Direct FFT3DFilter algo integration in MVTools - for fixed blocksizes. Common overlap for estimation and denoising.
6) Remove too small blocksize=4, and may be replace it by 8x4. More stable and fast (MMX)

Hm. i am very agressive today :)

Manao
22nd August 2006, 19:36
Removing idx will result in n useless unpacks, where n is the number of time the same idx would be used ( hence, mostly 2 or 4 ). Furthermore, since you interpolate half sample only, you can easily code an interpolator that will be faster than lanczos or bilinear.

The callback hack is there for efficiency purpose, and I didn't find a way to go around that cleanly.

What you could do, however, could be make a filter "MarkAsIdx(clip c, int idx)" that does nothing expect putting an index in the VideoInfo of the clip ( let's say in the audiochannel, or samplerate field ), and then to give that clip to MVxxx.

remove compensation from vector streamWhy ? there again, it was for efficiency purpose. The downstream filters say whether or not the compensation is needed, so it isn't computed needlessly. Yet, when the compensation is needed, storing it at the time the vector is found is the most efficient way : everything is in the cache.

Fizick
22nd August 2006, 20:27
Manao,
thanks for response. The MVTools is quite heavy load.
Do you ready to release me from it? :)

About compensation.
Yes, the speed is better for stored compensation (about 10-20 percents).
But the current implementation of stored compensation is almost not-usable (IMHO). It lacks in overlapping and produces too big blockiness.
Probably overlapped support may be implemented too, but it is no so direct, and quite hard for me to double every function in two places of code (in planeofblocks.cpp and MVCompensate.cpp for example).

IDX is other story. Thanks for suggestion.
I want to clean vector stream from most non-vector things. IMHO, the creating (adapting) of some external interpolator is more Avisynth-freindly way. This clip will be ordinary Avisynth clip. Why we hide it internally in MVTools? (and use some hack to get its pointer.)

About callback hack. It be not needed if we make two my suggestions above. All info about estimation parameters may be stored in vector stream.
Another info translated now is luma masking and variance. But it is not used in any existant filter. And if we will need in it some days, we can simply add some parameter to MVAnalyse.

May be I am partially wrong, and I am sure, that there are many possible ways to improve MVTools,
and may be I never make stripped v1.5 (have little time now :( )

Fizick
25th August 2006, 04:42
More "to do" for v1.6:
7) Luma flicker protection of motion vectors estimation

il9ad
25th August 2006, 06:33
MVDenoise's noise removal anomaly?

I adjust the MVDenoise filter to remove noise in a video by running the AVS script in Windows Media Player (paused) and clicking the timeline to check various shots.

I've noticed that as long as I click progressively forward on the timeline, the processed picture retains much of the noise (as if the filter isn't fully working). However, if I then click backward on the timeline, the noise vanishes thereafter (as if the filter is then properly working). It looks like some kind of "seeking" problem, where MVDenoise is not getting all the before-and-after frames to process. See these WMP screen captures (cropped) of a noisey wall:

http://i98.photobucket.com/albums/l280/il9ad/DenoiseSeekCompare.jpg

As a confirmation, I've tested this by running the AVS script within VDub and TMPGEnc (in "source range" for viewable video). The same problem shows itself. Only a backward seek at some point gets MVDenoise to properly function.

An interesting side effect of this "forward moving only" anomaly is the massive artifacts it generates at scene changes (to be expected ... it's not working right). See this same section of wall when the scene is changed to it:

http://i98.photobucket.com/albums/l280/il9ad/DenoiseSceneChange.jpg

Note that after a backward seek, these scene change artifacts no longer appear.

The bad part is trying to create a processed video in TMPGEnc -- it generates the "forward only" result (partial MVDenoise operation). Manual backward seeking (in TMPGEnc's "source range") before processing doesn't keep MVDenoise working properly for the subsequent encoding (an internal "reset" must take place when encoding actually starts).

Has anyone come across this problem? Is there a solution (or work-around)?


programs:
Win2K-SP4, WMP6.4, VDub1.6.14, TMPGEnc2.02, AviSynth2.5.5, MVTools1.2.4 & 1.4.10

script:
##====================
## AVS 2.5.5 script to:
## read video file
## apply filter(s)
## send to video renderer

## Retrieve file
#videoclip = AVISource( "frameserved.avi" )
videoclip = Mpeg2Source( "test.d2v" )

## One set for non-filtered, one set for filtered
videoclip_before = videoclip
videoclip_after = videoclip

## MVDenoise - temporal w/motion tracking
videoclip_after = videoclip_after.Denoise_Temporal()

## NOTE: "Levels()" clamps to TV lumina range but doesn't handle chroma's wider range
videoclip_after = videoclip_after.Levels( 16, 1, 235, 16, 235, coring=true )

## DEBUG: split-screen for unfiltered/filtered comparison
videoclip_before = crop( videoclip_before, 176, 0, 352, 480 )
videoclip_after = crop( videoclip_after, 176, 0, 352, 480 )
videoclip_after = StackHorizontal( videoclip_before, videoclip_after )

videoclip_after

##====================
## Functions
##====================

##----------
## DE-NOISING - temporal filter
##----------
function Denoise_Temporal( videoclip ) {
backward_vectors4 = videoclip.MVAnalyse( isb=true, lambda=1000, delta=4 )
backward_vectors3 = videoclip.MVAnalyse( isb=true, lambda=1000, delta=3 )
backward_vectors2 = videoclip.MVAnalyse( isb=true, lambda=1000, delta=2 )
backward_vectors1 = videoclip.MVAnalyse( isb=true, lambda=1000, delta=1 )
forward_vectors1 = videoclip.MVAnalyse( isb=false, lambda=1000, delta=1 )
forward_vectors2 = videoclip.MVAnalyse( isb=false, lambda=1000, delta=2 )
forward_vectors3 = videoclip.MVAnalyse( isb=false, lambda=1000, delta=3 )
forward_vectors4 = videoclip.MVAnalyse( isb=false, lambda=1000, delta=4 )
videoclip = MVDenoise(
videoclip, backward_vectors4, backward_vectors3, backward_vectors2,
backward_vectors1, forward_vectors1, forward_vectors2, forward_vectors3,
forward_vectors4, tht=100, thsad=1000, thMV=10 )
return videoclip
}
##----------

##====================

Manao
25th August 2006, 19:32
Luma flicker protection of motion vectors estimationThe simplest thing I can think of is ignoring the average value of the blocks when computing the sad. That would be easy to implement, since only the sad function would need to be changed. I wonder how good it is, however.

Fizick
25th August 2006, 20:13
Manao,
Yes, I want modify SAD function mostly,
but I want to compensate average luma changes not from current, but from previous (coarser) hierarhical level (for stablity and speed without iterations). And probably partial compensation may be done.
But the SAD function modification is not trivial for MMX to use pasdbw. Seems, two branches are needed (for positive and negative corrections). Will look next month.

Fizick
25th August 2006, 20:15
il9ad,
my answer is: no MVDenoise, no problem :)
(sorry)


More seriously:
Try remove delta=4 vectors. And try old v0.9.9.1.


more "to do" for v1.5:
8) internal limiting of pixel changes in MVDegrain (like Degraingmedian, Dust). Right now we can use external fuction or Kassandro's plugin.

il9ad
26th August 2006, 23:45
Try remove delta=4 vectors.

Actually, that was among my initial tests. The vector count went from 4, to 3, to 2, to 1. Same problem ... only it was harder to see a difference between the raw and processed videos. With only 1 vector, I couldn't see a difference for sure. At that point, however, the filter was near useless for this denoising.

And try old v0.9.9.1

A good idea! But when I tried it, same problem. That no one has noticed it up until now is puzzling. Am I the only one who has tried it was this many vectors, where the difference would be noticeable? That would be puzzling, too. The strength of this kind of denoiser is the ability to blend away noise over time without smearing moving detail; and the more frames that can be used, the more the noise will cancel itself out. A high delta count should be expected in normal operation.

my answer is: no MVDenoise, no problem :)
(sorry)

Fortunately, I did some more thinking and testing. If it really is just a "seek" problem, then that was something familiar to me. In my use of AviSynth, I discovered I could use MPGSource() to generate the .d2v file needed for reading MPEG1-2 video files. However, there was a bug in it and it would not accurately seek when clicking around on (for example) the WMP timeline. So, with the .d2v file generated, I would then use MPG2Source(), which would accurately seek. But, what if it couldn't handle the MVDenoise kind of seeking?

That was easy to test. I found I could read the .MPG file, directly, with DirectShowSource() ... and guess what? My jump-around seeking was taking 2 or 3 times longer to generate a picture -- an indication that MVDenoise was getting and processing all of my delta frames. And the picture looked great ... without backward/forward seeking to get it to work! Problem solved! But not yet finished.

Considering that those MPEG-read dll's I was using were old -- MPEG2Dec3.dll, MPEGDecoder_YV12.dll, I checked for newer ones. The replacement for these seems to be DGDecoder.dll & DGIndexer.exe, by neuron2. Interesting to note that his docs refers to the seeking problem in previous versions of the MPEG-reading plug-ins. So I removed the old ones and tried this new one. Guess what? Back to the same old problem! So there it was! The MPEG readers ALL have bad code or are wrongly accessing something in Windows (at least). Or AviSynth is linking to them wrong?
ATTENTION NEURON2: is this something you can check in DGDecoder?

TO THE DOCS WRITER: As for MVTools, may I suggest the documentation be updated with the information of NOT using MPGSource() or MPG2Source() for file reading, rather to try something else like DirectShowSource().

Thanks for the suggestions, Fizick!

Fizick
27th August 2006, 00:06
il9ad,
Have you similar problem with MVDegrain2?

I mostly use avisource (analog, DV).

What Dgindex version? Try inform neuron2 in dgindex forum.
http://forum.doom9.org/forumdisplay.php?f=5

Didée
27th August 2006, 03:48
@ il9ad

Probably there is no such "seeking error" in *all* mpeg reader filters, while just the personified inreliability DirectShowSource, in combination with a suspicious MS player, shall happen to do everything right ... from experience, it's usually the other way round. ;)

However, that's two different kind of artefacts you're showing there.

1) For the issue with ineffective denoising after popping-around-on-the-timeline, could you please cross-check by loading the script in VirtualDub/Mod, and NOT in Windows Media Raper. MVDenoise I didn't use for quite some time, but I'm toying a lot with more "complicated" denoising through motion compensation, I'm using Mpeg2Source(DGDecode) for 99% of all sources, and never experienced such a seeking problem.

2) For those artefacts-at-scenechanges ... well, I'm not surprised, since
videoclip = MVDenoise( ... , tht=100, thsad=1000, thMV=10 such very high thresholds tell to average even the crappiest parts of the compensation into the result, no matter what. MVDnoise is a "simple" function. (However I'm not sure what length of vectors actually corresponds to thMV=10. How long is that?)

BTW, that's the reason why I don't use MVDenoise ... small thresholds -> safe against artefacts, but inefficient denoising because some noise will escape the thresholds. Big thresholds -> good denoising, but too much artefacts. The measurement is just not smart enough.

il9ad
27th August 2006, 08:19
Have you similar problem with MVDegrain2?

I mostly use avisource (analog, DV).

What Dgindex version?

I haven't tried MVDegrain2, but maybe I will. If it uses the same temporal seeking, I wouldn't expect any better operation ... if I were to continue to use MPEG2Source(), et al.

AVISource() doesn't seem to like (my) MPEG files.

Also noticed that DirectShowSource() plays the audio out-of-sync while timeline skipping. I hope that won't be a problem when encoding.

Little wonder that, with the modern miracle of the time-saving computer, no-one can get anything done.

I picked up the latest version 1.4.8 of DGIndex & DGMPGDec at neuron2's webpage http://neuron2.net/dgmpgdec/dgmpgdec.html .

For the issue with ineffective denoising after popping-around-on-the-timeline, could you please cross-check by loading the script in VirtualDub/Mod

Yes, I did test this in VDub and in TMPGEnc (in "source range" with it's video viewer) -- same results as in WMP.

For those artefacts-at-scenechanges ... such very high thresholds tell to average even the crappiest parts of the compensation into the result, no matter what.

Those only showed, with MPEG2Source(), on forward timeline motion only. Once I did a back-seek, the picture thereafter appeared fully de-noise and scene-change artifacts didn't show anymore. NOTE: according to my testing, any encoded result is the same as forward-only timeline movement and therefore produces the "bad operation" video. One must "seek" around in a viewer during AviSynth "live processing" to see the difference between bad and good operation, as I've described it.

I started my settings with the default values and then (visually) tweaked them to assure that 4 frames forward and backward blended on anything that didn't move too far too quickly. Anyway, that's my theory, based on descriptions in the docs. It works well on color-noisy, captured, analogue camcorder video ... that is, when it works.

BTW, that's the reason why I don't use MVDenoise ... Big thresholds -> good denoising, but too much artefacts. The measurement is just not smart enough.

Could it be your experience with "big thresholds" is the same problem I had here using MPEG2Source() to read the files for MVDenoise processing?

foxyshadis
27th August 2006, 09:37
If any seeking is all you need, try adding
trim(framecount-1,0)+last
at some point. It'll start with the last frame and after that seek back to the beginning for the real start. A workaround, but you said that's all you needed for now.

Didée
27th August 2006, 12:58
OK now, this is strange. MVDenoise is definetly buggy. The phenomena of almost-no-denoising and artefacts-at-scenechanges appears with d2v sources as well as with AviSource. And with DirectShowSource, it appears to be the same. Seeking backward by a good amount (enough to bypass any caching of previously rendered frames) cures the problem, and MVDenoise seems to work properly, then.
Funny thing is, I mixed up the order of vector clips in MVDenoise in several ways, but still the scenechange artefacts always appeared only on one side of the scenechange, never on both.

il9ad
28th August 2006, 01:07
AVISource() doesn't seem to like (my) MPEG files.

I neglected to mention this earlier. To explore this "seek" problem, I set up a simplified test using a plain MPEG file. However, I first noticed it when reading a VideoTools (v.0.93) generated "sign-post" file, frame-served from Premiere (v.5.1c) into AviSynth. This .AVI file was read with AVISource().

There are too many variables involved in that whole process, but it brings AVISource() into suspect, too. Just FYI.


try adding trim(framecount-1,0)+last at some point. It'll start with the last frame and after that seek back to the beginning for the real start.

An excellent work-around idea! Wish I had thought of that. And even better ... it works! Both with the old MPEGSource() & MPEG2Source() in my test file and with AVISource() in the frame-served file! A fully denoised picture without any (additional) seeking. Thanks, foxyshadis!

Well, that would seem to verify my "seek problem" hypothesis. Now if someone else on a different machine could confirm the problem ...

... oh, it seems Didee just did.

Boulder
30th August 2006, 09:54
Is there some alignment problems in MVDegrain1() with Avisynth 2.5.7a3?

With this script I get a messed-up video:
MPEG2Source("E:\Temp\Captures\TS\Demux\hiidenvirta_1.d2v",cpu=4)
TDeint(mode=1)
cleaned=TemporalSoften(2,5,0,8,2)
vbw1=cleaned.MVAnalyse(isb=true,truemotion=true,delta=1,pel=2,chroma=false,blksize=16,idx=1,sharp=2)
vfw1=cleaned.MVAnalyse(isb=false,truemotion=true,delta=1,pel=2,chroma=false,blksize=16,idx=1,sharp=2)
MVDegrain1(last,vbw1,vfw1,thSAD=400,idx=2)
Limiter()
AssumeTFF()
SeparateFields()
SelectEvery(4,0,3)
Weave()If I put SetPlanarLegacyAlignment(true) right after MVDegrain1(),the video is OK. MVDegrain2 works fine without that line. The source is a DVB capture, the resolution is 720x576.

Fizick
4th September 2006, 21:32
Thanks for report, Boulder.
this small bug with pitch for overlap=0, YV12 in MVDegrain1 fixed in next version (1.5.1 ?).

Fizick
6th September 2006, 16:56
Released final v1.4.11, one more final 1.4.x :)
Corrected vector predictors interpolation (from coarse to fine scale) for overlap>0.
Fixed bug with pitch for overlap=0, YV12 in MVDegrain1 (thanks to Boulder for report)

(also fixed v1.5.1 beta)

Alain2
10th September 2006, 11:22
Thank you for the new version :)
Small thing: in the documentation, the default settings of mvanalyse were not updated as per the changelog of 1.4.10

Fizick
10th September 2006, 19:02
Alain2,
thanks, fixed.

Fizick
15th September 2006, 18:14
As was noted by cwk,
I forgot to add the same comment to MVDeGrain1/2 doc as for MVCompensate.
Overlaped blocks processing is implemented as window block summation (like FFT3DFilter, overlap value up to blksize/2) for blocking artefactes decreasing.
MVAnalyse works well for almost any overlap size.
Larger overlap for compensation (and degrain) can be implemented too, but not in current versions.
It is more difficult to program, and slower (more numbers of overlapped blocks for every pixel - try draw it on paper).
I will add this comment to docs and the overlap size check to the code in next MVTools version.

Fizick
25th September 2006, 20:33
One more final 1.4.x version :)
1.4.12 (25.09.2006)
Fixed (?) bug with frames caching in MVDenoise (and possible in MVDegrain) (thanks to il9ad for report)
The cache problem http://forum.doom9.org/showthread.php?p=879614#post879614 is partially solved,
but please test and report.

nibbles
26th September 2006, 01:56
These are immensely significant tools to so many people around here.
From all of us lurkers, a huge thank you for working on them!
Could you tell me approximately how much time it would take an
experienced programmer like yourself of shodan for instance to
code a 64bit version of mvtools? I have no idea, but I would
to understand the challenge. Ok, thanks again. nib

Fizick
28th September 2006, 17:34
nibbles,
64bit is still not mainsteam.
And I am not an experinced programmer.

Released v1.4.13 (28.09.2006) - next final v1.4.x :)
Fixed bug with possible wrong frames pointers in core (MVClip.Update), hided by caching (thanks to IanB for advice)

I make this version on the base of v1.4.11 and disabled all v1.4.12 changes. it use more correct way to prevent the bug.
But I make correction to almost all functions,
so may be created some new copy-paste bugs. ;)

anton_foy
28th September 2006, 17:44
@Fizick

Thats great!
But when I download the 1.4.13 the file is named 1.4.12.

Fizick
28th September 2006, 18:20
thanks, fixed.
try again.

Fizick
28th October 2006, 22:13
Released v1.5.8 beta (dll 14.10.2006)
Many functions: added clip2x parameter to use 2X upsampled clip instead of internal subpixel interpolation for pel=2
MVFlowFps, MVFlowFps2: added thSAD parameter; use local blending of neighbour frames pixels in regions with bad motion vectors
MVFlowFps, MVFlowFps2: may use motion vectors for any frames delta
MVFlowFps, MVFlowFps2: fixed a bug for video with big nominators and denominators (thanks to Trixter for report)
MVCompensate: added experimental fields parameter to compensate fields shift of fieldbased video for pel=2
MVAnalyse: changed pnew parameter to relative of SAD

foxyshadis
5th November 2006, 13:51
MVDegrain and MVDegrain2 crash whenever I try to use them with 2.5.7 RC1 (not with tritical's latest build though), causing an avistreamsynth exception, and when recompiling a debug version it seems something is missing: SADToMask is unresolved.

Fizick
5th November 2006, 17:59
Oops. I updated mvtools158.zip archive with correct maskfun.cpp and maskfun.h source files.
(binary MVtools.dll is the same, not updated)
Post your script, system and other detail.
What if you add isse=false ?

Fizick
19th November 2006, 17:11
Luma flicker and fades are plorblem for current MVTools.
Some time ago (in unpublished v1.5.2) I tryed use local luma difference compensation at motion estimation but without great success.

But DCT (discrete cosinus frequency transform) is more interesting for me :)
What if we make DCT of blocks and compare coefficients with DCT of block at other frame?
I try to use the same SAD (sum of absolute diferences) function for DCT coefs.

Released MVTools v1.6.2
MVAnalyse: added experimental DCT mode to improve motion estimation at luma flicker and fades (fast for blksize=8 only).

dct: using of block DCT (frequency spectrum) for blocks difference (SAD) calculation. In particular it can improve motion vector estimation at luma flicker and fades.
0 - usual spatial blocks, do not use DCT;
1 - use block DCT instead of spatial data (slow);
2 - mixed spatial and DCT data; weight is dependent on mean frame luma difference;
3 - adaptive per-block switching from spatial to equal-weighted mixed mode (experimental, a little faster).
4 - adaptive per-block switching from spatial to mixed mode with more weight of DCT (experimental, a little faster).
Default = 0.

Mode dct=2 works quite good at (global) fades in my test.
All new dct modes are experimental, probably more optimal combination of 'traditional' SAD with DCT SAD is possible.
The question is about weight of DC (null frequency = block mean luma) component. For example, in DCT coder it is usually decreased.

netsnake
7th December 2006, 03:43
thanks fizick for the new version updates~

actionman133
10th December 2006, 04:26
Fizick, I'm downloading your latest version, but WinRAR keeps telling me the archive is corrupted... 'Unexpected end of archive'.

Anyone else having this issue?

Fizick
10th December 2006, 09:20
actionman133,
try re-download (or continue stopped download).
I hope you do not use MS IE :)

superuser
14th December 2006, 07:49
Currently I am experimenting with MVDeGrain2, MVDegrain1, DeGrainMedian and RemoveGrain. For past couple of months was using RemoveGrain (mode 2 and 17)and sometimes in combination with RemoveDirt

Purpose is to filter out grain noise from source and avoid using heavy grain removers like RemoveDirt as removedirt with grain also seems to eat away color sharpness and details. Currently I am using with default values, tomorrow will start tweaking SADs. Comments and suggestions, which would be better choice for grain removal while preserving details.

original_source=last
denoised_source = DeGrainMedian()
SeeSaw(original_source, denoised_source, NRlimit=a, NRlimit2=b, sootheT=xx, bias=yy)


MVDeGrain2
original_source=last

backward_vector_2=original_source.MVAnalyse(pel=2, search=3, chroma=true, isb = true, lambda = 1000, delta = 2, plevel=2)
backward_vector_1=original_source.MVAnalyse(pel=2, search=3, chroma=true, isb = true, lambda = 1000, delta = 1, plevel=2)

forward_vector_1=original_source.MVAnalyse(pel=2, search=3, chroma=true, isb = false, lambda = 1000, delta = 1, plevel=2)
forward_vector_2=original_source.MVAnalyse(pel=2, search=3, chroma=true, isb = false, lambda = 1000, delta = 2, plevel=2)

denoised_source=original_source.MVDegrain2(forward_vector_2, backward_vector_2, forward_vector_1, backward_vector_1)

SeeSaw(original_source, denoised_source, NRlimit=a, NRlimit2=b, sootheT=xx, bias=yy)


Aah, one more thing when I try to load the script in VirtualDub (VD), which I do for preview and syntax checking of script, for MVDeGrain1 it is giving System Exception - Access violation, for MVDeGrain2 is working fine!!! Ny ideas why so?

MVDegrain1
original_source=last

backward_vector_1=original_source.MVAnalyse(pel=2, search=3, chroma=true, isb = true, lambda = 1000, delta = 1, plevel=2)
forward_vector_1=original_source.MVAnalyse(pel=2, search=3, chroma=true, isb = false, lambda = 1000, delta = 1, plevel=2)

denoised_source = MVDegrain1(backward_vector_1, forward_vector_1)

SeeSaw(original_source, denoised_source, NRlimit=a, NRlimit2=b, sootheT=xx, bias=yy)

a, b, xx, yy are defined parameters.

Fizick
14th December 2006, 19:45
About System Exception - Access violation.
I have no idea what is SeeSaw function (exactly), and their parameters, and what filters versions you use.

But did you try this?:
...
denoised_source = original_source.MVDegrain1(backward_vector_1, forward_vector_1)
...

superuser
14th December 2006, 22:32
About System Exception - Access violation.
I have no idea what is SeeSaw function (exactly), and their parameters, and what filters versions you use.

But did you try this?:
...
denoised_source = original_source.MVDegrain1(backward_vector_1, forward_vector_1)
...

Yes, I tried with that, passing in one forward and one backward vector to MVDegrain1, that does not work. While MVDegrain2 works fine with two fwd and two bckwd vectors being passed in followed by call to SeeSaw. The Access Violation I am getting is on the line in script where I am making a call MVDegrain1. Once I get back to my place, I will try taking out SeeSaw from script and c if problem still exists and post the result.

Thanks.

Edit: Took out SeeSaw and still there is problem - Access violation. This exception is reported at where I am calling MVDegrain1.

Pookie
15th December 2006, 04:25
Does it crash on this ?


backward_vec2 = last.MVAnalyse(isb = true, delta = 2, pel = 2, overlap=4, sharp=2, idx = 1)
forward_vec2 = last.MVAnalyse(isb = false, delta = 2, pel = 2, overlap=4, sharp=2, idx = 1)
last.MVDegrain1(backward_vec2,forward_vec2,thSAD=400,idx=1)

superuser
15th December 2006, 06:05
Does it crash on this ?


backward_vec2 = last.MVAnalyse(isb = true, delta = 2, pel = 2, overlap=4, sharp=2, idx = 1)
forward_vec2 = last.MVAnalyse(isb = false, delta = 2, pel = 2, overlap=4, sharp=2, idx = 1)
last.MVDegrain1(backward_vec2,forward_vec2,thSAD=400,idx=1)

oops my bad in previous post.

I had forgot to specify MVdegrain on original_source, so may be it was trying to execute MVDegrain1 on a vectorized source. Sorry.

Good thing is it is working now, can experiment continue on my experiment - compare between removegrain (mode=2, 19) , MVDegrain1 and MVDegrain2.

thanks fizick and pookie for the help and resolving my silly mistake.

superuser
24th December 2006, 03:15
needed advice on following :


source = last

#Step 1 - Compute Backward & Forward Vectors
backward_vectors = source.MVAnalyse(pel=2, search=3, chroma=true, isb = true, truemotion=true, idx = 1, lambda = 1000, delta = 1)
forward_vectors = source.MVAnalyse(pel=2, search=3, chroma=true, isb = false, truemotion=true, idx = 1, lambda = 1000, delta = 1)

#Step 2 - Compute Compensation
forward_compensation = source.MVFlow(forward_vectors, idx=1)
backward_compensation = source.MVFlow(backward_vectors, idx=1)

#Step 3-Create interleaved 3 frames sequences
interleave(forward_compensation, source, backward_compensation)

#Step 4 - Denoise the source
FFT3DFilter(sigma=2, plane=4, bt=4, interlaced=true)

#Step 5 - Get non compensated frame
denoisedSource=selectevery(3,1)

#Step 6 - If need be apply sharpner, SeeSaw or LS + Soothe
sharpenedSource=denoisedSource.SomeSharpner



1 - Reason for using mvtools is to take into account the motion compensation and than after applying denoisers Step 1 to 4. With FFT3D and computed interleaved frames using vectors, can there be any conflicts or introduce artifacts?

2 - Will using more vectors and computing more interleaved frames in step 3 help in improving results. Or that can be over kill and not really needed or can be spoiler?

3 - What is better approach - use sharpening and dehaloing capability provided by FFT3D or use some external sharpners and have Step 6

4 - Depending on input from above, should Step 6 be performed before Step 5


Thanks for your time.

Merry Christmas and happy holidays.

Mug Funky
24th December 2006, 08:31
1. yes, there can and will be artefacts, but depending on the thresholds you use and the artefact protection your denoiser uses, it shouldn't be noticable. so fft3d at low settings will be fine.

2. more frames are useful when the denoiser knows what to do with them. so for fft3d's bt=4, you could compute 1 forward and 2 backward compensations, but any more wont be used.

3. that's outside the scope of this thread.

4. results will be identical, only slower if you swap these steps. selectevery will ditch 2/3 of the frames.

johnmeyer
24th December 2006, 15:09
You always need to run your own tests on your own source material, and then view the results on the monitor you use for viewing such material (i.e., the computer monitor is NOT the place to view the results). Sometimes this means burning a test DVD (on a DVD+RW or DVD-RW) and then viewing this on your TV.

FWIW, I have seldom found huge improvements in using the motion compensation (there is some) compared to the improvements that can be had by spending time tweaking the settings in step #4. The settings of the FFT denoiser are where all the action is. I would recommend temporarily eliminating all the motion compensation, and then taking 10-20 seconds of representative footage (or longer, if you have the time), and doing test runs with various settings. People have posted various settings here, and I have used some of those as starting point (although some of the settings posted are a little odd). Here are a few that I've collected and modified:
fft3dfilter(x, sigma=3, plane=0, sharpen=1, bt=3, interlaced=false)

YToUV(fft3dfilter(x, sigma=2, plane=1, sharpen=.25,interlaced=false).UToY,\
fft3dfilter(x, sigma=2, plane=2, sharpen=.25,interlaced=false).VToY,\
fft3dfilter(x, sigma=7, plane=0, sharpen=1, bt=3, interlaced=false))

fft3dfilter(x, sigma=5, sigma2=10, sigma3=12, sigma4=20, plane=0, bt=3, bw=16,\
bh=16, ow=8, oh=8, sharpen=0.3, smin=20, smax=1000, wintype=2, kratio=1.0,\
measure=true, interlaced=true, degrid=1)

fft3dfilter(x, sigma=8, sigma2=18, sigma3=12, sigma4=8, plane=0, sharpen=1,\
measure=true, interlaced=true, degrid=1,wintype=2)
After trying lots of these different settings, I keep coming back to this very simple one that does a pretty good job on lots of clips:chroma=source.Cnr2("oxx",8,16,191,100,255,32,255,false)
final=chroma.fft3dfilter(sigma=6, plane=0, sharpen=1, interlaced=true)I only use the chroma filter on VHS sources. For other sources, I just use the FFT filter by itself and then vary the sigma and sharpen settings.

Hope this helps.

foxyshadis
25th December 2006, 00:09
This one doesn't make much sense:

YToUV(fft3dfilter(x, sigma=2, plane=1, sharpen=.25,interlaced=false).UToY,\
fft3dfilter(x, sigma=2, plane=2, sharpen=.25,interlaced=false).VToY,\
fft3dfilter(x, sigma=7, plane=0, sharpen=1, bt=3, interlaced=false))
Since it's functionally identical to:

fft3dfilter(x, sigma=2, plane=3, sharpen=.25,interlaced=false)
fft3dfilter(x, sigma=7, plane=0, sharpen=1, bt=3, interlaced=false)
And probably a little slower, as well. But yeah, good advice to worry more about fft3d settings.

superuser
25th December 2006, 07:54
Thnxs Mug Funky, johnmeyer, Didee (though i do not know where your post went away), and foxyshadis for your input and time. This is one of the reasons I love doom9.

Info on my part for what I am trying this for: I am trying the suggested options (tweaking settings a little bit) on a newer source which needs more than grain remover (with and without motion compensation). Once I find the appropriate method for the source will apply those settings for encoding DVD 9 -> DVD 5 using CCE.

1. yes, there can and will be artefacts, but depending on the thresholds you use and the artefact protection your denoiser uses, it shouldn't be noticable. so fft3d at low settings will be fine.

2. more frames are useful when the denoiser knows what to do with them. so for fft3d's bt=4, you could compute 1 forward and 2 backward compensations, but any more wont be used.

3. that's outside the scope of this thread.

4. results will be identical, only slower if you swap these steps. selectevery will ditch 2/3 of the frames.

1 - I did try couple of different settings with and without motion compensation, though the results are not much different. The only observable difference is the compression, without motion compensation there is more compression achieved. (Had tried 4 CCE pass @3000 bitrate for 4000 frames). Was thinking of one thing, with motion compensation, and using external denoiser like fft3D, the number of frames because of interleaving process, which would mean a bump in time by the factor equal to number of vectors used + 1. Am I missing or messing up something here?

2 - Another point clicked to me, will interleaving say using with 2 compensated vectors and source, the the previous, current and next frame would be the same. Will this make block temporal size "bt" inefficient for bt parameters 3 and 4, as it will have three frames from same frame to work on, not sure. What do you guys think about it?

If I am going offtopic to this thread, mods please my post to fft3d post.

Edit: though i observe the color and sharpness difference with same settings one used with motion compensation and another one without. Motion compensation one seems to be better whereas one without appears slightly dull.

3 - I will take this one to fft3d thread. Though do not know where the didees comment on this disappeared. Though at the point Didee made, currently I am trying LSF + Soothe (soothe with newer masktool version from soothe thread).

4 - Yes sir, that was dumb on my part. did not gave it a thought.


You always need to run your own tests on your own source material, and then view the results on the monitor you use for viewing such material (i.e., the computer monitor is NOT the place to view the results). Sometimes this means burning a test DVD (on a DVD+RW or DVD-RW) and then viewing this on your TV.

Ya, I agree. But as I use my computer LCD as TV also, so sadly most of the experimentation result I view on it. you definetly made a good point.

fft3dfilter(x, sigma=3, plane=0, sharpen=1, bt=3, interlaced=false)
#1
YToUV(fft3dfilter(x, sigma=2, plane=1, sharpen=.25,interlaced=false).UToY,\
fft3dfilter(x, sigma=2, plane=2, sharpen=.25,interlaced=false).VToY,\
fft3dfilter(x, sigma=7, plane=0, sharpen=1, bt=3, interlaced=false))

#2
fft3dfilter(x, sigma=5, sigma2=10, sigma3=12, sigma4=20, plane=0, bt=3, bw=16,\
bh=16, ow=8, oh=8, sharpen=0.3, smin=20, smax=1000, wintype=2, kratio=1.0,\
measure=true, interlaced=true, degrid=1)

#3
fft3dfilter(x, sigma=8, sigma2=18, sigma3=12, sigma4=8, plane=0, sharpen=1,\
measure=true, interlaced=true, degrid=1,wintype=2)
After trying lots of these different settings, I keep coming back to this very simple one that does a pretty good job on lots of clips:chroma=source.Cnr2("oxx",8,16,191,100,255,32,255,false)
final=chroma.fft3dfilter(sigma=6, plane=0, sharpen=1, interlaced=true)I only use the chroma filter on VHS sources. For other sources, I just use the FFT filter by itself and then vary the sigma and sharpen settings.

Hope this helps.

Thanks for sharing the above methods. Had couple of questions though:
- To process all planes, I generally use plane=4. Is processing one plane at a time better, though time wise I understand, processing one plan at a time, may be higher.
- wondering about why you are using high values for sigma 2, 3, & 4 and is there any correlation for values of sigma 2 ,3 & 4?

This one doesn't make much sense:

YToUV(fft3dfilter(x, sigma=2, plane=1, sharpen=.25,interlaced=false).UToY,\
fft3dfilter(x, sigma=2, plane=2, sharpen=.25,interlaced=false).VToY,\
fft3dfilter(x, sigma=7, plane=0, sharpen=1, bt=3, interlaced=false))
Since it's functionally identical to:

fft3dfilter(x, sigma=2, plane=3, sharpen=.25,interlaced=false)
fft3dfilter(x, sigma=7, plane=0, sharpen=1, bt=3, interlaced=false)
And probably a little slower, as well. But yeah, good advice to worry more about fft3d settings.

thnxs for yuv part, i did not notice the subtlety. was looking more into settings for step #3 suggested by john for the source I am playing with.

Regards and happy holidays to all !!!

Serbianboss
4th January 2007, 15:53
Just some questions about strenght of filtering in MVtools

What is the most higher parameter for filtering for MVdegrain 2 or MVDenoise:

I am using this scripts(for interlaced material, Pal, DV avi 720x576,BFF). Source is yuy2


#SetMTMode(2) //To speed up
source=AVISource("C:\Documents and Settings\Nenad\Desktop\vulkani.avi")


fields=source.AssumeBFF().SeparateFields()

backward_vec2 = fields.MVAnalyse(isb = true, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec1 = fields.MVAnalyse(isb = true, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec1 = fields.MVAnalyse(isb = false, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec2 = fields.MVAnalyse(isb = false, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
fields.MVDegrain2(backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=800,idx=1)
Weave()


Here is thSad 800, but result is the same when set to 2000 for example

Only when set to 200 i see that is low quality.

The same thing is with these script:


LoadPlugin("mvtools.dll")
LoadPlugin("MaskTools.dll")
import("C:\Program Files\AviSynth 2.5\plugins\SeeSaw.avs")

#setmtmode(2)
source = AVISource("C:\Documents and Settings\Nenad\Desktop\vulkani.avi")

fields=source.AssumeBFF().SeparateFields()

backward_vec2 = fields.MVAnalyse(isb = true, lambda = 1000, delta = 2, idx = 1)
backward_vec1 = fields.MVAnalyse(isb = true, lambda = 1000, delta = 1, idx = 1)
forward_vec1 = fields.MVAnalyse(isb = false, lambda = 1000, delta = 1, idx = 1)
forward_vec2 = fields.MVAnalyse(isb = false, lambda = 1000, delta = 2, idx = 1)
fields.MVDegrain2(backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=800,idx = 1)
Weave()


This is the similar script with above(its faster), and also i cant get higher filtering from these.

So, my question is, how to get stronger filtering with MVtools.


And one more, where in this script i can put FFT3d filter. Because with that i can get better filtering.

thanks

Fizick
4th January 2007, 17:38
There is no "filtering strength" parameter in MVDegrain.
It uses "simple" (i.e. very complex) temporal averaging.
The more frames, the more averaging.
But you can get more strong filtering with "overlap" option (up to half of block size).

Serbianboss
4th January 2007, 17:49
I read your manual,


Overlap-Must be even and less than block size


What this exactly mean? What overlap can be max to get stronger denoise? In first script i am using at value 4.

Can in script just have overlap and not pel that script is runing little faster?

Fizick
4th January 2007, 18:02
for other functions, overlap may be simply lesser block size.
For mvdegrain: ... like FFT3DFilter, overlap value up to blksize/2
Any overlap is summation. Any summation is averaging. i.e. parial denoising.

I can not give specific advice. try yourself for your clip.
Time-quality is compromiss.

Serbianboss
4th January 2007, 18:08
Not clear but i will try to higher overlap parameter

One more, where is proper way to put fft3dfilter in this MVtools interlaced scipts(3 post above). Because with this scripts i remove noise but not all, and with fft3d i can remove little more noise.

Fizick
4th January 2007, 20:06
IMHO, you can simply put fft3d at the end of script to little polish and stablilize.

Serbianboss
4th January 2007, 22:46
Did you mean to put fft3d filter after weave() and does need to specific interlaced=true or not.


SetMTMode(2)
source=AVISource("C:\Documents and Settings\Nenad\Desktop\vulkani.avi")

fields=source.AssumebFF().SeparateFields()

backward_vec2 = fields.MVAnalyse(isb = true, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec1 = fields.MVAnalyse(isb = true, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec1 = fields.MVAnalyse(isb = false, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec2 = fields.MVAnalyse(isb = false, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
fields.MVDegrain2(backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=800,idx=1)

Weave()

fft3dfilter(sigma=1.2,interlaced=true)



thanks

Pookie
4th January 2007, 22:56
Weave()
fft3dfilter(sigma=1.2,interlaced=true)

is correct, and

fft3dfilter(sigma=1.2)
Weave()


is correct.

Try both and see which looks better.

Serbianboss
5th January 2007, 01:49
I try before and after weave and result are similar. Also tried with MT and 2 way is better because use both core.


Overlap-Must be even and less than block size


Just few questions. What is block size here? Because need to be evan and less, how do i know that? Can i set overlap=2 in my scripts. It little faster than overlap=4

I mean, how do i know when to set overlap=1 or 2 or 3 or 4 ? Any example would be helpful.

foxyshadis
5th January 2007, 02:07
Block size is bw and bh. Check the docs for what it defaults to. Overlap is in # of pixels, for instance if you have a 32x32 block size, overlap could be 24 (but slooooooooow). 2 is a very limited overlap, though even that's better than 0, which is rather blocky.

Serbianboss
5th January 2007, 11:53
So in MVtools block is blksize, and we have overlap.

Overlap value is blksize/2 or blksize/4

And blksize can be 4,8,16. Default is 8

So if we want blksize=4 overlap must be 2 or blksize=8 then overlap must be 4


Just one note:

Can we in script write overlap=4 and not to write blksize=8 ?

Does we for thSad parameter we must to define with value of overlap or no?

Serbianboss
5th January 2007, 17:02
Just this:

If set overlap=1 or 2 can we use if blksize=8. And if can, does we need to write blksize=8,overlap=1 or 2 or we can just write in script overlap=1 or 2 witout blksize.

thanks

Fizick
5th January 2007, 19:08
Try ;)

Serbianboss
5th January 2007, 20:37
overlap=1 dosnt work, need to be evan.

Its works overlap=2 without blksize=8 but does it is correct(syntax) to put just overlap withour blksize.

Didée
5th January 2007, 21:27
Are you familiar with the concept of plugin/function parameters & the concept of "default" values?

"blksize" is a parameter. It can be manually set to 4, 8 or 16.
If this parameter is not explicitely specified, the default value of blksize=8 is used.


That's what the documentation says. It says also that overlap has to be an even number.

I can't really see what is unclear about this?

Serbianboss
6th January 2007, 01:26
Asked just to be sure.

Didee just one question

Recently in my older thread "Where to put MT in reinterlance script" you say that is better "Assign Avisynth / CCE each to one core"

What that means, how to do that?

thanks

Fizick
6th January 2007, 11:40
Serbianboss,
ask in that thread.

Velocity 7
8th January 2007, 04:05
Could MVTools() be used for anime in terms of dropping frames like DeDup() does?

Serbianboss
9th January 2007, 00:47
Can be seesaw be used with MVtools on interlaced material like this:


source=AVISource("C:\Documents and Settings\Nenad\Desktop\vulkani.avi").converttoyv12().Trim(6707,8206)
import("C:\Program Files\AviSynth 2.5\plugins\SeeSaw.avs")

fields=source.AssumebFF().SeparateFields()

backward_vec2 = fields.MVAnalyse(isb = true, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec1 = fields.MVAnalyse(isb = true, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec1 = fields.MVAnalyse(isb = false, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec2 = fields.MVAnalyse(isb = false, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)

a=fields.MVDegrain2(backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=800,idx=1)

b = a.fft3dfilter(sigma=1)
SeeSaw(a,b, NRlimit=5, NRlimit2=6,Sstr=1.5, Slimit=8, Spower=8, Szp=16,soothet=80)


Weave()

Mug Funky
9th January 2007, 01:54
it'll lose you a little detail, but most methods will do that...

halfpel precision will handle the field-bobbing, but will also blur things a bit.

Serbianboss
9th January 2007, 09:29
I know that bobing might be better method but is very slow, 1 fps.
With separatefields/weave i have good results. Now i am just interesting can seesaw be used with interlaced material this way.

Didée
9th January 2007, 11:25
can seesaw be used with interlaced material this way.

You can use it that way, if you want. But it'll be of little use ...

Understand that SeeSaw is keeping "full sharpening" only for static areas. For not-static areas, sharpening is automatically reduced.

After SeparateFields(), there are no more static areas: because of the up-down-jumping of fields, everything is "in motion".

Serbianboss
9th January 2007, 13:47
So better way is using if we bob video.

Its very important that seesaw can be used just with separatefields/weave
Does exist better way instead bobing or separatefields to apply on interlaced material?

I have good results with seesaw and mvdegrain2(separatefields/weave), pictures:

Original

http://img115.imageshack.us/img115/25/originalcopyvx4.png (http://imageshack.us)

MVDegrain 2

http://img440.imageshack.us/img440/8524/degrain2copyeh9.png (http://imageshack.us)


MVDegrain2 and seesaw:

...separatefields...
a=fields.MVDegrain2(backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=800,idx=1)

b = a.fft3dfilter(sigma=1.2)
SeeSaw(a,b, NRlimit=5, NRlimit2=6,Sstr=1.5, Slimit=8, Spower=8, Szp=16,soothet=80)

Weave()

http://img154.imageshack.us/img154/2658/mvdegrain2seesawcopynl8.png (http://imageshack.us)

Maiko Herajin
14th January 2007, 02:10
If I may ask, is there some internal reason why the num variable in mvflowFPS has to be an integer divided by the den integer? Why can't num be a float? I ask because it's very unintuitive to not be able to simply write num=59.94, and avisynth needs all the help being intuitive it can get. (:

Fizick
14th January 2007, 10:52
Avisynth is not intuitive, but precise and advanced program.
what is 59.94 ? in will be converted to some integer num and den internally. But to what num and den? It is not-intuitive question. Please read Assumefps doc in avisynth 2.5.7. Interpretation was changed from v2.5.6.
IMHO, in my opinion, the most intuitive way is to change NTSC standard to 30 Hz. For some stupid historical reason it is 29.97... :)

superuser
15th March 2007, 20:52
Coming back to MVDegrain2 from fft3dfilter. Couple of questions on MVDegrain2, not sure if this is already covered:

- Which user supplied parameters to MVDegrain2 control strength of noise removal. Does SAD in MVAnalyse and threshold SAD (thSAD) in MVDegrain2 has impact on it, I think it has? Though I am not sure, so pitching up this question.
- how does idx plays role into it. One of the reasons from documentation I get is to speed up. But apart from it, how does it help and what is the job of idx really. It will in calling MVDegrain2 & MVAnalyze with right idx values.
- I have a feeling like fft3dfilter, MVDegrain2 can help in achieving higher compression without much loss in quality, say for new source with good quality. Is that a correct statement?
- If above holds, wht would be recommended parameter values to call for MVAnalyse and MVDegrain2 from ur experience. Generally I am into It would be great if you share tht information. I use it to compress DVD 9 to DVD 5 (low bitrate sources) using DVD RB as the tool.

Pardon me if my question seems stupid or n00b to you.

Thanks for your time and help in advance.

Fizick
15th March 2007, 22:14
1. there is no arbitrary denoise strength parameter. you must use resonable (for your video) values of sad threshold in both functions for good results. MVanalize must correctly detect scenechange. MVdegrain must compensate good block only.
2. idx is for speed and memory (internal buffering).
3. probably no. try.
4. default settings :)

superuser
16th March 2007, 00:17
1. What would be good values of SAD and thSAD for blocksize of 4 and overlap size of 2, say one for good source and another nosiy source?
2. K, so how does that relate. Higher the idx lower the memory usage and more the speed or ... please clarify.
3. have been playing with fft3d, an awesome fliter. But for DVD compression processing all planes and motion compensation takes about 4-7 days of encoding effort!!! wanna speed up things.


Thnxs.

foxyshadis
16th March 2007, 01:47
idx doesn't work like that. There are some explanations in the docs; you need to use the same idx when using the same input, especially when using pel=2, or you'll waste time repeating operations internally. It's nothing but an identifier.

But mvdegrain is probably the wrong direction to look if fft3d is too slow; it's usually what, half the speed?

superuser
16th March 2007, 02:06
^ yes, m using pel = 2 and i will be using same idx value for both MVAnalyse and MVDegrain2. From MVTools documentation I am not sure what values of idx one should pick and how it plays role mainly if in terms of quality if any and thn speed.

I pmed u the script which I had used last time with fft3d processing all three planes. I am trying to do something similar with MVDegrain2.

foxyshadis
16th March 2007, 02:18
It's just an identifier, the exact value is meaningless. The use in your script is correct, just continue that in the new one. You only need separate idx values if you're using mvtools more than once, or with denoised and original sources.

Now that I see your script is not just fft3d, but mvflow+fft3d, yes mvdegrain will probably save you some time.

(As fft3d trivia, you should use plane=3 instead of separate plane 1 & 2, unless you really have a good reason. But the time saved won't be much.)

Fizick
16th March 2007, 06:04
For noisy sources I prefer to use MVDeGrain2 with following not Motion compensated fft3dfilter (with small sigma).

superuser
19th March 2007, 18:19
thnxs foxyshadis as u stated earlier, there was not much speed difference. To gain a little bit, not sure that would had effected anything or not, I had am processing all planes at same time instead of individually. But that also did not make much difference.

Still prefer mvdegrain2 as had applied on some samples and had came out fine. Will play around more in after work hours, and try to gain understanding on this fabulous tool. Thnxs fizick for the tool and ur effort u have put :thumbup:

yup
21st March 2007, 19:08
Hi folks!

Advise set parameters for estimation motion in noisy video (analog capture old VHS). I think that need use trumotion=false and tune parameter manual, increase thSCD1 from default, I do not know which search method best for noisy video (2 or 3 or even 1), may be need use pel=1. Also advise better way for calculation compensated frames MVCompesate (with increased thSAD) or MVFlow?
If any have some expirience please advise.

With kind regards yup.

yup
24th March 2007, 13:08
Hi folk!
Very difficult question? Even for script writer:) .
If I right understand search=3 is block matching algorithm, search=2 the same but not use all variant during search. Can I use pnew parameter for tuning motion search in noisy video (like parameter supposed by Boyce)? search=0 and search=1 gradient method and not very good for noisy video?
With kind regards yup.

redfordxx
24th March 2007, 19:04
Hi
I already second time (unsuccessfully) came to try to find setting to make the MVAnalyse detect motion of "nothing".

Here is what I mean. Example of motion of an object in color 5 on a background in color 0
frame0: 0 0 0 5 5 5 5 0 0 0 5
frame1: 0 0 5 5 5 5 0 0 0 0 5
frame2: 0 5 5 5 5 0 0 0 0 0 5
frame3: 5 5 5 5 0 0 0 0 0 0 5
frame4: 5 5 5 0 0 0 0 0 0 0 5

All I receive is motion detected on the edges,
frame0: <- <-
frame1: <- <-
frame2: <- <-
frame3:<- <-
frame4: <-
but, in fact, the whole object 5 is moving, not only its edges.
frame0: <-<-<-<-<-
frame1: <-<-<-<-<-
frame2: <-<-<-<-<-
frame3:<-<-<-<-<-
frame4:<-<-<-<-
The reason I am asking is that in real life the object is not all the same color "5 5 5 5", but it contains slight detail and/or noise.
But the detail is not strong enough to be detected by MVAnalyse correctly. After time domain denoising, even the rest of the detail will be washed.

That is what I thought the lambda parameter takes care of (the motion vectors should be coherent), but it does not help.

1. Did I explain what i have in mind sufficiently?
if so
2. Are there any settings which help?

Fizick
24th March 2007, 21:22
yup,
advice: use default settings (search=2, etc) and increase thSCD1 a little.

redfordxx,
1. Unclear: Have you some real video or it is theoretical question?
MVAnalise use hierarchical search (from coarce to fine), and usually can detect big objects well.
But at every hierarchical level MVTools scan blocks (in frame) from left to right, from top to bottom, and use as a predictors vectors:
1. from previous coarse hierachical level
2. left block
3. top block
4. top-right block.

By the way, if we flip videoframes, motion vectors will be different (due to scan direction change). It may be used as additional data, but speed will be halved.

2. All truemotion-related settings may help: Lambda, pnew.
May be not. Block-based method is not ideal.
But for denoising it is not very important IMHO.

yup
25th March 2007, 08:22
Fizick!
Thank You for reply. Small precise, search=2 is block matching algorithm or not? Also how I can precise motion estimation change searchparam parameter? Until I understand that search=3 is block matching algorithm and searchparam means radius in pixel. I read in Your recomended link http://www.mee.tcd.ie/~ack/papers/a4ackphd.ps.gz that for noisy video need use block matching algorithm as more robust for video with noise. Also how I can change pnew parameter for robust motion estimation.
With kind regards yup.

redfordxx
25th March 2007, 14:18
1. Unclear: Have you some real video or it is theoretical question?
Real.
But on top of that, I made interesting test. Try this scripts on any movie:s=AviSource("...")
sh=2
sv=2
moved=StackHorizontal(s.crop(sh,0,0,0),s.crop(0,0,sh,0))
moved=StackVertical(moved.crop(0,sv,0,0),moved.crop(0,0,0,sv))
moved
smo=interleave(moved,s)

vfmo1=smo.MVAnalyse(isb = false,blksize=4,truemotion=true,search=3,searchparam=4)
cfmo1=smo.MVCompensate(vfmo1, mode = 0)

dcmo=mt_lutxy(smo,cfmo1,"x y - 5 * 128 +", y=3,u=3,v=3)
dcmoa=dcmo.mt_lut("x 128 - abs 5 *", y=3,u=3,v=3)
dcmo=ScriptClip(dcmo,"Subtitle(String(AverageLuma(dcmoa.crop(64,64,-64,-64))))")

dcmo

It shows that even if you shift a exactly same frame, MVAnalyse is not able always to find the correct compensation. I guess it also depends on if the shift is multiply of blocksize.
you can change sh or sv as wish. to change the the shift.

By the way, if we flip videoframes, motion vectors will be different (due to scan direction change). It may be used as additional data, but speed will be halved.
Wow...

redfordxx
25th March 2007, 15:05
2. All truemotion-related settings may help: Lambda, pnew.
May be not. Block-based method is not ideal.
But for denoising it is not very important IMHO.
Example (this whole image goes moreorless to left):
On the moon and clouds the ME is really to left direction, but on the sky inbetween it goes to all directions because of noise...
vf1=s.MVAnalyse(isb = false,blksize=4,truemotion=true,lambda=500)
s.MVShow(vf1,scale=4)

http://img364.imageshack.us/img364/6023/image2tn8.png

My idea was spatially denoise a clip and maybe enhance edges, then make on this denoised video ME.
Then compensate the original clip with these vectors and make time domain denoising...

That's why I thought that the moon and the clouds vectors and the coherence settings would drive the sky also left. But it does not as you see here... vf1=s.MVAnalyse(isb = false,blksize=4,truemotion=true,lambda=5000)
s.MVShow(vf1,scale=4)
http://img369.imageshack.us/img369/3194/image3wr0.png

Fizick
25th March 2007, 16:50
yup,
all MVTools motion estimation metods are block based. Did you read documentation?
For robust ME you may try use prefilter.
Please read this thread.


redfordxx,
Almost nothing to say. Try disable global motion.
But blocksize=4 is very bad choice anyway.

yup
25th March 2007, 18:15
Fizick!
Thanks for advice. I read documentation thoroughly and know about block. Noise in my source impulse (mainly black or white lines) not white or grain. Best result I get combining use MVTools and ml3dex. Former I try find better median denoiser, but now I understand that problem in ME. Use search=3 and searchparam=12 solve my problem, even with bloksize=16, all other parameter default. Please precise thread. Also I try use medianblur for prefilter before MVAnalyse, but result was worse than use source for ME and ml3dex for filtering. Now work script:
AviSource("seldv2.avi")
AssumeBFF()
ConvertToYV12(interlaced=true)
SeparateFields()
SelectEven()
source=last
backward_vectors = source.MVAnalyse(blksize=8, isb = true, truemotion=true, search=3, searchparam=12, delta = 1, idx = 1,overlap=4, dct=1)
forward_vectors = source.MVAnalyse(blksize=8, isb = false, truemotion=true, search=3, searchparam=12, delta = 1, idx = 1, overlap=4, dct=1)
forward_compensation = source.MVFlow(forward_vectors, idx=1)
backward_compensation = source.MVFlow(backward_vectors, idx=1)
interleave(forward_compensation, source, backward_compensation)
ml3dex(mc=false)
selectevery(3,1)
Problem only one speed, but this better if I can not find how clean my video source.
With kind regards yup.

redfordxx
26th March 2007, 13:05
Almost nothing to say.
Well, when you see my previous post:It shows that even if you shift a exactly same frame, MVAnalyse is not able always to find the correct compensation. there should be something to say:
Either is something wrong with MVTools
or with my computer.
I would like to know which one is it, so definitely appreciate if someone tries to use that script I provided and tell whether has same experience.
There is SAD of the whole frame reported and highlighted difference. Easy to see: every second frame SAD should be zero and no difference highlighted.
Thanx

redfordxx
26th March 2007, 13:15
scan blocks (in frame) from left to right, from top to bottom, and use as a predictors vectors:
1. from previous coarse hierachical level
2. left block
3. top block
4. top-right block.
So, If I understand correctly, if there will be completely white frame with one black dot in first block moving down, then every block will be detected as moving down? (because it will be predicted by the first one and nothing will be there to "change the opinion")

redfordxx
26th March 2007, 13:57
Is there any function to process/refine the vectors?
I mean some motion estimation search, what will take as predictors not the left or top block, but the vectors from previous search. To make myself clear, something like:
newvec=MVAnalyse(clip,oldvec)
Because I see great potential there...for example make first search on reduced resolution and then refine on full res.

Other idea to refine ME would be to assign to each vector some relative reliability coefficient (say RRC) and then use the vectors with high RRC as predictors to the neighboring blocks.
RRC is defined high when the SAD of the vector is low and SAD of little bit different vectors is high. Maybe:RRC(<x,y>)=Min{SAD(<x-1,y>),SAD(<x,y-1>),SAD(<x+1,y>),SAD(<x,y+1>)}/SAD(<x,y>)RRC would basically say if we change the vector little bit, what will happen.

Sorry for bothering but it just crossed my mind and I needed to share. The reason is still to be able make *true* ME also in the areas where noise is stronger than signal (which happens quite often in video: original noise, film grain, bad compression quality loss, mosquito noise, bad deinterlacing...)

If there exists something, pls lemme know...

BTW:is that true that mosquito noise is just result of bad ME? (not subpel enough?)

redfordxx
26th March 2007, 15:34
BTW: do not understand it as complaining at you or any developer.
I appreciate definitely your work.
I just want to contribute with small piece of maybe useful idea.

Fizick
26th March 2007, 17:53
1. refining is implemented as hierachical ME.

2. I forget to say about one more predictor - zero vector.
And optional predictor - global motion vector.
Probably in this case global motion is estimated wrongly (too many zero vectors).
May be it may be implemented othe way, with RRC.
But in any case motion middle part in your example frame is unclear (fuzzy?).
And imagine that instead of the moon we have some bird moving to opposite direction. Or we watch a moon sky around trees on wind...
Certainly some more smart heuristic analisis is possible.
May be in some case we may omit zero predictor. But it may result in chaotic vectors like your first picture.

3. Mosquito noise is usually arized from DCT (nonlocal) transform, not from bad ME.

4. Thanks for ideas. There were some various ideas (from literature) in my head too.
But right now I am interested in a little other topics (for example, motion compensated superresolution).

Try use some pre-filter (denoise, local contrast ?).

But best solution: take MVTools source and make custom build. :)

krieger2005
28th March 2007, 15:04
Is it possible to use the compensation of motion.dll from mg262 for MVDegrain? Still the MC of motion.dll is often much better that those of MV-Tools. But MVTools are well developed...

Fizick
28th March 2007, 16:54
krieger2005,
It is old story. Once upon a time I asked Manao and mg262 to create and use one interface for motion data. But mg262 said that it is better to create some wrapper.
So, we wait this wrapper. May be from you. :)
But it is not easy task.

krieger2005
28th March 2007, 22:04
I know this story. I thought it could be done in some way through "MVChangeCompensate". Or does MVDegrain need also the Motiondata (and not only the compensated clip)?

Fizick
29th March 2007, 04:37
MVDegrain and most other filters (besides MVDenoise) does NOT use compensated clip stored in vectors clip.
They use only motion data . But they also usually use upsized frames stored with idx tricks.

Boulder
10th April 2007, 18:20
Is there any possible harm done when running two simultaneous but separate jobs (i.e. two HC encoder instances) with same idx values?

Fizick
11th April 2007, 04:49
Boulder,
I do not know :) Never tryed.
But it must be safe (it creates two instances of script environment).

Alain2
11th April 2007, 20:27
Done it several times, never had any problem

yup
12th April 2007, 08:30
Hi folk!
Please explain how I can use fields parameter for deinterlacing video? Clip after deinterlacing will be consist from compesated frames? Please advise simlpe script.
AVISource("clip.avi")
source=SepareteFields()
vectors=source.MVAnalyse(isb=false,pel=2)
source.MVCompensated(vectors,fields=true)
Weave()
This script right or wrong or I need use for even and odd fields separately?
With kind regards yup.

Fizick
12th April 2007, 15:34
Denoiser script for interlaced video

function MVDegrain2i(clip "source", int "dct", int "idx")
{ # MVDegrain2i - motion compensated denoiser for interlaced source clip
# uses MVTools plugin
dct=default(dct,0) # use dct=1 for clip with light flicker
idx=default(idx,1) # use various idx for different sources in same script
fields=source.SeparateFields()
backward_vec2 = fields.MVAnalyse(isb = true, delta = 2, pel = 2, overlap=4, sharp=2, idx = idx,dct=dct)
forward_vec2 = fields.MVAnalyse(isb = false, delta = 2, pel = 2, overlap=4, sharp=2, idx = idx,dct=dct)
backward_vec4 = fields.MVAnalyse(isb = true, delta = 4, pel = 2, overlap=4, sharp=2, idx = idx,dct=dct)
forward_vec4 = fields.MVAnalyse(isb = false, delta = 4, pel = 2, overlap=4, sharp=2, idx = idx,dct=dct)
fields.MVDegrain2(backward_vec4,backward_vec2,forward_vec2,forward_vec4,thSAD=400,idx=idx)
Weave()
}

source=MPEG2Source("F:\Internet\070710\nirvana_chunk_1.d2v", cpu=0)
mvdegrain2i(source,1,1)


(It is not answer to yup's question)

Fizick
14th April 2007, 16:36
yup,
your script with fields is not quite correct. Here is correct version:

source=AVISource("clip.avi")
field=source.SeparateFields()
blured=field.blur(0.0,1.0) # vertical blur for estimation clip
vb=blured.mvanalyse(pel=2, isb=true,overlap=4)
secondfield=field.mvcompensate(vb,fields=true,thSAD=400)
interleave(field,secondfield)
weave()
#selecteven() # uncomment it if you do not need a Bob


Of course, it is simply for illustrating of syntax.
For real deintrlace it must be improved by adding forward compensation, masking, artifact protection, edge directed interpolation, etc.

For example, we can use external upsized clip2x with EEDI2:
(name it ... MVBobSimple)

source=last
field=source.SeparateFields()
blured=field.blur(0.0,1.0) # vertical blur for estimation clip
clip2x=field.eedi2().LanczosResize(width(field)*2,height(field)*2,src_left=0.25)
bclip2x=clip2x.blur(0.0,1.0).blur(0.0,1.0) # not quite correct
vb=blured.mvanalyse(pel=2, isb=true,overlap=4,clip2x=bclip2x)
secondfield=field.mvcompensate(vb,fields=true,thSAD=400,clip2x=clip2x)
interleave(field,secondfield)
weave()
#selecteven()


it is only draft of script.
Why use field insted bobbed? To increase the speed.
Probably MC deinterlace must be implemented as a plugin.
But I am not very interested in bobbing and deinterlacing.

yup
16th April 2007, 18:10
Fizick:thanks: for reply!
My aim very simple I want using MVTools from innerlaced source 720x576 25fps get fields at same polarity 720x288 50fps make denoising based on MVTools, increase resolution and using standardt conversion (SeparateFilds(), SelectEvery(4,0,3), Weave()) get interlaced source. I do not want use bob() because in my video impulse noise (black lines with luma value 16) and during interpolation I get from one bad line 3 bad lines (for remove this noise I could use more MC frames or more than 1 pass filtering). May be for this problem suite folowing approach
clip=AVISource("clip.avi")
bob()
VerticalReduceBy2()
MotionCompensatedDenoiser()
LanczosREsize(720,576)
SeparateFields()
SelectEvery(4,0,3)
Weave()

Also use 50fps fields I can use more frames for MC at same time interval than at 25fps fields. Also I have other idea but using MVTools I spent more time for filtering (I obligatory make report after results). One more thank You for reply.
yup.

videoFred
23rd April 2007, 11:35
I have a question about MvFlowFps():

My originals are 16fps, progressive.
I always use MvFlowFps2() to convert to 25fps, preserving the original play speed.

Does MvFlowFps creates 25 entire new frames?
If not, where do I find the originals?
I do not need them, just curiosity:p

PS: MvFlowFPS2() works great!
It beats commercial programs:devil:

Fred.

scharfis_brain
23rd April 2007, 13:02
after a framerate conversion you'll only be able to get your originals back, if the up-conversion had been done with a integer factor of the original framerate.

i.e.: original 16 2/3 fps. result 50 fps.
so every third frame is an original.

but if you converted 16 2/3 fps to 25 fps you'll loose every second original!

videoFred
24th April 2007, 06:38
I understand.
16 2/3 to 25... That's what I do.

Fred.

foxyshadis
28th April 2007, 04:02
Fizick, would it be possible to create a version of MVCompensate/MVFlow that outputs the raw hpel/qpel internal representation? Mainly as a place to start for a really quick & dirty motion-compensated upsize.

Fizick
30th April 2007, 21:50
I tried to create MC superresolution but without great succcess.

Delerue
23rd May 2007, 09:02
I'm wondering if there's any newbie tutorial to teach how to use MVTools. I'm trying to use the 'MVFlowFps2' script inside the Avisynth FFDShow tab. My wish is to duplicate the number of FPS, but without changing the timing. So I pasted this:


loadplugin("C:\arquivos de programas\avisynth\mvtools.dll")
source = AVISource("D:\Downloads\Filmes\A Bugs Life trailler.avi")


# Assume progressive PAL 25 fps source. Lets try convert it to 50.
backward_vec = source.MVAnalyse(isb = true, truemotion=true, pel=2, idx=1)
# we use explicit idx for more fast processing
forward_vec = source.MVAnalyse(isb = false, truemotion=true, pel=2, idx=1)
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)
forward_vec2 = cropped.MVAnalyse(isb = false, truemotion=true, pel=2, idx=2)
return source.MVFlowFps2(backward_vec,forward_vec,backward_vec2,forward_vec2,num=50,idx=1,idx2=2)


Of course, I have Avisynth (AviSynth_070518.exe) installed and MVTools 1.6.2 too. I get no script errors, but unfortunately, the image gets out of sync with audio, and, althought I can notice the new added frames, the FPS still the same, so I spend 2 seconds to see each movie second. What I'm doing wrong?

Thanks a lot

Leak
23rd May 2007, 09:36
Of course, I have Avisynth (AviSynth_070518.exe) installed and MVTools too. I get no script errors, but unfortunately, the image gets out of sync with audio, and, althought I can notice the new added frames, the FPS still the same, so I spend 2 seconds to see each movie second. What I'm doing wrong?
I assume you're using one of the ffdshow builds off the ffdshow-tryouts page, so...

The AviSynth filter in those is way too basic to be able to handle your script; it won't allow your script to access more than the current frame, it won't update the timestamps to compensate for the added frames and it won't correctly support adding or dropping frames at all.

It probably works a lot better with my updated AviSynth filter (http://forum.doom9.org/showthread.php?p=1005593#post1005593), but are you sure your CPU is able to handle doing what you want in realtime?

Delerue
23rd May 2007, 09:53
I assume you're using one of the ffdshow builds off the ffdshow-tryouts page, so...

Yeah. In fact, I was using the 1193 build.

The AviSynth filter in those is way too basic to be able to handle your script; it won't allow your script to access more than the current frame, it won't update the timestamps to compensate for the added frames and it won't correctly support adding or dropping frames at all.

Hmmmm...

It probably works a lot better with my updated AviSynth filter (http://forum.doom9.org/showthread.php?p=1005593#post1005593)

Ok. I downloaded your FFDShow patched version. How do I do the job? :)

but are you sure your CPU is able to handle doing what you want in realtime?

Well, a Core 2 Duo running at real 3 GHz isn't enough? At last I can't see a full load in Task Manager.

Leak
23rd May 2007, 10:34
Ok. I downloaded your FFDShow patched version. How do I do the job? :)
Well, did you read the documentation? (okay, it needs a bit of updating, but the changes are rather small)

Fill in your script, enable buffering, figure out the correct value for the number of frames to buffer ahead.

Well, a Core 2 Duo running at real 3 GHz isn't enough? At last I can't see a full load in Task Manager.
Yeah, but unless the filters you use are multithreaded or work correctly with MT (which I'm not so sure with MVTools) it'll only ever utilize on CPU core, which means it won't go over 50%...

But of course you won't really know until you try it out - it's just that motion compensation is quite a bit more CPU hungry than your average filter... :)

Delerue
23rd May 2007, 10:52
Well, did you read the documentation? (okay, it needs a bit of updating, but the changes are rather small)

Fill in your script, enable buffering, figure out the correct value for the number of frames to buffer ahead.

I'm reading, but at this moment the only thing I get is a weird green screen:

http://img.photobucket.com/albums/v256/Delerue/Avisynth_green.png

I used this configuration:

http://img.photobucket.com/albums/v256/Delerue/Avisynth01.png

P.S.: the script used was the same that I quoted in the first post.

But of course you won't really know until you try it out - it's just that motion compensation is quite a bit more CPU hungry than your average filter... :)

Yeah! Let's make it works first. :)

anahita
23rd May 2007, 11:17
Thx a lot :)

Leak
23rd May 2007, 11:24
I used this configuration:

http://img.photobucket.com/albums/v256/Delerue/Avisynth01.png

P.S.: the script used was the same that I quoted in the first post
Exactly what made you think using AVISource inside ffdshow was the right thing to do? After all, ffdshow should already be decoding your AVI file so loading it again is a surefire way to mess things up.

Just drop AVISource out of there - the filter automatically adds a line with "ffdshow_source()" at the top of your script that'll pull in the video ffdshow is currently decoding. So either you add a "source=last" at the top or uncheck "add ffdshow video source" and use "source=ffdshow_source()".

Delerue
23rd May 2007, 20:33
Exactly what made you think using AVISource inside ffdshow was the right thing to do? After all, ffdshow should already be decoding your AVI file so loading it again is a surefire way to mess things up.

Yeah, you're right. I did what you said and it worked. But maaaan... it's REALLY heavy! I just can't handle with my CPU if I use another filter (Resize, Blr & NR, etc.) at the same time. I thought that MVTools script was light as TrimensionDNM (do you know?).

I tried the simple script (from MVTools website) and set it to generate 'only' 48 FPS, but didn't help too much. Do you have any idea of how can I make it run faster?

Cheers

Leak
23rd May 2007, 22:07
Do you have any idea of how can I make it run faster?
Sorry, I've never used MVTools much - but maybe someone else reading this thread has a suggestion? :)

np: David Sylvian - Come Morning (Everything And Nothing (Disc 2))

Boulder
24th May 2007, 03:26
You could try using block size of 16 pixels and use MVFlowFPS instead so that you'll only need to do two MVAnalyse calls. Also use chroma=false, sharp=0 and pel=1 in MVAnalyse.

However, I still doubt that it would run in realtime.

Delerue
24th May 2007, 07:51
You could try using block size of 16 pixels and use MVFlowFPS instead so that you'll only need to do two MVAnalyse calls. Also use chroma=false, sharp=0 and pel=1 in MVAnalyse.

However, I still doubt that it would run in realtime.

Hmmm... It helped a little. But unfortunately not enough. It makes me think what the guys from Philips did to make the TrimensionDNM so fast. It's sad that we must use the bad WinDVD to see it working, and always limited to MPEG2.

Thanks, guys.

actionman133
24th May 2007, 07:53
I can run sub-DVD resolution video in realtime with MVTools. I use these parameters:

blksize = 16
pel = 1
search = 1 (or whatever is the lowest option)
searchparam = 1

I only do two passes using idx (apparently it's faster that way) and use MVFlowFPS for realtime framerate conversion as a preview. I wouldn't use it for anything else though (I strictly use search = 3 with a high searchparam when I actually convert).

Terranigma
26th May 2007, 17:03
Fizick, I have a question for you Here (http://forum.doom9.org/showthread.php?t=126269&highlight=mvtools) =P

Fizick
26th May 2007, 19:35
Which would be more efficient to use? DCT 1 or 2?
1 - use block DCT instead of spatial data (slow);
2 - mixed spatial and DCT data; weight is dependent on mean frame luma difference;
Would mode 2 be combining the spatial and DCT data for a frame, or would it decide whether or not to use spatial or DCT data on a per-frame basis? If it combines and use both the spatial and DCT data for a frame, rather than being adaptive with it and having it choose which it thinks would be more suitable, then obviously mode 2 would be more efficient. Basically I need a better understanding of how DCT 2 works. :devil:


Algo:
Firstly we caclulate mean luma change between current and reference frames per pixel.

then we calculate spatial SAD for every block.
then we calculate DCT SAD for this block (with some empirical correction of reduced DC component)
then we calculate weighted result: the more is mean luma difference, the more weight of DCT. Dct and spatial weights are equal for mean LumaChange=8 (empiricaly).

Current Implementation is not perfect: mean luma change calculated not quite for whole frame, there are some rounding error, etc.

Adaptive switchin is hard to impement: spatial and dct SAD are not coinside, so some osclillation.

All other DCT modes are experimental too (mode dct=3 has a bug, it will be fixed soon in new beta).
Chroma planes is always normal spatial SAD.
The aim was to provide correct motion estimation for bad sources with global and local luma flicker (old cartoon film).
The best was dct=1. But for normal sources the pure dct mode sometimes get not corect motion vectors (ignore luma change).

so dct=2 is usually better.
But it is slow. Sometimes I prefer dct=4. but usually use old good dct=0 :)

Terranigma
26th May 2007, 19:58
Thanks for that thorough explaination. I really appreciate it :)

Fizick
6th June 2007, 15:13
Released MVTools v1.6.4
MVAnalyse: modified vectors order for Enhausted search (expanding squares).
MVAnalyse: fixed bug with dct=3.
MVFlowFps, MVFlowFPS2, MVFlowInter: now blend frames with bad motion estimaton (at scenechanges, flashes).
MVFlowFps, MVFlowFPS2: fixed bug with thSAD parameter (and correspondent mask).


to moderator: please rename this thread to " MVTools" (without version number)

Terranigma
6th June 2007, 15:20
Thanks for the update Fizick. I'll be definately getting this. :D

Fizick
10th June 2007, 17:40
Release v1.7.0 beta
MVAnalyse: added blksizeV and overlapV parameters for non-square blocks 8x4 and 16x8.

(Many subroutines were changed, so some bugs may be introduced.)

Terranigma
10th June 2007, 18:16
Thanks once again. :cool:

Terranigma
16th June 2007, 15:26
Fizick, will there be an update to MVDenoise whereas it'd be possible to specify overlap values? :D

Fizick
16th June 2007, 16:30
no,
at least not from me.

Now I (will) work on more correct occlusion mask and moving object halo reduction.

Delerue
16th June 2007, 21:21
Now I (will) work on more correct occlusion mask and moving object halo reduction.

Cool, man. This is certainly the most important thing to be improved. :)

BTW, do you know TrimensionDNM algorithm? Maybe you could learn a lot if you get some material about it, and so improve your MVFlowFPS script. ;)

Fizick
16th June 2007, 21:47
Delerue, do YOU know TrimensionDNM algorithm? :)
Or can you provide frame by frame pictures with it?
It outputs to overlay, but may be somebody can capture somehow ...
But I am afraid, that it is very simple and we can not learn anythig from it.

Boulder
17th June 2007, 12:42
Out of interest, why is motion rather rarely detected in the very bottom of the frame compared to the top? (the same seems to happen on the right side, not much motion detected there)

http://img504.imageshack.us/img504/7540/mvtools1ob9.th.png (http://img504.imageshack.us/my.php?image=mvtools1ob9.png)
http://img223.imageshack.us/img223/6596/mvtools2xd5.th.png (http://img223.imageshack.us/my.php?image=mvtools2xd5.png)

Terranigma
17th June 2007, 15:43
no,
at least not from me.


Just thought i'd ask. I find it to be better than mvdegrain because mvdegrain not only removes noise, but grain, while denoise seems to just remove noise like how i'd like it to. I'd like to retain that grain, because for me it seems to boost overall quality.

otoh, could you recommend a great filter that is great @ removing noise but keeping the grain?

Didée
17th June 2007, 16:32
mvdegrain not only removes noise, but grain, while denoise seems to just remove noise
[...]
otoh, could you recommend a great filter that is great @ removing noise but keeping the grain?
Technically, grain is just noise. It has its certain characteristics, which are different from encoder's noise, but in the end it's just noise.

However you can quite easily "rebuild" MVDenoise to use overlapped blocks. Just compensate, interleave, temporalsoften or ttempsmooth the interleave, then selectevery again. It's already done in MCNR_simple2/3, you can copy&paste it from there. :)

Delerue
20th June 2007, 02:01
Delerue, do YOU know TrimensionDNM algorithm? :)

I don't. Sorry. I only use it, and I really love it. The sad things: 1 - we have to pay (or use for 30 days only); 2 - only works with MPEG2; 3 - only works with WinDVD (would be REALLY great if someone tell us a way to use it without WinDVD). But the result is amazing. To give you an ideia, The Matrix DVD consumes something around 8% of my CPU with TrimensionDNM enable. But MVFlowFPS script simply can't do the job, because it uses more than 50% (remembering that I have a dual-core CPU, but unfortunately MVTools works only in single-thread). The image quality of TrimensionDNM is another thing to consider: almost no artifact or moving object halo.

Or can you provide frame by frame pictures with it?[ It outputs to overlay, but may be somebody can capture somehow ...

I can capture frame by frame with TrimensionDNM disable, but when I enable I got only green pictures. :(

But I am afraid, that it is very simple and we can not learn anythig from it.

Yeah... very sad. This algorithm drives me crazy.

Boulder
20th June 2007, 15:03
Out of interest, why is motion rather rarely detected in the very bottom of the frame compared to the top? (the same seems to happen on the right side, not much motion detected there)

http://img504.imageshack.us/img504/7540/mvtools1ob9.th.png (http://img504.imageshack.us/my.php?image=mvtools1ob9.png)
http://img223.imageshack.us/img223/6596/mvtools2xd5.th.png (http://img223.imageshack.us/my.php?image=mvtools2xd5.png)

Fizick, do you happen to know the reason? The MVAnalyse code is

vbw1=MVAnalyse(isb=true,truemotion=true,delta=1,pel=2,chroma=false,blksize=16,idx=1,sharp=2,overlap=8)
vfw1=MVAnalyse(isb=false,truemotion=true,delta=1,pel=2,chroma=false,blksize=16,idx=1,sharp=2,overlap=8)
vbw2=MVAnalyse(isb=true,truemotion=true,delta=2,pel=2,chroma=false,blksize=16,idx=1,sharp=2,overlap=8)
vfw2=MVAnalyse(isb=false,truemotion=true,delta=2,pel=2,chroma=false,blksize=16,idx=1,sharp=2,overlap=8)

And then MVShow, of course.

Fizick
20th June 2007, 15:27
Boulder,
no, i do not know.
Of cource, borders are processed differently if width do not covered by integer number of (overlapped) blocks.
But I wondered why leftmost and topmost vectors are very near borders.
May be small bug in MVShow (vectors are not at centers of bloks)


Confirmed: Yes, this offset bug of MVShow will be fixed in next version

Boulder
20th June 2007, 18:51
Boulder,
no, i do not know.
Of cource, borders are processed differently if width do not covered by integer number of (overlapped) blocks.
But I wondered why leftmost and topmost vectors are very near borders.
May be small bug in MVShow (vectors are not at centers of bloks)


Confirmed: Yes, this offset bug of MVShow will be fixed in next versionOK, good to know that there's nothing wrong with MVAnalyse :)

halsboss
25th June 2007, 15:43
Denoiser script for interlaced video

function MVDegrain2i(clip "source", int "dct", int "idx")
{ # MVDegrain2i - motion compensated denoiser for interlaced source clip
# uses MVTools plugin
dct=default(dct,0) # use dct=1 for clip with light flicker
idx=default(idx,1) # use various idx for different sources in same script
fields=source.SeparateFields()
backward_vec2 = fields.MVAnalyse(isb = true, delta = 2, pel = 2, overlap=4, sharp=2, idx = idx,dct=dct)
forward_vec2 = fields.MVAnalyse(isb = false, delta = 2, pel = 2, overlap=4, sharp=2, idx = idx,dct=dct)
backward_vec4 = fields.MVAnalyse(isb = true, delta = 4, pel = 2, overlap=4, sharp=2, idx = idx,dct=dct)
forward_vec4 = fields.MVAnalyse(isb = false, delta = 4, pel = 2, overlap=4, sharp=2, idx = idx,dct=dct)
fields.MVDegrain2(backward_vec4,backward_vec2,forward_vec2,forward_vec4,thSAD=400,idx=idx)
Weave()
}

source=MPEG2Source("F:\Internet\070710\nirvana_chunk_1.d2v", cpu=0)
mvdegrain2i(source,1,1)



Just wondering if the order of the arguments in the MVDegrain2 line is right ? as the documentation says

MVDeGrain2 (clip, clip "mvbw", clip "mvfw", clip "mvbw2", clip "mvfw2",int "thSAD", int "plane", clip "clip2x", int "idx")

MVDeGrain2 has temporal radius 2
(uses vectors of two previous mvfw2, mvfw and
two next mvbw,mvbw2 frames).
It is slower, but produces a little
better results (more strong denoising).

eg

fields.MVDegrain2(backward_vec2,forward_vec2,backward_vec4,forward_vec4,thSAD=400,idx=1)

Terranigma
25th June 2007, 16:59
Yes, it's correct. Those lines are just specifiers, they can be anything.
e.g.

function MVDegrain2i(clip "source", int "dct", int "idx")
{ # MVDegrain2i - motion compensated denoiser for interlaced source clip
# uses MVTools plugin
dct=default(dct,0) # use dct=1 for clip with light flicker
idx=default(idx,1) # use various idx for different sources in same script
fields=source.SeparateFields()
left1 = fields.MVAnalyse(isb = true, delta = 2, pel = 2, overlap=4, sharp=2, idx = idx,dct=dct)
right1 = fields.MVAnalyse(isb = false, delta = 2, pel = 2, overlap=4, sharp=2, idx = idx,dct=dct)
left2 = fields.MVAnalyse(isb = true, delta = 4, pel = 2, overlap=4, sharp=2, idx = idx,dct=dct)
right2 = fields.MVAnalyse(isb = false, delta = 4, pel = 2, overlap=4, sharp=2, idx = idx,dct=dct)
fields.MVDegrain2(left2,left1,right1,right2,thSAD=400,idx=idx)
Weave()


source=MPEG2Source("F:\Internet\070710\nirvana_chunk_1.d2v", cpu=0)
mvdegrain2i(source,1,1)
}

Fizick
25th June 2007, 20:38
It seems, the order of vectors clip is not important for mvdegrain1 or mvdegrain2. At least I had intention to implement it so way. All clips have equal weight for averaging.
Please check it yourself with Subtract.

But vectors order is important for MVFlowFPS, MVFlowFPS2:
different vectors are used diferently.

halsboss
25th June 2007, 23:57
It seems, the order of vectors clip is not important for mvdegrain1 or mvdegrain2. At least I had intention to implement it so way. All clips have equal weight for averaging.
Please check it yourself with Subtract.

But vectors order is important for MVFlowFPS, MVFlowFPS2:
different vectors are used diferently.

Thankyou. I guess if only to be consistent, I should rearrange the order in my copy of the function to align with the documentation... just in case, as you never know the wonderours improvements you might make in these functions, Fizick !

wonkey_monkey
26th June 2007, 10:34
Re: Trimension DNM...

The sad things: 1 - we have to pay (or use for 30 days only);

I can't enable it with WinDVD 8 trial for some reason, but I took a look at the demo.

2 - only works with MPEG2;

That bit makes me wonder... is it somehow using the information in the MPEG2 stream to determine motion vectors, rather than having to match blocks as mvtools does? If so, most of the hard work is already done...

David

Delerue
26th June 2007, 13:50
I can't enable it with WinDVD 8 trial for some reason, but I took a look at the demo.

Maybe you should try to disable hardware acceleration. Or first try the built-in demo (video).

That bit makes me wonder... is it somehow using the information in the MPEG2 stream to determine motion vectors, rather than having to match blocks as mvtools does? If so, most of the hard work is already done...

Hmmmm... I don't have the knowledge to answer this, but what you said makes sense to me. Maybe Fizick could inform us better. Let's wait.

wonkey_monkey
26th June 2007, 16:04
Maybe you should try to disable hardware acceleration. Or first try the built-in demo (video).

Acceleration was disabled initially (and apparently during the install process too ;) ), but I could still only get to the Trimension/Advanced window and select the Trimension mode (Cine and the other one). The other options, in the bottom half of the window, were greyed out.

I got the demo from the Trimension website, but it's just a horizontally scrolling image, so not really a good indicator of what's possible :)

Perhaps someone could capture some Trimensionalised video from their TV-out, if deeper analysis is required?

David

Delerue
26th June 2007, 17:58
I got the demo from the Trimension website, but it's just a horizontally scrolling image, so not really a good indicator of what's possible :)

When I said 'demo' I mean the built-in one. It's a video, and you can find it manually inside the WinDVD folder.

Also try to close all the tray stuff. At least in my machine TrimensionDNM can't work with ATI Tray Tools or Fraps.

P.S.: maybe you should open a new thread just to avoid a mess with the Fizick work. :)

Delerue
28th June 2007, 14:15
Fizick, I noticed that you finished the 1.8.0 beta version ('Developed MVTools 1.8.0 beta (improved MVFlowFps, etc'), from your website), but I can't see a link to test. Can you provide?

Thanks.

Fizick
28th June 2007, 17:34
"Finished" is not correct word.
And "Developed" is not "Released". :)

I also almost developed v1.8.1:
MVAnalyse: added postrocesssing motion vectores by dividing blocks into subblocks to decrease zone of motion vectors interpolation.
MVFlowFps: added "mode" parameter to select processing method at occlusion areas (and speed).
Some internal changes (padding in MVAnalysisData, header to vector stream frames, etc).

But these new versions are not yet available for public download. See more info at my site.

Delerue
28th June 2007, 19:07
Hmmm... I see. Sorry. :)

Xitsa
29th June 2007, 09:42
Please help me understand
what this is supposed to do:

MV=OriginalClip.MVAnalyse(isb = true)
CompensatedClip=OriginalClip.MVCompensate(MV)

Is CompensatedClip[i] will be like OriginalClip[i+1] or
CompensatedClip[i+1] will be like OriginalClip[i]?

foxyshadis
29th June 2007, 12:02
When isb=false, CompensatedClip[i] is based on OriginalClip[i-1], and when isb=true, CompensatedClip[i] is based on OriginalClip[i+1].

Xitsa
29th June 2007, 12:28
When isb=false, CompensatedClip[i] is based on OriginalClip[i-1], and when isb=true, CompensatedClip[i] is based on OriginalClip[i+1].

So blocks in OriginalClip[i] moves to its recent positions in OriginalClip[i-1]?
or CompensatedClip[i] consist of blocks of OriginalClip[i-1] moved to its positions in OriginalClip[i]?

Fizick
30th June 2007, 11:26
isb=false:
CompensatedClip[i] consist of regularly placed (step=blocksize-overlap) blocks which are taken from any (not regular) places of OriginalClip[i-1], most similar (by content) to OriginalClip[i] regular blocks.

buletti
1st July 2007, 12:38
First of all: Hi there, this is my first posting to these forums. :)

isb=false:
CompensatedClip[i] consist of regularly placed (step=blocksize-overlap) blocks which are taken from any (not regular) places of OriginalClip[i-1], most similar (by content) to OriginalClip[i] regular blocks.

Oh well, now I'm confused. Assuming we are setting isb = false (which means doing a forward search) shouldn't we use OriginalClip to compute the CompensatedClip[i]?

To my yet vague understanding of MVtools we are trying to compute an intermediate frame between the current and the next frame or between the current and the previous frame. The [I]isb parameter defines whether we are computing a following intermediate frame or a previous intermediate frame.

isb = true computes frame[i]' with frame[i - 1] < frame[i]' < frame[i]
isb = false computes frame[i]' with frame[i] < frame[i]' < frame[i + 1]

i = relative frame index
frame[i]' = computed, motion compensated frame of frame[i]

The computed frames will be inserted at the specific position in the clip, thus doubling the frame rate.
If a previous frame was computed the absolute index of the reference frame and all following frames are increased by 1.
If a following frame was computed the absolute index of the reference frame remains untouched, but the absolute frame index of the neighbour as well as all indices of the following frames will be increased by 1.

Well, this is my current mental model of how I think motion compensation affects a clip. But somehow I feel this might not necessarily be true. Please correct me if I'm wrong :)

Fizick
1st July 2007, 16:16
buletti,
you are wrong. It is implemented as I wrote.

MVTools (specifically MVAnalyse) does not try to compute intermediate frames.
It compute frame similar to current.

buletti
1st July 2007, 20:31
Thanks for making this clear Fizick.
So, if we are doing a backward search we take the following frame [i + 1] of the reference [i] and get the motion vectors that are affecting [i] from there.

But 1 more question:
What if I had 2 frames with a red ball on a black background. On the first frame the ball is on the far left side and on the second frame the ball is on the far right side. Then a motion compensation of the first frame using a backward search won't result in a frame drawing the ball in the center. Instead the ball will only move very little to the right, leaving the frame very similar to its reference.
Is this assumption right?

foxyshadis
1st July 2007, 21:21
If mvtools could ever find that much motion, mvcompensate would place the ball in the same position that it was in, in the original, with any deformation from the relocation. In this case the ball should be on the far left, if I'm reading your description right.

MVAnalyse takes an original frame and an offset, and slides blocks in the offset around to match the original as closely as possible. MVCompensate will output the results of the sliding (plus some more), and will look as much like the frame it replaces as possible. MVFlowFps will slide blocks from frames bounding the new frame to create it; this is the only time fractional vectors are involved.

Try a simple mvcompensate script, interleaved with the original, and see for yourself.

Fizick
1st July 2007, 21:36
No, your next assumption (about red ball) is wrong again. :)
More precisely, I do not understand your question (it is unclear).
MVTools consist of several functions for motion estimation and full or partial motion compensation. What you talk about?

Try to draw your red balls and try to use MVTools :)

EDIT: Seems, I repeat foxyshadis's post :)

Terranigma
1st July 2007, 21:47
Fizick, is it possible to use mvdegrain2 with mvanalyse/mvcompensate, if so, how would I go about doing this?

Fizick
1st July 2007, 22:00
Who knows...

Didée
1st July 2007, 22:13
darn ... did refresh before posting, but didn't notice the pagewrap that had happened in the meantime. :D


Instead the ball will only move very little to the right, leaving the frame very similar to its reference

Ideally, in the compensated frame the ball will be at *exactly the same* position as it's in the reference frame, leaving the frame *identical* to its reference.

This is also one of the major appliances: temporal denoising. If you have a statical scene, every frame looks exactly like the previous and the following frames, except for the noise (e.g. film grain). When using a strong temporal denoiser, like say temporalsoften(2,255,25), all noise will be averaged away.
But when there is motion, the temporal averaging can't work out, it would produce ghosting. A smart temporal filter tries to detect such motion areas, and will not process them. This avoids ghosting, but the downside is that the moving areas are not denoised. (Plus the danger that the smart filter is not smart enough, and either doesn't reckognize all motion areas [resulting in artefacts in denoised motion areas], or reckognizes too much motion [noise is interpreted as motion, resulting in static areas not being denoised].)
By using motion compensation, what happens is that the previous and following frames are made "identical" to the current frame. In a sense, a "static" scene is created out of a motion scene, so that the temporal denoiser can work safely at full strength.

That's the main idea behind motion compensation and its most common appliance ( leaving out the problems and foot-traps that come along with it;)).


Another story is motion interpolation, mostly used for framerate conversions.
Here, it is like you previously mentioned: an intermediate frame is created, where the blocks are compensated by only a fraction of the vector lenghts, thus created objects at intermediate positions between two frames.

But here, other big problems pop up: take your example with a red ball. Now imagine there are two red balls in the frame ...
In frame[i], we have two red balls at their respective positions. In frame[i+1], we have also two red balls at their respective positions. But how do you tell safely which red ball in frame[i+1] belongs to which red ball in frame[i]? Short answer: you can't. For a human spectator, it seems easy because we "see" the fluid motion in the running scene, so it's obvious to us which ball belongs to which. But for a dumb computer, this can be a very hard task (imagine the balls are close to each other, and their motion path is just crossing over!).

Motion compensation is not easy. Motion interpolation is difficult.

buletti
2nd July 2007, 20:09
OMG! Thank you very much for your detailed explanation Didee.
I wasn't aware of the difference between motion compensation and motion interpolation, so I used those terms as synonyms. I was actually thinking on motion interpolation when I used the term motion compensation in my previous posts. Sorry for the babel and confusion.. :)

PS: motion compensation is cool :)

Xitsa
3rd July 2007, 09:39
2 buletti
As I think now there are two cases

red ball is in motion estimation range and detected as next position. First compensated frame will be like first original
red ball not in range and considered independent. First compensated frame wiil be like second original


Compensation work in that way (if i wrong i hope i'll be corrected:) ):
Let you have original frames: Original[i] (red ball at left side), Original[i+1] (red ball at right side).
Backward compensated frame Compensated[i] created from Original[i+1] by moving red ball from right side to left and will be like Original[i].
This is first case.
In second ball will be absent or on right side because for MVTools both will be independent objects.

johnmeyer
3rd July 2007, 16:13
Didee - I echo the comments made above. Very useful explanation. I've been using MVTools for years, but didn't fully appreciate the difference between compensation and interpolation.

Fizick
3rd July 2007, 16:30
It seems, this German man can speak English much better than French and Russian MVTools authors :)


About "fluid motion in the running scene". By the way, in Motion plugin (by mg262) the one of motion predictors (candidate vector) is temporal predictor (from previous analysed frame).
I considered to add similar predictor to MVTools (as an option). May be I will add it.

yup
5th July 2007, 10:33
Hi folk!
Please advice how can write script. Idea very simple:
Estimation motion vectors
bv=MVAnalyse(isb=true, chroma=false)
fv=MVAnalyse(isb=false, chroma=false)
use MVDegrainX for luma and chroma plane separately, using different thSAD, for chroma greater than for luma. This will be very useful for analog capture and also for DV footage.
With kind regards yup.

Boulder
5th July 2007, 10:41
org=last
bv=MVAnalyse(isb=true, chroma=false, idx=1)
fv=MVAnalyse(isb=false, chroma=false, idx=1)
chroma=MVDegrain1(org,bv,fv,thsad=...,plane=3,idx=1)
MVDegrain1(org,bv,fv,thsad=...,plane=0, idx=1)
MergeChroma(chroma)

yup
5th July 2007, 10:53
:thanks:Boulder
yup.

Fizick
5th July 2007, 23:19
I tried to implement quarter-pixel accuracy in MVTools because of pel=2 results of mvtools is not accurate for non-integer pixel movements.
But I discovered that I never correctly understand method used for pel=2 in MVTools.
MVEstimate use hierarchical search: from coarse reduced frames to finest full-scale (or to doubled for pel=2).
Now I discover that MVTools (all versions) goes from last but one reduced-frame level to doubled frame level at last stage (i.e. skips normal full-frame scale search). It searches at 4 sub-planes at once.

Probably some changes must be applied: at least search radius must be increased at finest level.
global motion predictor is wrong.
May be some more bugs.

I recall Manao said that pel=2 is not the same as applying MVTools to clip with doubled image size.

Delerue
5th July 2007, 23:48
I'm very anxious to see the new version. :)

superuser
7th July 2007, 06:15
Fizicks as u r supporting multi-cpu capability in fft3d, do u have plans for implementing similar multi cpu feature in MVTools also , esp for MVDegrain2 and MVDegrain1 ? It will help on speeding up the processing.

thnxs and mvdegrain2 really gives wonderful results on some grainy source which is hard for other grain removers ... :thumbup: for wonder plugins and ur efforts.

Fizick
8th July 2007, 20:30
superuser,
sorry, currently I have no plan for multi-cpu support in MVTools.
1. I do not know ho to program it.
2. I do not have multi CPU.
3. I do not know what may be multi-threaded. May be MVAnalyse forward and backward vectors,
May be MVDegrain for different frames.
As first step must be removed hack with idx.
But id we do not use idx, it will result in slowdown.
Probably it may be resolved by external caclulations of hierarhical frames by separate function (MVPrepare ?)
4. I do not have much time.

Didée
8th July 2007, 22:00
Another thought (a rather simple one):
What about support of bigger blocksizes? blksize=32 could help if someone wants to use MVTools on HD content ... less slow (probably), and better noise resilience.

superuser
9th July 2007, 04:40
@fizicks: thnxs for the feedback .... it is totally understandable time wise and efforts needed to it ... appreciate effort and time invested by many guys arnd put for open community and users like us. I was curious to know if you had plans for multi cpu feature and if possible it can squeezed into ur scheduled task list. i got my answer :).

if u can push backward and forward vectors on seperate threads would be good, though not sure wht will synchronization issues here. But if it can be done than later can expand this logic to multi CPU one too :). Though me not aware much abt logic of algorithm used, so not sure hw realistic this is with respect to ur schedule.

odedia
9th July 2007, 22:25
Just took my first shot at MVTools, and it looks great. Almost as good as TremensionDNM, and I only used the most basic settings.

Which brings me to my question:

Is it possible for us to start some kind of a repository for MVTools recommended definitions? I see so much short blocks of code in this thead, it is hard to go over it all.

I am thinking about setting up recommended settings for various types of video sources. For example: HDTV content in MKV/x264, one for action shows and one for drama shows (I guess it shouldn't be the same). Same thing for standard XVid content, and for 1080P content etc. etc. etc.

I'd be happy to help organize the data if needed.

Thanks again!

odedia
9th July 2007, 22:28
@fizicks: thnxs for the feedback .... it is totally understandable time wise and efforts needed to it ... appreciate effort and time invested by many guys arnd put for open community and users like us. I was curious to know if you had plans for multi cpu feature and if possible it can squeezed into ur scheduled task list. i got my answer :).

if u can push backward and forward vectors on seperate threads would be good, though not sure wht will synchronization issues here. But if it can be done than later can expand this logic to multi CPU one too :). Though me not aware much abt logic of algorithm used, so not sure hw realistic this is with respect to ur schedule.

How about dividing the source video into seperate clips as the number of cores, and giving each core its own task to be performed on a given timeframe from within the video? Maybe is can be added with a short estimation of scene change so that there won't be ugly atifacts when they are stitched back together.

I think this is doable without any serious code modifications.

But then again, but the heck do I know :)

fight2win
12th July 2007, 05:59
DGDecode_mpeg2source("C:\discs\bb\MainMovie\BATMAN BEGINS DISC 1\VIDEO_TS\VTS_01_1.d2v",info=3)
ColorMatrix(hints=true)
crop( 0, 74, 0, -76)
LanczosResize(720,304)

how to use mvdegrain in this script?pls help

Boulder
12th July 2007, 06:02
Why don't you consult the MVTools documentation? It includes an exact sample of MVDegrain2 usage.

fight2win
12th July 2007, 06:09
Why don't you consult the MVTools documentation? It includes an exact sample of MVDegrain2 usage.

thks,

source.MVDegrain2(backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=400,idx=1)

but what to write in place of source?

if i use this, it's not applying resize and all:

DGDecode_mpeg2source("C:\discs\bb\MainMovie\BATMAN BEGINS DISC 1\VIDEO_TS\VTS_01_1.d2v",info=3)
ColorMatrix(hints=true)
crop( 0, 74, 0, -76)
LanczosResize(720,304)
source = mpeg2source("C:\discs\bb\MainMovie\BATMAN BEGINS DISC 1\VIDEO_TS\VTS_01_1.d2v")
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)
source.MVDegrain2(backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=400,idx=1)

Boulder
12th July 2007, 06:35
You don't need the "source" statement there. If you don't specify a source clip, Avisynth assumes "last".

Fizick
17th August 2007, 20:25
I released MVTools v1.8.3

MVDegrain1, MVGegrain2 - added "limit" parameter.
MVAnalyse: corrected (increased) search radius at finest level for pel>1.
Added pel=4 option for quarter pixel precision.
Renamed clip2x parameter to pelclip.
MVAnalyse: added postrocessing motion vectores by dividing blocks into subblocks to decrease zone of motion vectors interpolation.
MVFlowFps: added "mask" parameter to select processing method at occlusion areas (and speed).
Some internal changes (padding in MVAnalysisData, header to vector stream frames, etc).
MVFlowInter, MVFlowFPS, MVFlowFPS2, MVMask: improved occlusion mask by extent
MVFlowInter, MVFlowFPS: decreased objects halo at occlusion areas by using motion vectors of adjacent frames
MVFlowInter, MVFlowFPS: disabled SAD mask and thSAD parameter
MVShow: fixed drawn positon of vectors
Added error messages on missed vector clips

Terranigma
17th August 2007, 20:32
Thanks a lot, keep up the great work. :)
A lot of great new additions. :D

Fizick
17th August 2007, 20:39
Yes, the list is long, and I waiting for bug reports :)

Delerue
18th August 2007, 01:17
Great news, man! I was waiting for this. :)

I tried these scripts and got no image:


loadplugin("C:\arquivos de programas\avisynth\plugins\mvtools.dll")
source=ffdshow_source()
backward_vec = source.MVAnalyse(blksize=16, isb = true, chroma=false, pel=1, searchparam=1, idx=1)
forward_vec = source.MVAnalyse(blksize=16, isb = false, chroma=false, pel=1, searchparam=1, idx=1)
source.MVFlowFps(backward_vec, forward_vec, num=0, \
den=0, mask=0, idx=1)


loadplugin("C:\arquivos de programas\avisynth\plugins\mvtools.dll")
source=ffdshow_source()
# assume progressive PAL 25 fps or NTSC Film 23.976 source
backward_vec = source.MVAnalyse(blksize=16, isb = true, chroma=false, pel=1, searchparam=1, idx=1)
# we use explicit idx for more fast processing
forward_vec = source.MVAnalyse(blksize=16, isb = false, chroma=false, pel=1, searchparam=1, idx=1)
source.MVFlowFps(backward_vec, forward_vec, num=2*FramerateNumerator(source), \
den=FramerateDenominator(source), mask=0, idx=1)

I think the problem has something to do with the bold commands, because if I use this it works perfectly:


loadplugin("C:\arquivos de programas\avisynth\plugins\mvtools.dll")
source=ffdshow_source()
backward_vec = source.MVAnalyse(blksize=16, isb = true, chroma=false, pel=1, searchparam=1, idx=1)
forward_vec = source.MVAnalyse(blksize=16, isb = false, chroma=false, pel=1, searchparam=1, idx=1)
source.MVFlowFps(backward_vec, forward_vec, num=48, \
den=1, mask=0, idx=1)

BTW, MVFlowFPS seems to use more CPU now.

Thanks a lot.

Fizick
18th August 2007, 17:02
Delerue,
What is your source properties (num, den) with Info() ?

I updated v1.8.3 today. Please test.

Delerue
18th August 2007, 17:40
Delerue,
What is your source properties (num, den) with Info() ?

I updated v1.8.3 today. Please test.

I don't know exactly how to do it. I tried 'info(source)', and it informs this: 2997/125. Is it? :)

I tested with your last build (from today), but I got the same error. BTW, I tried too many videos, so I don't think that the problem has somethig to do with the source itself.

Ah! Testing better last night I saw that the new mask with value '2' is really amazing. Thanks a lot.

Fizick
18th August 2007, 18:13
Hmmm. What avisynth version do you use?
What is "no image"?
Anybody else can confirm the bug?

And yes, mask=2 should be amazing ;)

Delerue
18th August 2007, 20:24
I installed the AviSynth_070518.exe file and make a copy of your 'mvtools.dll' file to the avisynth\plugins folder.

'No image' is a completely black screen. If I'm watching a video with avisynth plugin disable I see the image, but in the moment I enable it the image frozens in the last frame before I enable avisynth. I'm using MPC last version from clsid (http://forum.doom9.org/showthread.php?t=128616) and FFDShow build 1425.

Fizick
18th August 2007, 20:47
what is your source (type,resolution, codec)?
may be it is ffdshow bug?
How do you watch? MPC? Try VirtualDub(Mod) instead - simply open avs file.

Delerue
19th August 2007, 07:02
what is your source (type,resolution, codec)?
may be it is ffdshow bug?
How do you watch? MPC? Try VirtualDub(Mod) instead - simply open avs file.

Please, can you paste a complete AVS script for me to test?

Fizick
19th August 2007, 07:38
loadplugin("mvtools.dll")
#avisource("g:\doom9.avi")
version()
shifted=addborders(4,0,0,0).crop(0,0,-4,-0)
interleave(last,shifted)
converttoyv12()
#assumefps(2997, 125)
source=last
backward_vec = source.MVAnalyse(blksize=16, isb = true, chroma=false, pel=1, searchparam=1, idx=1)
forward_vec = source.MVAnalyse(blksize=16, isb = false, chroma=false, pel=1, searchparam=1, idx=1)
source.MVFlowFps(backward_vec, forward_vec, num=0, den=0, idx=1)

Can you paste a complete AVS script for me to test ? :)

Did you input avs script to ffdshow avisynth window? or you simply open avs with MPC?

Delerue
19th August 2007, 17:36
I created an .avs file exactly like this:


loadplugin("C:\arquivos de programas\avisynth\plugins\mvtools.dll")
AVISource("D:\Downloads\Filmes\Bloodsport-trailler.avi")

version()
shifted=addborders(4,0,0,0).crop(0,0,-4,-0)
interleave(last,shifted)
converttoyv12()
#assumefps(2997, 125)
source=last
backward_vec = source.MVAnalyse(blksize=16, isb = true, chroma=false, pel=1,

searchparam=1, idx=1)
forward_vec = source.MVAnalyse(blksize=16, isb = false, chroma=false, pel=1,

searchparam=1, idx=1)
source.MVFlowFps(backward_vec, forward_vec, num=0, den=0, idx=1)


I saved and open with MPC, but I got an error: 'cannot render the file'. Instead, if I paste this in the Avisynth FFDShow filter I got that 'no image' problem I told you before:


loadplugin("C:\arquivos de programas\avisynth\plugins\mvtools.dll")
source=ffdshow_source()

version()
shifted=addborders(4,0,0,0).crop(0,0,-4,-0)
interleave(last,shifted)
converttoyv12()
#assumefps(2997, 125)
source=last
backward_vec = source.MVAnalyse(blksize=16, isb = true, chroma=false, pel=1, searchparam=1, idx=1)
forward_vec = source.MVAnalyse(blksize=16, isb = false, chroma=false, pel=1, searchparam=1, idx=1)
source.MVFlowFps(backward_vec, forward_vec, num=0, den=0, idx=1)


The only way to run is using Avisynth FFDShow filter with the third script I pasted here (http://forum.doom9.org/showpost.php?p=1034985&postcount=468). Any idea?

Fizick
20th August 2007, 04:42
I do not support FFDSHOW environment.
Firtly you must get working script for native environment.

Try remove or comment line:
AVISource("D:\Downloads\Filmes\Bloodsport-trailler.avi")

Are inter-line spaces (blank lines) exist in oroginal script?

superuser
20th August 2007, 05:05
^ just saw u released the latest version, gr8. quarter pixels should be fun. thnxs Fizick sir for ur efforts.

will try the latest version. just a question popped up: are there changes related to idx which you were thinking of making or we can keep using idx as before?

Terranigma
20th August 2007, 16:13
Fizick, now can we expect blk overlap support for MVDenoise? Seems you're done with what made you held off on updating this function the last time.

Fizick
20th August 2007, 16:36
no.
I created MVDegrain to replace MVDenoise.

Terranigma
20th August 2007, 16:56
no.
I created MVDegrain to replace MVDenoise.

Ok, I see that obviously I can't convince you; so do you plan on removing MVDenoise from MVTools then? I mean, it's not going to get any more support from what I can tell. I've been asking for further support only because i've sometimes found MVDegrain to be a bit too strong, even when using a low thsad value such as 100, while MVDenoise, otoh, seemed to handle the processing in a more gentle sorta way, not destroying detail... But the blocks it created gave me a headache.

Fizick
20th August 2007, 17:10
did you try new limit parameter ?

Terranigma
20th August 2007, 17:23
did you try new limit parameter ?

No, I thought that was only for artifacts prevention, but i'll give the new limit parameter a try and report back. :)

Terranigma
20th August 2007, 18:43
Does limit even work? When trying to preview the filtered input via, AvsP, with any other value than 255, the script crashes. :confused:
I tried using 150, 200, and 254, and it crashed everytime.

Boulder
20th August 2007, 18:58
Works here, checking with limit=2 against a non-limited one.

Terranigma
20th August 2007, 19:34
Works here, checking with limit=2 against a non-limited one.

Well I guess it's just broken for me. I'm using the last version Fizick worked on btw. I used the following


source=last
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)
source.MVDegrain2(backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=400,limit=2,idx=1)

And I get this everytime.
http://img50.imageshack.us/img50/4089/avsperrorrc3.png

Maybe it's conflicting with a plugin/script that i'm not aware of? Weird if so, because limit=255 works just fine, or maybe it's source dependent?

Fizick
20th August 2007, 20:42
try today updated version

Terranigma
20th August 2007, 20:47
Okay, it now works. Thanks a lot Fizick. :)

cwk
20th August 2007, 21:31
Hello Fizick,

Thank you for your efforts with this plugin.

Using 1.8.3, mvdegrain1 and mvdegrain2 produce a distorted image when I use overlapped blocks and divide=1 in the same script. Divide=1 works if overlap=0 in mvdegrain1 and 2. Divide=1 also works as expected with overlapped blocks in mvflowfps.

The distorted image appears to have 3 overlayed copies of the original, two of which are aligned diagonally. I can re-create this with both yv12 and yuy2 sources.

Here is my script:

source = AVISource("Deinterlaced.avi")

backward_vec2 = source.MVAnalyse(isb=true, delta=2, blksize=8, overlap=4, divide=1, idx=2)
backward_vec1 = source.MVAnalyse(isb=true, delta=1, blksize=8, overlap=4, divide=1, idx=2)
forward_vec1 = source.MVAnalyse(isb=false, delta=1, blksize=8, overlap=4, divide=1, idx=2)
forward_vec2 = source.MVAnalyse(isb=false, delta=2, blksize=8, overlap=4, divide=1, idx=2)
source.MVDegrain2(backward_vec2,backward_vec1,forward_vec1,forward_vec2,thSAD=400,idx=2)

Fizick
21st August 2007, 04:45
this mode is not implemented.
and I do not see much reason for it

Delerue
22nd August 2007, 00:57
I do not support FFDSHOW environment.
Firtly you must get working script for native environment.

Try remove or comment line:
AVISource("D:\Downloads\Filmes\Bloodsport-trailler.avi")

Are inter-line spaces (blank lines) exist in oroginal script?

I must find some docs to read. It's too much dificult without it. I can't understand a lot of things. Why do I have to comment the line that tells the path of the video? If I do that, MPC simply can't open anything.

BTW, I also can't run YADIF from an AVS file pasting this in the notepad and saving as 'test.avs':


Load_Stdcall_plugin("C:\arquivos de programas\avisynth\plugins\yadif.dll")
avisource("D:\Downloads\Filmes\Bloodsport - trailler.avi")
yadif(mode=1,order=1)


The only way to work is inside the FFDShow AviSynth tab using this:


Load_Stdcall_plugin("C:\arquivos de programas\avisynth\plugins\yadif.dll")
source=ffdshow_source()
yadif(mode=1,order=1)


However, the new MVFlowFPS doesn't work inside the FFDShow AviSynth tab.

I also tried to uninstall both AviSynth and FFDShow, clean the paths, reg and stuff like that. So a made a clean install, but doesn't help.

Fizick
22nd August 2007, 04:23
1)I asked you to comment simply for testing.
version() will be your source (temporarary).

2) as I wrote abnove, i do not support ffdshow here.
forget about ffdshow for a day and try work withou it (for test), with virtualdub or MPC.
(scripts above)
Probably yo do not have video codec for your AVI file.

3) then, try in ffdshow
[CODE]
loadplugin("C:\arquivos de programas\avisynth\plugins\mvtools.dll")
ffdshow_source()
source=last
backward_vec = source.MVAnalyse(blksize=16, isb = true, chroma=false, pel=1, searchparam=1, idx=1)
forward_vec = source.MVAnalyse(blksize=16, isb = false, chroma=false, pel=1, searchparam=1, idx=1)
source.MVFlowFps(backward_vec, forward_vec, num=0, \
den=0, mask=0, idx=1)
[/CODE}

scharfis_brain
22nd August 2007, 05:12
ffdshow's avisynth section canNOT change the framerate.

If you try this, ffdshow wil alter the framecount and the duration, but the framerate will be locked to the framerate of the source.

I think this is a bug.

Leak
22nd August 2007, 08:36
ffdshow's avisynth section canNOT change the framerate.

If you try this, ffdshow wil alter the framecount and the duration, but the framerate will be locked to the framerate of the source.
Ummm... I take it you haven't tried this (http://ffdshow-tryout.sourceforge.net/html/en/avisynth.htm) lately? (Or at least not since rev. 1194 (http://ffdshow-tryout.svn.sourceforge.net/viewvc/ffdshow-tryout?view=rev&revision=1194)...)

True, you can't just do an AssumeFPS() anymore since the output timestamps will be interpolated based on the input timestamps and thus you can't change the total length of the video in seconds, but if you alter the frame count of the clip the framerate (and the timestamps of the frames) will be adjusted accordingly.

Try a simple "Bob()" (or SelectEvery) if you don't believe me... :D (Okay, so I use it for TIVTC mostly, but it still works... :))

Fizick
22nd August 2007, 15:45
cwk,
probably I know now how :) implement divide with overlap (in MVCompensate, MVDegrain) and can do it in next version.
But may be I simply remove divide mode completely to simplify the life. Anybody can say something about it?

Terranigma
22nd August 2007, 15:49
I haven't tested divide, but I have done what you've asked and compared mvdegrain with the limit parameter to mvdenoise. mvdenoise = stronger denoising now and kills almost all the grain, so there's no need for you to improve it now. :sly:

cwk
22nd August 2007, 19:03
Hello Fizick,

My impression of the divide parameter is that it leads to more accurate interpolations within mvflowfps. I use mvtools with high motion sequences, sports mainly. It appears to give a better picture in situations where a detailed image moves a long distance from frame to frame.

Based on that experience, I was interested in trying divide with MVDegrain. Sports' video has many small details in constant motion on field of low detail (like black hockey pucks on white ice), so I have to keep thSAD at low settings. That may lead to less of an improvement within mvdegrain, due to MVDegrain's "averaging" of different interpolations.

cwk

Fizick
22nd August 2007, 20:55
cwk,
you may try it today ;)

cwk
23rd August 2007, 14:18
Thanks Fizick,

I will give it a whirl.

cwk

cwk
23rd August 2007, 22:06
Yup, that works!

The differences in using overlap with or without divide in mvdegrain are minor. They are much more noticeable--and can be good--when used together in mvflowfps.

Boulder
28th August 2007, 06:32
Using the limit parameter in a function crashes VDub and VDubMod on my system. I have the function in an autoloading avsi file. Using it without having the limit parameter in MVDegrain2, no crash occurs.

function Degrain( clip c, int "blk", int "ol", int "sh", int "sad", int "pl", int "div", int "lim" )
{
blk = default( blk, 16 )
ol = default( ol, 4 )
sh = default( sh, 2 )
sad = default( sad, 200 )
pl = default( pl, 4 )
div = default( div, 0 )
lim = default( lim, 0 )
vbw1=MVAnalyse(c,isb=true,truemotion=true,delta=1,pel=2,chroma=false,blksize=blk,idx=1,sharp=sh,overlap=ol,divide=div)
vfw1=MVAnalyse(c,isb=false,truemotion=true,delta=1,pel=2,chroma=false,blksize=blk,idx=1,sharp=sh,overlap=ol,divide=div)
vbw2=MVAnalyse(c,isb=true,truemotion=true,delta=2,pel=2,chroma=false,blksize=blk,idx=1,sharp=sh,overlap=ol,divide=div)
vfw2=MVAnalyse(c,isb=false,truemotion=true,delta=2,pel=2,chroma=false,blksize=blk,idx=1,sharp=sh,overlap=ol,divide=div)
return MVDegrain2(c,vbw1,vfw1,vbw2,vfw2,thSAD=sad,idx=1,plane=pl,limit=lim)
}

I use the latest MVTools version and Avisynth 2.5.8 alpha.

Fizick
28th August 2007, 16:17
Boulder,
it works fine for me.
Your exact version and script?

Boulder
28th August 2007, 16:36
Oh man..didn't see that you had released v1.8.4. It works, v1.8.3 doesn't. Did you do something else than just make divide work with overlapping?

Fizick
28th August 2007, 16:53
nothing more, but i rewrote many functions to implement it ;)

Boulder
1st September 2007, 14:56
Fizick,

would it be possible to do add a feature to limit luma and chroma separately?

Fizick
1st September 2007, 19:44
Yes, it is possible, but i am busy (lazy) now.

Boulder
1st September 2007, 19:48
OK, no problem. Fortunately I can use kassandro's LimitChange whenever such behaviour is needed :)

Boulder
3rd September 2007, 07:08
Is there a specific reason why MVAnalyse doesn't detect motion on the edges of the frame? That can be fixed by adding borders before MVAnalyse and then removing them after using the results, but it causes an unnecessary slowdown.

Also, when you separate the fields and use MVAnalyse, is the estimation done exactly the same way compared to when you have bobbed the stream and use MVAnalyse on the result (except that in the first case, every frame is half the height of the original frame)?

Fizick
3rd September 2007, 17:31
1. I do not know. may be due to hierarhical levels dividing.
It uses padding internally, but for compared frames only.

2. of cources not exactly the same.

Terranigma
30th October 2007, 20:44
Fizick, honestly I can't tell any differences between the mvmask in 1.7.0, and mvmask in the current (up-to-date) version. The only difference, I can tell, is based on speed. The new mvmask is superbly slow, not even usable imo compared to the older one in 1.7.0. Any chance you could revert, or include the old algorithm so that we could use it instead? Like
mvmask(old=true,kind=1)
?

Fizick
30th October 2007, 22:00
Terranigma,
what mask you talk about?

Seems, I changed kind=2 mask only in mv1.8.x

may be it is MVAnalyse speed?

Terranigma
30th October 2007, 22:27
may be it is MVAnalyse speed?
Just did a test using mvdegrain2 to see if was mvanalyse, and you're absolutely correct. :D
Here's the avg speed I received from mvdegrain2 (1.7.0), search=3, searchparam=2, and overlap=8/2.
http://img102.imageshack.us/img102/5756/oldmvtoolsgi8.png

Here's the avg speed I received from mvdegrain2 (1.8.4.2), search=3, searchparam=2, and overlap=8/2.
http://img102.imageshack.us/img102/8586/newmvtoolszx1.png

Why is it so much slower, and what'd be the equivalent, per se, in regards to speed/quality from 1.7.0 to 1.8.4.2?

Fizick
31st October 2007, 05:34
probably it is from this change:
v1.8.2 beta (30.07.2007 by Fizick)
MVAnalyse: corrected (increased) search radius at finest level for pel>1.

Terranigma
31st October 2007, 15:14
MVAnalyse: corrected (increased) search radius at finest level for pel>1.
Oh yes, that's definately it. You think you could add in the old algorithm for pel, from <1.7.0, and allow us to use it like
MVAnalyse(isb=true,pel=2,pelA=old........)
where pelA represents the pel algorithm used? By default, you can leave it as the new. :)

Fizick
31st October 2007, 15:44
No, I will not revert old algo so direct way.
But some mod may be done.

Discussion:

The "old algo" used same search radius (in pixel units) for finest (pel>1) plane as for rest planes.
Planes width and effective pixel size is scaled by factor 2 for all planes but finest.
At this last step the scale change is 4 (for pel=2).
So, we must refine search with radius at least 2 at this finest plane.
But for minimal searchparam=2 the radius in fact is 1.
This way we never check some points even for enhastive search method.

Now (since 1.8.2) I increased (double for pel=2) search radius at finest plane.

Possible workaround: Do not increase search radius, if it is not lesser than theoretical minimum.
So, it will be increased for searchparam=2 (default),
but not for searchparam=3.

superuser
5th November 2007, 21:30
about frames=3.
It is quite possible that you will see MVdegrain3 soon...
;)


Thts good news. fizicks can u please provide insight into what we would be expecting with this. One thing, I can guess here is now MVDegrain3 will taking into account 3 forward and 3 backward vectors. Besides this, what other cookies u r to this filter, esp some interesting bump in the processing speeds. also r u planning it to be thread safe to be used with MT plugin :).

Will be looking forward to it.

Fizick
6th November 2007, 00:15
superuser, it is delayed.
Now I consider Terranigma's request.

mroz
6th November 2007, 18:13
Not sure if this is the right place to post this query, but...

Has anyone ever written a successful script to analyse motion in a video in order to try to determine the orientation? I'm thinking about random camcorder clips.

How about for starters just distinguishing between horizontal & vertical? Could average orientation of motion vectors give a clue? Is it possible to get this info out of MVTools? I'm just after methods of guessing based on a whole clip atm.

Fizick
6th November 2007, 21:41
Global motion? MVDepan?

mroz
7th November 2007, 00:05
Yes, something along those lines might work, but one would need to get the statistics out of the script.

I've just had a play with MVDepan(last, forward_vec1, info=true), but to see if there's any significant correlation between patterns in the output stats & the video orientation, I really need to be able to write dx, dy, rot & zoom to a log file for each frame.

Currently I can't see a way to do this other than to write a plugin which extracts the info from your signalling in the top left corner of the vid. Any chance you could add runtime functions which return each of the stats, much like the internal runtime functions such as AverageLuma? Something along the lines of MVDepanDx(source, data=globalmotion), which returns the dx stat for current_frame in source (& so on for the other stats)?

BTW Thanks for pointing me at MVDepan - ashamed to say I'd not read all the MVTools docs.

Fizick
7th November 2007, 18:35
mroz,
probably it may be done, but i do not know how and it is not in my "to do" list.

Th most intrigue for me is returning array :)

mv=MVAnalayse(source)
array=MVGlobal(mv) # like MVDepan
dx=array[0] # in conditional env

mroz
7th November 2007, 20:03
Ok, fair enough. I don't think there's anything special about runtime functions - I tried calling one outside of a conditional environment & as long as you manually define current_frame to some value it will work.

So it should be 'just' a matter of defining the function as you would normally do, but return an integer or array, as you prefer, instead of a clip.

Of course as I've never written a plugin & have only dipped a toe into poking around in MEncoder's handling of AVISynth script input, the 'just' is not so small for me :)

Ah well, never mind.

Oh, I did notice in the MVTools MVDepan source there's some logging code. Any idea how I turn that on? Is it a compile time option?

Fizick
7th November 2007, 23:12
MVTools 1.8.5 (05.11.2007 by Fizick)
Added pelsearch parameter as search parameter (radius) at finest level (request by Terranigma). Default=pel
Decreased internal buffer to decrease memory usage, with some changes in critical sections.
Added block size 16x2 (requested by ab_99).

I do not merge latest 1.8.4.3 code by TSP.
I independenly developed similar solution (probably worse, but I must firstly read and undestand TSP circular buffer concept).


mroz, MVDepan is very old code.
My codes are ugly, but my English is even more, so please read a code. :)
Brobably the simplest solution is to add some func to MVDepan code to output array

superuser
7th November 2007, 23:40
superuser, it is delayed.
Now I consider Terranigma's request.

sure, thanks for the update. I was going through that another where you had posted about MVDegrain3 and was excited about it. But I agree the point raised by Taerranigma's is higher priority. I will wait no probs :).

Terranigma
8th November 2007, 00:16
MVTools 1.8.5 (05.11.2007 by Fizick)
Added pelsearch parameter as search parameter (radius) at finest level (request by Terranigma). Default=pel
Thanks so much for this. I'm now getting the speed I was once accustomed to with 1.7.0. :D

mroz
9th November 2007, 00:39
mroz, MVDepan is very old code.
My codes are ugly, but my English is even more, so please read a code. :)
Brobably the simplest solution is to add some func to MVDepan code to output array
No worries :)

If I pluck up the courage I'll have a play with the code. Can you recommend build tools? What do you use to compile MVTools?

Fizick
10th November 2007, 17:53
mroz,
Any Microsoft compler since VCToolkit 2003, plus Platorm SDK.

Probably my MVGlobal suggestion instead of MVDepan is bad.
It is not possible to return array.
And every MVGlobalDx, MVGlobalDy... will ineffective recalculate global motion.
So, your suggestion of separate function (plugin) MVPepanDx(MVDepan()) is better.

But it also may be implemented as (global) variables (MVDepanDx, ... ) in MVDepan like "current_frame".
I can implement it. But should its names to be fixed or user defined (for every MVDepan instance) ?

Terka
10th November 2007, 20:11
how to mask (by black) areas which move
1. less then treshold in both directions (sqr(x^2+y^2));
2. in vertical direction only?

mroz
10th November 2007, 23:58
mroz,
Any Microsoft compler since VCToolkit 2003, plus Platorm SDK.

Probably my MVGlobal suggestion instead of MVDepan is bad.
It is not possible to return array.
And every MVGlobalDx, MVGlobalDy... will ineffective recalculate global motion.
So, your suggestion of separate function (plugin) MVPepanDx(MVDepan()) is better.

If it is, then only by chance. I thought your idea to return an array was better, so I must have very little idea of what's going on - which doesn't surprise me ;(

But it also may be implemented as (global) variables (MVDepanDx, ... ) in MVDepan like "current_frame".
I can implement it. But should its names to be fixed or user defined (for every MVDepan instance) ?
Eek, not sure. Anyone else?

Would appending string(idx) to Dx etc be enough? Though I suspect I've again revealed how little I understand.

Edit: no sorry, that's obviously not helpful. I guess the names would need to be user defined. Sorry, had a few drinks.

BTW Thanks for considering this :)

superuser
11th November 2007, 21:31
If MVFlowFPS/MVFlowFPS2 is used to bring down the framerate to half, in this case does MVFlowFPS/MVFlowFPS2 will select the same frames as SelectEven or SelectOdd would had? If not who different will it behave be. I tried differentiating between both of the approaches, but it was not clear to me, so posted this question here.

When using MVFlowFPS2 on would following be a good approach to follow:


numerator = dcSrcFramerateNumerator()/2
denominator = dcSrc.FramerateDenominator()/2
#
backward_vec = dcSrc.MVAnalyse(isb = true, truemotion=true, pel=2, idx=1, delta=1, search=3)
forward_vec = dcSrc.MVAnalyse(isb = false, truemotion=true, pel=2, idx=1, delta=1, search=3)
backward_vec2 = dcSrc.MVAnalyse(isb = true, truemotion=true, pel=2, idx=2, delta=2, search=3)
forward_vec2 = dcSrc.MVAnalyse(isb = false, truemotion=true, pel=2, idx=2, delta=2, search=3)
dcSrc = dcSrc.MVFlowFps2(backward_vec,forward_vec,backward_vec2,forward_vec2,num=numerator, den=denominator, idx=1, idx2=2)


or MVFlowFPS2 has been crafted to take vectors on cropped frames which depends on the block size used in MVAnalyze?

talen9
12th November 2007, 01:23
I *think* that, using that script, you're not changing FPS at all :p

The FPS value is given by (numerator)/(denominator), right? So, dividing both of them by 2, the resulting "new" FPS will be ... the same as the original one ;)

I think that you'll need to change it a bit ... like, you'll have to divide by 2 the numerator and keep unchanged the denominator:

numerator = dcSrcFramerateNumerator()/2
denominator = dcSrc.FramerateDenominator()
...

mroz
12th November 2007, 01:28
Double the denominator rather than halve the numerator, else you'll have a problem when the numerator is odd.

foxyshadis
12th November 2007, 11:45
The way you use it is just an extremely slow no-op. Flow will use the input frame if it matches up perfectly with the output. What you probably want is to use mvflowblur(...).selecteven() instead, so that you lengthen the shutter to compensate for lowering the framerate. (Films generally have longer shutters than DV, it's an important part of the 'film look' everyone treasures.)

If not, you're going to have to explain what you're looking for.

superuser
12th November 2007, 15:54
I *think* that, using that script, you're not changing FPS at all :p

The FPS value is given by (numerator)/(denominator), right? So, dividing both of them by 2, the resulting "new" FPS will be ... the same as the original one ;)

I think that you'll need to change it a bit ... like, you'll have to divide by 2 the numerator and keep unchanged the denominator:

numerator = dcSrcFramerateNumerator()/2
denominator = dcSrc.FramerateDenominator()
...

Double the denominator rather than halve the numerator, else you'll have a problem when the numerator is odd.

thnxs for pointing that out. In my scripts I m using it first doubling the framerate (using Bobber), and than bring it back to the original framerate. I have detailed why below why I am doing so. Though again this methodology may not be the appropriate way to do it :scared:


The way you use it is just an extremely slow no-op. Flow will use the input frame if it matches up perfectly with the output. What you probably want is to use mvflowblur(...).selecteven() instead, so that you lengthen the shutter to compensate for lowering the framerate. (Films generally have longer shutters than DV, it's an important part of the 'film look' everyone treasures.)

If not, you're going to have to explain what you're looking for.

Thnxs, I will try this out.

Details of what I trying to do: Currently I am processing a movie about 3 hours run time. The problem with these movies are released as NTSC, but they were converted from PAL. So as to over-come poorly interlaced frames effects, what I had in mind is first double the framerate, in my case was using yadiff for the same (2*29.97), than bring the framerate to original using mvflowfps (29.97). With this frames looked much better and smoother than before. I am using DVD-RB and CCE as the encoder. Had tried for manual encoding CCE so as to encode as Film, but I did not get it right so reverted back to DVD-RB. The idea of playing with framerate being is do not disturb the output framerate, keep it same as the input one and deinterlace them, if the above is the appropriate one to follow. I had used DVD-RB's features for deinterlacer, but the results were not that soothing, so am exploring other options which can work with DVD-RB.

Again I am in learning process so feel free to slam the ideas or approach which does not seem appropriate.

thxs once again for ur input and I will try out what Foxyshadis suggested.

Didée
12th November 2007, 16:17
The problem with these movies are released as NTSC, but they were converted from PAL.
Usually such conversions are done either by normal pulldown, or by a converter box that produces field-blending.
For the former you should use IVTC, for the latter you should use MRestore (or Restore24, or RePal).
Motion compensated Yabba-dabba-doo most times is of zero use in this context.

superuser
12th November 2007, 16:32
Thnxs Didee for the input.

Usually such conversions are done either by normal pulldown, or by a converter box that produces field-blending.


Would normal Pull-down work with DVD-RB? Also if possible can you please where can I find information


For the former you should use IVTC, for the latter you should use MRestore (or Restore24, or RePal).
Motion compensated Yabba-dabba-doo most times is of zero use in this context.

Above is what I had started with and I was getting shaky or not much clear frames, so I switched to above approach. But I was bringing the framerate back to the original which of the limitation of the process I am following :confused:. When I get back to my place, I will post the what calls I was using (I was making calls to tritical's TDient plugins for the same).

IanB
12th November 2007, 22:56
You first need to identify your input.xxxSource("file")
Assume?ff() # choose TTF or BFF
Bob()Step thru the Bobbed fields looking for the pattern of how moving parts are rendered. If the original was 24 fps film then you should be able to decern how it has become intertwined with video field structure. If the motion steps 2 forwards then 1 backward then use the other TFF/BFF.

E.g. If it is simple 3-2 pulldown from the dumb bob you will see Frame1, dup1, dup1, Frame2, dup2, Frame3, dup3, dup3, Frame4, Dup4, Frame5, ...

Or if field blending has occured Frame1, dup1, blend12, Frame2, Frame3, blend34, Frame4, ....

Once you have your pattern then you can start reseaching how to recover the original frames. :search: Didée has offered 2 prime candidates.

Terranigma
13th November 2007, 02:22
Fizick, is there any way to use dct=1 on all frames except those at scene changes? That's only where oscillation occurs.

---
OK, I noticed that there's only errors when using dct 1, 2, & 4 during backward searches; I wonder why that is :scared:

Fizick
13th November 2007, 17:37
Terranigma,
Please provide (much) more info.
:)

Fizick
18th November 2007, 13:51
mroz, Ii can implement motion info as AviSynth global variables (via SetGlobalVar in internal code):

...
MVDePan(..,vdx="dx")
ScriptClip(last,"Subtitle(String(dx))",after_frame=true)

or as local variables:

...
dx=0.0 # must be initialized in this case
MVDePan(..,vdx="dx")
ScriptClip(last,"Subtitle(String(dx))",after_frame=true)

What is better for MT environment?
probably first, but some trick may be needed anyway if you want different names for difrerent threads.

IanB
18th November 2007, 22:34
Please don't implement global variable crap except as a last resort.

ScriptClip, Animate, and friends, etc all work by recompiling parts of the script every frame! This is not how Avisynth is supposed to be abused.

Write clip oriented fundamental functions that can be used to efficiently realize the goal. In this case probably Conditional Filter modules (i.e. like AverageLuma) are a better answer than Vars.

In mroz's case he needs an up-down de(average vertical movement)izer and a left-right de(average horizontal movement)izer. (Watch out for pans! i.e. movement is always left, left, left, ....)

Doing this the ScriptClip way will no doubt involve abusing the resizer, of all the core filters, these are the ones that should least be used in this way.

mroz
19th November 2007, 03:33
@IanB: what I was after (& it was only a casual query prompted by a desire to discover if camera orientation can be guessed from movement patterns), was a means to write to a logfile the stats MVDepan calculates, on a per frame basis, much as one can use existing runtime functions like AverageLuma(clip) to read stats on a per frame basis.

As such, surely either ScriptClip or FrameEvaluate is needed?

@Fizick: I don't know which is best for MT, though as you say, unless you use locals you'll either need to distinguish between threads or accept some data will be lost. What's the disadvantage of locals?

Fizick
19th November 2007, 05:55
IanB,
Well, I will not use SetGlobalVar to set global var. But may I use SetVar ? or it is same case?

alternative (clip-oriented function) is like this?:
vec=MVAnalyze(clip)
gmc=MVDepan(clip,data=vec)

# in conditional env only (Scriptclip, etc) :
dx=MvDx(gmc)
dy=MvDy(gmc)

mroz,
can you please provide simple disirable scripts with new hypotetic functions or variables?

mroz
19th November 2007, 13:06
Something simple like:SetMTMode(2,0)
leaf="somefile"
global clip=AVISource("APath"+leaf+".avi")
global file="APath"+leaf+".log"
BlankClip(clip, width=16, height=16)
global vec=MVAnalyse(clip)
global gmc=MVDepan(clip, data=vec)
WriteFileStart(file, """ "vim:tabstop=6"+chr(10) """, """ Time("%#c")+chr(10) """, """ "Frame"+chr(9)+"AStat" """, append=true)
WriteFileEnd(file, """ "Test complete."+chr(10) """)
ScriptClip( """
dx = MvDx(gmc)
# nb1 keeping writefile inside here allows us to store stats as locals, reducing problems with running in MTMode 2
WriteFile(file, "current_frame", "chr(9)", "dx")
return last
""" )
Distributor()

NB Excuse if stupid mistake above: Been decorating & only had four hrs sleep.

tsp
19th November 2007, 16:41
if used with my version of avisynth the local vars are thread specific if they are set inside GetFrame() using SetVar(). So if MvDx sets the local var inside the GetFrame call there should be no need to put it inside ScriptClip. I also suggest that MvDx gets an extra parameter that controls the name of the local var.

Fizick
19th November 2007, 18:16
tsp,
I considered MVDepan(...., vdx="dx", vdy="dy")
with SetVar in GetFrame

BTW, since v1.8 DepanStabilize it is already implemented this way (but not documented - so unofficial ;) _

Fizick
19th November 2007, 18:19
mroz, it is too simple task :)
Logfile option do it (almost).
I guessed you need in some conditional processing.

tsp
19th November 2007, 18:32
tsp,
I considered MVDepan(...., vdx="dx", vdy="dy")
with SetVar in GetFrame

BTW, since v1.8 DepanStabilize it is already implemented this way (but not documented - so unofficial ;) _
That should be safe. You can initialize "dx" inside the constructor to avoid doing it inside the script.

Fizick
2nd December 2007, 19:15
how to mask (by black) areas which move
1. less then treshold in both directions (sqr(x^2+y^2));
2. in vertical direction only?

Try MVTools v1.8.6 with kind=3,4 of MVMask for motion vector component mask

Terranigma
2nd December 2007, 19:26
Try MVTools v1.8.6 with kind=3,4 of MVMask for motion vector component mask

Thanks Fizick for the update with the new masks :D

mroz
2nd December 2007, 20:18
mroz, it is too simple task :)
Logfile option do it (almost).
I guessed you need in some conditional processing.

First apologies - this is the second time in the last month or two that I've missed an update to a thread I'm subscribed too. Not sure how it happened :(

Yes, this case would be simple. Subsequent use might not be, but I can't predict that as I don't know what conclusions I might be able to reach from initial experiments. Regarding the logfile, yes - I think I even mentioned that once myself - but iirc I didn't even know how to turn it on (maybe a compile time option?).

Fizick
2nd December 2007, 20:38
mroz, simply type log=some filename and you will see the magic :)

After IanB words i have no plan to add 'vdx' parameters.

IanB
2nd December 2007, 21:06
Ahh Damn!, I left out a sentence from my post above.

It should have said :-

Write clip oriented fundamental functions that can be used to efficiently realize the goal. In this case probably Conditional Filter modules (i.e. like AverageLuma) are a better answer than Vars.

mroz
3rd December 2007, 01:16
mroz, simply type log=some filename and you will see the magic :)

LOL, figures I'd miss something simple. Thanks

After IanB words i have no plan to add 'vdx' parameters.

Perhaps after his response above you'll consider Conditional Filter modules?

Are there developer docs on this stuff anywhere? I'm interested for myself just out of curiousity, to get a better idea of how stuff works under the bonnet.

Just from casual experimenting I wasn't even sure if they differed from regular plugin functions (since they can be called outside of a conditional environment if current_frame is first defined to some value).

Fizick
3rd December 2007, 18:04
mroz,
http://forum.doom9.org/showthread.php?t=132026

mroz
3rd December 2007, 19:13
mroz,
http://forum.doom9.org/showthread.php?t=132026

Thanks. Love the "He who can, does. He who cannot, teaches." quote in the context you use it :)

Terranigma
7th December 2007, 19:06
04.12.2007 - Developed MVTools v1.9.0 beta (MVDeGrain3)

I would love to try this out. :D

ficofico
7th December 2007, 21:18
me too:D

foxyshadis
11th December 2007, 18:28
It's easy to test it out, just send a few dollars fizick's way. :p

Terranigma
12th December 2007, 00:11
Fizick, could you elaborate a bit on how to use the outfile parameter to store the vectors for later use? I mean, after it's stored, then what? Won't it continue to build upon, in size since the string file writes on a per-frame basis? I would think it'd be more efficient to have a string parameter for input as well; one that doesn't overwrite the vectors, imploding it.. Or is there a way to do that already? :confused:
Also, should idx be disabled when storing vectors this way?

Fizick
12th December 2007, 06:21
the usage of stored vectors is not implemented (in MVTools).
And I do not work on it (not see good reason and way).

Terranigma
12th December 2007, 15:56
the usage of stored vectors is not implemented (in MVTools).
And I do not work on it (not see good resaon amd way).
Well, I was thinking that it'd eliminate the need for doing a motion search, since the vectors would be stored externally, and would make processing much faster, if you were to say, encode to a highly compressible format such as avc using pel level 4, or something similar which takes a long time for ME..

About not knowing how: wouldn't it be possible to have it read the external vectors (in mvanalyse) using the string "input" and then ignore/disable all other parameters? tritical does something similar with tshints in tdeint.

Maybe this' just wishful thinking and can't be done. :D

Fizick
12th December 2007, 18:41
If somebody will implement vector reading, please consider to add new function like MVRead instead of Mvanalyse mod.
BTW, Manao prepared some framework for it in his (old) versions.

Hittz
12th December 2007, 20:01
Hi community, I would like to know how I would create slow motion segments in a script. Ex. if I had 50,000 frames total in a clip and wanted frames 0-19,999 to move at normal speed 29.976fps, then frames 20,000 to 30,000 to be in slow motion, and starting with 30,001 continue with the movie at the normal speed of 29.976fps?

johnmeyer
12th December 2007, 21:58
I've had some success with the script below, although I'm sure others can suggest modifications that would make it better (such as using MVFlowFps2).

As for how to have only part of the clip slowed, I use AVISynth in conjunction with Vegas, and feed the clips from Vegas that I want slowed. Vegas lets you do gradual speed changes, but you have to use it's own slow-mo for that, which just does adjacent frame blending rather than motion estimation. I don't know if it is possible to do gradual shifts in playback speed from within an AVISynth script.

Anyway, here's a prototype script for you to build upon:
loadplugin("C:\Program Files\AviSynth 2.5\plugins\MVTools\mvtools.dll")

a=AVISource("K:\Coach Slo-Mo (input to slo-mo).avi")

# the following is for HDV, change to bff for DV
b=assumetff(a)
g=converttoyv12(b)
h=g.separatefields

#I have played around with Bob instead of separatefields, but am not using it here
#h=Bob(g)

vec_back = h.MVAnalyse(isb=true,truemotion=true, pel=2, idx=1)
vec_forw = h.MVAnalyse(isb=false,truemotion=true, pel=2, idx=1)

#"num" equals result of 30 fps times 2 times slo-mo factor
#e.g., 300 is 1/5 normal speed, not 1/10 (because of separatefields)

MVFlowFps(h,vec_back, vec_forw, num=300, den=1)

#Use one of the following when using bob, instead of just the plain weave
#assumetff().separatefields().selectevery(4,1,2).weave()
#assumebff().separatefields().selectevery(4,0,3).weave()

weave()
assumefps(29.97,true)

Hittz
12th December 2007, 22:02
Thanks Johnmeyer I'll give it a try.

IanB
13th December 2007, 02:04
@Hittz,

...
A=Trim(0, 19999)
C=Trim(30001, 0)
Trim(20000, 30000)

<code from johnmeyer>

AssumeFPS(A, True)
ResampelAudio(AudioRate(A) # Maybe use TimeStretch instead
A ++ Last ++ C

@johnmeyer,

There is no direct way to slew the playback rate but you could easily manufacture the effect with some Trims and SelectEvery...
A=Trim(0, 999)
Trim(1000, 0)
<slow mo code> # 4x desired rate == x8
C=Trim(60, 0).SelectEvery(4, 0).AssumeFPS(A)
Trim(0, 59)
SelectEvery(50, 0, 8, 16, 23, 30, 36, 42, 47, 52, 56)
AssumeFPS(A)
A + B + C

Didée
13th December 2007, 02:26
There is no direct way to slew the playback rate but you could easily manufacture the effect with some Trims and SelectEvery
What about feeding Animate() appropriately with "MVFlowFPS(..,num=[start.frate]|[end.frate]).AssumeFPS([fixed.frate])" ?

(Beware: Possible hardware meltdown alert!) :)

Hittz
15th December 2007, 02:31
I'm having some difficulty understanding this part:

AssumeFPS(A, True)
ResampelAudio(AudioRate(A) # Maybe use TimeStretch instead
A ++ Last ++ C

Would you please explain. Thanks IanB

IanB
15th December 2007, 08:40
AssumeFPS(A, True) # Assuming 2 time slow mo, what used to 10000 frames in now 20000 frames, i.e. it takes twice as long to play. To join it back with the rest of the clip it needs to be compatible. Here we make the FPS the same as clip A and as a side effect we change the audio samplerate to keep the audio length matching i.e. twice as long. Depending on the actual output FPS of the johnmeyer code you may need to use AssumeScaledFPS(2, 1, False) or similar as well.

ResampelAudio(AudioRate(A) # Two choices here, either just force the audio samplerate to match so it can be joined the pitch will be halved as well or ...

# Maybe use TimeStretch instead to keep the pitch the same but force the audio to be twice as long i.e. slo mo as well.

A ++ Last ++ C # Paste all the bits back together.

The above is only a prototype and may need some adjusting in principle to match the code from johnmeyer. Bottom line is the output video must still 25 fps with 48000Hz audio, you must coerce the slow mo section to conform.

Hittz
15th December 2007, 18:08
I thank you much IanB and all others for your time and patience but I am having a most troublesome time understanding exactly what to include in the slow mo script (ex. your scipt and/or johnmeyers). If time permits, would you create a script for me from the below sample properties, for study and understanding?

Total frames: 3653
Video: 23.976FPS
Audio: AC3 48000Hz CBR

If I wanted to have frames 0-1000 move at normal speed
Then move in Slow Motion from frames 1001-2000
Then move again at normal speed from frames 2001-3653 (end)

The sample clip above represents an xvid avi.

IanB
15th December 2007, 23:24
@Hittz,

Perhaps some simple tutorial scripts will help. Getting involved with MVTools is not for the faint hearted.

These 2 scripts are self contained with a frame counted colour bars sources and audio with right channel pulsing once per second.

Both use AssumeScaledFPS and ChangeFPS to do a quick and dirty slow motion effect i.e. they just repeat the same frame 4 times. This is what you replace with MVTools code to do a full motion interpolated slow motion effect.

In the first script the Audio sample rate is changed to match the change in video rate and ResampleAudio is used to force it to match the desired output audio sample rate.ColorBars().ShowFrameNumber(True) # Cheapo source

A=Trim(0, 100) # Part 1
C=Trim(201, 0) # Part 3
Trim(101, 200) # Part 2, the slow mo target range

AssumeScaledFPS(1, 4, True) # Set FPS and AudioRate to 25%
ChangeFPS(A, True) # Cheapo Slow mo convert Video

ResampleAudio(AudioRate(A)) # Make AudioRate correct.

A ++ Last ++ C # Assemble parts 1, 2 & 3In this second script TimeStretch is used to independantly adjust the tempo of the Audio while maintaining the original audio sample rate.ColorBars().ShowFrameNumber(True) # Cheapo source

A=Trim(0, 100) # Part 1
C=Trim(201, 0) # Part 3
Trim(101, 200) # Part 2, the slow mo target range

AssumeScaledFPS(1, 4, False) # Set FPS to 25%
ChangeFPS(A, True) # Cheapo Slow mo convert Video

TimeStretch(Tempo=25.0) # Make Audio tempeo 25% to match

A ++ Last ++ C # Assemble parts 1, 2 & 3Experiment with both scripts. Put an Info() statement in various places throughout the script to see the effect that each statement has on FPS, AudioRate, FrameCount and AudioLength.

Experiment with ConvertFPS() in place of ChangeFPS(), this will give blended frames for the Slow motion effect to further help you understand what is to come next.

Finally replace the ColorBars with your Xvid source and adjust the trim points. These 2 scripts should have the effect you are looking for apart from the jumpy repeated frame slo-mo effect instead of a nice fluid effect that MVTools can give.

Once you understand the principles involved and can make a choice of how to process the matching audio we can deal with getting the nice fluid MVTools slow motion working.

Hittz
16th December 2007, 00:08
Getting involved with MVTools is not for the faint hearted.
That's for sure:o I have been trying to understand this for a couple of months, off and on. I will give your script a try, and I appreciate your time and patience.

IanB
16th December 2007, 01:20
Now we can try for a final scriptSloMoDen = 2
SloMoNum = 5 # Slow down 5/2 = 2.5 times

AviSource("Xvid.avi")

A=Trim(0, 1000) # Part 1
C=Trim(2001, 0) # Part 3
Trim(1001, 2000) # Part 2, the slow mo target range

Fv = MVAnalyse(isb=false,truemotion=true, pel=2, idx=1)
Bv = MVAnalyse(isb=true, truemotion=true, pel=2, idx=1)

MVFlowFps(Last, Bv, Fv, num=SloMoNum*FramerateNumerator(),
\ den=SloMoDen*FrameRateDenominator(), idx=1)

## AssumeFPS(A, True) # Make FPS
## ResampleAudio(AudioRate(A)) # and AudioRate correct.

AssumeFPS(A, False) # Make FPS
TimeStretch(Tempo=100.0*SloMoDen/SloMoNum) # and AudioLength correct.

A ++ Last ++ C # Assemble parts 1, 2 & 3One point to note is that MVFlowFPS does not do a good job at scene changes, it just tries to flow (mutate) the last frame of the scene to the first of the next. With slo-mo involving faces this can look truely horrible. If you read this thread there are lots of schemes to detect scene changes and do special processing.

Given your apparent need, I would suggest just manually Triming each scene and MVFlowFPS each separately and finally paste them all back together at the end.

Hittz
16th December 2007, 06:24
I tried the first one:

ColorBars().ShowFrameNumber(True) # Cheapo source

A=Trim(0, 100) # Part 1
C=Trim(201, 0) # Part 3
Trim(101, 200) # Part 2, the slow mo target range

AssumeScaledFPS(1, 4, True) # Set FPS and AudioRate to 25%
ChangeFPS(A, True) # Cheapo Slow mo convert Video

ResampleAudio(AudioRate(A)) # Make AudioRate correct.

A ++ Last ++ C # Assemble parts 1, 2 & 3

It worked a treat. I do see rainbow type artifacts in my clip in certain areas. Certain parts of the script(s) for slow mo doesn't look too simple, but I will study them to familiarize myself with them. I will give the finale' a try tomorrow, I'll post back with results. Thanks much for the help.

Fizick
16th December 2007, 10:02
@Hittz,
Getting involved with MVTools is not for the faint hearted.

....

One point to note is that MVFlowFPS does not do a good job at scene changes, it just tries to flow (mutate) the last frame of the scene to the first of the next.


Hmm, there is scene detection code and ThScD1 parameter in MVTools for your health
:cool:

It usually works for real (substantial) scene changes. Nothing is perfect, of course.

IanB
16th December 2007, 12:22
@Fizick,

Yes, ThScD1/ThScD2 controls a switch between Blend mode and Motion mode. But the scene change transition is always flawed with MVFlowFPS.

Either you get a fade transition from the last frame of the previous scene to the 1st frame of the next scene. Or you get a motion morph from the last frame of the previous scene into the 1st frame of the next scene.

For a genuine scene changes it really needs to do a hard switch at the 50% point. i.e. for a 3x speed change the sequence should be ..., -2.33, -2.0, -1.66, -1.33, -1.0, -1.0, 0.0, 0.0, 0.33, 0.66, 1.0, 1.33, ...

For bonus points the end of scene could borrow the vectors from the 2nd last frame and continue the motion up to the hard transition, and the start of scene could borrow the vectors from the 2nd frame to reverse continue the motion back to the hard transition.

Fizick
16th December 2007, 19:31
MVFlowfps is not like ChangeFps.
IMO blenging (i.e. short crossfade transition) is much better than frame duplicating... -1.0, -1.0,..
That is why it was introduced in version 1.6.4.
I experimented on video with flashes (photo).

Anyway, Trim() is not forbidden command :)

IanB
16th December 2007, 22:11
MVFlowfps is not like ChangeFps.True, it is more akin to ConvertFPS() which of course has no scene change detection and would do a really lousy job as a slow-mo filter.
IMO blenging (i.e. short crossfade transition) is much better than frame duplicating... -1.0, -1.0,..
That is why it was introduced in version 1.6.4.
I experimented on video with flashes (photo).Yes, when the MV fails mid scene blending is a satisfactory approximation.

But i did say "For a genuine scene change ...", yes MVFlowFPS is not a perfect slow-mo filter. Hell MV is really really hard, what we have here is really quite good.

I guess the true issue is that vector tearing is not the same as a scene change. Yes a scene change causes vector tearing but so do lots of other things.

It is a logic bomb of this form. Firetrucks are always red. Your car is red. Therefore your car is a Firetruck.

Anyway, Trim() is not forbidden command :)And this is what I recomended to Hittz, and now we are discussing the Why.

Hint: A really cheap solution would be to have an override file that specifies "genuine scene changes" and specifies "vector tearing problem type 1" and specifies "vector tearing problem type 2" and .... :D

Terranigma
24th December 2007, 21:30
I was thinking that today we'd see the release of mvtools 1.9.1 as a Christmas present, but you guys celebrate Christmas on the 7th of January, so looks like we've probably got some more waiting to do. :P

jeffy
6th January 2008, 19:35
Merry Christmas, Alexander!

Boulder
9th January 2008, 06:52
Hi Fizick,

a small bug regarding the source clip in MVTools functions, see this thread: http://forum.doom9.org/showthread.php?p=1084799#post1084799. Somehow it seems that they don't assume "last" as the source.

On my system, if I don't specify "last" in MVDegrain2, I usually get an unrecognized exception error when loading the script.

Fizick
9th January 2008, 23:16
jeffy, thanks!

Boulder, it is known. the reason is more than one input clip (last and vectors). I do not know how to handle it.

Terranigma
11th January 2008, 00:39
Fizick, When can we expect an eta for mvtools 1.9... release ?

IanB
11th January 2008, 03:51
... it is known. the reason is more than one input clip (last and vectors). I do not know how to handle it.You are running into a design short coming in the parser's handling of implicit Last.

Your MV filters typically declare an argument definition like "c[mvbw]c[mvfw]c...". This declares the filter requires at least 1 clip and optionally support upto 3, which is not really the case, the filter actually needs 3 clips.

The [...]'s make an argument optional and give it a name. Unfortunatly there is no syntax for named mandatory arguments.

To get correct implicit last processing you will have to give up the clip argument naming and use the form "ccc..."

Fizick
11th January 2008, 16:39
Terranigma, probably not before I merge this contribution
http://forum.doom9.org/showthread.php?p=1084103#post1084103
and consider IanB's "ccc..." suggestion

Terranigma
11th January 2008, 16:49
Oh ok, thanks for the answer. I think I found something with tritical's latest colormatrix; on one source I have, the whole video is green. I guess I should let tritical know about this, and ask for him to let me upload the video to somewhere, like a private server, so that he may check it.

Vesi
14th January 2008, 11:23
I want to learn how to great mask using MvMask. I tried alot, but it is some how complicated for me,

script:
DGDecode_mpeg2source("C:\Documents and Settings\vesi\Desktop\Test\test.d2v")
LoadPlugin("C:\Program Files\AviSynth 2.5\plugins\mvtools.dll")
tfm(order=1).tdecimate(hybrid=3)
crop( 4, 60, -10, -56)


Spline36Resize(624,272) # Spline36 (Neutral)
FFT3DFILTER(sigma=2.1,bw=32,bh=32,ow=16,oh=16,bt=3, sharpen=0.8)

O. Now I don't know should i use MvMask before resizing and denoising or after?

Didée
14th January 2008, 13:24
@ Vesi: what result or what operation are you trying to achieve? MVMask on its own doesn't do anything useful to the source. It just produces a mask, which then can be used to do different things.

Zep
14th January 2008, 17:51
@ Vesi: what result or what operation are you trying to achieve? MVMask on its own doesn't do anything useful to the source. It just produces a mask, which then can be used to do different things.

how about a mask that varies based on detail found in source clip. So the more detail found in say an 8 x 8 block the more the mask will will not allow change in that 8 x 8 block. Then Vesi can use his

FFT3DFILTER(sigma=2.1,bw=32,bh=32,ow=16,oh=16,bt=3, sharpen=0.8)

and it will have most affect on non detailed areas like Walls and clear blue sky but leave detailed areas like grass alone.


or maybe an edge finder that masks out all non edges then you could sharpen just the edges to get some edge pop.
While you are at it how about an example of color masker so you can change all blue sky in some scene to sunset orange :D

Vesi
14th January 2008, 20:55
Didee; as i'm totaly noob to scripting, i have seen some rips to have some kind of mask, and i found in MvTools MvMask, and i thought i can do this with my normal script... with good sources or bad to use denoisers like fft3d, removegrain and degrainmedian and shrpner seesaw or lsf and creat a mask. i am sure i am wrong 90% but i have read the mvtools documentation, and that was honistly for me some advance work that i couldn't make it alone, and i asked here that how to do this for different type of source and why to creat mask on the rip?

if this post is out of topic, should i open a thread?

krieger2005
15th January 2008, 10:13
Old Story: What are details? Noise? Noisy clouds are full of details ;). Didée wrote a longer text not only one time about this problem...

Zep
16th January 2008, 09:39
Old Story: What are details? Noise? Noisy clouds are full of details ;). Dideé wrote a longer text not only one time about this problem...

This problem was for the most part solved a long time ago and many great papers have been written on this topic. Noise is mostly random where as detail is not. Even a non random pixel chess pattern mixed in that might be seen as detail spatially will not temporally. Detail will track across frames without much basic change so your cloud example is not as hard to deal with as you think. :D

krieger2005
16th January 2008, 09:57
Think what you want to think. For me the problem is not solved and will not be solved until semantic recognation of images are implemented. Till then all great papers just describe a suboptimal solution where some work better (MV Tools) but most not. This is also the reason why you must do finetuning for every Filter available and the word 'best' is forbidden here.

Didée
16th January 2008, 10:05
It's easy to get excited when reading some papers. But usually there's a rude awakening following up. It's called "practice".

From your various hooray's and icandobetter's over the last days, we've heard only your speech, but didn't see any practice. :)

Zep
17th January 2008, 13:00
Think what you want to think. For me the problem is not solved and will not be solved until semantic recognation of images are implemented. Till then all great papers just describe a suboptimal solution where some work better (MV Tools) but most not. This is also the reason why you must do finetuning for every Filter available and the word 'best' is forbidden here.

I never said it was solved 100% the way you seem to imply I was saying lol Anyway, lets face it Hollywood is years ahead of everyone else and odds are has tricks that may never reach avisynth.

Zep
17th January 2008, 13:29
It's easy to get excited when reading some papers. But usually there's a rude awakening following up. It's called "practice".

From your various hooray's and icandobetter's over the last days, we've heard only your speech, but didn't see any practice. :)

Oh please it was me that started the 300 grain thread and *asked for help* which you conveniently forgot lol here I will now be as sarcastic as you are being and say your scripts were a great starting point but I have moved on :)


note: as for "practice" my latest 300 encode is the best yet and it will get better and better because I have a lot to learn still.

Didée
17th January 2008, 13:59
Oh please it was me that started the 300 grain thread and *asked for help* which you conveniently forgot lol here I will now be as sarcastic as you are being and say your scripts were a great starting point but I have moved on :) If you call that sarcasm, you didn't experience yet when I'm really starting out.;)

But you're missing the point. There was a query for suggestions. I made a suggestion. I showed screenshots, offered a test encode, and, most importantly, showed the script that does the processing, and gave explanations about the how and why.

Now, you say you can get better results by more simple means. Sounds exciting, but there are no screenshots or samples to give an idea of how "better" does look like. Not to speak of a script that other people could try out, too.

So far you showed exactly nothing.

If I'd tell you I could turn lead into gold, you would not believe my bragging. You would ask for proof. There's no sarcasm in that.

Sagekilla
17th January 2008, 19:56
Is there any news of a possible MVtools 1.8.7 featuring MVDegrain3? :)

Fizick
18th January 2008, 16:14
no, it is 1.9.X series :)

Sagekilla
18th January 2008, 19:26
no, it is 1.9.X series :)

Well, in that case any news of a 1.9.X series coming out any time soon? Gonna have to find a way to make a donation, since this wait is killing me!

Terranigma
18th January 2008, 20:59
since this wait is killing me!

It's killing everyone. I'm more interested in the faster mvanalyse more so than anything though. :)

cestfait
18th January 2008, 23:44
Me too.... mmm.... mvanalyse....

Then again, every day more that we wait probably means better code, so I guess I shouldn't complain. :)

Oh, wait, does this guy have a life, too?! Hmmm.... that could get in the way....

Terranigma
19th January 2008, 00:08
every day more that we wait probably means better code, so I guess I shouldn't complain. :)

Yes, that's exactly what the hold up is. I asked for an eta in a previous post, and he told me it'd be released after he's done with tweaking/implementing. :)


Oh, wait, does this guy have a life, too?! Hmmm.... that could get in the way....

:D

Sagekilla
19th January 2008, 00:09
It's killing everyone. I'm more interested in the faster mvanalyse more so than anything though. :)

Faster MVAnalyse sounds very nice actually.. It could help out quite a bit on my 0.5 - 1ish fps (up to 2ish with MT) MVDegrain based function. Any news on any other improvements in 1.9.x?


Oh, wait, does this guy have a life, too?! Hmmm.... that could get in the way....

I say we hire a double to live his life, so he can get to coding MVtools! :)

Fizick
24th January 2008, 16:36
I hope to release v1.9.2 next week.

ankurs
24th January 2008, 16:45
^^^

woohoo :D

josey_wells
25th January 2008, 01:13
Fizick,

I finally got a chance to run MVTools through a performance profiler and work on it some. Attached is updated source code which is about 30% more efficient than the original 1.8.6 version. I am almost at 4.00 fps vs 3.00 fps to start.

Take a look at let me know if I screwed up anything. :)

cestfait
25th January 2008, 07:28
oh, yeah.... :)

Fizick
25th January 2008, 17:40
josey_wells,
thanks, i will look to it.
I study all your changes from your previous contribution.
It was not very easy - all files in archive has updated date.
Its a pity that you do not mark your changes.
I had intention to merge two files only : SADfunctions.h and variance.h in v1.9.2.
They give great speedup, up to about 70% if SSEMMX is disabled (with C code). With SSEMMX the difference is not so big. v1.8.6 uses C function for chroma 4x4 block and lesser
(but I added assember SSE in v1.9.1 for them).
All other changes give no any speed differences (1% more or lesser) for my system. :(

I wiill look to your new update.
Probably only files with date 24.01.2008 are updated?

I see, many updated files has variables initiated by 0 like:
unsigned char *pDstYUY2=0;
int nDstPitchYUY2=0;
is it for speed or safety?

Can I ask the stupid question to learn C++. What is the differences between:
for ( int k = 0; k < nBlkSizeY; k++ )
and
for ( int k = 0; k < nBlkSizeY; ++k )
Number of cycles are same or not?

Delerue
25th January 2008, 19:41
Can I ask the stupid question to learn C++. What is the differences between:
for ( int k = 0; k < nBlkSizeY; k++ )
and
for ( int k = 0; k < nBlkSizeY; ++k )
Number of cycles are same or not?

++k --> increase 'k' first, then execute;
k++ --> execute first, then increase 'k';

With '++k' the first value of 'k' will be 1. With 'k++' the first value will be 0. I read somewhere that '++k' is faster. I don't know why. :(

BTW, I'm very anxious for the new version. Keep going! ;)

Fizick
25th January 2008, 20:06
josey_wells, you use real profiler :)
I look to updated code, and I see KthElement faster replacement!
But for v1.9.1 I used profiler too ;), and implemented other fast algo of global motion estimation code.
I am not sure, what algo is better (new or old). Old code can predict even (doubled) vectors length only. Some testing is needed, probably I will release v1.9.2 with new (v.1.9.1) code for comparing. If somebody find it worser, we can return old algo with your updated faster code in v1.9.3.

pdanpdan
25th January 2008, 21:15
k++ makes a copy of k to use inside loop, so it is more expensive both in memory and speed

josey_wells
25th January 2008, 21:41
Fizick,


What is the differences between:
for ( int k = 0; k < nBlkSizeY; k++ )
and
for ( int k = 0; k < nBlkSizeY; ++k )
Number of cycles are same or not?

Short answer it depends on the compiler whether these give these same efficiency or not.

++K is equivalent to
{
k+=1;
}


k++ is equivalent to
{
int t=k;
k+=1;
return t;
}

so k++ creates and returns a temporary. Some compilers optimize it out some don't. It is better to use ++k if the old value is not needed.

While we are on the subject:

Array[i] is equivalent to *(Array+i) so there is always an implicet integer add. So this loop

for(int i=0; i<10; ++i)
Arracy1[i]=Array2[i];


can be speeded up by
int *pArray1=Array1, *pArray2=Array2;
for(int i=0; i<10; ++i, ++pArray1, ++pArray2)
*pArray1=*pArray2;

unsigned char *pDstYUY2=0;
int nDstPitchYUY2=0;

These changes were to get rid of a compiler warning for unitialized variable. I actually didn't see anything wrong with the code but the compiler didn't recognize that the variables had values assigned to them in a previous if statement.

You are correct that I had a real profiler. I replaced the KthElement routine with one that takes almost 0 time compared to the old one. Several other places was just changed i++ to ++i and lastly I made a couple changes where the same value was used multiple times. I also changed a lot of the search routines(DiamondSearch, ExhaustiveSearch, etc.) and I changed some of the sad I think. These are the files I made changes to since the last source code list.

==== //AviSynth/MVTools/GroupOfPlanes.cpp#2 (ktext) - //AviSynth/MVTools/GroupOfPlanes.cpp#1 (ktext) ==== content
==== //AviSynth/MVTools/MVCompensate.cpp#2 (ktext) - //AviSynth/MVTools/MVCompensate.cpp#1 (ktext) ==== content
==== //AviSynth/MVTools/MVDenoise2.cpp#2 (ktext) - //AviSynth/MVTools/MVDenoise2.cpp#1 (ktext) ==== content
==== //AviSynth/MVTools/MVFlow.cpp#2 (ktext) - //AviSynth/MVTools/MVFlow.cpp#1 (ktext) ==== content
==== //AviSynth/MVTools/MVFlowFps.cpp#2 (ktext) - //AviSynth/MVTools/MVFlowFps.cpp#1 (ktext) ==== content
==== //AviSynth/MVTools/MVFlowFps2.cpp#2 (ktext) - //AviSynth/MVTools/MVFlowFps2.cpp#1 (ktext) ==== content
==== //AviSynth/MVTools/MVFlowInter.cpp#2 (ktext) - //AviSynth/MVTools/MVFlowInter.cpp#1 (ktext) ==== content
==== //AviSynth/MVTools/MVMask.cpp#2 (ktext) - //AviSynth/MVTools/MVMask.cpp#1 (ktext) ==== content
==== //AviSynth/MVTools/MVShow.cpp#2 (ktext) - //AviSynth/MVTools/MVShow.cpp#1 (ktext) ==== content
==== //AviSynth/MVTools/Padding.cpp#2 (ktext) - //AviSynth/MVTools/Padding.cpp#1 (ktext) ==== content
==== //AviSynth/MVTools/PlaneOfBlocks.cpp#4 (ktext) - //AviSynth/MVTools/PlaneOfBlocks.cpp#1 (ktext) ==== content
==== //AviSynth/MVTools/PlaneOfBlocks.h#2 (ktext) - //AviSynth/MVTools/PlaneOfBlocks.h#1 (ktext) ==== content
==== //AviSynth/MVTools/SADFunctions.h#3 (ktext) - //AviSynth/MVTools/SADFunctions.h#1 (ktext) ==== content

I use Perforce and could give exact differences for a file if you want it.

I would very much like to see your current source code if you would like to share it. This filter is one of the most important ones for cleaning up even good DVD's so I am willing to help make it better.

Thanks

Fizick
26th January 2008, 00:22
my simple question was: Number of cycles are same or not?
And the very first k is 0 or 1 in body?

josey_wells
26th January 2008, 00:25
Both have the same number of loop cycles with k=0 as first value.

++k version is more efficient.

squid_80
26th January 2008, 00:56
Um, you didn't profile a debug build did you? The optimizations you describe should definitely be done by the compiler.

josey_wells
26th January 2008, 01:23
I did profile in debug but that was only to find the functions that the code was spending the most time in.

Not all compilers are equally as efficient in removing unneeded temporaries. I have run the same code(different project) through several compilers and received different results for speed.

squid_80
26th January 2008, 06:56
You can compile as release and still generate symbols/program database. Profiling a debug build is pretty pointless because the compiler will generate A LOT of unnecessary code.

Fizick
26th January 2008, 11:51
1. Yes, I profile release buid (with added /Zi key for compiler and /debug key for linker).
Usualy my "hand" optimization give miserable result by speed for used compiler (MS VC2003) unless I implement MMX, SSE or more effective algo.

2. source code of v1.9.1 is on my www

3. may be related:
http://www.nr.com/licenses/redistribute.html

Manao
26th January 2008, 12:05
++k faster than k++ is a myth if k has a basic type (int, float, etc...)

It may become true with object whose ++ operator has been overloaded. ++k modify the object in place, while k++ does make a copy. Usually the compiler will optimize it out but it's not necessarily possible in all cases.

Delerue
26th January 2008, 23:36
++k faster than k++ is a myth if k has a basic type (int, float, etc...)

It may become true with object whose ++ operator has been overloaded. ++k modify the object in place, while k++ does make a copy. Usually the compiler will optimize it out but it's not necessarily possible in all cases.

You're right: http://hvanbrug.com/b2/blogs/programming_st.php/2007/05/28/i_vs_i_should_we_pre_or_post_increment

:)

josey_wells
27th January 2008, 13:20
Fizick,

Thanks for the updated plugin.

I think the following two routines may have a typo:

1. void Degrain3_16x8_C

- looks like it is missing

pRefB3 += B3Pitch;
pRefF3 += F3Pitch;

2. void PlaneOfBlocks::NStepSearch(int stp)

CheckMV(dx + length, dx + length);
CheckMV(dx + length, dx);
CheckMV(dx + length, dx - length);
CheckMV(dx, dx - length);
CheckMV(dx, dx + length);
CheckMV(dx - length, dx + length);
CheckMV(dx - length, dx);
CheckMV(dx - length, dx - length);

I think the dx after the comma should be dy.

The NR3 doesn't apply since you removed the KthElement routine. Also, I don't think it applied anyway since I typed the routine in by hand and modified it from the original.

I am no longer going to debate performance, but with my tweaked version I get the following performance for comparison.

720*370 YUY2 4.00 fps with MVDegrain2 and 2.6 fps MVDegrain3 feeding my H.264 converter(unnamed). This is on an unoverclocked Q6600.

Boulder
27th January 2008, 13:50
I am no longer going to debate performance, but with my tweaked version I get the following performance for comparison.

720*370 YUY2 4.00 fps with MVDegrain2 and 2.6 fps MVDegrain3 feeding my H.264 converter(unnamed). This is on an unoverclocked Q6600.Could you post your binary for comparing the performance?

josey_wells
27th January 2008, 14:23
Here it is.

Boulder
27th January 2008, 14:38
Thanks, I'll do some tests as soon as my current project finishes. I've got an E6750 so I should see similar results to yours.

Fizick
27th January 2008, 14:52
josey_wells,
thanks for bug report!

can you provide the performance of v1.9.1 under same codition for comparison?

i found the "debates" very useful :)

josey_wells
27th January 2008, 15:39
Fizick,

I can if Boulder doesn't do it first. The computer is tied up now converting a movie and won't be done for some time.

Here is a snapshot of a performance report run on a release build for comparison if you have similar.

Name Inclusive Samples Exclusive Samples Inclusive Samples % Exclusive Samples %
MVDegrain3::GetFrame(int,class IScriptEnvironment *) 37,156 293 87.30 0.69
GenericVideoFilter::GetFrame(int,class IScriptEnvironment *) 35,456 1 83.31 0.00
MVAnalyse::GetFrame(int,class IScriptEnvironment *) 35,453 0 83.30 0.00
GroupOfPlanes::SearchMVs(class PMVGroupOfFrames,class PMVGroupOfFrames,enum SearchType,int,int,int,int,int,int,bool,int,int *,short *,int,class DCTClass *) 33,525 0 78.77 0.00
PlaneOfBlocks::SearchMVs(class MVFrame *,class MVFrame *,enum SearchType,int,int,int,int,int,int,int *,struct VECTOR *,short *,int,class DCTClass *,int *,int) 33,260 206 78.15 0.48
PlaneOfBlocks::PseudoEPZSearch(void) 33,054 308 77.66 0.72
PlaneOfBlocks::DiamondSearch(int) 27,879 309 65.51 0.73
PlaneOfBlocks::CheckMV2(int,int,int *,int) 27,570 1,853 64.78 4.35
PlaneOfBlocks::LumaSAD(unsigned char const *) 22,926 1,707 53.87 4.01
DCTINT::DCTBytes2D(unsigned char const *,int,unsigned char *,int) 20,724 7,684 48.69 18.05
_fdct_mmx 13,040 13,040 30.64 30.64
_Sad4x8_iSSE 4,465 4,465 10.49 10.49
PlaneOfBlocks::CheckMV(int,int) 2,295 204 5.39 0.48
_Sad8x8_iSSE 1,271 1,271 2.99 2.99
MVPlane::GetAbsolutePointer(int,int)const 1,231 1,231 2.89 2.89
PlaneOfBlocks::GetRefBlockV(int,int) 866 473 2.03 1.11
PlaneOfBlocks::GetRefBlockU(int,int) 784 412 1.84 0.97
Degrain3_8_C(unsigned char *,int,unsigned char const *,int,unsigned char const *,int,unsigned char const *,int,unsigned char const *,int,unsigned char const *,int,unsigned char const *,int,unsigned char const *,int,int,int,int,int,int,int,int) 536 536 1.26 1.26
Degrain3_4x8_C(unsigned char *,int,unsigned char const *,int,unsigned char const *,int,unsigned char const *,int,unsigned char const *,int,unsigned char const *,int,unsigned char const *,int,unsigned char const *,int,int,int,int,int,int,int,int) 503 503 1.18 1.18
MVGroupOfFrames::Refine(enum MVPlaneSet,int) 339 0 0.80 0.00
MVPlane::Refine(int) 339 0 0.80 0.00
YUY2ToPlanes(unsigned char const *,int,int,int,unsigned char const *,int,unsigned char const *,unsigned char const *,int,bool) 304 207 0.71 0.49
Average2(unsigned char *,unsigned char const *,unsigned char const *,int,int,int) 248 248 0.58 0.58
PlaneOfBlocks::InterpolatePrediction(class PlaneOfBlocks const &) 219 219 0.51 0.51
PlaneOfBlocks::FetchPredictors(void) 159 144 0.37 0.34

Boulder
27th January 2008, 21:35
Here are the results of the comparison:

Fizick's build: 1st pass 13.2fps (1894.55 s), 2nd pass 13.1fps (1915.07 s)

josey_wells's build: 1st pass 13.3fps (1882.82 s), 2nd pass 13.1fps (1902.07 s)

Only a small difference on my system. I used HC022 with SMP disabled to encode, 2-pass with the "BEST" profile.

EDIT: The script was a simple "load the source" + Crop + MVDegrain2 stuff.

josey_wells
28th January 2008, 14:13
Boulder,

Thanks for the results. Not much savings, oh well.

Fizick,

I have been studying the MVDegrainX functions and notice that they spend 95% of their time calling avisynth GetFrame and only 5% of their time actually processing data.

Also this function accounts for 50% of the processing script. If I comment out MVDegrain2 or 3 then I double the FPS just using MVAnalyze.

It seems that if one could cache the data from MVAnalyze which should have already called all the GetFrame from avisynth or cut down on the GetFrame calls then the processing script could be doubled. Just a thought? Maybe you can look at it and I will look some more.

Boulder
28th January 2008, 14:48
Just for the record, this is the MVTools-related part of the script:

function DegrainC( clip c, int "blk", int "ol", int "sh", int "sad", int "pl", int "div", int "limy", int "limuv" )
{
global idx_1 = idx_1 + 1
global idx_2 = idx_2 + 1
blk = default( blk, 16 )
ol = default( ol, 8 )
sh = default( sh, 2 )
sad = default( sad, 200 )
pl = default( pl, 4 )
div = default( div, 0 )
limuv = default( limuv, 255 )
vbw1=MVAnalyse(c,isb=true,truemotion=true,delta=1,pel=2,chroma=true,blksize=blk,idx=idx_1,sharp=sh,overlap=ol,divide=div)
vfw1=MVAnalyse(c,isb=false,truemotion=true,delta=1,pel=2,chroma=true,blksize=blk,idx=idx_1,sharp=sh,overlap=ol,divide=div)
vbw2=MVAnalyse(c,isb=true,truemotion=true,delta=2,pel=2,chroma=true,blksize=blk,idx=idx_1,sharp=sh,overlap=ol,divide=div)
vfw2=MVAnalyse(c,isb=false,truemotion=true,delta=2,pel=2,chroma=true,blksize=blk,idx=idx_1,sharp=sh,overlap=ol,divide=div)
nolimit = MVDegrain2(c,vbw1,vfw1,vbw2,vfw2,thSAD=sad,idx=idx_1,plane=pl)
defined(limy) ? LimitChange(MVDegrain2(c,vbw1,vfw1,vbw2,vfw2,thSAD=sad,idx=idx_1,plane=pl),c,limy,limuv) : nolimit
}

Doesn't the idx thingie deal with the caching?

josey_wells
28th January 2008, 15:00
Boulder,

Different caching.

If you comment out the MVDegrain2 line and leave all the MVAnalyze's what FPS do you get? This will show how much time is being eaten up by this line.

Boulder
28th January 2008, 15:04
Then it should do (almost?) nothing as the result of the MVAnalyze parts are not being used anywhere. IIRC Avisynth is smart enough to skip parts that it doesn't need.

josey_wells
29th January 2008, 14:46
Boulder and Fizick,

I was incorrect in my statement about where MVDegrain3 is spending all it's time. I am currently reordering/optimizing several sections and have achieved a 25% increase in scripts using MVDegrain3.

I will post updated binary for comparison when I finish optimizing the code.

Fizick,

One other bug report

MVFilter(mvfw3, "MVDegrain2", env) instead of MVDegrain3 in MVDegrain3.cpp

Boulder
29th January 2008, 14:48
Thanks, I'm happy to test it tonight :) I haven't tried MVDegrain3 yet so it'll be an interesting test regarding that as well.

Fizick
29th January 2008, 17:46
josey_wells,
thanks for report.
I decided to release bugfixed version 1.9.2 right now (without including your optimization).
Go ahead!

All: I am interested in speed results comparing with version 1.8.6 for various block sizes (especially small) for your CPU.

Boulder
29th January 2008, 20:27
Here are the results of my current test run:

v1.8.6 0:17:27 (14.3 fps) MVDegrain2
v1.9.2 0:17:11 (14.5 fps) Fizick, MVDegrain2
v1.9.x 0:17:03 (14.7 fps) josey_wells_v1, MVDegrain2
v1.9.x 0:24:38 (10.1 fps) Fizick, MVDegrain3
v1.9.x 0:24:29 (10.2 fps) josey_wells_v1, MVDegrain3

I'll run more tests with blocksize 8 (with and without overlapping) shortly. I'll also run the test for josey_wells's new binary as soon as he publishes it :)

global idx_1 = 100
global idx_2 = 200
LoadPlugin("c:\mvtools_186.dll") # or Fizick's v1.9.2 or josey_wells's build
MPEG2Source("pirates.d2v")
Crop(0,78,-0,-76,true)
DegrainC(sad=200,ol=8) # or Degrain3C
AddBorders(0,78,0,76)

function DegrainC( clip c, int "blk", int "ol", int "sh", int "sad", int "pl", int "div", int "limy", int "limuv" )
{
global idx_1 = idx_1 + 1
global idx_2 = idx_2 + 1
blk = default( blk, 16 )
ol = default( ol, 0 )
sh = default( sh, 2 )
sad = default( sad, 200 )
pl = default( pl, 4 )
div = default( div, 0 )
limuv = default( limuv, 255 )
vbw1=MVAnalyse(c,isb=true,truemotion=true,delta=1,pel=2,chroma=true,blksize=blk,idx=idx_1,sharp=sh,overlap=ol,divide=div)
vfw1=MVAnalyse(c,isb=false,truemotion=true,delta=1,pel=2,chroma=true,blksize=blk,idx=idx_1,sharp=sh,overlap=ol,divide=div)
vbw2=MVAnalyse(c,isb=true,truemotion=true,delta=2,pel=2,chroma=true,blksize=blk,idx=idx_1,sharp=sh,overlap=ol,divide=div)
vfw2=MVAnalyse(c,isb=false,truemotion=true,delta=2,pel=2,chroma=true,blksize=blk,idx=idx_1,sharp=sh,overlap=ol,divide=div)
nolimit = MVDegrain2(c,vbw1,vfw1,vbw2,vfw2,thSAD=sad,idx=idx_1,plane=pl)
defined(limy) ? LimitChange(MVDegrain2(c,vbw1,vfw1,vbw2,vfw2,thSAD=sad,idx=idx_1,plane=pl),c,limy,limuv) : nolimit
}

function Degrain3C( clip c, int "blk", int "ol", int "sh", int "sad", int "pl", int "div", int "limy", int "limuv" )
{
global idx_1 = idx_1 + 1
global idx_2 = idx_2 + 1
blk = default( blk, 16 )
ol = default( ol, 0 )
sh = default( sh, 2 )
sad = default( sad, 200 )
pl = default( pl, 4 )
div = default( div, 0 )
limuv = default( limuv, 255 )
vbw1=MVAnalyse(c,isb=true,truemotion=true,delta=1,pel=2,chroma=true,blksize=blk,idx=idx_1,sharp=sh,overlap=ol,divide=div)
vfw1=MVAnalyse(c,isb=false,truemotion=true,delta=1,pel=2,chroma=true,blksize=blk,idx=idx_1,sharp=sh,overlap=ol,divide=div)
vbw2=MVAnalyse(c,isb=true,truemotion=true,delta=2,pel=2,chroma=true,blksize=blk,idx=idx_1,sharp=sh,overlap=ol,divide=div)
vfw2=MVAnalyse(c,isb=false,truemotion=true,delta=2,pel=2,chroma=true,blksize=blk,idx=idx_1,sharp=sh,overlap=ol,divide=div)
vbw3=MVAnalyse(c,isb=true,truemotion=true,delta=3,pel=2,chroma=true,blksize=blk,idx=idx_1,sharp=sh,overlap=ol,divide=div)
vfw3=MVAnalyse(c,isb=false,truemotion=true,delta=3,pel=2,chroma=true,blksize=blk,idx=idx_1,sharp=sh,overlap=ol,divide=div)
nolimit = MVDegrain3(c,vbw1,vfw1,vbw2,vfw2,vbw3,vfw3,thSAD=sad,idx=idx_1,plane=pl)
defined(limy) ? LimitChange(MVDegrain2(c,vbw1,vfw1,vbw2,vfw2,vbw3,vfw3,thSAD=sad,idx=idx_1,plane=pl),c,limy,limuv) : nolimit
}

Fizick
29th January 2008, 21:37
so, it was test for blksize=16 and overlap=8?
(with 720x576 ?)

Boulder
29th January 2008, 21:42
Yes, in that test blksize was 16 and overlap 8 pixels, and the resolution was 720x576.

10000 frames of the same source with the DegrainC function with blocksize 8:

v1.8.6 0:07:46 (21.4 fps), no overlapping
v1.8.6 0:28:30 (5.8 fps), overlap=4
v1.9.2 0:07:37 (21.9 fps), no overlapping
v1.9.2 0:25:40 (6.5 fps), overlap=4

A clear boost with v1.9.2 in the overlapped test there :)

josey_wells
30th January 2008, 02:45
OK, here is the latest binary for test. Let me know if I accomploshied anything with 12 hours of optimizing. :)

Amefurashi
30th January 2008, 09:38
function Degrain3C( clip c, int "blk", int "ol", int "sh", int "sad", int "pl", int "div", int "limy", int "limuv" )
{
global idx_1 = idx_1 + 1
global idx_2 = idx_2 + 1
blk = default( blk, 16 )
ol = default( ol, 0 )
sh = default( sh, 2 )
sad = default( sad, 200 )
pl = default( pl, 4 )
div = default( div, 0 )
limuv = default( limuv, 255 )
vbw1=MVAnalyse(c,isb=true,truemotion=true,delta=1,pel=2,chroma=true,blksize=blk,idx=idx_1,sharp=sh,overlap=ol,divide=div)
vfw1=MVAnalyse(c,isb=false,truemotion=true,delta=1,pel=2,chroma=true,blksize=blk,idx=idx_1,sharp=sh,overlap=ol,divide=div)
vbw2=MVAnalyse(c,isb=true,truemotion=true,delta=2,pel=2,chroma=true,blksize=blk,idx=idx_1,sharp=sh,overlap=ol,divide=div)
vfw2=MVAnalyse(c,isb=false,truemotion=true,delta=2,pel=2,chroma=true,blksize=blk,idx=idx_1,sharp=sh,overlap=ol,divide=div)
vbw3=MVAnalyse(c,isb=true,truemotion=true,delta=3,pel=2,chroma=true,blksize=blk,idx=idx_1,sharp=sh,overlap=ol,divide=div)
vfw3=MVAnalyse(c,isb=false,truemotion=true,delta=3,pel=2,chroma=true,blksize=blk,idx=idx_1,sharp=sh,overlap=ol,divide=div)
nolimit = MVDegrain3(c,vbw1,vfw1,vbw2,vfw2,vbw3,vfw3,thSAD=sad,idx=idx_1,plane=pl)
defined(limy) ? LimitChange(MVDegrain2(c,vbw1,vfw1,vbw2,vfw2,vbw3,vfw3,thSAD=sad,idx=idx_1,plane=pl),c,limy,limuv) : nolimit
}


Hi,

may I ask what's that "Limit" thing? How is it supposed to work in the script posted above?

Many thanks to Fizick for releasing MVTools 1.9.x to public! ;)

Boulder
30th January 2008, 12:35
It limits the change to whatever is defined in the function call. If the "limy" (limit for luma change) is not found in the function call, then a simple MVDegrain3 call is done without any limits to the change. If limy is set, then the change done by the function is limited to the specified amount. The LimitChange function is in kassandro's SSETools plugin.

Note that I had forgotten to change the MVDegrain2 to MVDegrain3 in the last line of the function. It didn't affect my test results as I didn't do any limiting.

josey_wells
30th January 2008, 15:58
Boulder and Fizick,

I tweaked some more. I'm done tweaking and don't think it can be improved anymore. Someone can run a performance comparison if desired.

If it is any faster I will release the source code; otherwise, I will retreat in shame.

Boulder
30th January 2008, 16:37
Thanks, I'll do a test run with your latest build tonight provided the attachment is approved early enough.

Fizick
30th January 2008, 17:20
josey_wells,
please increment the version number (and update doc, etc in package) to privent mess

Boulder
30th January 2008, 20:43
All tests were done at 720x576.

MVDegrain2, blocksize 16, overlap 8, 15000 frames with HC022 and CQ mode
-----------------------------------
v1.8.6 0:17:27 (14.3 fps) Fizick
v1.9.2 0:17:11 (14.5 fps) Fizick
v1.9.x 0:17:03 (14.7 fps) josey_wells_v1 (the first binary)
v1.9.x 0:17:06 (14.6 fps) josey_wells_v2 (the last binary)

MVDegrain3, blocksize 16, overlap 8, 15000 frames with HC022 and CQ mode
-----------------------------------
v1.9.2 0:24:38 (10.1 fps) Fizick
v1.9.x 0:24:29 (10.2 fps) josey_wells_v1 (the first binary)
v1.9.x 0:24:34 (10.2 fps) josey_wells_v2 (the last binary)
v1.9.x 0:13:18 (18.8 fps) josey_wells_v2 (the last binary), with SetMTMode(2)
v1.9.2 0:13:14 (18.9 fps) Fizick, with SetMTMode(2)


MVDegrain2, blocksize 8, overlap 0, 10000 frames with HC022 and CQ mode
----------------------------------
v1.8.6 0:07:46 (21.4 fps), Fizick
v1.9.2 0:07:37 (21.9 fps), Fizick
v1.9.x 0:07:39 (21.8 fps), josey_wells_v2 (the last binary)



MVDegrain2, blocksize 8, overlap 4, 10000 frames with HC022 and CQ mode
----------------------------------
v1.8.6 0:28:30 (5.8 fps), Fizick
v1.9.2 0:25:40 (6.5 fps), Fizick
v1.9.x 0:25:38 (6.5 fps), josey_wells_v2 (the last binary)

Sorry josey_wells, no improvements here. It would be interesting to see some tests on an AMD system though.

Amefurashi
31st January 2008, 11:11
It limits the change to whatever is defined in the function call. If the "limy" (limit for luma change) is not found in the function call, then a simple MVDegrain3 call is done without any limits to the change. If limy is set, then the change done by the function is limited to the specified amount. The LimitChange function is in kassandro's SSETools plugin.

Note that I had forgotten to change the MVDegrain2 to MVDegrain3 in the last line of the function. It didn't affect my test results as I didn't do any limiting.

Thanks! :)

josey_wells
31st January 2008, 14:21
Boulder :thanks:,

Oh well, at least I found some bugs. :) And I was wondering why my performance was so much slower and it is becauuse I am using DCT, and pel=4. I find that the program is spending most of its time doing DCT(30%) and most of the rest is in SAD functions. Fizick has already optimized SAD to be about the best it could be.

function BryanDenoise(clip c, int "iLevel", int "iTHSAD", int "iBlksize", int "iOverlap", int "iPel", bool "bChroma", bool "bTrueMotion", int "iSearch", int "iSharp", int "iDct")
{
global iIdx1=iIdx1+1 #index incremented with each call to avoid multithread buffering problem

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

processed=(iLevel==1) ? Eval("""
#1nd level
backward_vec1=c.MVAnalyse(isb=true, delta=1, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
forward_vec1 =c.MVAnalyse(isb=false, delta=1, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
return c.MVDegrain1(backward_vec1, forward_vec1, thSAD=iTHSAD, idx=iIdx1)
""") : ( \
(iLevel==2) ? Eval("""
#2nd level
backward_vec2=c.MVAnalyse(isb=true, delta=2, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
backward_vec1=c.MVAnalyse(isb=true, delta=1, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
forward_vec1 =c.MVAnalyse(isb=false, delta=1, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
forward_vec2 =c.MVAnalyse(isb=false, delta=2, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
return c.MVDegrain2(backward_vec1, forward_vec1, backward_vec2, forward_vec2, thSAD=iTHSAD, idx=iIdx1)
""") : Eval("""
#3rd level
backward_vec3=c.MVAnalyse(isb=true, delta=3, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
backward_vec2=c.MVAnalyse(isb=true, delta=2, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
backward_vec1=c.MVAnalyse(isb=true, delta=1, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
forward_vec1 =c.MVAnalyse(isb=false, delta=1, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
forward_vec2 =c.MVAnalyse(isb=false, delta=2, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
forward_vec3 =c.MVAnalyse(isb=false, delta=3, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
return c.MVDegrain3(backward_vec1, forward_vec1, backward_vec2, forward_vec2, backward_vec3, forward_vec3, thSAD=iTHSAD, idx=iIdx1)
"""))
return processed
}

Fizick,

There is a typo on the web page where MVDegrain2 has been shown twice.

I'm going to lay off this awhile now unless inspiration strikes me. :rolleyes:

Sagekilla
1st February 2008, 03:14
IMO, it would be better to use something like this, since it would be cleaner and easier to read/modify.


(iLevel==3) ? bvec3 = o.MVAnalyse() : BlankClip
(iLevel>=2) ? bvec2 = o.MVAnalyse() : BlankClip
bvec1 = o.MVanalyse()
fvec1 = o.MVAnalyse()
(iLevel>=2) ? fvec2 = o.MVAnalyse() : BlankClip
(iLevel==3) ? fvec3 = o.MVAnalyse() : BlankClip

output = (iLevel==1) ? o.MVDegrain1() : (iLevel==2) ? o.MVDegrain2() : o.MVDegrain3()

talen9
1st February 2008, 12:46
Fizick, there's a mini-bug in the documentation of MVDegrain1/2/3: the syntax line for MVDegrain3 still reports "MVDegrain2 " as the calling name :)

MVDeGrain2 (clip, clip "mvbw", clip "mvfw", clip "mvbw2", clip "mvfw2", clip "mvbw3", clip "mvfw3",int "thSAD", int "plane", int "limit", clip "pelclip", int "idx")

:helpful:

ficofico
3rd February 2008, 08:46
I've a problem with mvflowfps2, when I try to use it, almost always I got an x264 error. The encoding work well untill the end, but at this point x264 crash reporting this error:

IMAGE (http://www.rigenerator.com/immagine.jpg)

If I use mvflofps I get no error, and this with all the mvtool.dll and with all the x264.exe version I've test.
The error it's frequently, but not always........ the script I use it's

source=last
backward_vec = source.MVAnalyse(isb = true, truemotion=true,pelsearch=4, pel=4, idx=1, divide=2,overlap=4,search=3)
forward_vec = source.MVAnalyse(isb = false, truemotion=true,pelsearch=4, pel=4, idx=1, divide=2,overlap=4,search=3)
cropped = source.crop(4,4,-4,-4)
backward_vec2 = cropped.MVAnalyse(isb = true,truemotion=true, overlap=4,pelsearch=4, pel=4, idx=2, divide=2,search=3)
forward_vec2 = cropped.MVAnalyse(isb = false,truemotion=true, overlap=4,pelsearch=4, pel=4, idx=2, divide=2, search=3)
source.MVFlowFps2(backward_vec,forward_vec,backward_vec2,forward_vec2,mask=2,num=60,den=1,idx=1,idx2=2)


Also in other computer x264 crash at the end of encoding....

And now the good news:)

I've made a simple gui that it's used in an italian nokia forum for restoring video shot with symbian phone, like n95 , n73 ecc ecc
I've made different profile , and with "insane quality" profile it's now possible to get this amazing result........ very thanks Fizick!!

Profile it's (waiting for mvflowfps2)

ffmpegsource("originale_automen.avi", seekmode=1)
setmemorymax(1024)
assumefps(fico)
converttoYv12()





source=last
w=width()
h=height()
backward_vec3 = source.MVAnalyse(isb=true,truemotion=true, delta=3,blksize=8,search=3,pel=4,overlap=4,overlapV=4/2,dct=4,idx=3)
backward_vec2 = source.MVAnalyse(isb=true,truemotion=true, delta=2,blksize=8,search=3,pel=4,overlap=4,overlapV=4/2,dct=4,idx=3)
backward_vec1 = source.MVAnalyse(isb=true,truemotion=true, delta=1,blksize=8,search=3,pel=4,overlap=4,overlapV=4/2,dct=4,idx=3)
forward_vec1 = source.MVAnalyse(isb=false,truemotion=true, delta=1,blksize=8,search=3,pel=4,overlap=4,overlapV=4/2,dct=4,idx=3)
forward_vec2 = source.MVAnalyse(isb=false,truemotion=true, delta=2,blksize=8,search=3,pel=4,overlap=4,overlapV=4/2,dct=4,idx=3)
forward_vec3 = source.MVAnalyse(isb=false,truemotion=true, delta=3,blksize=8,search=3,pel=4,overlap=4,overlapV=4/2,dct=4,idx=3)
maskp1 = mvmask(kind=1, vectors=forward_vec1, ysc=255).UtoY()
maskp2 = mvmask(kind=1, vectors=forward_vec2).UtoY()
maskp3 = mvmask(kind=1, vectors=forward_vec3).UtoY()
maskp4 = mvmask(kind=1, vectors=backward_vec1, ysc=255).UtoY()
maskp5 = mvmask(kind=1, vectors=backward_vec2).UtoY()
maskp6 = mvmask(kind=1, vectors=backward_vec3).UtoY()
maskf = average(maskp1, 0.25, maskp2, 0.25, maskp3, 0.25, maskp4, 0.25, maskp5, 0.25, maskp6, 0.25).spline36resize(w,h)
smooth = source.mt("fft3dfilter(bw=16, bh=16, bt=5, sigma=5, plane=4)")
source2 = maskedmerge(source,smooth,maskf)
source2.MVDegrain3(backward_vec1,forward_vec1,backward_vec2,forward_vec2,backward_vec3,forward_vec3,thSAD=700,idx=4)

source=last
backward_vec = source.MVAnalyse(isb = true,truemotion=true, overlap=4,pelsearch=4,dct=4, pel=4, idx=1, divide=2,search=3)
forward_vec = source.MVAnalyse(isb = false,truemotion=true, overlap=4,pelsearch=4,dct=4, pel=4, idx=1, divide=2, search=3)
source.MVFlowFps(backward_vec,forward_vec,mask=2,num=60,den=1,idx=1)

dull = last
sharp = dull.mt("LimitedSharpenfaster(ss_x=3.0,ss_y=3.0,smode=3,strength=240,overshoot=3)")
Soothe(sharp,dull,15)

And this it's result:

VIDEO BEFORE AND AFTER (http://www.rigenerator.com/incredible.rar)

Fizick
3rd February 2008, 09:27
josey_wells,
Yes. most time is in SAD. And No, it was optimized not by me, but Manao :)

josey_wells, talen9,
Opps, MVDegrain3 typo must be fixed.

ficofico,
MVFlowFps2 is obsolete.
From MVTools manual: ...Functions with overlap support are: MVFlow, MVFlowInter, MVFlowFps (not MVFlowFps2),....
Do you have the x264 crash with overlap=0?

I could add Error message for this case...

ficofico
3rd February 2008, 12:11
Yes, even with overlap=0 I get x264.exe crash

Dark Shikari
3rd February 2008, 12:34
Have you considered porting x264's cachesplit code to MVTools' SAD?

It cuts the clock cycles for an unaligned SAD in half on Intel CPUs. Average clocks for a 16x16 SAD go from 101 -> 48.

Kumo
8th February 2008, 10:46
i'm trying to remove grain in an anime dvd.i found mvdegrain2 works very fine with thisbackward_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)
source.MVDegrain2(backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=400,idx=1)
default settings i found in its documentation.know i'm reading about mvdegrain3, what kind of improvement could it make on my script(stronger grain removal?better accuracy?)?where can i find a default setting like the one i used for mvdegrain2(can't find it in its doumentation)

talen9
8th February 2008, 11:34
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)

This should work ... it isn't so difficult, if you try to understand the way MVDegrainX works from the docs :)

jeffy
11th February 2008, 21:19
I'm sorry, I know I have seen the topic mentioned previously in the MT thread (MT 0.7). Is there anyone who was able to get a speed up and/or a higher CPU usage when compared with a dual core?

I had a chance to compare E6600/3.51 GHz OCed with a Q6600/2.4 GHz non-OCed where a simple MVDegrain2 was used, MVAnalyse parameters were quite fast:
MVAnalyse(isb=true,truemotion=true,delta=1/2,pel=1,chroma=false,blksize=16,idx=idx1,sharp=0), but the speed was nearly the same although it was used in a following way:

DGDecode_MPEG2Source("video.d2v",idct=4)
yadif(mode=0)
global idx1 = 10
MT("""
changefps(last,last,true)
idx1 = idx1 + 1
vbw1=MVAnalyse(isb=true,truemotion=true,delta=1,pel=1,chroma=false,blksize=16,idx=idx1,sharp=0)
vfw1=MVAnalyse(isb=false,truemotion=true,delta=1,pel=1,chroma=false,blksize=16,idx=idx1,sharp=0)
vbw2=MVAnalyse(isb=true,truemotion=true,delta=2,pel=1,chroma=false,blksize=16,idx=idx1,sharp=0)
vfw2=MVAnalyse(isb=false,truemotion=true,delta=2,pel=1,chroma=false,blksize=16,idx=idx1,sharp=0)
MVDegrain2(last,vbw1,vfw1,vbw2,vfw2,thSAD=400,idx=idx1)
""",4,2) or """,4,4)

Quad core usage was around 60-75%.

EDIT:
The speed was measured in VirtualDub-MPEG2 1.6.19.24586, fast recompress video, Uncompressed, File -> Run video analysis pass.

Zep
12th February 2008, 02:52
I'm sorry, I know I have seen the topic mentioned previously in the MT thread (MT 0.7). Is there anyone who was able to get a speed up and/or a higher CPU usage when compared with a dual core?

I had a chance to compare E6600/3.51 GHz OCed with a Q6600/2.4 GHz non-OCed where a simple MVDegrain2 was used, MVAnalyse parameters were quite fast:
MVAnalyse(isb=true,truemotion=true,delta=1/2,pel=1,chroma=false,blksize=16,idx=idx1,sharp=0), but the speed was nearly the same although it was used in a following way:

Quad core usage was around 60-75%.



IMHO it is better to use SetMTMode() with MVAnalyse. Then overload the number of cores. (try 6 to 10) Where the sweet spot is depends on many factors like how much ram you have etc...

Kumo
16th February 2008, 18:11
there's a way to increase the strength of mvdegrain?i'm using it like thissource = 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)

but even if it's working fine,it's not enough to remove all the grain,so i need to call anothere denoiser after it.

Reuf Toc
16th February 2008, 18:54
there's a way to increase the strength of mvdegrain?i'm using it like thissource = 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)

but even if it's working fine,it's not enough to remove all the grain,so i need to call anothere denoiser after it.

You can reduce block size, use overlap,increase pixel precision and increase by reasonable amount thSAD to increase filtering force. Note that increasing pel precision and using overlap slow down significantly the process.
I've also noticed that if you feed mvanalyse with a pre-processed clip (cleaned with removegrain for example) the results are better.

Terranigma
24th February 2008, 22:44
Feature Request (for MVDegrain):
Ability to specify separate thsad values for both, the luma and chroma planes. Why? because, using a high thsad value (lets say, 600) may lead to frames smeared with rainbow artifacts (assuming that plane is set to 4 or 3), but this will never happen if the plane is set to filter the luma plane only; so I was thinking that it'd be great to have the chroma planes filtered at a set value (preferably 300 or so) while I can adjust the luma as much as I want without sharing it with the chroma.

AVIL
25th February 2008, 21:46
Hi,

In all the Mvanalyse steps previous to Mvdegrain set chroma parameter to true.

Good luck

Terranigma
25th February 2008, 22:36
Hi,

In all the Mvanalyse steps previous to Mvdegrain set chroma parameter to true.

Good luck
So you're saying that the chroma plane will be filtered if plane is set to 0, as long as chroma is taken into account during the motion estimation process? btw, by default, chroma is enabled. :)

talen9
25th February 2008, 22:37
That's something different from what's he's asking for ;)

Anyway, the "chroma" parameter for MVAnalyse is "true" by default (per MVTools' docs).

EDIT: preceded :p

AVIL
26th February 2008, 12:21
Hi, again:

Sorry then. I'm not an expert in C++ and I've misundertood the source code in MVanalyse:

analysisData.nFlags |= chroma ? MOTION_USE_CHROMA_MOTION : 0;

In fact when I do motion compensation with values of delta around 9, I obtain chroma errors that dissapear when I explicitly set the chroma parameter to true. But it is referred to mvcompensate. So I suggest try this trick in mvdegrain.

Good luck

TSchniede
10th April 2008, 00:51
I have a question concerning the idx / pelclip parameter. I had assumed if pelclip (or clip2x in earlier versions) is defined, idx is irrelevant. But according to debugview that seems wrong. So has idx to be defined to share data?

The reason is, that I have found out that sometimes there is some sort of "crosstalk" between the different clips that are worked on at the same time. I don't mean between the ones that use the same clip (and the same pelclip (or idx)). I mean between clip1.mvcompensate(idx=1) and clip2.mvdegrain(idx=2). Last time I thoroughly tested it (around version 1.6.x) functions that used mvtools like mvbob seemed to work if I added a parameter to set different idx but named it different to idx, for example idxref. Recently I used idx again and had a different clip for the analysis than than compensation and denoising and got a faint shadow of one clip on the other on a few frames even though I made the analysis with a different idx. defining pelclip and leaving idx undefined seemed to solve the problem. Pinning things down proved quite difficult as these things only happen very sporadic and non-deterministic.

Fizick
12th April 2008, 13:33
TSchniede:
1. Quick revision a source code: I see that pelclip option for pel=4 is broken. :(

2. Probably Even if you use pelclip (instead internal interpolation) , it is useful to use idx

I will look it more.
But generaly it is better to re-design MVTools without idx...

Please provide a script to catch possible bug with "shadow".

Terranigma
13th April 2008, 16:11
Fizick, what do you think of my idea to allow different thsad values for mvdegrain; one for the luma plane, and the other for the chroma planes? Like, thsad1=800, thsad2=300 (thsad1 would be the filtering threshold for the luma plane only, and if plane is set to 1-4, thsad2 would be the filtering threshold for the chroma plane(s)).
Would this be too hard to implement?

Fizick
13th April 2008, 16:56
Terranigma,
I amm not sure how useful it is, but it may be implemented easy.

scharfis_brain
13th April 2008, 17:03
Hi Fizick,

If you should go on to re-design mvtools, would you also implement true multithreading?

The current issue with mt is that the frame needs to be split up into several slices, which prevent motion-vectors to go from one slice to another.

Terranigma
13th April 2008, 17:17
I amm not sure how useful it is, but it may be implemented easy.

Probably not all that useful, but it'd allow us to reduce the chroma/rainbow artifacts that are caused by high threshold values (when a chroma plane is set to be filtered).

We'd also be able to diminish the color shift mvdegrain does when the chroma planes are filtered. :cool:

Fizick
13th April 2008, 19:33
Hi scharfis_brain,
Probably you say about MT() plugin.
Sorry, currently I do not plan to redesign MVTools in general and for M.T. specifically.

Terranigma,
well, v.1.9.3 beta with thSADC parameter is ready and almost released.

Terranigma
13th April 2008, 20:08
well, v.1.9.3 beta with thSADC parameter is ready and almost released.

Thanks a lot Fizick! You Rule. :D

TSchniede
15th April 2008, 17:45
I am sorry, I can't give you a simple demonstration. The issue is quite rare, and as far as I know not directly your fault. It seems to be several several issues.
Last time I tried (more than one year ago) I found out that two separate instances(two different scripts, each called from a different application on the same machine) of avisynth are less independent than you would assume. The same idx values seem to point to the same streams (this can be avoided), but if the names of variables / parameters on the called functions / plugin matched such as example(idx=idx) they could influence each other across thread barriers. Unfortunately this would be completely indeterministic. I suppose some optimization in the parser for basic types is the reason for that. That issue MIGHT still exist, but I haven't checked since tests would take several hours.

Concerning the shadow - I don't know if that case even counts. A few days ago I had experimented on a new script for several hours and it was likely another instance of avisynth which existed simultaneously with the same idx values, when I used pelclip instead this issue would get solved. It could have been an avisynth weirdness too.I sometimes encounter them after dozens of refreshes.

I had hoped to be able to avoid the whole issue with pelclip, but the documentation on the issue is unfortunately very vague - hence my post. In theory pelclip should contain all data which idx provides as the remaining things are in recent versions recomputed anyway(according to the documentation).

Fizick
15th April 2008, 22:15
TSchniede, please provide versions of avisynth and mvtools if you get error.

Terranigma
16th April 2008, 00:56
Fizick, would you mind taking another request? If not, I was wonderin' if you could either add MVDegrain4 so that we can search up to 4 frames, or perhaps make MVDegrain function in the way MVDenoise does, where you can just call MVDenoise and use virtually however many vector clips you want.

That'd be all the requesting i'll be doing about mvdegrain for a good while. :)

SPiKA
18th April 2008, 17:34
I've also noticed that if you feed mvanalyse with a pre-processed clip (cleaned with removegrain for example) the results are better.

Like this?

source = last.RemoveGrain(mode=1)
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)


Or like this?

RemoveGrain(mode=1)

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)

Boulder
18th April 2008, 17:41
Rather like this:
source = last.RemoveGrain(mode=1)
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)
MVDegrain3(last,backward_vec1,forward_vec1,backward_vec2,forward_vec2,backward_vec3,forward_vec3,thSAD=400,idx=2)

thetoof
18th April 2008, 20:25
and I'd add that you can get even better results with TemporalDegrain.

These posts might be of some use to you for the reference clip:

http://forum.doom9.org/showthread.php?p=1119265#post1119265

http://forum.doom9.org/showthread.php?p=1121332#post1121332

SPiKA
18th April 2008, 22:02
Is there a way to prevent macroblocks when filtering anime using mvtools?

cestfait
18th April 2008, 23:38
if the blocking is in the dvd, use more frames (i.e. mvdegrain3 over mvdegrain2).

if the blocking is the result of the filtering, either lower thSAD, lower blocksize, or use overlap.

in fact, always use overlap, at least for anime, in my opinion. it takes a lot longer, but it's worth it.

blocking in your final encode will depend on your codec, your settings, and your bitrate, of course.

p.s. the only way of making anime really clean in my opinion is to max out your motion estimation, both in the filtering and in the encoder (and give the final encode a decent bitrate). spatial smoothing always ends up destroying too many details or blocking somewhere, even if the untrained eye can't see either one.

SPiKA
18th April 2008, 23:49
if the blocking is in the dvd, use more frames (i.e. mvdegrain3 over mvdegrain2).

if the blocking is the result of the filtering, either lower thSAD, lower blocksize, or use overlap.

in fact, always use overlap, at least for anime, in my opinion. it takes a lot longer, but it's worth it.

blocking in your final encode will depend on your codec, your settings, and your bitrate, of course.

p.s. the only way of making anime really clean in my opinion is to max out your motion estimation, both in the filtering and in the encoder (and give the final encode a decent bitrate). spatial smoothing always ends up destroying too many details or blocking somewhere, even if the untrained eye can't see either one.

Blocking is the result of the filtering... how do I lower blocksize and use overlap?

Terranigma
18th April 2008, 23:55
how do I lower blocksize and use overlap?
In MVAnalyse. Check out the example for MVDegrain2 in the MVTools documentation.

SPiKA
19th April 2008, 00:03
Something like this is OK?

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

Terranigma
19th April 2008, 00:26
You might want to use an overlap value that's half that of the blocksize, so use overlap=4 (since the default blksize is 8). Other than that, everything looks good. :)

SPiKA
19th April 2008, 00:41
Can I reduce blocksize like this?

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

It's incredibly slow though... xD

Dark Shikari
19th April 2008, 00:41
Overly small block sizes are generally bad with MVDegrain.

Reuf Toc
19th April 2008, 02:15
Can I reduce blocksize like this?

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

It's incredibly slow though... xD

Be carefull, with this script, your video is processed by removegrain AND mvdegrain, I'm not sure this is what you want to do. If you want to use the preprocessing trick, your script should be like that :


#clip to process :
source = last

#pre-processed clip to help motion estimation :
mvanalyse_clip = source.RemoveGrain(mode=1)

backward_vec3 = mvanalyse_clip.MVAnalyse(isb = true, delta = 3, pel = 2, blksize=4, overlap=2, sharp=1, idx = 1)
backward_vec2 = mvanalyse_clip.MVAnalyse(isb = true, delta = 2, pel = 2, blksize=4, overlap=2, sharp=1, idx = 1)
backward_vec1 = mvanalyse_clip.MVAnalyse(isb = true, delta = 1, pel = 2, blksize=4, overlap=2, sharp=1, idx = 1)
forward_vec1 = mvanalyse_clip.MVAnalyse(isb = false, delta = 1, pel = 2, blksize=4, overlap=2, sharp=1, idx = 1)
forward_vec2 = mvanalyse_clip.MVAnalyse(isb = false, delta = 2, pel = 2, blksize=4, overlap=2, sharp=1, idx = 1)
forward_vec3 = mvanalyse_clip.MVAnalyse(isb = false, delta = 3, pel = 2, blksize=4, overlap=2, sharp=1, idx = 1)

source.MVDegrain3(backward_vec1,forward_vec1,backward_vec2,forward_vec2,backward_vec3,forward_vec3,thSAD=400,idx=2)

Terranigma
19th April 2008, 03:03
Well, you're only half right. To do preprocessing, they'd have to use a different idx value for MVDegrain.
But RemoveGrain(mode=1) is so weak, that he/she shouldn't worry about using it for preprocessing. They can use rg1 with full strength.

Nikos
19th April 2008, 10:14
Terranigma is right.
The correct script.

#clip to process :
source = last

#pre-processed clip to help motion estimation :
mvanalyse_clip = source.RemoveGrain(mode=17)

backward_vec3 = mvanalyse_clip.MVAnalyse(..., idx = 1)
backward_vec2 = mvanalyse_clip.MVAnalyse(..., idx = 1)
backward_vec1 = mvanalyse_clip.MVAnalyse(..., idx = 1)
forward_vec1 = mvanalyse_clip.MVAnalyse(..., idx = 1)
forward_vec2 = mvanalyse_clip.MVAnalyse(..., idx = 1)
forward_vec3 = mvanalyse_clip.MVAnalyse(..., idx = 1)

source.MVDegrain3(...,idx=2)

With prefiltering the idx's must be different.
The mvanalyse_clip must be "calm" enough.

SPiKA
19th April 2008, 14:59
Thanks to everyone... :thanks:

Fizick
22nd April 2008, 21:19
v1.9.3
MVAnalyse: fixed bug for pelclip (broken since v1.8.5).
MVDegrain: added thSADC as chroma threshold (request by Terranigma).


almost not tested

Terranigma
23rd April 2008, 01:39
Thanks for the update - i'll test it. :)
Could you elaborate a bit on just what the bug was for pelclip and how it affected the analysis?
:thanks:

Spuds
23rd April 2008, 02:19
@Terranigma .. Dare I say it, check post #666 to see the hellacious error ....

Fizick
23rd April 2008, 16:46
I fixed (stupid) bug in pelclip parameter enemeration (parsing), so pelclip never worked in recent versions.
and also replace extclip 2 to pel in some places (for pelclip=4).

I am not sure that v.1.9.3 fixed "post 666" error.

Terranigma
23rd April 2008, 19:45
I fixed (stupid) bug in pelclip parameter enemeration (parsing), so pelclip never works in recent versions.
and also replace expicip 2 to pel in some places (for pelclip=4).


OK, thanks for clearing that. up. I was wonderin' why most of the times I was getting worse results using an external interpolation method than internal, and expicip 2 sounds interesting. :)

Terka
24th April 2008, 10:44
is the resolved bug related to
http://forum.doom9.org/showthread.php?t=131141&highlight=Terka&page=3
?

Fizick
24th April 2008, 17:15
Terka,
I do not understand what you talk about.

nonsens112
27th April 2008, 05:26
Fizick, many thanks for this great plugin and its prompt support.

One question - did you think about taking into account in your denoisers not only SAD but average difference (or absolute sum of differences) too?
I think it would be very useful. Just some parameter like thASD at least.

Terka
27th April 2008, 09:14
>Fizick: Please have a look at
http://forum.doom9.org/showthread.php?t=131141&highlight=Terka&page=3
is this a mvtoos bug?

Fizick
27th April 2008, 23:05
Terka,
what do you talk about?

Didée
28th April 2008, 00:30
About the script in this post (http://forum.doom9.org/showthread.php?p=1110859#post1110859).

Load it & start wondering what's going on.

Fizick
28th April 2008, 18:49
Terka, Didee,

probably it is not bug, but feature.


function DoubleFramerate (clip c, int "_idx")
{
#To double fps with MVFlowFps for 'best' results (but slower processing):
backward_vec = c.MVAnalyse( isb = true, truemotion=true, pel=2, overlap=4, search=2, searchparam=8, idx=_idx) #pel 2 +-ok pel 1 rozmazne
forward_vec = c.MVAnalyse( isb = false, truemotion=true, pel=2, overlap=4, search=2, searchparam=8, idx=_idx)
c.MVFlowFps(backward_vec, forward_vec, num=2*FramerateNumerator(c), den=FramerateDenominator(c), idx=_idx)
}

1. that script uses crazy value of searchparam=8.
Default value (2) is generally optimal. Sometimes even 1 is fine.
It is due to hierarchical method.
2. of cource search=3 is the best. but slowest.
3. Computer grafics is very special kind of sources with big flat areas where any local vector is good.

for this specific test clip I recommend to use level=1 or even level=2 to prevent extra big vectors:

function DoubleFramerateCG (clip c, int "_idx")
{
#To double fps with MVFlowFps for 'best' results (but slower processing):
backward_vec = c.MVAnalyse( isb = true, truemotion=true, pel=2, overlap=4, search=2, searchparam=8, idx=_idx, level=2)
forward_vec = c.MVAnalyse( isb = false, truemotion=true, pel=2, overlap=4, search=2, searchparam=8, idx=_idx, level=2)
c.MVFlowFps(backward_vec, forward_vec, num=2*FramerateNumerator(c), den=FramerateDenominator(c), idx=_idx)
}


also some blured estimation clip may be used

Chainmax
23rd May 2008, 02:24
I used to use MVDeGrain2 in the following manner:

source=last
denoised=RemoveGrain(mode=5).FFT3DFilter(sigma=6,plane=3,bw=32,bh=32,bt=3,ow=16,oh=16)
backward_vec2 = MVAnalyse(denoised,isb = true, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec1 = MVAnalyse(denoised,isb = true, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec1 = MVAnalyse(denoised,isb = false, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec2 = MVAnalyse(denoised,isb = false, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
MVDegrain2(source,backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=350,idx=2)

would the equivalent MVDeGrain3 version be

source=last
denoised=RemoveGrain(mode=5).FFT3DFilter(sigma=6,plane=3,bw=32,bh=32,bt=3,ow=16,oh=16)
backward_vec3 = MVAnalyse(denoised,isb = true, delta = 3, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec2 = MVAnalyse(denoised,isb = true, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec1 = MVAnalyse(denoised,isb = true, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec1 = MVAnalyse(denoised,isb = false, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec2 = MVAnalyse(denoised,isb = false, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec3 = MVAnalyse(denoised,isb = false, delta = 3, pel = 2, overlap=4, sharp=1, idx = 1)
MVDegrain3(source,backward_vec1,forward_vec1,backward_vec2,forward_vec2,backward_vec3,forward_vec3,thSAD=350,idx=2)

?

Terranigma
23rd May 2008, 02:31
Yes, that would be correct.

Chainmax
23rd May 2008, 03:27
Thanks :).

Didée
24th May 2008, 10:40
For those having the urgent need of a MVDegrain4/5/6() filter (me not), here is a script block that builds close approximations:

bvec1 = source.MVAnalyse(isb=true, delta=1, [params], idx = X )
bvec2 = source.MVAnalyse(isb=true, delta=2, [params], idx = X )
bvec3 = source.MVAnalyse(isb=true, delta=3, [params], idx = X )
bvec4 = source.MVAnalyse(isb=true, delta=4, [params], idx = X )
bvec5 = source.MVAnalyse(isb=true, delta=5, [params], idx = X )
fvec1 = source.MVAnalyse(isb=false,delta=1, [params], idx = X )
fvec2 = source.MVAnalyse(isb=false,delta=2, [params], idx = X )
fvec3 = source.MVAnalyse(isb=false,delta=3, [params], idx = X )
fvec4 = source.MVAnalyse(isb=false,delta=4, [params], idx = X )
fvec5 = source.MVAnalyse(isb=false,delta=5, [params], idx = X )

mvdg12 = source.MVDegrain2(bvec1,fvec1,bvec2,fvec2, [params], idx = X )
mvdg34 = source.MVDegrain2(bvec3,fvec3,bvec4,fvec4, [params], idx = X )
mvdg45 = source.MVDegrain2(bvec4,fvec4,bvec5,fvec5, [params], idx = X )
mvdg123 = source.MVDegrain3(bvec1,fvec1,bvec2,fvec2,bvec3,fvec3, [params], idx = X )
mvdg456 = source.MVDegrain3(bvec4,fvec4,bvec5,fvec5,bvec6,fvec6, [params], idx = X )

mvdg1234 = Merge( mvdg12, mvdg34, 0.4444 ) # this gives MVDegrain4()
mvdg12345 = Merge( mvdg123, mvdg45, 0.4545 ) # this gives MVDegrain5()
mvdg123456 = Merge( mvdg123, mvdg456, 0.4615 ) # this gives MVDegrain6()

You get the idea, pick what you need, it's not difficult. Just keep in mind that in this case the idx values are the same in all these lines.

bartrobinson
6th June 2008, 15:34
Is it possible to do motion tracking / transfer with MVTools?

Example:
Lets say I have two clips. One is a "background" clip that shows a close up of someone's arm moving in frame. I also have a still frame of a fake scar on black. The scar is made to look like it is in the proper shape and location to be on the arm for the first frame of the other clip. Is it possible to MVAnalyse the arm clip and then apply the motion vectors (using another function) to the scar frame so each frame it moves the same as the arm? I would then composite the scar on the arm later myself.

Thanks a lot!

Bart - VFX Artist

rkalwaitis
7th June 2008, 09:51
Hello,

I am attempting to understand QMTrim which used MVTools. I guess a good place to start would be for me to understand more about qmtrim, but to documentation is in Italian and a lot is lost through translation. I think I understand the jest of it, but would like to know more about the setting and how to manipulate them and the cause of the manipulations.

:thanks:

TSchniede
9th June 2008, 00:48
@bartrobinson:

this is as far as i know only possible on a very limited scale.

MVAnalyse estimates motion based on finding the best match of a part of of one frame on an other frame. There are several strategies at work that make the final guess better and faster than simply looking for the closest match, BUT it is only a guess. This guess is quite good for preventing artifacts on temporal filtering, but with increasing distance to (both spatial and temporal) of motion the chances for a correct prediction dwindle.

You could make chains of "mvanalyse with increasing delta" and apply the compensation (mvcompensate / MVFlow) to the scar/tattoo frame.
Unfortunately that breaks on scene changes (real or estimated) and can only possibly work if the input is quite low on noise and quite rich on detail (low detail increases the chances of finding similar areas on other parts (like mt_motion or motionmask only motion on outside of flat areas gets good estimation) and noise simply throws mvanalyse off.
Even on the best case scenario you might have to set the image every 10-20 frames yourself.

bartrobinson
11th June 2008, 03:48
Thanks for the reply.

It doesn't sound like a go for the current toolset. I have two thoughts in going forward.

Would anyone like to program a new function called MVWarp which takes the motion vectors from a previous MVAnalyze and uses them to warp a single image? On the first frame the image would remain unchanged, positioned at the base of the vectors, but on the second frame the image would be warped to the tip of the vectors. Then on the third frame the image would be warped from it's position on the second frame to the tip of the third frame's vectors. The effect would appear as if a single image of a tattoo or decal were applied to the object in the analyzed clip and would move with it.

My second thought is this. The vectors that are output from MVAnalyze... In what form are they? I was curious and attached a ConvertToRGB after the MVAnalyze and the output looked like a single row of randomly changing pixels, roughly (width / blocksize * height / blocksize) pixels wide. Can anyone explain exactly what I'm seeing and what the data actually is, and if I can reconstruct it into a widthxheight image? I'd love to have access to this vector data outside of AVISynth.

AVIL
11th June 2008, 20:56
Hi,

Using blksize=16,blksizev=2 in mvanalyse Virtualdub crashes with error:

Avisynth read error: CAVIStreamSynth: Sys+.

No matter the overlap, truemotion or pel I use.

SO:Windows XP. CPU: AMD Athlon 64 3200+, single core. No overclocking.

Fizick
12th June 2008, 20:22
AVIL, script? blksize 16x2 is still not implemented for several functions.

bartrobinson,
How to "explain"? Read source code and docs.
you are not the first who asked vectors. ;)
but it is not easy to use them.

TSchniede
12th June 2008, 23:53
Like Fizick said, the best way is to look into the code and read the documentation (I would add read: the forum too).

Some threads where aspects of MVTools are discussed:
Thread about removing idx (http://forum.doom9.org/showthread.php?p=1057448#post1057448)
original MVTools development thread, some things are definitely outdated (http://forum.doom9.org/showthread.php?p=490356#post490356)
seems to be the current development tread, but definitely abadonned for some time, most development things are discussed somewhere else (http://forum.doom9.org/showthread.php?p=730915#post730915)
The MT thread, sparked the first mentioned thread and made MTools MT friendly (example of external development discussion) (http://forum.doom9.org/showthread.php?p=1056462#post1056462)

TSchniede
13th June 2008, 00:06
By the way... in current versions (1.9.x) MVDegrain3 (.h & .cpp) is missing from the solution. And I found a minor error, the stdio header is missing if debug output gets disabled (the outfile needs it too, so it should be moved outside the #ifdef pragma).

The more I get into the inner workings, the more i have to admit how impressed I am. It is nearly impossible to further improve the performance (unfortunately).

Dark Shikari
13th June 2008, 00:12
It is nearly impossible to further improve the performance (unfortunately).I find this doubtful given that MVTools doesn't have cacheline-split handling code like x264 does ;).

Of course, given that x264's cacheline-split code is nasm syntax also, I suspect porting it would not be too difficult.

Fizick
13th June 2008, 14:24
TSchniede,
the solution project file was provided for older version by tsp (probably). I use Codeblocks instead. You may sent updated project files to me.

TSchniede
13th June 2008, 15:46
I find this doubtful given that MVTools doesn't have cacheline-split handling code like x264 does ;).

Of course, given that x264's cacheline-split code is nasm syntax also, I suspect porting it would not be too difficult.

I meant, that most optimizations, that don't fundamentally change the algorithm tend to change performance, but most only degrade it. The problem is that the block analysis is quite fast (NASM), but there are many variants tested. I don't see where cacheline dependent loops would help, as a change in the block orderings is undesirable as it usually prevents to include the local movement data.
There are a few things left which might hep, the nasm code for SAD for example might be somewhat faster if the new longer sse instructions are used instead of the old MMX/SSE1 ones (unfortunately I only worked with alpha assembler yet).
I am looking into a variant of the divide option, that way there might be less blocks which have to be computed and the result might be somewhat less prone to noise, but I am still looking if that can be done without breaking existent code and if it really is faster is the other unknown factor.

TSchniede
13th June 2008, 15:50
TSchniede,
the solution project file was provided for older version by tsp (probably). I use Codeblocks instead. You may sent updated project files to me.

I only have Visual Studio 2005, so any solution file I create will only work with that and newer.

Dark Shikari
13th June 2008, 16:12
I meant, that most optimizations, that don't fundamentally change the algorithm tend to change performance, but most only degrade it. The problem is that the block analysis is quite fast (NASM), but there are many variants tested. I don't see where cacheline dependent loops would help, as a change in the block orderings is undesirable as it usually prevents to include the local movement data.Cacheline does not require any change in the algorithm--it simply makes each individual SAD faster. It helps on Intel machines only, of course. See this page (http://x264dev.multimedia.cx/?p=8) for more details.

Fizick
13th June 2008, 18:43
Dark Shikari,
thanks for pointing! x264 has many opimizations!
(my CPU is Athlon XP :)).

Boulder
13th June 2008, 19:11
If someone (*cough* *cough*) is about to try these optimizations, I'm up for testing as needed :)

TSchniede
14th June 2008, 00:25
Cacheline does not require any change in the algorithm--it simply makes each individual SAD faster. It helps on Intel machines only, of course. See this page (http://x264dev.multimedia.cx/?p=8) for more details.

Thanks, that is a quite unique limitation. Odd behavior like that is one reason I don't like doing assembler code. If things should really be faster, you have to know the quirks of the target CPU or testing every variant if an algorithm.

Fizick
14th June 2008, 07:36
Boulder, me too :)

TSchniede, nobody likes doing assember code :)

Dark Shikari
14th June 2008, 07:40
TSchniede, nobody likes doing assember code :)Nobody? I beg to differ. :p

AVIL
14th June 2008, 12:22
@Fizick

The script which crashes is :

#To unify jitter in averaging two captures of VHS tape. The second clip is mocomped,
#line based, to the first. To profit 16x2 mode in mvtools, each video line is
#duplicate. Best solution could be a 16x1 mode, but ...

setmemorymax(768)

Loadplugin("D:\Mis documentos\MiSoft\MULTIMEDIA\Video\Proceso_edicion\Avisynth\plugins2\mvtools.dll")
Loadplugin("D:\Mis documentos\MiSoft\MULTIMEDIA\Video\Proceso_edicion\Avisynth\plugins2\Average_24Oct05.dll")

y1=Avisource("i:\zapatera1.avi").trim(662,0)
y2=Avisource("i:\zapatera2.avi").trim(632,0)

z1=y1.pointresize(y1.width(), 2* y1.height())
z2=y2.pointresize(y2.width(), 2* y2.height())

m1=interleave(z2,z1)


m1f1=m1.mvanalyse(isb=false,delta=1,overlapv=0,blksize=16,overlap=8,blksizev=2,truemotion=true,idx=10)
j2=m1.mvcompensate(m1f1,idx=10).selectodd().separatefields().selecteven()

average(y1,0.5,j2,0.5)

Terranigma
14th June 2008, 15:04
I thought that the only possible blocksizes were
32x16, 16x16, 16x8, 8x8, 8x4, and 4x4.

Fizick
14th June 2008, 16:09
16x2 is secret size :)
But it is not imp0lemented for MVConmpensate. It wil be fixed in next release.

Probably I can implement 16x1 or 32x1 too, but for yuy2 only.

AVIL
16th June 2008, 18:27
@Fizick

16x2 is secret size
But it is not imp0lemented for MVConmpensate. It wil be fixed in next release.

Probably I can implement 16x1 or 32x1 too, but for yuy2 only.

Thanks.

Fizick
16th June 2008, 20:34
AVIL,
it was my question :)

Dreassica
17th June 2008, 16:14
Would it be possioble for mvtools/mvdegrain to use an external spatial filter on frames it cant degrain because of having no nearby matches ( like flashes)? Or at least able to output framenumbers for me to use in applyrange easily?

thetoof
17th June 2008, 16:36
-Maybe using dct would help for this (dct=2 or 3, I think)
-Some filter to detect "scene changes" (big difference in luma when there is a flash) and apply a frequency based filter on the frames around that change
The latter would be very nice if someone could find how to do it (maybe with masktools :))

TSchniede
17th June 2008, 18:24
Dreassica, that depends on what you want. MVDegrain does now "only" compute the mean of all motion compensated frames, weighted by their SAD (it's computed on a per-block-basis). It doesn't know if a block will get through because the SAD of most of the relevant blocks is bvery bad compared to the block. theoretically it should be possible to test if the weight of the current block in the mean exceeds a certain value (perhaps > 80%) and then take the corresponding block on a prefiltered clip. I fear the overhead for the extra clip management would make that quite slow. in the mean time you could at least use MVmask of the previous and next frame and together with masktools, if the sad is > some value switch to your second clip for that block.

TSchniede
17th June 2008, 19:27
Concerning the Cache-line-split issue. After some experimenting I think, I got a port of that algorithm running (mmx & SSSE3 fix), my first test don't seem that promising.

I tried it on my Pentium M and my Q9300, the results are quite different. The Pentium M reacts quite obvious to most changes in the SAD function, the difference between default and dummy(empty function that only returns 0(xor eax,eax ret) made MVDegrain3 take less than 50% of default time (MVAnalyse only took 30% of the usual time). The difference cache line split fix was minimal (only tested as chroma of 16x16 block so far).
To get the whole thing working I had to force MVPlane to produce aligned planes ( shifted the source pointer in the constructor by %16 pixel). Using SSE2 (port to xmm register with the source block accessing aligned 128bit (ref still 64 bit)) significantly slowed the SAD16 down :-( . I assume the access to mmx register is still full speed, while xmm is definitely on half speed. The cache line fixed 8 block is slightly faster(~1%) than default.
On the Q9300 the difference between dummy and default is still similar, but the fixed mmx version is even slower than default (I think that is because I have no fast version for the unaligned case). The simple SSE2 version is slightly faster than default. The fixed SSSE3 version, which uses a faster version for aligned blocks (the shift 0 instance) and palignr for the remaining cases is even faster (together with mmx fixed chroma). I haven't tried every combination yet, but every version which outputs the correct data is only faster slower <5% than default. Other modifications like commenting the dct code out in plane of blocks usually have at least the same effect.

So far I am not very impressed.

Dark Shikari
17th June 2008, 19:31
I tried it on my Pentium M and my Q9300, the results are quite different. The Pentium MThe Pentium M has such bad SSE2 support that x264 actually disables SSE2 code on it. Don't use it for testing of any SSE code.

To get the whole thing working I had to force MVPlane to produce aligned planes ( shifted the source pointer in the constructor by %16 pixel).You have to align to 64-byte boundaries, and use a 64-byte aligned stride. This makes the misalignment for each line of the source constant. 16 byte is not sufficient.

If you can't get SAD at least 20-30% faster, you didn't implement cacheline split correctly.

Manao
17th June 2008, 19:36
You just need a 64-byte aligned pitch, you don't need to align the pointer to 64-byte boundaries.

TSchniede
17th June 2008, 20:35
The Pentium M has such bad SSE2 support that x264 actually disables SSE2 code on it. Don't use it for testing of any SSE code.

You have to align to 64-byte boundaries, and use a 64-byte aligned stride. This makes the misalignment for each line of the source constant. 16 byte is not sufficient.

If you can't get SAD at least 20-30% faster, you didn't implement cacheline split correctly.

Ok, I wasn't planning on stopping there.
I thought the same, SSE2 is useless on the Pentium M (for performance).
I know the code doesn't create exceptions due to misalignment => MOVDQA, so it should be reasonably aligned, but perhaps half or the like "works" too.

"My" mmx implementation is nearly 1:1 the same, so it might only be some shift issue and the missing part for aligned reference blocks. The SSSE3 version is somewhat different, because it's for 32 bit OS.

@Manao:
By default the planes are 8bit aligned by VC. The solution with the least changed code I could think of, was creating a slightly larger array (+16) and an extra pointer(inclusive new pointer array) to it while setting the currently used one to the first element with a ~15 aligned pointer and changing the destructor. Otherwise the point of (0,0) is not aligned and every block is aligned to that. To keep the differences to one spot (or virtually every access to the plane would be affected), so I sort of shifted the reference pointer. Other options might be better, but except the few additional pointer which are only used my the destructor and a few extra reserved bytes there is no additional change.

Manao
17th June 2008, 20:40
Use _aligned_malloc and _aligned_free instead of reinventing the wheel.

Dark Shikari
17th June 2008, 20:45
The way x264 does it is by keeping a set of pointers to the start of the malloced data (to free) and then re-aligning each of them for the actual pointers used in the program.

TSchniede
20th June 2008, 03:44
Dark Shikari, you were right. Some tests showed minor bugs, probably connected to some attempts to find the reason for missing scaling. Nevertheless I learned a lot, so this time I converted as little as possible and left key assumptions variable with macros. Since both MVTools and x264 are licenced under the GPL v2 it should create no problem, that I have rather adapted MVTools to x264 rather than reinvent it myself. The differences are fortunately minor - only the second parameter has to be switched with the third and obviously align the source planes.

Testing was done with Chroma set to dummy (see 8) as only mmx functions allow 8x8 and smaller blocks, so the performance is only limited by one variable. The tests are MVDegrain3 times.
These tests were done on 64Byte aligned plane arrays, 16 and 32 byte alignment helps, but the best case only speeds up to 93% (6 vs 0) on Core2, on Pentium M 98% difference. The dummy case shows how much the impact if the function on the whole time and how much the computation and jumps impact performance. It shows too, that the cache troublesdo impact the performance as the dummy functions perform identical on any alignment of the planes. The only changes to MVTools are on the alignment of the luma/chroma planes and on the PlaneOfBlocks SAD-function acces and of course the interface to the old SAD functions (the .asm and the .h). The "new" SAD functions are simply a copy of sad-a.asm and the 2 included asm files from x264 v880.
6 on luma and 3 on chroma is combined at 83% of the default for luma & chroma on Core2 (In that case the other parts of MVTolls take a smaller percentage of the combined time)

So this time my tests showed this:
0: Default_ISSE
1:x264_pixel_sad_16x16_mmxext
2:x264_pixel_sad_16x16_cache32_mmxext
3:x264_pixel_sad_16x16_cache64_mmxext
4:x264_pixel_sad_16x16_sse2
5:x264_pixel_sad_16x16_sse3
6:x264_pixel_sad_16x16_cache64_sse2
7:x264_pixel_sad_16x16_cache64_ssse3
8:dummy (returns 0)
9:dummy (similar to sse2 only minimal computation, umrolled, access always 16byte aligned)

Pentium4: (Dothan)
0:100%
1:100%
2:98%
3:95%
4:104%
5:-
6:98%
7:-
8:62%
9:80%

Core2 (Penryn) Singlethread:
0:100%
1:100%
2:92%
3:88%
4:96%
5:97%
6:85%
7:85%
8:56%
9:67%

Core2 multithreaded (4 - Q9300) SetMTMode2:
0:100%
1:100%
2:94%
3:92%
4:98%
5:98%
6:88%
7:62%
8:75%

Dark Shikari
20th June 2008, 03:53
That's pretty impressive: up to a 15% speed boost!

How about trying x264's 8x8 cacheline split variants?

TSchniede
20th June 2008, 06:11
I have included every exported function (I have only listed the 16x16 variants though, because most exist only as 16xY variants and comparisons between different block sizes are not comparable), For example 16x16 with the SSSE3 cache split code, there are no 8x8 or 8x16 variants, as far as I can tell, so i set the 64_mmxext variants for the color planes. I used all functions which produce single sad and are visible (cglobal) in all defined variants.
8x8 blocks have the disadvantage, that chroma is 4x8 or 4x4 which only exists in the default functions of MVTools and on the plain mmxext function. Everything SHOULD work right now and as far as possible the most applicable x264 function is chosen (if any exists).
I haven't modified the x264 assembler files because I still can't predict if that would degrade the performance (at best I can test it on my machines) and I wanted to make an update possible where only the new files had to be transfered and recompiled.

TSchniede
20th June 2008, 09:22
If anyone is curious....

My modified version can be acquired here mvtools-CLS-F.zip (http://stud3.tuwien.ac.at/~e9727008/mvtools-CLS-F.zip)

Please mind, that it is still beta.

used functions:
Beware that chroma for YV12 is half the block size and YUY2 has half width, so only 16x16 and 16x8 has a cache line depended function for both chroma & luma
as far as possible the same cache line optimization is used.
If a function doesn't exist for the requested block size, the default ISSE function is used.

SadXxY_iSSE with X and Y being anything with 16, 8 & 4

x264_pixel_sad_16x16_sse2
x264_pixel_sad_16x8_sse2
x264_pixel_sad_16x16_sse3
x264_pixel_sad_16x8_sse3
x264_pixel_sad_16x16_cache64_sse2
x264_pixel_sad_16x8_cache64_sse2
x264_pixel_sad_16x16_cache64_ssse3
x264_pixel_sad_16x8_cache64_ssse3

x264_pixel_sad_16x16_cache32_mmxext
x264_pixel_sad_16x8_cache32_mmxext
x264_pixel_sad_16x16_cache64_mmxext
x264_pixel_sad_16x8_cache64_mmxext
x264_pixel_sad_8x16_cache32_mmxext
x264_pixel_sad_8x8_cache32_mmxext
x264_pixel_sad_8x4_cache32_mmxext
x264_pixel_sad_8x16_cache64_mmxext
x264_pixel_sad_8x8_cache64_mmxext
x264_pixel_sad_8x4_cache64_mmxext

Fizick
20th June 2008, 22:41
TSchniede,
thanks for contribution (from Dark Shikari :))!
Please increment the version number to 1.9.5 or greater.

TSchniede
21st June 2008, 14:04
Ok,

So here is the somewhat cleaned version.

mvtools_1.9.5 (http://stud3.tuwien.ac.at/~e9727008/mvtools-v1.9.5.zip)

Differences to MVTools1.9.3:
added parameter sadx264 to MVAnalyse
modified the old SAD functions to work with the same interface as the ones of x264, which in turn made changes to PlaneOFBlocks necessary. MVPlane has now a longer array of planepointers -> the upper half is used to free the memory and both pitch and planepointer after adding padding is aligned to the alignment constant defined in MVInterface (64 now).
minor: DebugPrint can now be disabled in MVinterface - stdio outside #ifdef area. disabled annoying security warnings
The information which sad function should be used is transported via additional flags. For simpler function pointer definitions the copycode, Luma and Variance functions now all follow the XxY naming scheme. which also means the respective files are modified and Mvincrease and MVcompensate got modified as well. The documentation in English is up to date too.

Dark Shikari
21st June 2008, 15:09
You should probably just port the CPU detection code too while you're at it so that people don't have to select the SAD to use manually.

Fizick
21st June 2008, 15:19
TSchniede,
OK, will try merge my betas with your :)

TSchniede
21st June 2008, 16:11
I'll to port the CPU detection code, a manual override probably won't hurt though.

Fizick
21st June 2008, 18:06
Released public beta 1.9.5.1 - Merged all changes by TSchniede.
Almost not tested.

superuser
21st June 2008, 22:34
^ thnxs will soon give it a try :thumbup:

Fizick
22nd June 2008, 17:23
One man says me that some sadx264 modes (=7) does not work with overlap.

Boulder
22nd June 2008, 20:51
A quick test:

5000 frames of a simple MPEG2Source + MVDegrain2 script on my Q6750:


MPEG2Source("path\clip.d2v")
Denoise()

function denoise(clip c)
{
vbw1=MVAnalyse(c,isb=true,truemotion=true,delta=1,pel=2,chroma=false,blksize=8,idx=1,overlap=4,sadx264=3)
vfw1=MVAnalyse(c,isb=false,truemotion=true,delta=1,pel=2,chroma=false,blksize=8,idx=1,overlap=4,sadx264=3)
vbw2=MVAnalyse(c,isb=true,truemotion=true,delta=2,pel=2,chroma=false,blksize=8,idx=1,overlap=4,sadx264=3)
vfw2=MVAnalyse(c,isb=false,truemotion=true,delta=2,pel=2,chroma=false,blksize=8,idx=1,overlap=4,sadx264=3)
return MVDegrain2(c,vbw1,vfw1,vbw2,vfw2,thSAD=400,idx=1)
}

sadx264=0 : 0:20:19
sadx264=1 : 0:20:14
sadx264=3 : 0:19:07

A nice improvement, I'd say :) Too bad the higher modes are not available for blocksize 8.

TSchniede
23rd June 2008, 00:12
One man says me that some sadx264 modes (=7) does not work with overlap.

This is unfortunately true. The reason is simple: overlap obviously creates non-aligned source blocks, which effectively means that both source and reference are unaligned access. This would not be any real problem if the reason for the work-arounds didn't exist in the first place. Only the LLDQU and MMX work around can be done on unaligned source blocks. I don't expect real performance gain if data access is unaligned for both. 8 overlap on 16 width blocks work obviously with mmx without serious performance loss.

An additional version for 8 overlap on 16 width blocks might work with the SSE2 / SSSE3 workaround as there would only be alternating between aligned and known misalignment.

Dark Shikari
23rd June 2008, 00:20
This is unfortunately true. The reason is simple: overlap obviously creates non-aligned source blocks, which effectively means that both source and reference are unaligned access. This would not be any real problem if the reason for the work-arounds didn't exist in the first place. Only the LLDQU and MMX work around can be done on unaligned source blocks. I don't expect real performance gain if data access is unaligned for both. 8 overlap on 16 width blocks work obviously with mmx without serious performance loss.

An additional version for 8 overlap on 16 width blocks might work with the SSE2 / SSSE3 workaround as there would only be alternating between aligned and known misalignment.Why not load the source pixels for each block into an aligned buffer before doing the motion search on that block? I suspect that would save time even without x264's assembly (though only for width16 blocks and SSE code, of course).

akupenguin
23rd June 2008, 19:31
Too bad the higher modes are not available for blocksize 8.
Too bad we don't use width 16 registers to process width 8 blocks? :confused:

Boulder
23rd June 2008, 19:43
Too bad we don't use width 16 registers to process width 8 blocks? :confused:Oh, you'll have to explain this in laymen's terms..I'm merely a simple end user myself:)

akupenguin
23rd June 2008, 21:42
mmx can sad a 8byte block in 1 cycle. xmm can sad a 16byte block in 1 cycle. xmm doesn't help if your blocks are only 8 bytes.

TSchniede
24th June 2008, 01:03
mmx can sad a 8byte block in 1 cycle. xmm can sad a 16byte block in 1 cycle. xmm doesn't help if your blocks are only 8 bytes.

the MMX/SSE versions of the (spatial) sad calculations use the fact, that MMX has a special instruction, that can calculate the sad of the bytes in an mmx register this is 64 bit wide => 8 bytes or in layman'sv terms 8 luma pixel. SSE2 allows the same instruction to work on XMM registers, which have 128 bit.
So each line in a 16 pixel wide blocks the sad can be calculated with SSE2 in 1 instruction, or 2 with MMX.

Which means SSE2 is best for 16xY Blocks, MMX best for 8xY blocks. Other sizes take more time to get the data into the instruction.
On intel chips alignment in memory is very important, so using 2 aligned memory accesses instead of an unaligned one is faster -> hence the speedup by using the cache optimized sad functions imported from x264.

It is possible to load two lines into one xmm register, but then both operands of the sad analysis have to be registers, ie. load 2 lines into register 1, load the other 2 lines into register 2 the do the sad, which are 5 instructions opposed to load first line(16 pixel) then make sad with memory => which are 2 instructions.
In most cases the additional overhead for copying in the data and then getting the output makes SSE2 style sad calculations slower than mmx on 8 pixel wide sad functions.
Additional advantage of mmx is, that it is far easier to use on unaligned data

TSchniede
24th June 2008, 15:28
I have created a version which copies the source block to a aligned buffer area before doing the sad calculation, because this is reused a few times the overhead is small. The cache optimized functions get speed up (if they worked at all) with unaligned source blocks.

I still have to do a bit of testing and optimizing.
I an curious though, why has the buffer block for dct a minimum width of 16 (the pitch)?

yup
24th June 2008, 17:04
Hi all!
Simple question default value for searchparam for search=3?
yup.

TSchniede
24th June 2008, 18:27
Hi all!
Simple question default value for searchparam for search=3?
yup.

The default for searchparam is 2 for all search types.

TSchniede
24th June 2008, 18:41
This is the new version with buffered source block.
It is still based on 1.9.5.0

The only changes are a new constant in MVInterface and in PlaneOfBloacks (all code is controlled by the constant)

My tests show a slight variation on speed (<1%) if source blocks are aligned anyway (no overlap) as the overhead and the better locality almost cancel each other out. On overlapped blocks 'I measured up to 10% performance increase.

Dark Shikari
24th June 2008, 20:13
If you aren't already, have you tried using x264's mc.copy for creating the aligned source blocks from the source data? It's blazingly fast.

Also, note that when you're using an aligned source block you can probably take great advantage of the constant stride in the various assembly functions.

Another idea: DCT is slow as hell, and x264's SATD is quite fast. How about replacing the "dct" option with a SATD option instead, borrowing x264's SATD code? And while we're taking assembly from x264, you could try using x264's 6-tap upscaling filter for hpel; its extremely fast.

Boulder
24th June 2008, 20:29
It seems that the new version is somewhat slower on my E6750.

With blocksize 8 and overlap 4:

The first version
x264_sad=3 : 5.7 fps

New version
x264_sad=3 : 5.3 fps


With blocksize 8 and no overlapping:

The first version
x264_sad=3 : 18.4 fps

The new version
x264_sad=3 : 16.8 fps

TSchniede
24th June 2008, 21:12
Dark Shikari, I was looking into those things, but they are a bit more complicated than importing the sad functions, so that will take some time. Though I wasn't really looking for a dct replacement yet.

Boulder, interesting - on my Q9300 and on my Pentium M the performance is quite good. Quite a chunk of the additional overhead comes by copying, so by speeding that up, it should be better. I tried to switch between direct source block references and buffered based on the alignment, but that was even slower, as the overhead for that is definitely bigger than doing it always. If you are comparing Fizick's merge with my version, different compiler / Win-API versions can make a difference too (and I have no idea yet what additional tweaks were introduced).

Boulder
24th June 2008, 21:16
Yes, it's Fizick's merge that I tested. I could run the same tests on your first build tomorrow to verify if the difference still exists.

TSchniede
25th June 2008, 04:29
If you aren't already, have you tried using x264's mc.copy for creating the aligned source blocks from the source data? It's blazingly fast.

Also, note that when you're using an aligned source block you can probably take great advantage of the constant stride in the various assembly functions.

Another idea: DCT is slow as hell, and x264's SATD is quite fast. How about replacing the "dct" option with a SATD option instead, borrowing x264's SATD code? And while we're taking assembly from x264, you could try using x264's 6-tap upscaling filter for hpel; its extremely fast.
I tried the calling SSD & SATD. they are slow compared to naked SAD as was to expect (150% for SSD, 250% for SATD) if used as replacements to SAD (both luma & chroma).but blazingly fast compared to the current dct (which needs 6x the time of SATD for luma alone), but it is not really comparable this way. It has to be at least scaled to match default assumptions and probably weighted with spatial SAD. Nevertheless it promises to be a faster alternative. I haven't been able to verify the correctness of my implementation, as it obviously isn't equivalent to a current option. It "works" in the way as it doesn't crash and does "something".

I looked into mc-copy too, but it is far simpler than the other functions (as most optimizations are of no advantage in such a simple algorithm) and uses a different interface, so I think the best option is a reimplementation.

Soon most assembler functions will come from x264 :D

I am working on a optimized 4xY SAD function which takes advantage of the special source block properties too.
Right now it is faster working on a upscaled clip with 8x8 blocks compared to 4x4 with pel=2.

The hpel filter is something i have to try first as a stand alone avisynth filter to make sure it will work.

Dark Shikari
25th June 2008, 06:40
Have you tried using sad_x3/sad_x4? They're quite a bit faster than doing one SAD at a time.

SATD is a drop-in replacement for SAD (its used as such in x264 too, for --me tesa). It doesn't need scaling and there's a satd_x3/satd_x4 in pixel.c just to "fake" the multiple-SAD-call to allow it to be a drop-in replacement.

Terka
25th June 2008, 09:07
Hi guys,
its good to hear you are improving the mvtools speed. Would it be possible to port them to run using GPU like fft3dgpu?
Maybee this way the speedup gain will be greater?

Boulder
25th June 2008, 16:12
It seems that the new version is somewhat slower on my E6750.

With blocksize 8 and overlap 4:

The first version
x264_sad=3 : 5.7 fps

New version
x264_sad=3 : 5.3 fps


With blocksize 8 and no overlapping:

The first version
x264_sad=3 : 18.4 fps

The new version
x264_sad=3 : 16.8 fps
I tested the first build and here are the results:

blksize 8, overlap 4 : 5.2 fps
blksize 8, overlap 0 : 17.1 fps

Apparently Fizick's official 1.9.5.1 build is a tad bit faster.

Fizick
25th June 2008, 18:59
IMO, SSD or SATD is not useful.
But Hadamard (if i spelled it correctly) transform is interesting faster alternative to DCT.
I do not remember where I saw it, Mplayer or x264 :)

TSchniede
25th June 2008, 19:47
Hi guys,
its good to hear you are improving the mvtools speed. Would it be possible to port them to run using GPU like fft3dgpu?
Maybe this way the speedup gain will be greater?

Right now we are talking about making MVAnalyse faster. Unfortunately the algorithm is highly linear and you can't split the frame into smaller chunks without sacrificing quality. Even single threaded the memory footprint is huge. So I really doubt moving to a (relatively) memory constrained, low clock rate platform with many cores will help. A basic 8x8, overlap=0 MVDegrain3 on a PAL clip runs nearly real time with SetMTMode(2,4) on my Q9300 anyway even without the last tweaks. And we already use SSE to work on several pixel at once, so there is little which can still be done better in parallel. I have no real knowledge how well GPUs respond to huge amounts of conditional code and synchronization, but it doesn't seem really plausible.

TSchniede
25th June 2008, 19:56
IMO, SSD or SATD is not useful.
But Hadamard (if i spelled it correctly) transform is interesting faster alternative to DCT.
I do not remember where I saw it, Mplayer or x264 :)

You are unfortunately right. In the current code SATD seem to work inverse to SAD, meaning the best "SAD" is on the worst case scenario - the scene change. Currently I was investigating how Hadamard is supposed to work. I can't say it something is working as expected / useful, if I don't know what it should do in the first place.

Dark Shikari
25th June 2008, 21:08
IMO, SSD or SATD is not useful.
But Hadamard (if i spelled it correctly) transform is interesting faster alternative to DCT.SATD is the Hadamard transform and is better than SAD because it doesn't fail miserably in the case of fades. Its a far faster alternative to the DCT.

TSchniede
26th June 2008, 00:05
SATD is the Hadamard transform and is better than SAD because it doesn't fail miserably in the case of fades. Its a far faster alternative to the DCT.

I think i have found my previous error. I had forgotten a debug instruction AND SATD triggered a lot of scene changes. It is definitely far more sensitive to noise than SAD. So it is somewhat "sharper". SSD is even more extreme in that part.

On a blurred clip the picture is completely reversed - SATD is definitely superior to SAD.
On a grainy source -addgrain(20) the blurred SATD is virtually identical to SAD without blur(1). On fades only SATD produces decent quality. I suppose better prefiltering even works better. Besides it is a lot faster than default dct.

Terranigma
26th June 2008, 00:18
Have a compile with "SATD" that we can test?

TSchniede
26th June 2008, 01:52
Have a compile with "SATD" that we can test?

you can get my current version here (http://stud3.tuwien.ac.at/~e9727008/mvtools-v1.9.5.3.zip).
It is still based on 1.9.3. I think it's time to get Fizick version and update my Win API :rolleyes:

there are two ways to access the new functions:
sadx264: 8-12
dct: 5-10

for a description see the documentation.

I have only tested base functionality yet. And I haven't thoroughly looked for potential performance problems with dct mode. There are definitely some minor parts which will need some work if this is going to stay.

The changes are in SADFunctions.h and PlaneOfBlocks (and of course MVInterface & MVAnalyse) pixel*.asm were added

Terranigma
26th June 2008, 03:26
Thanks TSchniede.
Since you guys are borrowing code from x264, how difficult would it be to port over the hexagon and multi hexagon search algorithms?

TSchniede
26th June 2008, 04:05
Since you guys are borrowing code from x264, how difficult would it be to port over the hexagon and multi hexagon search algorithms?

I don't know. A quick glance over the source wasn't that informative :p

I don't know the algorithm yet so I can't say if it would be useful in the first place. It might be possible to add a hexagonal search function to MVTools along the other. There seems to be some similarity to the logarithmic search. But it would be more a reimplementation anyway. The other functions were small assembler functions where the possible interfaces were very limited. I have only adapted the interface of MVTools in calling them, (if necessary) as they are more complex than the default functions.

Manao
26th June 2008, 05:58
SATD is the Hadamard transform and is better than SAD because it doesn't fail miserably in the case of fadesI disagree, it still fails miserably on fades. Fades make motion vectors go crazy because of DC change, and SATD is as sensitive to that as SAD.

Manao
26th June 2008, 06:07
Adding hex is easy, though not necessarily very usefull.

Adding umh is probably an overkill. umh shines because it tries arbitrarily long vectors, but MVTools inherently hierarchical motion estimation already handles the long motion vectors quite well. So it might help a bit, but it'll mostly slow it down I think.

Terranigma
26th June 2008, 14:02
Adding umh is probably an overkill. umh shines because it tries arbitrarily long vectors, but MVTools inherently hierarchical motion estimation already handles the long motion vectors quite well. So it might help a bit, but it'll mostly slow it down I think.

More so than even the already implemented Exhaustive Search? :p

Manao
26th June 2008, 15:26
More so than even the already implemented Exhaustive Search? /Exhaustive is simpler to code, and has its theorical use for the developper, since it ensures to get the optimal vector. As a user, it's of course useless (and even harmful, since we want the motion vector, not the best vector according to a dumb algorithm)

MfA
26th June 2008, 17:04
Right now we are talking about making MVAnalyse faster. Unfortunately the algorithm is highly linear and you can't split the frame into smaller chunks without sacrificing quality.
Obviously to make good use of a GPU you have adapt your algorithm a bit ... the GPU is better suited to a situation where each pixel needs only local information, iterative refinement from block MVs to pixel MVs is something a GPU could do quite well for instance.

Fizick
26th June 2008, 17:27
I agree, that UMH is not needed for hierarhical search.
Exhaustive search is really non exhaustive :) but limited by radius (and I modified it to spiral).

TSchniede,
please use merged version 1.9.5.1 as a base to prevent mess!
what is the problem with API?

Terranigma
26th June 2008, 18:59
OK guys, but obviously there can be some improvements upon Diamond Search. Maybe something not too extreme like UMH, but something more useful than hex. Have you guys seen this (http://forum.doom9.org/showpost.php?p=1151980&postcount=86) post ?

Dark Shikari
26th June 2008, 19:02
Diamond isn't bad at all if you're doing hierarchical like MVTools does; I'm not sure exactly its method but look at Snow's iterative ME for an example of how diamond search can be surprisingly effective.

Hex would be better though and hardly much slower.

Terranigma
26th June 2008, 19:10
Hex would be better though and hardly much slower.

Well, I wasn't sure since Manao said it wasn't very useful.
You're the M.E. expert. What do you suggest? :D

Dark Shikari
26th June 2008, 19:14
Well, I wasn't sure since Manao said it wasn't very useful.
You're the M.E. expert. What do you suggest? :DI'm actually not much of an expert with iterative ME/hierarchical algorithms so Manao might be more familiar with the topic than I.

Manao
26th June 2008, 19:21
Diamond search in MVTools isn't the same as "dia" in x264. Whenever the diamond might stop, diagonals are checked, and if one improve the SAD cost, the diamond starts again (it's an idea taken from XviD's ME). The documentation also names it "Logarithmic" search, and there's a reason for it. It starts by doing a diamond of size "searchparam", then each time the diamond stops, the size is divided by two.

So, with default searchparam (2), it covers as much ground as "hex", though in a slightly different manner.

Terranigma
26th June 2008, 19:23
I'm actually not much of an expert with iterative ME/hierarchical algorithms so Manao might be more familiar with the topic than I.

smh. Oh well, I threw an idea out there in the hopes that we wouldn't happen to resort to such drastic methods, such as what Didée mentioned, and use the likes of photoshop as an option of last resort.....

g-force
26th June 2008, 19:44
Manao,

I have a feature request. Currently in MVCompensate:
If block SAD is above the thSAD, the block is bad, and we use source block instead of the compensated block.
Could you add a switch to make this possible:
If block SAD is above the thSAD, the block is bad, and we use Compensated block instead of the source block.

I know this may seem counter-intuitive, but I have an application where this would be very handy.

thanks,

-G

TSchniede
27th June 2008, 02:35
I agree, that UMH is not needed for hierarhical search.
Exhaustive search is really non exhaustive :) but limited by radius (and I modified it to spiral).

TSchniede,
please use merged version 1.9.5.1 as a base to prevent mess!
what is the problem with API?
I merged my code with version 1.9.5.1. It is available here (http://stud3.tuwien.ac.at/~e9727008/mvtools-v1.9.5.4.zip).
It seems your selection code for 32x16 blocks got left out in PlaneOfBlocks by your merge.
I added the autodetection Dark Shikari requested. I tried adding the mc-copy, but in my tests it was as fast as default at best, so it is deactivated right now.

Boulder mentioned performance problems with my build, so I updated the VS2005 default WinAPI to 2008 and activated all performance options, it seems to be equal to your builds now.

Exhaustive search might be improved for 4xY blocks with SSSE4.1 - MPSADBW.

I was considering a few modifications to the hierarchy algorithm. As 4xY blocks are clearly slower than the larger ones, it seems advantageous to do a divide, but do a last search with the smaller blocks, that should be very close to the result of a native smaller block search.
Right now a search with 8x8 blocks, pel=1 on a 2x up sized clip is faster than a 4x4 blocks, pel=2 search.

Dark Shikari
27th June 2008, 02:38
Exhaustive search might be improved for 4xY blocks with SSSE4.1 - MPSADBW.SEA is much faster. MPSADBW is only about 20% faster than 8 cacheline SADs alone for unaligned 16x16 blocks, for example. SEA is about 7 times faster.

g-force
27th June 2008, 05:23
Another feature request: thSADC for MVCompensate.

thanks,

-G

akupenguin
27th June 2008, 08:54
Right now a search with 8x8 blocks, pel=1 on a 2x up sized clip is faster than a 4x4 blocks, pel=2 search.
That's weird. x264's width4 SAD is the same speed as the width8 SAD. So doubling the width of both the frame and the block shouldn't affect speed (aside from cache pressure), but doubling the height should make it slower.

TSchniede
27th June 2008, 14:17
That's weird. x264's width4 SAD is the same speed as the width8 SAD. So doubling the width of both the frame and the block shouldn't affect speed (aside from cache pressure), but doubling the height should make it slower.

I think part of that is the implementation of the 2xY SAD functions

ficofico
27th June 2008, 22:39
I use mvtool for denoising and to double framerate of smartphone videos...... for doubling framerate I use I script like:

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

but i see artifact in most of my videos....... How can I use mvtool for doubling framerate at " top of the possibilities" of this great tool? I've tried pel=4, but i cannot see difference with pel=2....... it's better if I use mvflowfps2?

TSchniede
28th June 2008, 08:03
So this time I improved the internal 2xY SAD function (avoided one push & pop and switched half of the segment register reads with regular ones - 8% faster).
After a good idea I added a optimized version which avoided most reg->mmx moves and used a new fact(1.9.3.2) - the aligned source block buffer is continuous (pitch = blockwidth), so only one read is needed for that. This resulted in an other 8% gain of MVDegrain3 with block=8 on YUY2, the gain with YV12 is less.
Since the second version is clearly faster, it is now the only one used. The Source contains both though.

You can get it here (http://stud3.tuwien.ac.at/~e9727008/mvtools-v1.9.5.5.zip).

So I suppose that should solve the 4xY block issue.

Undead Sega
28th June 2008, 11:06
To Manao,

MVTools is an excellent piece of work! i use it for motion compensation deinterlacing and results look great!

but may i ask, what is the possibilities of having MVTools ported to the GPU?

TSchniede
28th June 2008, 17:47
To Manao,

MVTools is an excellent piece of work! i use it for motion compensation deinterlacing and results look great!

but may i ask, what is the possibilities of having MVTools ported to the GPU?

like I replied to Terka here (http://forum.doom9.org/showthread.php?p=1152367#post1152367)
and MfA replied here (http://forum.doom9.org/showthread.php?p=1152648#post1152648), a port to the GPU will only get any performance gain if either the GPU is ridiculously faster than the CPU or if a completely different approach to motion estimation is used.
MVTools estimates the motion by interpolating the estemated motion based on a reduced version (the hierarchical part) and on the direct neighbor blocks - the up and left blocks, which have been calculated at this point. This means each block is in part dependent on every other block in the whole frame, because this is repeated down to a single line of blocks.
So the only useful parallel part is doing several frames in parallel, but you will never be able to do 50+ frames like that, it needs too much RAM (try SetMTMode(2,20) and you will always need far more than 2GB memory... then image using 100+ threads...)

Terranigma
28th June 2008, 19:02
TSchniede, any chance you could perhaps update MVDenoise with important features such as overlap support, allow use of index clip, limit, thSADC, & pelclip? =P

Fizick
28th June 2008, 20:06
Terranigma,
like TSchniede answered instead of Manao, I may answer instead of TSchniede :) : No.
1. why rename degrain (or have two similar functions)?
2. Mvdenoise was faster in past when it used compensated frames inplace. Now it is obsoleted and may be simply removed.
3. TSchniede is great coder. Do not impede him to optimize the code :)

Terranigma
28th June 2008, 20:11
Mvdenoise was faster in past when it used compensated frames inplace. Now it is obsoleted and may be simply removed.


So, are you going to remove it?

Fizick
28th June 2008, 20:44
Terranigma
As you ask, No, it will not be removed for compatibility with old scripts. :)

TSchniede,
is SSE2 and overlap problem solved (e.g. by switching to original MVTools mode)?

Undead Sega
28th June 2008, 23:34
a port to the GPU will only get any performance gain if either the GPU is ridiculously faster than the CPU or if a completely different approach to motion estimation is used.

well i dont want to use the features of a GPU, but use the GPU as a processor, due to the many more transistors it contains, thus making the filter take advantage of it, as in speed wise and not let the CPU do the handling as already proved, it needs to be faster/powerful to gain a faster fps, do it is definately worth a try for a GPU.

my question has yet still not been answered. Can it be ported?

Dark Shikari
28th June 2008, 23:39
wbut use the GPU as a processor, due to the many more transistors it containsGPUs don't generally contain larger numbers of transistors than modern CPUs.

Undead Sega
28th June 2008, 23:52
im sure they do, thats why some consider GPU render over CPU rendering, and there was even a chart showing the FPS differences (i cant find it anymore at the moment). and think of the Gefore 8 series :D

TSchniede
29th June 2008, 00:05
TSchniede,
is SSE2 and overlap problem solved (e.g. by switching to original MVTools mode)?

Yes it should be solved since 1.9.5.2. I used the solution Dark Shikari suggested (I buffered the source block in a aligned area before calling PseudoEPZSearch (see ALIGN_SOURCEBLOCK regions), so each of the SAD calls uses the same source data. In most cases the cost is compensated with the better cache performance and in the case of the new 2xY SAD only one load is needed instead of 2 or 4.

One thing still bugs me: 4xY blocks are ~7% slower than 8xY blocks, at least on my Intel systems. I think the cache split issue might be the cause here. I only affects 4xY(2xY) Blocks, 8xY blocks don't benefit from up sizing to 16xY blocks(that would slow it down by 14%).:confused:

kandrey89
29th June 2008, 00:19
GPUs don't generally contain larger numbers of transistors than modern CPUs.

That's not exactly true.

Although the number of transistors is comparably equal, because of the manufacturing process, GPUs tend to have more transistors than CPUs.

CPU - 0.731 billion transistors
http://www.anandtech.com/cpuchipsets/intel/showdoc.aspx?i=3102&p=2

GPU - 1.4 billion transistors
http://enthusiast.hardocp.com/article.html?art=MTUxOCwxLCxoZW50aHVzaWFzdA==

Both are relatively new and real products to be released this year.

Dark Shikari
29th June 2008, 00:20
im sure they do, thats why some consider GPU render over CPU rendering, and there was even a chart showing the FPS differences (i cant find it anymore at the moment). and think of the Gefore 8 series :DYou don't need more transistors to be faster at a specific task. The number of transistors is just a function of die size and the process used.CPU - 0.731 billion transistors
http://www.anandtech.com/cpuchipsets/intel/showdoc.aspx?i=3102&p=2

GPU - 1.4 billion transistors
http://enthusiast.hardocp.com/article.html?art=MTUxOCwxLCxoZW50aHVzaWFzdA==

Both are relatively new and real products to be released this year.A better comparison would probably be the Octocore Nehalem, as that would be an example of a "top of the line" equivalent to nVidia's offering. Being 8 cores, it would have twice the transistors as the 4 core version.

Also note that a very large amount of space on modern CPUs is taken up by cache, which graphics chips have very little of (which can be an absolute nightmare when trying to program them to do anything efficiently).

TSchniede
29th June 2008, 00:33
im sure they do, thats why some consider GPU render over CPU rendering, and there was even a chart showing the FPS differences (i cant find it anymore at the moment). and think of the Gefore 8 series :D
This is a classical comparison of two different things.
Take the newest AMD GPU - it has ~2x the transistor count (as Penryn), but as I stated before it is completely different to my CPU (see sig).
The RV770 has 800 "cores" running on 750MHz compared to my 4 cores at 3GHz. Yet on an algorithm like mvtools uses nearly only the 750MHz vs. 3GHz counts. Even though the memory bandwidth is higher, we will run out of memory AND memory bandwidth far before we compute 16 frames in parallel - and this is when both should about equal in performance. Not to mention that the architecture even of the new GPU cores is not optimized for complex conditional code. Either the parallel brute force approach waste or the branch mis prediction penalty must be enormous (and I am not certain the huge amount of "cores" could work with branches in the first place, IMHO that is restricted to the shader part, which is only 4 "cores". And that doesn't include performance loss due to memory latency. A geed deal of the CPU core is only dedicated to logic / buffers only to prevent / reduce performance loss, which CAN be far higher than 99%!

Something like blur() or sharpen on the other hand will work ridiculously fast (only local data is needed, so every pixel can be computed in parallel)

kandrey89
29th June 2008, 00:33
You don't need more transistors to be faster at a specific task. The number of transistors is just a function of die size and the process used.A better comparison would probably be the Octocore Nehalem, as that would be an example of a "top of the line" equivalent to nVidia's offering. Being 8 cores, it would have twice the transistors as the 4 core version.

Also note that a very large amount of space on modern CPUs is taken up by cache, which graphics chips have very little of (which can be an absolute nightmare when trying to program them to do anything efficiently).

True, then there is a discussion about floating point on GPUs and integers on CPUs.
However, Nehalem Octo-Core is going to be released in late 2009, so don't compare that with the now releasing 9800GTX+

talen9
29th June 2008, 10:23
True, then there is a discussion about floating point on GPUs and integers on CPUs.
However, Nehalem Octo-Core is going to be released in late 2009, so don't compare that with the now releasing 9800GTX+

That said, I think that's a total waste of time to start programming GPU-optimized MVTools when only in a few months technology enhancements will make it obsolete (= slower than the CPU-optimized one) ... the porting could very well be not completed by that time :rolleyes:

Boulder
30th June 2008, 03:57
I tested the first build and here are the results:

blksize 8, overlap 4 : 5.2 fps
blksize 8, overlap 0 : 17.1 fps

Apparently Fizick's official 1.9.5.1 build is a tad bit faster.Fizick's build is still faster than v1.9.5.5 on my computer.

blksize 8, overlap 0, x264_sad=3 : 18.4 fps (Fizick) vs. 17.9 fps (v1.9.5.5).

Dark Shikari
30th June 2008, 04:03
Fizick's build is still faster than v1.9.5.5 on my computer.

blksize 8, overlap 0, x264_sad=3 : 18.4 fps (Fizick) vs. 17.9 fps (v1.9.5.5).What CPU are you using?

Boulder
30th June 2008, 06:41
What CPU are you using?Intel Core2Duo, E6750.

TSchniede
2nd July 2008, 01:06
I did some profiling and improved MVAnalyse a bit.
I added Overlap_2xY_mmx (virtually no difference, mostly for symmetry). I optimized my Sad2x2_iSSE_T a bit (very minor improvement)
The things that did bring an improvement were: CheckMV2 - removed all checks except IsVectorOK(), as the are virtually never used and create a lot of work themselves. I made the LumaSAD prioritize standard spatial SAD. This two things brought up to 10% improvement (quite uniform on Pentium M), 5-10% on Core2. Smaller block sized benefit more. Dct (I tried dct=7) halves the benefit.

Further improvement should be more difficult, as the very frequent GetAbsolutePointer is now one of the most time consuming operations together with GetRefBlock and of course the obvious CheckMV2 / CheckMV. On 2x2 blocks I found the jump penalty of the function sometimes larger than the SAD calculation itself.

Anyway here is the link (http://stud3.tuwien.ac.at/~e9727008/mvtools-v1.9.5.6.zip) to the Source & dll.

Boulder, until both Fizick and me use the same compiler (version & options) the performance between our builds will always be different.

Fizick
2nd July 2008, 18:08
i tried to rebuilt v 1.9.5.5, but pixel-a.asm is not compiled with NASM: error in x264_pixel_ads_mvs - short jge jump is out of range.
should replace it to jl, jmp pair

.loopi0:
add esi, 8
cmp esi, edi
jl .loopi ; fix short jump for nasm (Fizick)
jmp .end
.loopi:



UPDATE:
jge NEAR .end works fine too.

Manao
2nd July 2008, 18:10
You should use yasm, it automatically computes proper jump sizes (nasm should to, but is (was?) buggy)

akupenguin
3rd July 2008, 13:13
Further improvement should be more difficult, as the very frequent GetAbsolutePointer is now one of the most time consuming operations together with GetRefBlock and of course the obvious CheckMV2 / CheckMV.
Separate fullpel from subpel search. Fullpel GetAbsolutePointer or GetRefBlock should be just imul,add. Subpel should at least have constant shift and preferrably optimize-away most of the plane selections (e.g. derive one plane index by adding a constant to the previous, or know that opposing neighbors in a halfpel diamond have the same plane).
Don't keep track of both bestMV.sad and nMinCost during the search; you can derive one from the other when it's done.
Factor IsVectorOK out of a single CheckMV and into a higher level loop that checks several nearby mvs after once determining they're all valid.
I place a low value on reducing number of sads; x264 unconditionally checks all 4 points of the diamond because that was faster than checking only some of them dependent on previous direction (also has to do with multisad).

TSchniede
3rd July 2008, 17:14
Separate fullpel from subpel search. Fullpel GetAbsolutePointer or GetRefBlock should be just imul,add. Subpel should at least have constant shift and preferrably optimize-away most of the plane selections (e.g. derive one plane index by adding a constant to the previous, or know that opposing neighbors in a halfpel diamond have the same plane).
Don't keep track of both bestMV.sad and nMinCost during the search; you can derive one from the other when it's done.
Factor IsVectorOK out of a single CheckMV and into a higher level loop that checks several nearby mvs after once determining they're all valid.
I place a low value on reducing number of sads; x264 unconditionally checks all 4 points of the diamond because that was faster than checking only some of them dependent on previous direction (also has to do with multisad).

akupenguin, I think you are right, repeated "complex" operations AND a lot of conditional code which could possibly be done at a higher point in call graph is a bad idea if it is executed a few thousand times each frame. For example removing a lot of condition checks in CheckMV2 brought 5-15% performance, as they are only very rare to remove any work. Most of those examples seem a good idea, though I am not sure that they are all beneficial/feasible for MVTools. I planned to do more profiling and changes to the algorithm anyway (I had looked into other search patterns and "better" ways to do motion searches, but it seems we have eliminated most "useless" sad checks already. So there isn't much untapped potential left. Improving processor usage has more potential (though some solutions might generate too much code - for example 2xY SAD checks loose more time due to jumps than functional code)

Boulder
3rd July 2008, 17:24
akupenguin, I think you are right, repeated "complex" operations AND a lot of conditional code which could possibly be done at a higher point in call graph is a bad idea if it is executed a few thousand times each frame. For example removing a lot of condition checks in CheckMV2 brought 5-15% performance, as they are only very rare to remove any work. Most of those examples seem a good idea, though I am not sure that they are all beneficial/feasible for MVTools. I planned to do more profiling and changes to the algorithm anyway (I had looked into other search patterns and "better" ways to do motion searches, but it seems we have eliminated most "useless" sad checks already. So there isn't much untapped potential left. Improving processor usage has more potential (though some solutions might generate too much code - for example 2xY SAD checks loose more time due to jumps than functional code)Is there any way to implement any sort of multithreading inside MVTools? My tests with SetMTMode have been quite unstable.

Dark Shikari
3rd July 2008, 17:34
Is there any way to implement any sort of multithreading inside MVTools? My tests with SetMTMode have been quite unstable.Frame-based threading, x264-style, shouldn't be too difficult to implement.

Fizick
3rd July 2008, 21:38
I succesfully compiled v1.9.5.7 (not tested) specially for Boulder :)
tiny changes:
Fixed Overlap_2xY_mmx
Added (incomplete?) list of used projects to doc.

TSchniede
3rd July 2008, 23:40
Frame-based threading, x264-style, shouldn't be too difficult to implement.

Frame based is frankly the only useful option, as the data in a frame itself is too linear dependent. But SetMTMode(2) does work and should be virtually the same as doing it inside MVTools. It might be less erratic, but even that isn't guaranteed.

Revgen
4th July 2008, 06:29
^I've yet to successfully encode anything using SetMTmode and MCBob using the newer MVTools. It always crashes while in progress.

Any increase in stability would be welcome.

josey_wells
4th July 2008, 14:26
With regards to SetMTmode, I have been using the following for months to encode my DVD collection with Elecard Converter Studio with no crashes:

1. AviSynth 2.5.7.5
2. BZColorspace(My function which capability was rolled into ColorMatrix 2.3 by Neuron)
3. MVTools V1.9.1(My modified function with large rewrite in MVDegrain functions mostly reordering of code)
4. TDEINT V1.1
5. TIVTC V1.0.5
6. TMM V1.0

Albeit I did fix some compiler warnings and recompile each of these in VS2008 for my use.

I have not looked at the new MVTools yet since when I try to convert the project to VS2008 it gives me an error because of a custom YASM build rule.

Is the stability problem with regards to any time using SetMTMode or only with SetMTMode and MVTools?

I can provide DLL's of compilied files to trace down stability where needed.

TSchniede
4th July 2008, 15:12
Is it possible to get a bit more specific information?
I mean: which version works and which doesn't AND which non-default options are set?
Does it "only" apply to MVDegrain3, does it only apply with the x264 SAD functions?
(It is difficult to find a bug if it could possibly be in the whole program and a fast way to reproduce would be nice too)

josey_wells, did you make adjustments outside of MVDegrain, like PlaneOfBlocks?

josey_wells
4th July 2008, 15:58
Yes, I made changes outside MVDegrain. Post #640 of this thread contains the last source code with the modifications I made.

I am looking forward to having a faster MVtools since I consider it a citical element during my conversions.

Boulder
4th July 2008, 20:06
Here are my results compared with Fizick's latest build:

Blocksize 8, overlap 0 (either automatic or sadx264=3):

Fizick's original (no sadx264 at all) : 17.1 fps
MVTools v1.9.5.1 : 18.4 fps
MVTools v1.9.5.5 : 17.9 fps
MVTools v1.9.5.6 : 16.8 fps
MVTools v1.9.5.7 : 18.9 fps


Blocksize 8, overlap 4:

Fizick's original (no sadx264 at all) : 5.2 fps
MVTools v1.9.5.1 : 5.7 fps
MVTools v1.9.5.5 : 5.7 fps
MVTools v1.9.5.6 : 5.3 fps
MVTools v1.9.5.7 : 6.2 fps

Quite a nice speedup, thanks Fizick and TSchniede (along with those who have helped without actually coding) :)

In my opinion, internal multithreading in MVTools would be better than relying on SetMTMode. Besides, we haven't seen an up-to-date MT-capable Avisynth build in a long time now. But how would multithreading be implemented as there are usually many MVAnalyse calls etc?

TSchniede
5th July 2008, 04:40
Yes, I made changes outside MVDegrain. Post #640 of this thread contains the last source code with the modifications I made.

I only found one rar file here (http://forum.doom9.org/showthread.php?p=1094076#post1094076) which only contained the binary dll and no source.

josey_wells
5th July 2008, 15:37
Sorry, here is the source files. I don't have a changelist anymore since when my server died, I rechecked the code into source control but lost the changelists.

Hopefully, you can diff against your code and find change areas.

IMO multithreading belongs in AviSynth since writing multithreaded code is non-trivial and if done in the base project is an unecessary burden on all the filter writers.

TSchniede
5th July 2008, 17:06
Thanks josey_wells. I'll assume that the problem was introduced between 1.9.1 and 1.9.5.7.

Fizick
5th July 2008, 20:48
there is no problem until Revgen or somebody else will provide more detailed report (with versions).

Revgen
6th July 2008, 03:26
there is no problem until Revgen or somebody else will provide more detailed report (with versions).

The version BTW was 1.9.2.0. And it was awhile ago. The time in which it would crash was never the same, so it wasn't like there was a certain frame causing it.

The script was basically.

SetMTMode(mode=2,threads=4)
avisource("mysource.avi")
converttoyv12(interlaced=true)
mcbob()

Can you give me a version with a debugging feature? TSP used to give me a special version of his SetMTMode that would write a debug report to a .txt file everytime it was operated. Whenever something weird happened, he'd look at the debug report and usually he found out what was wrong.

Underground78
8th July 2008, 20:39
Just out of curiosity, is there a way to distinguish the "created" frames from the "real" ones when using MVFlowFps ?

josey_wells
9th July 2008, 02:27
Here is a VS2008 version for everyone to try. This version has taken the V1.9.5.7 from Fizick and integrated all the changes I made to the V1.9.1 version for stability problems.

Basically there are several places in the code where C++ errors can escape old compiler detections which affect stability in single threaded and especially multithreaded situations causing random crashes. For example delete x where should be delete [] x, etc.

I believe that all the new features will still work and will post the source code with changes later.

Please try with SetMTMode and report result.

By the way the VS2008 C++ express edition is free from Microsoft. It just lacks performance profiling, source control, and the advanced code analysis.

josey_wells
9th July 2008, 14:10
Here is the complete source code for MvTools V1.9.5.8 using VS2008 and YASM 0.71. The changes.txt file gives a list of all files changed.

IMO all these changes should be adopted into the baseline.

Comments welcome after the pending approval finished. Anyone know why this takes so long?

Terranigma
9th July 2008, 15:08
Is the archive with the 1.9.5.8. binary corrupt?
http://img141.imageshack.us/img141/9149/brokenzk2.png

Underground78
9th July 2008, 15:12
It seems to work for me (using 7-Zip) ...

josey_wells
9th July 2008, 15:17
That warning can be ignored. It means that the file was encrypted with the user information in it and then extracted on a machine where the user did not exists. However, the file is fine.

Fizick
9th July 2008, 20:09
josey_wells, thanks,
i will consider your changes in next week or two.
but generally i do not like to change the working code... :)

Undead Sega
12th July 2008, 15:41
i just dont understand, i think no one isnt really bothered to at least give a port a try to the GPU, because i know the mroe recent ones like the Geforce 8 and upwards is ever so powerful, and contains features like upscaling, deinterlacing, inverse telecine and pulldown correction, and surely those take up alot of memory.

MoComp deinterlacers such as MCBob, one of the best for us lot, takes forever and deems to be a thing to use for big projects, which is where porting the filter and plugins to a more dedicated processor to process the job. Unless, if the GPU itself has a deinterlacer itself, could it beat MCBob in both performace and quality wise?

foxyshadis
12th July 2008, 23:58
Unless you personally know enough to begin development of a GPU filter, especially the many restrictions and difficulties involved, and can provide assistance, don't keep pressing the issue. It just annoys the developers who only have so many resources and time.

Dark Shikari
13th July 2008, 00:14
i just dont understand, i think no one isnt really bothered to at least give a port a try to the GPU, because i know the mroe recent ones like the Geforce 8 and upwards is ever so powerful, and contains features like upscaling, deinterlacing, inverse telecine and pulldown correction, and surely those take up alot of memory.

MoComp deinterlacers such as MCBob, one of the best for us lot, takes forever and deems to be a thing to use for big projects, which is where porting the filter and plugins to a more dedicated processor to process the job. Unless, if the GPU itself has a deinterlacer itself, could it beat MCBob in both performace and quality wise?Patches are welcome if you want to spend a few months working full-time to try even writing a basic motion search for the GPU... :rolleyes:

CruNcher
14th July 2008, 12:15
My last tests showed that Nvidias GPU (8X) Deinterlacer is/was as good as Yadif (quality wise), tough that test was a while ago and it also was done when Nvidia changed the Deinterlacer in the Driver to a knew one that could compete with Yadif, could be that they have a much more powerfull one now implemented when releaseing the 9x respectively now the 200x series :) (ofcourse yadif didn't reach the 1080i 30>60p in realtime (Singlecore 1.8 Ghz Athlon64 Venice @ that time) what for the Nvidia GPU Deinterlacer was easy going (8800GT) useing Nvidias own PureVideo Mpeg-2 Decoder.

Didée
14th July 2008, 12:20
Out of curiosity, how do you manage to make sound-standing comparisons with/against a GPU deinterlacer? Capturing the output is a bit tricky ...

CruNcher
14th July 2008, 12:34
Quality was compared visualy useing drmpegs wonderfull test paterns http://www.w6rz.net/, HQV HD/SD and alot of Real Life Footage(before the driver update Nvidia was behind Yadif after it was on par with it in it's motion and quality behaviour), but anyway it was about the speed/visual percepted quality difference and ther Nvidia won hands on (balance, energy efficiency same visual quality).
Hehe try to capture it and you will get a Interlaced Picture i know that problem, maybe with Vista it's easier to capture it now and compare on a per pixel level :). Anyway soon we gonna see alot more of Pro(Con)sumer GPU stuff finaly :)

TSchniede
22nd July 2008, 15:48
The version BTW was 1.9.2.0. And it was awhile ago. The time in which it would crash was never the same, so it wasn't like there was a certain frame causing it.

The script was basically.

SetMTMode(mode=2,threads=4)
avisource("mysource.avi")
converttoyv12(interlaced=true)
mcbob()

Can you give me a version with a debugging feature? TSP used to give me a special version of his SetMTMode that would write a debug report to a .txt file everytime it was operated. Whenever something weird happened, he'd look at the debug report and usually he found out what was wrong.

is 1.9.2.0 the last working or the first crashing version?
is the input HD sized or smaller?
do you use this version (http://forum.doom9.org/showthread.php?p=1055264#post1055264)?
How do you call the Avisynth script, ie. from VirtualDub (or similar) or directly like in MeGUI?
Out of curiosity, Avisource works without glitches on your system with SetMTMode(2)

I'm working an a debug version, but reproducion the bug on my system is more helpful.

WorBry
22nd July 2008, 17:23
Not wishing to cross-post (or interrupt the flow of discussion), but perhaps my unanswered query (below) about the nature of MVFlowBlur might be better addressed in this thread.

http://forum.doom9.org/showpost.php?p=1161196&postcount=21

Revgen
23rd July 2008, 02:03
is 1.9.2.0 the last working or the first crashing version?
is the input HD sized or smaller?
do you use this version (http://forum.doom9.org/showthread.php?p=1055264#post1055264)?
How do you call the Avisynth script, ie. from VirtualDub (or similar) or directly like in MeGUI?
Out of curiosity, Avisource works without glitches on your system with SetMTMode(2)

I'm working an a debug version, but reproducion the bug on my system is more helpful.

Well, I don't have the original sources with me, so I can't reproduce it. I'm currently using Josey's version and have had no problems in SetMT so far, but I haven't done anything really long yet. Nothing over 1 hour anyway. So far his version works fine. Unfortunatley it only uses 2 of my 4 cores. So I still use 4 different scripts and assign each one to individual core using task manager for better speed.

Andrey /MAG/
23rd July 2008, 09:16
First of all: Thanx for subj and for making it better.

I use MVTools library for make movement's in movies more smoothly by changing frame rate by MVFlowFps.
I found that second parameter in SetMTMode before *Source is make affect overall performance.
For 2 core processors the better results gotten by threads=4, for 4 core - threads=6.

Example, that gives maximum performance and CPU load (for 4 core CPU):

SetMTMode(5,6)
DirectShowSource("VID-2D.avi", fps=23.98)

SetMTMode(2,4)
multi=2
num=FramerateNumerator(last)
den=FramerateDenominator(last)
backward_vec1 = MVAnalyse(isb = true, sadx264=0, blksize=16, pel=1, chroma=false, searchparam=1, idx = 1)
forward_vec1 = MVAnalyse(isb = false, sadx264=0, blksize=16, pel=1, chroma=false, searchparam=1, idx = 1)
last.MVFlowFps(backward_vec1,forward_vec1, num=multi*num, den=den, mask=0, idx=1)

This script can to process up to 1080p resolution clip in realtime (on-the-fly). I use Q6600 (2.4 GHz), AviSynth 2.5.7, MT 7.0, MVTools 1.9.5.7.

In case of 1080p clip it is nessesery to put line "SetMemoryMax(1024)" in the top of script. Otherwise I obtain instabillity in amount of used memory, then growing it's meaning and fall of CPU load.

TSchniede
23rd July 2008, 12:15
Example, that gives maximum performance and CPU load (for 4 core CPU):

SetMTMode(5,6)
DirectShowSource("VID-2D.avi", fps=23.98)

SetMTMode(2,4)
multi=2
num=FramerateNumerator(last)
den=FramerateDenominator(last)
backward_vec1 = MVAnalyse(isb = true, sadx264=0, blksize=16, pel=1, chroma=false, searchparam=1, idx = 1)
forward_vec1 = MVAnalyse(isb = false, sadx264=0, blksize=16, pel=1, chroma=false, searchparam=1, idx = 1)
last.MVFlowFps(backward_vec1,forward_vec1, num=multi*num, den=den, mask=0, idx=1)


one should add, that the first SetMTMode sets the number of threads.

Well, I don't have the original sources with me, so I can't reproduce it. I'm currently using Josey's version and have had no problems in SetMT so far, but I haven't done anything really long yet. Nothing over 1 hour anyway. So far his version works fine. Unfortunatley it only uses 2 of my 4 cores. So I still use 4 different scripts and assign each one to individual core using task manager for better speed.

This is somewhat puzzling, as most changes to Fizicks and my versions are minor, at least as far as mcbob is concerned.
It is mostly pointer related or to prevent a few compiler warnings which should not cause crashes anyway. I did a review with the diff of all versions since 1.8.x I could find (I don't have 1.9.1), but only found a minor bug in one of the copy templates, but those are not used by default. The only major difference of josey_wells versions is the copy instruction which are c-functions instead of mm-assember ones.

First experiments with deliberate mmx-floating point instructions confilcts showed far less obvious results than expected, so it could theoretically be related to that, as the time spent with mmx instructions has significantly grown (in that case however only the probbability to crash has changed).

josey_wells
23rd July 2008, 13:22
While it is true that a lot of the changes were pointer related for performance reasons and should have no changes to reliability. There were some changes to MVFrame which is the base to all of the MVfunctions. I have attached a document showing the diffs between two of the important areas for MVFrame. The first area is where the for loop bodies were being nullified because of a ; before the if. The second one has to do with the order of memory initialization/destruction.

I have been using this version of MVTools for several weeks now without a crash.

Also, this version is about 20% faster than V1.9.2 with TSchneide's integration of the x264 SAD functions. So thanks for that work. :)

TSchniede
23rd July 2008, 16:00
While it is true that a lot of the changes were pointer related for performance reasons and should have no changes to reliability. There were some changes to MVFrame which is the base to all of the MVfunctions. I have attached a document showing the diffs between two of the important areas for MVFrame. The first area is where the for loop bodies were being nullified because of a ; before the if. The second one has to do with the order of memory initialization/destruction.

I have been using this version of MVTools for several weeks now without a crash.

Also, this version is about 20% faster than V1.9.2 with TSchneide's integration of the x264 SAD functions. So thanks for that work. :)

I suppose you mean (your file was waiting for approval):
original (1.9.2):
for(int j=nFLN; (j>nNbFrames) && (iFLN->n != nFrameIdx); iFLN=iFLN->Prev(),j--);
if(iFLN->n==nFrameIdx)
GrowMVGroupOfFrames(j);
If I an not mistaken, then the if statement can never be true inside of the for loop as the condition of the for loop requires the negation of it. So IMHO the intended meanig would be:
int j;
for(j=nFLN; (j>nNbFrames) && (iFLN->n != nFrameIdx); iFLN=iFLN->Prev(),j--)
;
if(iFLN->n==nFrameIdx)
GrowMVGroupOfFrames(j); which is exactly what any version since 1.9.5 uses.
as for the memory initialization/destruction - I suppose you mean the try-catch block and the modified destructor. Shouldn't the "throw;" in the catch clause propagate the exception which is nowhere caught inside mvtools stop the script anyway?

squid_80
23rd July 2008, 16:50
That's not a for loop - it's a while loop in disguise. :D

TSchniede
23rd July 2008, 18:03
That's not a for loop - it's a while loop in disguise. :D

It is... then again, every for loop is a while loop in disguise :cool:

josey_wells
24th July 2008, 00:57
TSchniede you are absolutely correct about your statement on the for loop. That's what I get for modifying 20 files at one sitting even with 20 years of programming. :)

However, you have also inadvertenly hit on the instability in MVTools. When I changed the order of the code the if statement never got executed. If you look at the function containing the if statement there is no EnterCriticalSection corresponding to the LeaveCriticalSection. Thus when I changed the ordere of the code GrowMVGroupOfFrames was never executed which messes with all the memory pointers and would definetly cause random crashes if called like it could be in the original code.

I will fix this segment of code and post new source and will probably change the for to a while to make it more obvious also. :)

I may also take a stab at multithreading MVtools but I need to find object oriented classes I created a while ago to ease that task.

TSchniede
24th July 2008, 11:48
However, you have also inadvertenly hit on the instability in MVTools. When I changed the order of the code the if statement never got executed. If you look at the function containing the if statement there is no EnterCriticalSection corresponding to the LeaveCriticalSection. Thus when I changed the ordere of the code GrowMVGroupOfFrames was never executed which messes with all the memory pointers and would definetly cause random crashes if called like it could be in the original code.

I will fix this segment of code and post new source and will probably change the for to a while to make it more obvious also. :)

I may also take a stab at multithreading MVtools but I need to find object oriented classes I created a while ago to ease that task.

Thank you, one mystery solved. I should have been more careful, but I thought as the code "worked" in its original form with some compilers, there would be no bug, so I only looked for the right meaning.
The fist multithreading version didn't grow the list, so this didn't occur, but the tread scaling was lacking (this should explain Revgens problem). The first fixes used larger defaults or grew by large amounts, so the problem would only occur very seldom and the growing should be quite rare anyway - hence the long time it took to show.

TSchniede
24th July 2008, 12:41
josey_wells, if my doxygen view is correct, MVFrames::GetNewFrame is only called by MVFrames::GetFrame which hast the necessary EnterCriticalSection, and the corresponding LeaveCriticalSection is either there, or if new frames are created inside GetNewFrame.

josey_wells
24th July 2008, 13:08
TSchniede, unfortunately I have been really busy at work and have not had time to delve deeply into the code.

I want to get into MVframe and clean up the Critical Section logic. I found my object oriented classes to ease with all the multithreading. IMO critical section objects should be created as auto scope variables so that they are automatically cleaned up on exception or leaving routine etc.

Also, I want to look at the possibility of multi-threading MVTools itself but this may be more difficult.

josey_wells
28th July 2008, 00:49
I have looked at the code and fixed the for loops logic that TSchneide pointed out was incorrect. You were also correct that the critical section logic was ok.

I replaced the critical sections with autoscope variables which performed the enter and leave automatically which didn't make any difference speed wise, just cleaner code.

I tried to use MVtools on some blu-ray movies and kept getting random crashes when trying to use SetMTMode. I beleive that the crashes were in AviSynthMT and not MVTools. I also got crashes when commenting MVtools out of the script.

Since AviSynthMT seems to be abandoned. I am going to take a stab at multithreading MVDegrain2 since this seems to be the function using the most processor time in my script. I believe I can spin a thread each to process the Luma, ChromaU, and ChromaV components.

I will post test dll when I have something to test.

josey_wells
29th July 2008, 23:07
To those that are interested, here is a working mulithreaded MVDegrain2 capable mvtools. At the beginning when all 4 frames are brought in to be processed into an output frame, 4 threads are spun, 1 for each fetch. After that 3 threads are spun 1 each to process Luma, ChromaU, and ChromaV.

I get good CPU balancing on my Q6600 and am still in the process of tweaking the code before expanding to all the MVDegrain functions.

No changes to scripts are necessary and the SetMTMode is no longer needed in the script.

If you run into problems try using the multithreaded dll of AviSynth. I found that the latest 2.5.8 RC2 has some multithreading issues and returns frames with a refcount of 2 causing a crash from calls to env->NewVideoFrame(vi). This is not a problem in MVtools but in AviSynth.

josey_wells
30th July 2008, 03:31
Here is a version that multithreads all the MVDegrain functions.

If positive reaction to multithreaded versions then I will post source.

Ranguvar
30th July 2008, 03:39
Awesome work, josey! DGAVCDecode does not currently work with SetMTMode, so this is a blessing. Please, do continue :)

Zep
30th July 2008, 07:14
To those that are interested, here is a working mulithreaded MVDegrain2 capable mvtools. At the beginning when all 4 frames are brought in to be processed into an output frame, 4 threads are spun, 1 for each fetch. After that 3 threads are spun 1 each to process Luma, ChromaU, and ChromaV.

I get good CPU balancing on my Q6600 and am still in the process of tweaking the code before expanding to all the MVDegrain functions.

No changes to scripts are necessary and the SetMTMode is no longer needed in the script.

If you run into problems try using the multithreaded dll of AviSynth. I found that the latest 2.5.8 RC2 has some multithreading issues and returns frames with a refcount of 2 causing a crash from calls to env->NewVideoFrame(vi). This is not a problem in MVtools but in AviSynth.


awesome! thanks!

morsa
30th July 2008, 08:33
http://www.nvidia.com/object/cuda_home.html#state=detailsOpen;aid=e415e883-5349-4c9a-abb7-fefe294c5b08

http://www.cns.nyu.edu/pub/eero/simoncelli98c.pdf

May be this is useful for accelerating MVtools.

I took the link from Nvidia CUDA Zone

Delerue
30th July 2008, 18:46
Here is a version that multithreads all the MVDegrain functions.

If positive reaction to multithreaded versions then I will post source.

Is there any SS comparison between the most common denoise algorithms? Nvidia, for example, has a great denoise with its drive, and it's CPU cost zero. FFDShow idem, although it uses a lot of CPU. I'm telling this because I don't know if MVTools's denoise justify its heavy CPU usage.

talen9
30th July 2008, 18:50
Have a look at one of the sticky threads (http://forum.doom9.org/showthread.php?t=51181) in this very same forum.

Most recent posts (which talk about MVDegrain too) start from page 6 :)

Fizick
30th July 2008, 19:52
josey_wells,
unfortunatly i had not much time (at vacation) and still do not finish analysing your previous sources (in particular, MVDegrain).
IMO, rest (of revised) code changes are not important, and I do not see much reason to merge them immediately, sorry. They are variant of implementation with same peformance (and seems, stability).
Compiler warning is Warning, not an error. :)

Your new contribution with native multithreading is seems as real progress! (but I do not know much about threads and do not use them, so waiting for user reports).

P.S.: You must post a new source codes (under GPL) independently of our reaction. ;) I ask for it.

Boulder
30th July 2008, 21:11
I'll test the new multithreaded build as soon as I have some spare time, maybe on Friday or even tomorrow.

IanB
31st July 2008, 00:39
If you run into problems try using the multithreaded dll of AviSynth. I found that the latest 2.5.8 RC2 has some multithreading issues and returns frames with a refcount of 2 causing a crash from calls to env->NewVideoFrame(vi). This is not a problem in MVtools but in AviSynth.Yes Avisynth is not thread safe! You must use one of TSP's MT versions.

Have a look at the Pipeline filter in the Dev forum for doing the frame prefetch. Also watch for out of order hits at source filters, the time penalty for forcing a seek can be great.

Delerue
31st July 2008, 02:11
Have a look at one of the sticky threads (http://forum.doom9.org/showthread.php?t=51181) in this very same forum.

Most recent posts (which talk about MVDegrain too) start from page 6 :)

I'll take a look. Thanks a lot.

morsa
31st July 2008, 08:47
I can't tell exactly how, but this new code keeps crashing my scripts.

Intel QuadCore system

josey_wells
31st July 2008, 13:48
OK, I have been spending quite a long time tracing down instability in MVTools. Basically, AviSynth is pretty smart so if I run the following script under the following two conditions as follows:

backward_vec2=c.MVAnalyse(isb=true, delta=2, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
backward_vec1=c.MVAnalyse(isb=true, delta=1, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
forward_vec1 =c.MVAnalyse(isb=false, delta=1, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
forward_vec2 =c.MVAnalyse(isb=false, delta=2, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
return c.MVDegrain2(backward_vec1, forward_vec1, backward_vec2, forward_vec2, thSAD=iTHSAD, idx=iIdx1)

Condition 1:
Comment out the MVDegrain2 line.
1. the 4 constructors for MVAnalyse are called
3. teh 4 destructors for MVAnalyze are called.

Condition 2:
1. The 4 constructors for MVAnalyse are called in order
2. The constuctor for MVDegrain2 is called
3. The GetFrame function for MVDegrain2 is called
4. The GetFrame functions for MVAnalyze are called in the order that the clips are referenced in MVDegrain2

So it is obvious now that AviSynth does not evaluate a script line until the output is referenced.

The instability in MVTools comes from the fact that the GetFrame functions in MVDegrain2 sometimes complete before the MVAnalyze function producing the result finishes. Then a PVideoFrame function creates an Assert.

This shouldn't happen and I am trying to figure out why MVDegrain is continuing to process without the referenced frames being complete.

I get the same results whether I let MVTools run single or multi-threaded just takes longer in one vs the other.

Boulder
31st July 2008, 17:48
While you're all digging the MVTools code, do you see any reason why MVAnalyse doesn't usually detect motion near the borders of the frame (at least according to MVShow)? I've compensated for this by adding 16-pixel borders on each side in my script before any MVTools operations and then removed them afterwards, but this is, of course, a suboptimal approach.

josey_wells
31st July 2008, 22:19
Instead of sounding stupid and ramblinh, let me just say that I am working on a version of mvtools that works with AviSynth V2.5.8 RC3 and is multithreaded for the degrain functions.

I have a version that is working but want to put it through more testing as well as consolidate some code into common base classes.

I beleive I have most of the concurrecy issues solved and will post dll for test soon.

TSchniede
31st July 2008, 23:06
While you're all digging the MVTools code, do you see any reason why MVAnalyse doesn't usually detect motion near the borders of the frame (at least according to MVShow)?
This should be because of the min/max values of movement which IMO prevents movement where the compensated block in the reference frame lies (partially) outside the clip area (I haven't checked the details yet).

Gavino
31st July 2008, 23:45
Condition 1:
Comment out the MVDegrain2 line.
1. the 4 constructors for MVAnalyse are called
3. teh 4 destructors for MVAnalyze are called.

Condition 2:
1. The 4 constructors for MVAnalyse are called in order
2. The constuctor for MVDegrain2 is called
3. The GetFrame function for MVDegrain2 is called
4. The GetFrame functions for MVAnalyze are called in the order that the clips are referenced in MVDegrain2

So it is obvious now that AviSynth does not evaluate a script line until the output is referenced.
I don't see how you reach this conclusion and in fact I'm pretty sure this is false. Each statement is evaluated in order, causing the associated constructor to be called (whether the result is ever used or not). Then the GetFrame of the script result is called, which in turn calls GetFrame on its predecessor(s) in the filter chain, and so on. Filters not feeding into the final result will not have GetFrame called, but their constructors will have been called.

TSchniede
31st July 2008, 23:55
I have tried to implement the modifications mentioned by akupenguin here (http://forum.doom9.org/showthread.php?p=1155199#post1155199), although most only share the same idea. I got imprevements of about 15% on 8x8 blocks (Pentium M). Unfortunately that significantly reduces the readability of the code and slightly breaks the object orientation (the boost comes from shifting parts of the code of the called functions into the calling functions, even across object boundaries, which allowed to cut out redundant calculations). I still have to check performance on my other platforms, but first tests have shown at least some boost.

I have tried implementing a hex search (hexagonal pattern instead of cross/box for length >=2). It is a bit faster than diamond (less search points), but can only find matches for frames with good matches. I haven't found enough information on UMH yet.

Mutant_Fred
1st August 2008, 01:56
Hello all,

I am experiencing some crashes using MVFlowFps, I don't know if I am the only one.
Actually I have dug down quite deeply into the code, and reproduced all the circumstances in debug mode in Visual C++. So I know exactly where it crashes.
But my knowledge of the whole thing is really too little so I could find a correction by myself: if someone wants to help, I can give lots of details about that...

Thanks in advance,
Fred

josey_wells
1st August 2008, 02:29
Ok, here is the multithreaded version that does not require any special AviSynth and was tested with AviSynth V2.5.8 RC3.

All the MVDegrain functions were factored into a common base class. When MVDegrain is called, it will spin threads for each of the MVAnalyse functions previous in the script that have not been referenced, i.e. MVDegrain 1 - 2threads, MVDegrain2- 4 threads, MVDegrain3-6 Threads.

When these threads complete then 3 more threads are spun 1 each to process luma, chroma u, and chroma v.

The major cause of instability in MVtools turned out to be in MVanalyse. When a GetFrame or NewVideo frame occured simultaneously in either MVTools or MVTools and another script function there could be a crash. I was able to create this crash condition using 2.5.8 RC3, and multithreaded Avisynth.dll with both SetMTmode and no SetMTMode. After serializing all the MVAnalyse calls with critical sections I have been unable to repeat the crash.

I also made changes to MVFrame to avoid extra pointer copies and some critical section scopes. The source is attached. Of course MVDegrainX's are basically total rewrites.

Any script which uses MYAnalyse as a base may benifit from this dll.

Please beat on it.

Boulder
1st August 2008, 03:36
Thanks, I hopefully have the time to do some testing today.

Gavino
1st August 2008, 08:25
The major cause of instability in MVtools turned out to be in MVanalyse. When a GetFrame or NewVideo frame occured simultaneously in either MVTools or MVTools and another script function there could be a crash. I was able to create this crash condition using 2.5.8 RC3, and multithreaded Avisynth.dll with both SetMTmode and no SetMTMode. After serializing all the MVAnalyse calls with critical sections I have been unable to repeat the crash.
It's not urgent, but for 100% safety I would suggest the calls to GetParity be moved inside the critical section too. It's unlikely to be a problem, but in principle a source filter somewhere up the chain might just have a GetParity that is thread-unsafe.

With multi-threaded code, it pays to be paranoid.
Trusting anything outside your control is a hostage to fortune.

josey_wells
1st August 2008, 11:22
It's not urgent, but for 100% safety I would suggest the calls to GetParity be moved inside the critical section too. It's unlikely to be a problem, but in principle a source filter somewhere up the chain might just have a GetParity that is thread-unsafe.

Gavino thanks for the feedback. I have expanded the critical section block to encompass this call.

With multi-threaded code, it pays to be paranoid.
Trusting anything outside your control is a hostage to fortune.

Writing MT code is just difficult in general and there is a fine line between locking just enough or locking too much and losing efficency.

I will post new dll and source after feed back from original post. The change above should be negliable in most cases.

Boulder
1st August 2008, 16:34
This should be because of the min/max values of movement which IMO prevents movement where the compensated block in the reference frame lies (partially) outside the clip area (I haven't checked the details yet).So it actually is useful and I should not worry about it?

josey_wells
1st August 2008, 17:25
Here is updated version with fix mentioned earlier as well as one small memory leak fix.

I am done unless someone finds a problem when testing.

I have successfully used it on several DVD's and will now try a BluRay with AviSynth V2.5.8 RC3.

Have fun!

Lux Delux
1st August 2008, 17:42
Thanks can't wait to try it out on my q6600 :D

Now for someone to approve the attachment :p

Boulder
1st August 2008, 17:52
Some test results regarding performance with a simple MVDegrain-utilizing script:

the latest official MVTools:

MVDegrain3 4.5 fps
MVDegrain2 6.6 fps
MVDegrain1 12.4 fps

the multithreaded build:

MVDegrain3 7.0 fps
MVDegrain2 10.0 fps
MVDegrain1 17.3 fps

However, in one test encode using the multithreaded build, HC froze at one frame and wouldn't go any further. I couldn't reproduce it but I think I'll run some longer tests in batch mode to see if it happens again.

Boulder
1st August 2008, 18:06
One issue rose up..running two MVDegrains in the same script causes a green image.

Try any source with Didée's magic from this post: http://forum.doom9.org/showthread.php?p=1076491#post1076491 . I have a similar function that I use for processing but the code is really ugly :p

Lux Delux
1st August 2008, 19:01
Running this script

AssumeTFF()
Telecide(guide=1)
decimate()
crop(4,8,-4,-14)

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

a= last
b=a.degrainmedian(mode=4)
SeeSaw(a,b, NRlimit=6, NRlimit2=7, Sstr=1.5, Slimit=1, Spower=2, Sdamplo=6, Szp=16, soothet=90)

I'm getting ~27% CPU usage with q6600 quad. Latest avisynth beta and x264 Jarod's latest patch. SetMTmode was way faster, must be something wrong somewhere with my settings? :o

josey_wells
1st August 2008, 19:43
It has taken me 30 hours to create this version of MVTools so I need to take a break for awhile.

One issue rose up..running two MVDegrains in the same script causes a green image.

I beleive I know what is causing this and will take a look at it.

'm getting ~27% CPU usage with q6600 quad. Latest avisynth beta and x264 Jarod's latest patch. SetMTmode was way faster, must be something wrong somewhere with my settings?

When running set MTMode the entire script is frame based multithreaded across frames. When running this version of MVTools without SetMTMode the MVDegrain functions are mutlithreaded only unless other script functions are also. So if another function, I suspect SeeSaw, is slow without SetMTMode then the entire script will run slower with no SetMTMode.

You should be able to comment out lines in the script and see which one is slowing down the entire script.

This version of MVTools should also work with SetMTMode if you want to run it that way. So you would get multithreaded MVTools and mulithreaded frame processing with SetMTMode. In my application I get about 90% across 4 cores with the script I am running without SetMTMode. Given the fact that scripts in general should be much safer without SetMTMode I can live with the slight performance hit in my application.

But if the function slowing down the script is really needed then that author will need to speed its performance or SetMTMode will need to be used.

Lux Delux
1st August 2008, 19:55
I excluded everything except mvtools (with degrainmedian) and still the same result. Could you perhaps post a denosing mvdegrain script that you used for your tests?

Could perhaps be cause of Vista x64. And thanks for all your effort! :)

Spuds
1st August 2008, 19:58
I've been playing around with this a bit, no benchmarks to post but a couple of observations.

The first is that use of idx values seems to cause problems, sometimes green fields, defects or just depressed luma values. Not sure if idx should be used with the threaded version or not. A very simple example that on my system caused a problem is:

function denoise(clip c)
{
pre = c.fft3dfilter

vbw1=MVAnalyse(pre,isb=true,truemotion=true,delta=1,blksize=8,idx=1,overlap=4)
vfw1=MVAnalyse(pre,isb=false,truemotion=true,delta=1,blksize=8,idx=1,overlap=4)
vbw2=MVAnalyse(pre,isb=true,truemotion=true,delta=2,blksize=8,idx=1,overlap=4)
vfw2=MVAnalyse(pre,isb=false,truemotion=true,delta=2,blksize=8,idx=1,overlap=4)

return MVDegrain2(c,vbw1,vfw1,vbw2,vfw2,thSAD=400,idx=2)
}

Changing the idx=2 to idx=1 in the MVDegrain2 call removes the problem, although it should be a 2 for proper idx usage.

I've also had a couple of lockups that I think are caused by MVMask but need to do some more checking. This is all with 2.5.8rc3.

Here is an example that freezes the application, its not MVMask by itself (tried that) so it might be the idx nesting, although it still froze when I removed all the idx calls.

c=last
# quick clean for motion search
pre = c.fft3dfilter
# seach the qick clean clip
vbw1=MVAnalyse(pre,isb=true,truemotion=true,delta=1,blksize=8,idx=1,overlap=4)
vfw1=MVAnalyse(pre,isb=false,truemotion=true,delta=1,blksize=8,idx=1,overlap=4)
vbw2=MVAnalyse(pre,isb=true,truemotion=true,delta=2,blksize=8,idx=1,overlap=4)
vfw2=MVAnalyse(pre,isb=false,truemotion=true,delta=2,blksize=8,idx=1,overlap=4)
# denoise the original clip with the quick clean vectors
clp2=MVDegrain2(c,vbw1,vfw1,vbw2,vfw2,thSAD=400,idx=2)
# get new vector for mask
fv1 = MVAnalyse(clp2,isb=false,truemotion=true,delta=1,blksize=8,overlap=4,idx=3)
mm = clp2.mvmask(kind=1, vectors=fv1, gamma=2, ml=120)
#apply mask
mt_merge(clp2, clp2.RemoveGrain(mode=5), mm)

Lux Delux
1st August 2008, 20:04
DUH I'm a retard. I had wrong mvtools.dll loaded since I copied the script from an old encoding drive :o :stupid:

So anyways the same script as few posts above is running at ~63 % cpu usage.

Awesome :thanks:

josey_wells
1st August 2008, 20:19
I excluded everything except mvtools (with degrainmedian) and still the same result. Could you perhaps post a denosing mvdegrain script that you used for your tests?

Could perhaps be cause of Vista x64. And thanks for all your effort!

Please try taking out DegrainMedian. MVDegrain3 should do the same thing and should be much faster and there should not be a need to use both together.

I am using Windows Server 2008 x64 so I don't believe the x64 issue is a problem.


global iIdx1=100

#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")
{
global iIdx1=iIdx1+1 #index incremented with each call to avoid multithread buffering problem

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

processed=(iLevel==1) ? Eval("""
#1nd level
backward_vec1=c.MVAnalyse(isb=true, delta=1, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
forward_vec1 =c.MVAnalyse(isb=false, delta=1, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
return c.MVDegrain1(backward_vec1, forward_vec1, thSAD=iTHSAD, idx=iIdx1)
""") : ( \
(iLevel==2) ? Eval("""
#2nd level
backward_vec2=c.MVAnalyse(isb=true, delta=2, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
backward_vec1=c.MVAnalyse(isb=true, delta=1, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
forward_vec1 =c.MVAnalyse(isb=false, delta=1, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
forward_vec2 =c.MVAnalyse(isb=false, delta=2, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
return c.MVDegrain2(backward_vec1, forward_vec1, backward_vec2, forward_vec2, thSAD=iTHSAD, idx=iIdx1)
""") : Eval("""
#3rd level
backward_vec3=c.MVAnalyse(isb=true, delta=3, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
backward_vec2=c.MVAnalyse(isb=true, delta=2, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
backward_vec1=c.MVAnalyse(isb=true, delta=1, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
forward_vec1 =c.MVAnalyse(isb=false, delta=1, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
forward_vec2 =c.MVAnalyse(isb=false, delta=2, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
forward_vec3 =c.MVAnalyse(isb=false, delta=3, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
return c.MVDegrain3(backward_vec1, forward_vec1, backward_vec2, forward_vec2, backward_vec3, forward_vec3, thSAD=iTHSAD, idx=iIdx1)
"""))
return processed
}

The above is the only denoise I apply to videos.

Changing the idx=2 to idx=1 in the MVDegrain2 call removes the problem, although it should be a 2 for proper idx usage.

I've also had a couple of lockups that I think are caused by MVMask but need to do some more checking. This is all with 2.5.8rc3.

idx=1 is correct the MVDegrain and Analyze functions that go in it should all have the same idx value since this is how it finds the previously analyzed frames.

The global idx and idx increment statement where needed when using SetMTMode and idx can be left constant in a straight processing script.

I have not touched MVMask at this time.

talen9
1st August 2008, 20:26
The first script posted by Spuds needs two different idx values because the analysis is done on a pre-denoised version of the source clip, not for the inclusion of SetMTMode.

Spuds
1st August 2008, 20:39
Exactly as talon9 said ...

We did a motion search on clip "pre", but we want to compensate clip "c" with those vectors. Using the same idx would refer to the pelclip from "pre" and not one that needs to be created from clip "c". Using a new idx should make pelclip and compensation to "c".

Lux Delux
1st August 2008, 20:39
Josey thanks for that script! I'm running it with default settings and seesaw at ~80% cpu usage! That's awesome. Now I just wish I had 8 cores :p

Keep up the good work :D

Mutant_Fred
2nd August 2008, 01:58
I have moved a little bit forward in my investigation about crashes in MVFlowFPS. Here is some information about all this:
- using MVTools 1.9.5.7
- debugged in MSVC++, through the use of small avisynth script in Media Player Classic

Here is the script:

LoadPlugin("C:\Program Files\AviSynth 2.5\plugins\mvtools.dll")

source = Avisource("c:\Luxembourg.08-07-14_20-10.01.dblBob.avi")

source=ConvertToYV12(source)

# assume progressive PAL 25 fps source
source=AssumeFPS(source,25)
backward_vec = source.MVAnalyse(isb = true, truemotion=true, pel=2, idx=1)
# we use explicit idx for more fast processing
forward_vec = source.MVAnalyse(isb = false, truemotion=true, pel=2, idx=1)
source=source.MVFlowFps(backward_vec, forward_vec, num=200, den=1, mask=2, ml=100, idx=1)

source=AssumeFPS(source,25)

source=ConvertToRGB32(source)

return source


Crashes occur in function FlowInterExtra. They all do at very similar lines, like this one:

int dstB = prefB[vyB*ref_pitch + vxB + (w<<1)];


prefB is a pointer to a buffer related to the backward analyse, I guess. It evolves through the loop, as it increases all along. So, the index calculated by the formula (vyB*ref_pitch + vxB + (w<<1)) may actually be negative, as prefB does not point to the beginning of the buffer: this is ok. But still, it should not be less than the offset between the beginning of the buffer and prefB...
It appears that it sometimes happens anyway: this is when I get one of those crashes...

So, this example was with pel=2, and mask mode = 2. This also occurs with both other 2 mask modes 0 and 1 (FlowInterSimple and FlowInter) and with pel=4, as they compute very similar indexes to look into the same buffer. I could not reproduce it with pel=1.

It seems to occur more often when I increase num, to 200 for example.
Something I can't explain is that crash does not occur always at the same place of a given clip...

Does anybody know about these procedures? I would really appreciate it if someone could help me a little bit: I don't really know how to go much further right now... ;)
It happens with many clips I have. I can provide some, of course.

Thanks in advance,
Mutant_Fred

josey_wells
2nd August 2008, 02:51
The first script posted by Spuds needs two different idx values because the analysis is done on a pre-denoised version of the source clip, not for the inclusion of SetMTMode.

I have found the problem with the idx. I removed some code because it was unclear what it did. Obviously I now know that it was important and have added it back so that it is still multithreaded. I have a working copy but need to enhance the critical section logic before posting again.

Crashes occur in function FlowInterExtra. They all do at very similar lines, like this one:

This is very similar to the problems I was running into for thread unsafe buffer access. When I implement a single dll wide global critical section to serialize all GetFrame and NewFrame calls, it may help this situation.

josey_wells
2nd August 2008, 04:26
Here is a version which fixes the idx problem. All child->getframe, pelclip->getframe, and newvideoframe calls have been serialized through MVTools to avoid any multithreading issues.

Just about every cpp files was touched in the code.

I think I am done again :)

When approved have fun!

Zep
2nd August 2008, 08:46
Here is a version which fixes the idx problem. All child->getframe, pelclip->getframe, and newvideoframe calls have been serialized through MVTools to avoid any multithreading issues.

Just about every cpp files was touched in the code.

I think I am done again :)

When approved have fun!

I hope I didn't miss this earlier in the thread but how are you determining how many threads to run? I ask because even though I have only a quad core, when using setmtmode (), 8 threads is twice as fast as 4 threads so I am wondering if this behavior carries over to your code?

josey_wells
2nd August 2008, 17:16
I hope I didn't miss this earlier in the thread but how are you determining how many threads to run? I ask because even though I have only a quad core, when using setmtmode (), 8 threads is twice as fast as 4 threads so I am wondering if this behavior carries over to your code?

The threading was explained in post 883. It was split across boundaries where independence was guarenteed. Because of the nature of overlapping more threads cannot be used to process Luma, ChromaU, and ChromaV.

More threads are generally not faster once good CPU balancing is acheived since context switching over head will reduce efficiency.

Sagekilla
2nd August 2008, 20:43
I did a little testing with the new mvtools using a simple script that did a LimitedSharpenFaster followed by MVDegrain3 (which is what I use for most of my processing now). I tested 1.9.6.0 and 1.9.5.7 for the following and I got these results:


1.9.5.7 MT(): 1.38 fps
1.9.6.0 MT(): 1.17 fps

1.9.5.7 no MT or SetMT: 1.26 fps
1.9.6.0 no MT or SetMT: 1.27 fps

1.9.5.7 SetMTMode(): 1.35 fps
1.9.6.0 SetMTMode(): 1.26 fps

I have to test this again with MVDegrain3 in isolation, but the whole reason I tested with LSF enabled was because that's my standard procedure for processing a movie. Seems a bit odd that with the changes you made, I'm getting no speed up at all. For reference, my script looks basically like this (without the settings for simplicities sake):


SetMTMode(2,3)
LimitedSharpenFaster()
MVAnalyse()
MVDegrain3()

-or-

MT("""
LimitedSharpenFaster()
MVAnalyse()
MVDegrain3()
""",2,3)

Mutant_Fred
3rd August 2008, 02:18
This is very similar to the problems I was running into for thread unsafe buffer access. When I implement a single dll wide global critical section to serialize all GetFrame and NewFrame calls, it may help this situation.

Great, thanks Josey_Wells. I should probably try out your new version, then. I'm a bit amazed though, I have to say, as what I was running was not multithread at all, at least not that I was aware of. I will let you know of the result anyway.

Thanks again, bye
Mutant_Fred

TSchniede
3rd August 2008, 17:34
There seems to be a penalty of about 5-30% for the additional threads and critical sections (>5% on single core and >25% on quad core) (taken with mvdegain3).
I haven't tested enough, but my guess is a 7% penalty per core.

josey_wells
3rd August 2008, 18:07
Speed is largely dependent on how compiled. Here is a version compilied with the Intel Compiler V10 with the maximum optimizations but it requires SSE2 to run.

Also what is important here is the fact that SetMTMode is not needed and the newest and newer AviSynth can be used. There will be a performance hit because their is no longer frame based multithreading which will always utilize 100% cpu across all 4 cores. As long as other elements are in the script which are not multithreaded then 100% cpu usage is not possible because of the single line flow.

My goal was not to acheive faster but the ability to run without special SetMTMode as well as fix MVTools instability.

I was unable to use V1.9.5.7 to process a blu-ray film without a crash. V1.9.6.0 has not crashed yet.

Did this version fix the idx problem and has it crashed?

Finally, there are ways to enhance this version which I have not done yet. For one, the threads are now be created and destroyed each time in GetFrame which does incur overheard. The threads could be created in the constructor and deleted in the destructor and then kicked off during each get frame instead and go into a wait state when finished. This would give a few percentage improvement. But this is done after the concept is proven sound.

Spuds
3rd August 2008, 18:43
Trying the latest version appears to fix the idx issues, thanks. I have run into another issue that appears to still freeze the application.

original=last
# quick clean for motion search
prefiltered = original.fft3dfilter(sigma=3)

# search the clean clip
vbw1=MVAnalyse(prefiltered,isb=true,truemotion=true,delta=1,blksize=8,idx=1,overlap=4)
vfw1=MVAnalyse(prefiltered,isb=false,truemotion=true,delta=1,blksize=8,idx=1,overlap=4)
vbw2=MVAnalyse(prefiltered,isb=true,truemotion=true,delta=2,blksize=8,idx=1,overlap=4)
vfw2=MVAnalyse(prefiltered,isb=false,truemotion=true,delta=2,blksize=8,idx=1,overlap=4)

# denoise the original clip with the quick clean vectors
denoised=original.MVDegrain2(vbw1,vfw1,vbw2,vfw2, thSAD=400,idx=2)

# get a new vectors for a mask
fv1 = MVAnalyse(denoised,isb=false,truemotion=true,delta=1,blksize=8,overlap=4,idx=3)
bv1 = MVAnalyse(denoised,isb=true,truemotion=true,delta=1,blksize=8,overlap=4,idx=3)

# script works only with fv1, locks up if changed to bv1
mm = denoised.mvmask(kind=1, vectors=fv1, gamma=2, ml=120)
mm = mm.UtoY().BicubicResize(denoised.width(),denoised.height())

#apply mask
mt_merge(denoised, denoised.RemoveGrain(mode=5), mm)

In this script if you use the forward vectors (vectors=fv1) in the mm mask it works, if you use the backward vectors (vectors=bv1) instead then it freezes.

Boulder
3rd August 2008, 21:10
This script totally locks up VDub:
LoadPlugin("c:\mvtools.dll")
MPEG2Source("e:\temp\dvd-rip\the eagle has landed\eagle.d2v")

#Trim(25000,25999)

o = last
fft = o.fft3dfilter(sigma=16,sigma2=10,sigma3=6,sigma4=4,bt=5,bw=16,bh=16,ow=8,oh=8)


# "srch" is a prefiltered clip on which the motion serach is done.
# Here, we simply use FFT3DFilter. There're lots of other possibilities. Basically, you shouldn't use
# a clip with "a tiny bit of filtering". The search clip has to be CALM. Ideally, it should be "dead calm".
srch = fft


# "spat" is a prefiltered clip which is used to limit the effect of the 1st MV-denoise stage.
# For simplicity, we just use the same FFT3DFilter. There're lots of other possibilities.
spat = fft
spatD = mt_makediff(o,spat)


# motion vector search (with very basic parameters. Add your own parameters as needed.)
b3vec1 = srch.MVAnalyse(isb = true, delta = 3, pel = 2, overlap=4, sharp=2, idx = 1)
b2vec1 = srch.MVAnalyse(isb = true, delta = 2, pel = 2, overlap=4, sharp=2, idx = 1)
b1vec1 = srch.MVAnalyse(isb = true, delta = 1, pel = 2, overlap=4, sharp=2, idx = 1)
f1vec1 = srch.MVAnalyse(isb = false, delta = 1, pel = 2, overlap=4, sharp=2, idx = 1)
f2vec1 = srch.MVAnalyse(isb = false, delta = 2, pel = 2, overlap=4, sharp=2, idx = 1)
f3vec1 = srch.MVAnalyse(isb = false, delta = 3, pel = 2, overlap=4, sharp=2, idx = 1)


# 1st MV-denoising stage. Usually here's some temporal-median filtering going on.
# For simplicity, we just use MVDegrain.
NR1 = o .MVDegrain3(b1vec1,f1vec1,b2vec1,f2vec1,b3vec1,f3vec1,thSAD=300,idx=2)
NR1D = mt_makediff(o,NR1)

# limit NR1 to not do more than what "spat" would do
DD = mt_lutxy(spatD,NR1D,"x 128 - abs y 128 - abs < x y ?")
NR1x = o.mt_makediff(DD,U=2,V=2)


# 2nd MV-denoising stage. We use MVDegrain.
NR2 = NR1x.MVDegrain3(b1vec1,f1vec1,b2vec1,f2vec1,b3vec1,f3vec1,thSAD=300,idx=3)


# contra-sharpening: sharpen the denoised clip, but don't add more to any pixel than what was removed previously.
# (Here: a simple area-based version with relaxed restriction. The full version is more complicated.)
s = NR2.minblur(1,1) # damp down remaining spots of the denoised clip
allD = mt_makediff(o,NR2) # the difference achieved by the denoising
ssD = mt_makediff(s,s.removegrain(11,-1)) # the difference of a simple kernel blur
ssDD = ssD.repair(allD,1) # limit the difference to the max of what the denoising removed locally.
ssDD = SSDD.mt_lutxy(ssD,"x 128 - abs y 128 - abs < x y ?") # abs(diff) after limiting may not be bigger than before.

NR2.mt_adddiff(ssDD,U=2,V=2) # apply the limited difference. (sharpening is just inverse blurring)

return(last)

josey_wells
4th August 2008, 01:31
All these locks are caused by the same reason which is critical section locks because of spinning multiple threads to get all the frames at the beginning of MVDegrain. The only way I see around this which will take a bit of time is thus:

1. Create a special MVAnalyseMultiple which would replace all the seperate calls to MVAnalyse and would perform all the SearchMOV's in separate threads.
2. Use this data in a new MVDegrainMultiple which would recognize the combined data set.

I could then remove all the critical sections throughout since all threaded processing would be after getting the frames through GetFrame, NewVideoFrame, pelclip->GetFrame.

Gavino
4th August 2008, 10:04
All these locks are caused by the same reason which is critical section locks because of spinning multiple threads to get all the frames at the beginning of MVDegrain.
I would have thought that the critical section locks would at worst reduce the performance within MVTools to the level of single threading, not lock up altogether (since the filter graph is acyclic).

Could it be what is actually happening is this: calls to GetFrame up the filter chain (previously done single threaded in linear order) are now interleaved from different threads, causing sub-optimal performance of upstream filters, eg fft3dfilter.

If my theory is right (and I'd gladly be shown wrong) then multithreading in the proposed MVAnalyzeMultiple will not solve the problem.

Sagekilla
5th August 2008, 03:51
I have a question about block sizes... For what reason would someone use a non-square analyse pattern such as 16x8 or 16x2? If I understand correctly, MVTools supports all the variations (that are a power of 2) between 2 and 32?

I've always used 8x8 since it was good on performance and quality and I never knew (or understood) why you would use those block sizes.. If anyone could enlighten me I'd appreciate it :)

josey_wells
5th August 2008, 14:03
I would have thought that the critical section locks would at worst reduce the performance within MVTools to the level of single threading, not lock up altogether (since the filter graph is acyclic).

Could it be what is actually happening is this: calls to GetFrame up the filter chain (previously done single threaded in linear order) are now interleaved from different threads, causing sub-optimal performance of upstream filters, eg fft3dfilter.

I have proved that the problem is caused by critical section locks. The second MVDegrain tries to get the first MVDegrain frames which tries to spin more threads but these cannot complete since the critical section is being held by the second MVDegrain.

I am working on the multi versions previously discussed. This version will spin threads to do the searchMOV's in the MVAnalyseMulti and spin threads to do the MVDegrain luma, chromau, and chromav processing. Since these threads will be working on already acquired pointers indpendence is guaranteed and no critical sections are needed.

The threads will be created in the constructor and destroyed in the destructor with processing controlled by semaphores which should greatly reduce overhead since thread creation is expensive.

yup
5th August 2008, 14:13
Sagekilla!
See doc blksize 4, 8, 16, 32, blksizev 4,8,16.
I use non square block for interlaced video blksize=16, blksizev=8. Main reason if video have better resolution in one direction, mainly in horizontal. If Your video progressive better use square blocks.
yup.

Gavino
5th August 2008, 16:38
I have proved that the problem is caused by critical section locks. The second MVDegrain tries to get the first MVDegrain frames which tries to spin more threads but these cannot complete since the critical section is being held by the second MVDegrain.
Yes, I see now. Although the filter graph is acyclic, one instance of MVDegrain can request frames from another, effectively forming a loop at the class level, which is where the locking is done.

I can also see that your proposed solution will work. Indeed it illustrates a useful principle for multi-threading filter authors - the simplest approach is to do your GetFrame call(s) on the main thread and only go multi-threaded for the subsequent processing. Reason - when you call GetFrame you are calling external code that cannot be regarded as thread-safe, whereas the processing you do is totally under your control.

josey_wells
6th August 2008, 15:22
OK critics.

Here is a new version of MVTools with multithreaded MVAnalyseMulti and multithreaded MVDegrainMulti. All multithreading is done after frame pointers are acquired, i.e. only on the processing. All threads are created in constructors, and destroyed in destructors to avoid overhead.

This version will solve all idx problems and all lock problems experienced earlier.

This version also requires script changes to take full advantage of multithreading.

For example
backward_vec2=c.MVAnalyse(isb=true, delta=2, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
backward_vec1=c.MVAnalyse(isb=true, delta=1, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
forward_vec1 =c.MVAnalyse(isb=false, delta=1, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
forward_vec2 =c.MVAnalyse(isb=false, delta=2, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
last.MVDegrain2(backward_vec1, forward_vec1, backward_vec2, forward_vec2, thSAD=iTHSAD, idx=iIdx1)

Now becomes

MVMulti=c.MVAnalyseMulti(refframes=2, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
last.MVDegrainMulti(MVMulti, refframes=2, thSAD=iTHSAD, idx=iIdx1)

And if one really wanted to do an MVDegrain10 it would be

MVMulti=c.MVAnalyseMulti(refframes=10, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
last.MVDegrainMulti(MVMulti, refframes=10, thSAD=iTHSAD, idx=iIdx1)

Other functions are easily extensible to take advantage of MAnalyseMulti in the future.

The number of threads spun in MVAnalyseMulti is 2*refrrames. The number spun in MVDegrainMulti is 3, one for Luma, ChromaU, and ChromaV.

I will post source later as I am still working on it.

Two versions of dll are provided one MSVC2008 which should work for everyone and one IC10 which requires SSE2.

Have fun!

mikeytown2
6th August 2008, 16:59
@josey_wells how would you use MVDegrainMulti with Interlaced material?

josey_wells
6th August 2008, 17:08
@josey_wells how would you use MVDegrainMulti with Interlaced material?

I don't understand the question. Anywhere where multiple MVAnalyse and single MVDegrain was used in script can be replaced by MVAnalyseMulti and MVDegrainMulti equivalent.

mikeytown2
6th August 2008, 17:14
One of the examples listed (http://avisynth.org.ru/mvtools/mvtools.html#examples) has a function group called MVDegrain2i, where the delta's are 2 and 4 instead of 1 and 2


function MVDegrain2i(clip "source", int "overlap", int "dct", int "idx")
{
overlap=default(overlap,0) # overlap value (0 to 4 for blksize=8)
dct=default(dct,0) # use dct=1 for clip with light flicker
idx=default(idx,1) # use various idx for different sources in same script
fields=source.SeparateFields() # separate by fields
backward_vec2 = fields.MVAnalyse(isb = true, delta = 2, pel = 2, overlap=overlap, idx = idx,dct=dct)
forward_vec2 = fields.MVAnalyse(isb = false, delta = 2, pel = 2, overlap=overlap, idx = idx,dct=dct)
backward_vec4 = fields.MVAnalyse(isb = true, delta = 4, pel = 2, overlap=overlap, idx = idx,dct=dct)
forward_vec4 = fields.MVAnalyse(isb = false, delta = 4, pel = 2, overlap=overlap, idx = idx,dct=dct)
fields.MVDegrain2(backward_vec2,forward_vec2,backward_vec4,forward_vec4,thSAD=400,idx=idx)
Weave()
}

source=AVISource("video.avi")
mvdegrain2i(source,4,0,1)

Sagekilla
6th August 2008, 17:15
I believe the correct procedure before was to do the following, as MVtools does not handle interlaced material at all.

Separatefields()
MVProcessingHere()
Weave()

@Josey_wells, I like how you redesigned the function to only require one call for MVAnalyse, very handy! :) This is just my 2 cents, perhaps I like the old names too much, but I think keeping it without the multi suffix would be better.

Also, any chance you can upload the files to mediafire since we have to wait for moderators to approve attachments?

josey_wells
6th August 2008, 17:31
One of the examples listed has a function group called MVDegrain2i, where the delta's are 2 and 4 instead of 1 and 2

If this is really a desired feature then either a stepmultipler, or stepstart and stepsize would need be added to facilatate this.

Also, any chance you can upload the files to mediafire since we have to wait for moderators to approve attachments?

I am cleaning up the code(one little mistake) and will post here and try mediafire when done.

mikeytown2
6th August 2008, 17:35
If this is really a desired feature then either a stepmultipler, or stepstart and stepsize would need be added to facilatate this.

If this is a quick and easy thing to do, then go ahead and add in deltastep (my recommendation for a name). If it's a pain in the rear to add; doing 2 MVDegrainMulti, one for SelectEven() & SelectOdd() would work.

Sagekilla
6th August 2008, 17:41
If this is really a desired feature then either a stepmultipler, or stepstart and stepsize would need be added to facilatate this.



I am cleaning up the code(one little mistake) and will post here and try mediafire when done.

Thank you! :) Look forward to using the new version, considering my Opteron 170 is just barely chugging along with MVTools running.

Boulder
6th August 2008, 17:43
One of the examples listed (http://avisynth.org.ru/mvtools/mvtools.html#examples) has a function group called MVDegrain2i, where the delta's are 2 and 4 instead of 1 and 2


function MVDegrain2i(clip "source", int "overlap", int "dct", int "idx")
{
overlap=default(overlap,0) # overlap value (0 to 4 for blksize=8)
dct=default(dct,0) # use dct=1 for clip with light flicker
idx=default(idx,1) # use various idx for different sources in same script
fields=source.SeparateFields() # separate by fields
backward_vec2 = fields.MVAnalyse(isb = true, delta = 2, pel = 2, overlap=overlap, idx = idx,dct=dct)
forward_vec2 = fields.MVAnalyse(isb = false, delta = 2, pel = 2, overlap=overlap, idx = idx,dct=dct)
backward_vec4 = fields.MVAnalyse(isb = true, delta = 4, pel = 2, overlap=overlap, idx = idx,dct=dct)
forward_vec4 = fields.MVAnalyse(isb = false, delta = 4, pel = 2, overlap=overlap, idx = idx,dct=dct)
fields.MVDegrain2(backward_vec2,forward_vec2,backward_vec4,forward_vec4,thSAD=400,idx=idx)
Weave()
}

source=AVISource("video.avi")
mvdegrain2i(source,4,0,1)
I don't see the reason why there are deltas 2 and 4?? In interlaced material, every field is different (so you should be able to use deltas 1, 2...) and MVAnalyse should simply compensate for the small vertical shift between the two fields. Or is it that vectors are better found with a larger delta?

josey_wells
6th August 2008, 18:29
I will add a deltamult option to MVAnalyseMulti where for refframes=3 for examlpe the following will occur:

deltamult=1

B delta=3, B delta=2, B delta=1, F delta=1, F delta=2, F delta=3

deltamult=2

B delta=6, B delta=4, B delta=2, F delta=2, F delta=4, F delta=6

etc.

talen9
6th August 2008, 19:38
This is just my 2 cents, perhaps I like the old names too much, but I think keeping it without the multi suffix would be better.

I don't think this is a good idea, it would break compatibility with pre-existing scripts ... OTOH, old scripts would have to be adapted in either case, if you want them to be "thread-safe", right? :confused:

Sagekilla
6th August 2008, 19:53
Indeed. It's a very simple matter of updating the scripts so they're properly coded that way. But then again, what I'm suggesting is you rename it to MVDegrain and MVAnalyse. Analyse in the old scripts would have to be updated, but the MVDegrain would just be a matter of dropping the number and updating the params. Either way, that's just my preference ;) I'm in love with the fact that I don't have to use those extra lines to get the same functionality now, that it's just a minor annoyance.


To answer your question though, yes you would have to update all old scripts regardless with this new patch, since the syntax has completely changed, as well as the function names.

josey_wells
6th August 2008, 23:26
OK, here is the fixed version with deltamult option, default = 1, added to MVAnalyseMulti. For now I will keep the multinames for backward compatibility.

Obviously mediafire didn't work to well so here is rapidshare
The outside link is http://rapidshare.com/files/135417349/MVTools_V1.9.6.0_9.rar.html

This should be good to go for testing.

Have fun!

mikeytown2
7th August 2008, 04:23
@josey_wells Giving your latest dll a spin and it appears to work fairly well, no crashes so far! Using MCbob and MVDegrainMulti deltamult=2 in the same script. MVDegrainMulti by it's self uses a fair amount of my cpu (80%), haven't done a timed test yet.
:)

Sagekilla
7th August 2008, 05:39
I've gotten close to 100% speedup with your new filter. Filtering a blu-ray movie @ 720p with blksize=8, overlap=4, pel=4 I got 0.24 fps with 1.9.5.7 and 0.44 fps with 1.9.6.8 (You should really use that fourth number to enumerate your mini builds you've been making ;))

Very nice, I never got anywhere near 100% speedup using MT() or SetMTMode(). SetMTMode() was a horror for using on blu-ray movies for that matter, since I had two instances of DirectShowSource decoding the 1080p video, which resulted in almost no speedup.

Edit: By the way, which version will be faster, the IC10 or MSVC?

josey_wells
7th August 2008, 11:11
By the way, which version will be faster, the IC10 or MSVC?

The IC10 version should be slighter faster since the Intel Compiler peforms some parallel optimization and loop unrolling. However, I did set it up to require SSE2 so if your CPU supports that it should work fine.

Very nice, I never got anywhere near 100% speedup using MT() or SetMTMode(). SetMTMode() was a horror for using on blu-ray movies for that matter, since I had two instances of DirectShowSource decoding the 1080p video, which resulted in almost no speedup.

Blu-ray was the main reason I enchanced MVTools since I would get random crashes with all the options mentioned above. I have converted a blu-ray movie with this version at about 0.7 fps with my script

MVDegrainMulti by it's self uses a fair amount of my cpu (80%), haven't done a timed test yet.

My Q6600 averages between 85-95% CPU usage across all 4 cores.

1.9.6.8 (You should really use that fourth number to enumerate your mini builds you've been making

I was trying to use the _X as a build number with V1.9.6.0 being the completed baselined version. Maybe its time to go to 2.0.0.0 if some other users chime in with tying MVAnalyseMulti to some other MVTools filters.

krieger2005
7th August 2008, 12:30
I don't see a reason why you removed the isb and delta-parameter. There are several situations where one want only analyze the forward-movement or only the backward-movement or only the 5th Frame backward to the actual and so on.

josey_wells
7th August 2008, 13:59
I don't see a reason why you removed the isb and delta-parameter. There are several situations where one want only analyze the forward-movement or only the backward-movement or only the 5th Frame backward to the actual and so on.

One is free to use the old MVAnalyse as it still exists. However, Multithreading can only be leveraged when performing analysis over many frames. If it was really desired to do just a group of forward or a group of backward frames multithreaded then this could be done with flags such as forwardonly & backwardonly. Another option would be a direction flag(1=forward & backward, 2=Forward only, 3=backward only).

josey_wells
7th August 2008, 18:11
OK, here is the final post for MVTools V1.9.6.0.

I have finished cleaning up the code and fixed a memory leak in the destructor of MVMask and MVShow.

Take it or leave it.

MVTools V1.9.6.0_Final link http://rapidshare.com/files/135592280/MVTools_V1.9.6.0_Final.rar.html

Sagekilla
7th August 2008, 18:14
Here goes the stress test then ;) Do filtering on my Desktop, and send the frames over the network to my laptop for encoding. I'll try encoding the "Jungles" episode of Planet Earth, and see how well it performs and if there's any crashes or issues. There shouldn't be though, since I've been using the latest version you've released every day for encoding my Firefly episodes.

Boulder
7th August 2008, 18:27
OK, here is the final post for MVTools V1.9.6.0.

I have finished cleaning up the code and fixed a memory leak in the destructor of MVMask and MVShow.

Take it or leave it.

MVTools V1.9.6.0_Final link http://rapidshare.com/files/135592280/MVTools_V1.9.6.0_Final.rar.htmlThanks for your hard work :) A very quick test showed a very nice boost, going from 1.9 fps to 2.5 fps, and no crashes so far.

Andrey /MAG/
8th August 2008, 01:49
OK, here is the final post for MVTools V1.9.6.0.
Thanx. But I have some questions.

When we can see changed documentation?
Can You give short description what difference from 1.9.5.7?

TSchniede
8th August 2008, 04:20
I think it is basically his version 1.9.5.8 (http://forum.doom9.org/showthread.php?p=1157237#post1157237). But MVDegrain works similar to the previous threaded version (only the threads are only created and destroyed once) and MVDegrainMulti and MVAnalyseMulti were added, that's the obvious changes there are a lot of minor changes in most files though.

yup
8th August 2008, 11:46
josey_wells!
Good work. I find even MVTools.dll from folder MSVC08 work little faster, but I can not run IC10 version. At home I have old CPU
Number of processors in system: 1
Current processor: #1
Cores per processor: 1
Disabled cores per processor: 0
Processor Name: Intel(R) Pentium(R) 4 CPU 2.53GHz
Type: 0
Family: F
Model: 2
Stepping: 7
Revision: 37
Maximum CPUID Level: 2
L1 Trace Cache: 12 Kµops
L1 Data Cache: 8 KБ
L2 Cache: 512 KБ
Packaging: FC-PGA2
EIST: No
MMX(TM): Yes
SSE: Yes
SSE2: Yes
SSE3: No
SSE4: No
Enhanced Halt State: No
Execute Disable Bit: No
Hyper-Threading Technology: No
Intel(R) 64 Architecture: No
Intel(R) Virtualization Technology: No
Expected Processor Frequency: 2.53 ГГц
Reported Processor Frequency: 2.53 ГГц
Expected System Bus Frequency: 533 МГц
Reported System Bus Frequency: 533 МГц
My CPU support SSE2 but when I open avs file in VirtualDub, VirtualDub close without error report. Please advice.
yup.

josey_wells
8th August 2008, 11:50
Tschniede is basically correct.

In short, MVDegrain1, MVDegrain2, & MVDegrain3 were all changed to be multithreaded for the LumaY, ChromaU, and ChromaV processing where the threads to do the processing are created in the constructor and destroyed in the destructor. However, all frame getting operations are done on the mainline thread so in general little speed improvement will be achieved as the MVAnalyse calls will all be run on the main line thread only.

A new function MVAnalyseMulti was added which creates a seperate thread to do the analysing for each forward or backward frame. The threads are only created in the constructor and destroyed in the desctructor. The output is packed into an arrayed output only compatible at this time with MVDegrainMulti but other functions can easily be adopted to handle this arrayed format. MVAnalyseMulti is the same as MVAnalyse with the following changes:

1. isb and delta were removed
2. new parameters refframes and deltamult were added
refframes - is the number of forward and backward reference frames to analyse and can be set between 1-32. Default is 1. 1 would be 2 frames, 2 would be 4 frames, etc.
deltamult - is the multiplier used for the frame stepping. If deltamult is 1 then the offsets are 1, 2, 3. If deltamult is 2 then the offsets are 2, 4, 6, etc. Default is 1 and can be set between 1-32.

For example:
backward_vec2 = source.MVAnalyse(isb = true, lambda = 1000, delta = 2)
backward_vec1 = source.MVAnalyse(isb = true, lambda = 1000, delta = 1)
forward_vec1 = source.MVAnalyse(isb = false, lambda = 1000, delta = 1)
forward_vec2 = source.MVAnalyse(isb = false, lambda = 1000, delta = 2)

can be replaced by
ForBackVec = source.MVAnalyseMulti(refframes=2, lambda = 1000)

Some options still open for debate is whether it is worthwhile to add a sweep direction flag to enable forward only, backward only, or the standard forward and backward.

A new MVDegrainMulti was added which still does the multithreaded Luma, ChromaU, and ChromaV processing and has the following syntax:

MVDegrainMulti(clip, clip "MVForBack", int "refframes", int "thSAD", int "thSADC", int "plane", int "limit", clip "pelclip", int "idx")

MVForBack - is the arrayed analysis frames from MVAnalyseMulti which replaces all the seperate forward and backward clips
refframes - the number of reference frames used in MVAnalyseMulti to produce MVForBack. Default is 1.

These two calls allow all MVDegrain calls equivalent to MVDegrain1 up to MVDegrain32.

For example a MVDegrain16 would be

MVForBack = MVAnalyseMulti(refframes=16, pel = 2, overlap=4, sharp=1, idx = 1)
last.MVDegrainMulti(MVForBack, refframes=16, thSAD=400,idx=1)


As for the rest of the code, I made changes to the critical section logic used to use autoscope variables. I modified MVClip to act as normal or handle arrayed types. I formatted the text of the files to remove tabs and repalce with spaces so that display is uniform between text editors.

I fixed a memory leak in the desctructor of MVMask and MVShow.

Many other numerous small changes.

These calls can be used with the latest AviSynth V2.5.8 RC3 to due multithreaded processing or they can be combined with some of the MT or SetMTMode variants if desired.

josey_wells
8th August 2008, 12:18
Good work. I find even MVTools.dll from folder MSVC08 work little faster, but I can not run IC10 version. At home I have old CPU

I looked at project settings and was requiring SSE3 also.

Here are two versions one built for P4 with SSE2 and one built for Core2 Duo with SSE2 & SSE3

http://rapidshare.com/files/135785846/MVTools_V1.9.6.0_Final_IC10_Builds.rar.html

FYI: Do not use the Core2 Duo IC10 build. The intel compiler has an issue when I tested this build. Use the P4-SSE3 build which was the original IC10 build posted with the final, or the P4-SSE2 build posted here. Or use the MSVC08 build which should work for anyone.

Which is fastest is trial and error

yup
8th August 2008, 12:43
josey_wells!
Now all work from folder IC10-P4-SSE2.
One more :thanks:
yup.

Sagekilla
8th August 2008, 13:23
I've just finished running a test encode (Planet Earth) and the whole thing went through without a problem. I used the IC10 version, and got roughly ~1.36 fps using two computers, hah. This is far better than what I got on one computer and more modest x264 settings for that matter.

Gavino
8th August 2008, 17:02
A new MVDegrainMulti was added which ... has the following syntax:
MVDegrainMulti(clip, clip "MVForBack", int "refframes", int "thSAD",
int "thSADC", int "plane", int "limit", clip "pelclip", int "idx")
MVForBack - is the arrayed analysis frames from MVAnalyseMulti which replaces all the seperate forward and backward clips
refframes - the number of reference frames used in MVAnalyseMulti to produce MVForBack. Default is 1.

Would it be possible to store the value of refframes along with the data inside "MVForBack", so that it need not be passed as a parameter to MVDegrainMulti? One less thing for the user to keep track of (and possibly get wrong).

Boulder
8th August 2008, 17:12
Would it be possible to store the value of refframes along with the data inside "MVForBack", so that it need not be passed as a parameter to MVDegrainMulti? One less thing for the user to keep track of (and possibly get wrong).That doesn't work in situations where you use the same vectorset for two MVDegrainMultis with different temporal radii.. One solution would be to use the value used in MVAnalyseMulti unless specified otherwise.

Gavino
8th August 2008, 17:33
That doesn't work in situations where you use the same vectorset for two MVDegrainMultis with different temporal radii.. One solution would be to use the value used in MVAnalyseMulti unless specified otherwise.
I wasn't sure if this was allowed (different radii). Presumably MVDegrainMulti complains if you ask for a greater radius than the one used in MVAnalyseMulti?

josey_wells
8th August 2008, 17:38
Actually both of you bring up a good point. I do not check now for a differing refframes than the original set created from MVAnalyseMulti.

I could see where one would want to create an MVAnalyseMulti set with say refframes=3 but only use temporal radius 2, i.e. refframes=2 in MVDegrainMulti.

I will have to make these fixes.

On second though I could default refframes to 32 and if it is larger than the set passed then use the entire set from MVAnalyseMulti. If a smaller refframes was specified then the subset would be utilized.

Boulder
8th August 2008, 17:56
Actually both of you bring up a good point. I do not check now for a differing refframes than the original set created from MVAnalyseMulti.

I could see where one would want to create an MVAnalyseMulti set with say refframes=3 but only use temporal radius 2, i.e. refframes=2 in MVDegrainMulti.

I will have to make these fixes.

On second though I could default refframes to 32 and if it is larger than the set passed then use the entire set from MVAnalyseMulti. If a smaller refframes was specified then the subset would be utilized.So the current version forces for example 3 refframes in MVDegrainMulti if that is set in MVAnalyseMulti?

josey_wells
8th August 2008, 18:00
So the current version forces for example 3 refframes in MVDegrainMulti if that is set in MVAnalyseMulti?

In the current version refframes must be specified in both MVAnalyseMulti and MVDegrainMulti and must have the same value in each.

I propose to change so that refframes is specified in MVAnalyseMulti and if unspecified in MVDegrainMulti then will be the same as used MVAnalyseMulti, i.e. entire set. If specified and smaller thatn refframes used in MVAnalyseMulti then the subset of smaller temporal radius would be used.

Boulder
8th August 2008, 18:05
Yes, that sounds like a good idea :)

Fizick
8th August 2008, 19:55
josey_wells,
You make a real progress with new functions MVDegrainMulti and MVAnalyseMulti! It is really faster!
With new Multi syntax, the mvtools lose some ...universality (do not know right word). But speed is more important! However, the clear doc is very important too.

If your version is a final, what is state of other functions?

is it possible to mix multi and non-multi mvanalyse with other functions, is it possible to have several MVDegrainMulti in script, may idx be same.
is some functions compatible with SetMTMode or MT()?

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).
Is it possible to revert all your threading changes for old functions and combine it with new MVDegrainMulti and MVAnalyseMulti?
IMO, it would be the optimal way of MVTools evolution.
If it is possible, then your version is not final.
If it is not possible, then your version is not final too ;)

as for version number, v1.10 is seems most appropriate.

Spuds
9th August 2008, 00:27
@josey_wells,

First awesome work, thanks for sticking with it! I have not been able to get it to crash or freeze :)

Now of course I have a question.

Are the idx values between MVAnalyseMulti and MVAnaylse completely separate or do they refer to the same pool. For example if I did a

forback=input.MVAnalyseMulti(refframes=2, idx=1)

would a

for=input.mvanalyse(isb=false,delta=1,idx=1)

be able to retrieve the vector frame that MVAnalyseMulti already computed or does it recompute the frame since its in a different function? If different is there a way to get specific vector frames out of the MVAnalyseMultii array?

Revgen
9th August 2008, 10:40
For example:
backward_vec2 = source.MVAnalyse(isb = true, lambda = 1000, delta = 2)
backward_vec1 = source.MVAnalyse(isb = true, lambda = 1000, delta = 1)
forward_vec1 = source.MVAnalyse(isb = false, lambda = 1000, delta = 1)
forward_vec2 = source.MVAnalyse(isb = false, lambda = 1000, delta = 2)

can be replaced by
ForBackVec = source.MVAnalyseMulti(refframes=2, lambda = 1000)



Is there a way to use the ForBacVec thing in MVFlowInter?

I'm not exactly skilled with MVtools and I'm trying to modify MCBob to work with this. So far the obstacle is trying get MVFlowInter to use this.

Boulder
9th August 2008, 11:45
Is there a way to use the ForBacVec thing in MVFlowInter?

I'm not exactly skilled with MVtools and I'm trying to modify MCBob to work with this. So far the obstacle is trying get MVFlowInter to use this.AFAIK, at the moment it can only be used in MVDegrainMulti.

halsboss
9th August 2008, 13:32
Is there a way to use the ForBacVec thing in MVFlowInter?

... I'm trying to modify MCBob to work with this.

You beaut. Is this http://forum.doom9.org/showthread.php?p=1055263#post1055263 the version/thread you're hoping to modify (MCBob+NNEDI) ? I did what you said in that thread and added "threads=4" to all the NNEDI calls in MCBob and it went from 0.3 fps to 0.8 fps (1080i source, Q9450 quad-core CPU) ... any MCBob speedup would be a magnificent achievement.

josey_wells
9th August 2008, 14:05
Wow, lots of questions. Let me address the questions in order and then wrap up with talk about a new version that I believe will make this applicable to everyone until more functions can be modified.

If your version is a final, what is state of other functions?

All non multi functions work as they used to except for the MVDegrain1, 2, 3 which still have the multithreaded LumaY, ChromaU, and Chroma V threaded processing.

is it possible to mix multi and non-multi mvanalyse with other functions, is it possible to have several MVDegrainMulti in script, may idx be same.
is some functions compatible with SetMTMode or MT()?

1. It used not to be possible to mix mulit mvanalyse with other functions but this is no longer the case and will be explained below.
2. It is possible to have multiple MVDegrainMulti and multiple MVAnalyseMulti in the same script. The idx values may be different or the same and work as before.
3. All new functions should be just as compativle with SetMTMode or MT() and stability using these functions would be the same as before. For higher stability using the newer AviSynth without SetMTMode or MT is recommended.

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).
Is it possible to revert all your threading changes for old functions and combine it with new MVDegrainMulti and MVAnalyseMulti?

I have removed all thread locking from all the functions so that they are the same as before. The new functions are also not thread locked. All frame getting is done on the main line thread and processing is done in spun threads which guarantees independence and does not require thread locking.


as for version number, v1.10 is seems most appropriate.

IMO I'm still partial to V2.0 when all the issues are resolved. :)

I spent most of the day yesterday tracing an excessive memory usage condition and making some more enhancements. The memory usage problem turned out to be that if you pass pointers which increment a refcount to a thread which doesn't die between frame calls then the thread will hold references to frames no longer needed between calls and substantially increase memory usage. I have corrected by freeing pointers in the threads.

Now for the good stuff.

First it is now no longer necessary to add refframes to MVDegrainMulti. It will automatically know how many temporal frames were passed to it and perform the appropriate denoising. For example if MVAnalyseMulti had refframes=3 then MVDegrainMulti would be equivalent to MVDegrain3. If a smaller refframes is passed then a reduced temporal denoising can be done. If refframes=2 was specified in MVDegrainMulti then a MVDegrain2 will be performed even though MVAnalyseMulti was refframes=3.

MVMulti=c.MVAnalyseMulti(refframes=iLevel, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
last.MVDegrainMulti(MVMulti, thSAD=iTHSAD, idx=iIdx1)

Now before I go on with the next feature a little explanation is in order. MVAnalyseMulti will always produce forward and backward frames the following way.

MVAnalyseMulti with refframes 3 will produce the following frames corresponding to the array elements.
0 - Backward 3, 1 - Backward 2, 2 - Backward 1, 3 - Forward 1, 4 - Forward 2, 5 - Forward 3
And so on for higher refframes

I have added a MVMultiExtract Function which allows one to extract the regular MVAnalyse frames from a multi function call to be used in other MVTools functions until they can be modified to accept MVAnalyse directly. Thus everyone can take advantage of MVAnalyseMulti which seems to take the most processing power.

For example.

MVMulti=c.MVAnalyseMulti(refframes=1, pel=iPel, blksize=iBlksize, overlap=iOverlap, chroma=bChroma, truemotion=bTrueMotion, search=iSearch, sharp=iSharp, dct=iDct, idx=iIdx1)
back1=MVMulti.MVMultiExtract(0)
for1=MVMulti.MVMultiExtract(1)
last.MVDegrain1(back1, for1, thSAD=iTHSAD, idx=iIdx1)

This shows how the individual frames can be extracted and used in the old MVDegrain1. This can be carried to other MVTools functions.

So finally here it is V1.9.6.1:

http://rapidshare.com/files/136042473/MVTools_V1.9.6.1.rar.html

There are several versions in here use the one most appropriate for your system.

MSVC08 - Everyone
IC10-P4-SSE2 - Pentium 4 or above SSE2
IC10-P4-SSE3 - Pentium 4 or above with SSE3
IC10-Core2-SSE3 - Core 2 duo or above with SSE3

Now that the oylmpics are on I need a break, plus my DVD collection is backing up. :)

Have fun!

krieger2005
9th August 2008, 14:37
You made big improvements to the MVTools. For future development maybe it is intresting to note the development in avisynth:
http://forum.doom9.org/showthread.php?t=139629

So if i understand the result of the idea of IanB right it should make just the same as you have realized with the MVAnalyseMulti-Function. So if this will be reality in near future such functions should't be usefull then?

josey_wells
9th August 2008, 15:00
So if i understand the result of the idea of IanB right it should make just the same as you have realized with the MVAnalyseMulti-Function. So if this will be reality in near future such functions should't be usefull then?

This isn't necessarily true. What I have done is multithread a single line flow through a script.

The new AviSynth is looking to multithread individual frames, i.e. running the script in parallel for different frame numbers. There exists lots of issues with this with scripts that depend on previous/forward frames. AviSynth is the place to perform this since it has control of the frame getting mechanism which is why I had to go the way I did.

When AviSynth makes these modifications as well as pipeline improvements both modifications can exist together and benifit.

Spuds
9th August 2008, 16:06
I have added a MVMultiExtract Function

This is a great improvement. Not only are those frames used in other mvtools but they are often used in masktools processing so getting access to them to use in other functions is a big plus. Off to test!

Boulder
9th August 2008, 16:11
There's a little something with overlapping, at least when viewing the vectors with MVShow. I used the Core2Duo build of v1.9.6.1.

Script:
MPEG2Source("napa_6.d2v")
mvmulti=MVAnalyseMulti(last,refframes=1,pel=2,blksize=8,overlap=4,sharp=2,idx=1,chroma=true,sadx264=0)
for1=MVMulti.MVMultiExtract(1)
MVShow(last,for1)

with overlapping
http://img126.imageshack.us/img126/8200/overlapss5.th.jpg (http://img126.imageshack.us/my.php?image=overlapss5.jpg)

without overlapping
http://img126.imageshack.us/img126/1983/nooverlapjr4.th.jpg (http://img126.imageshack.us/my.php?image=nooverlapjr4.jpg)

Didée
9th August 2008, 16:42
Feature request (not related to MultiThreading):

clip10 = original
clip11 = clip10.SomeFilter()
vector = clip11.MVAnalyse()
#ShowSAD = clip10.MVMask(vector,kind=1)
ShowSAD = clip11.MVMask(vector,kind=1)

What is missing:

- Search vectors on clip10. But to produce the ShowSAD mask, re-calculate the SADs by applying the vectors to clip10.

Currently, when using a pre-denoised searchclip, it is only possible to get a SAD-mask from the pre-denoised clip. It would be good to be able to perform the search on the pre-denoised clip, but then to get the resulting SAD from applying the found vectors to the original not-denoised clip.

josey_wells
9th August 2008, 16:54
There's a little something with overlapping, at least when viewing the vectors with MVShow. I used the Core2Duo build of v1.9.6.1.



#mvmulti=MVAnalyseMulti(last,refframes=1,pel=2,blksize=8,overlap=4,sharp=2,idx=1,chroma=true,sadx264=0)
#for1=MVMulti.MVMultiExtract(1)

for1=MVAnalyse(last,isb=false, delta=1, pel=2,blksize=8,overlap=4,sharp=2,idx=1,chroma=true,sadx264=0)

MVShow(last,for1)

OK, using the two versions of computing for1 above I am able to confirm that the for1 from MVMultiExtract looks like it does not contain all the motion vector data. It is probably there I just didn't get all of it copied to the output.

I will take a look. Hopefully wont take to long.

josey_wells
9th August 2008, 17:27
OK, this was a stupid mistake. RGB32 data is 4 bytes per pixel and I was only copying 1/4.

Here is link to new dll's.

http://rapidshare.com/files/136083008/MVTools_V1.9.6.1_2.rar.html

Boulder
9th August 2008, 17:34
Yes, it works now just fine :)

Revgen
9th August 2008, 23:51
Okay I've tried out the MVMultiExtract thing and I'm still getting issues with MVFlowInter. It's specifically saying that it's getting the wrong forward vectors.

Here's what I've done so far with this section of MCBob. The non-multitreaded mvanalyse sections have been blocked. Any input would be appreciated. Thanks.

# Perform Motion Search
# ---------------------
lmbda = 128
pnw = 40
#bw_vec2 = srch.SelectEven().MVAnalyse(isb=true, truemotion=false,delta=1,lambda=lmbda,pel=2,searchparam=me,sharp=2,blksize=bs,overlap=1*bs/2,pnew=pnw,idx=idx_1)
#fw_vec2 = srch.SelectEven().MVAnalyse(isb=false,truemotion=false,delta=1,lambda=lmbda,pel=2,searchparam=me,sharp=2,blksize=bs,overlap=1*bs/2,pnew=pnw,idx=idx_1)
#bw_vec3 = srch.SelectOdd() .MVAnalyse(isb=true, truemotion=false,delta=1,lambda=lmbda,pel=2,searchparam=me,sharp=2,blksize=bs,overlap=1*bs/2,pnew=pnw,idx=idx_1+1)
#fw_vec3 = srch.SelectOdd() .MVAnalyse(isb=false,truemotion=false,delta=1,lambda=lmbda,pel=2,searchparam=me,sharp=2,blksize=bs,overlap=1*bs/2,pnew=pnw,idx=idx_1+1)
ForBacEven = srch.SelectEven().MVAnalyseMulti(refframes=1,truemotion=false,lambda=lmbda,pel=2,searchparam=me,sharp=2,blksize=bs,overlap=1*bs/2,pnew=pnw,idx=idx_1)
ForBacOdd = srch.SelectOdd().MVAnalyseMulti(refframes=1,truemotion=false,lambda=lmbda,pel=2,searchparam=me,sharp=2,blksize=bs,overlap=1*bs/2,pnew=pnw,idx=idx_1+1)
baceven = ForBacEven.MVMultiExtract(0)
foreven = ForBacEven.MVMultiExtract(1)
bacodd = ForBacOdd.MVMultiExtract(0)
forodd = ForBacOdd.MVMultiExtract(1)
# Create RAW motion interpolation
# -------------------------------
#alt_1 = bobbed.SelectEven().MVFlowInter(bw_vec2,fw_vec2,time=50.0,thSCD1=64*18,thSCD2=227,idx=idx_2)
#alt_2 = bobbed.SelectOdd() .MVFlowInter(bw_vec3,fw_vec3,time=50.0,thSCD1=64*18,thSCD2=227,idx=idx_2+1).DuplicateFrame(0)
alt_1 = bobbed.SelectEven().MVFlowInter(baceven,foreven,time=50.0,thSCD1=64*18,thSCD2=227,idx=idx_2)
alt_2 = bobbed.SelectOdd() .MVFlowInter(bacodd,forodd,time=50.0,thSCD1=64*18,thSCD2=227,idx=idx_2+1).DuplicateFrame(0)
alt = Interleave(alt_2,alt_1)


# Create motion interpolation of "nothing new" mask
# -------------------------------------------------
#interpol_1 = interpol.SelectEven().MVFlowInter(bw_vec2,fw_vec2,time=50.0,thSCD1=64*8,thSCD2=127,idx=idx_3)
#interpol_2 = interpol.SelectOdd() .MVFlowInter(bw_vec3,fw_vec3,time=50.0,thSCD1=64*8,thSCD2=127,idx=idx_3+1).DuplicateFrame(0)
interpol_1 = interpol.SelectEven().MVFlowInter(baceven,foreven,time=50.0,thSCD1=64*8,thSCD2=127,idx=idx_3)
interpol_2 = interpol.SelectOdd() .MVFlowInter(bacodd,forodd,time=50.0,thSCD1=64*8,thSCD2=127,idx=idx_3+1).DuplicateFrame(0)
interpol_comp= Interleave(interpol_2,interpol_1)
nothing_new = mt_lutxy(interpol,interpol_comp,"x y * 255 / 255 / 1 2 / ^ 160 *")

josey_wells
10th August 2008, 01:25
Okay I've tried out the MVMultiExtract thing and I'm still getting issues with MVFlowInter. It's specifically saying that it's getting the wrong forward vectors.


Ok, this error comes from the fact that I was not setting the MVMultiExtract Analysis data until GetFrame and MVFlowInter was checking it in the constructor.

I have changed MVMultiExtract to set in constructor and all is working now.

Here is the MSVC08 dll only to test. I will do other compiles later if no other problems.

http://rapidshare.com/files/136172055/mvtools_V1.9.6.1_3.rar.html

Revgen
10th August 2008, 05:14
Okay, I tried this version, and it works now.

But it's not much faster than using MCBob single-threaded. I guess that's to be expected at this stage.

Keep up the good work.

josey_wells
10th August 2008, 22:27
Didn't seem to be too much reaction from last build.

OK, here is V1.9.6.1 Final.

http://rapidshare.com/files/136380190/MVTools_V1.9.6.1_Final.rar.html

This contains the fixes to MVMultiExtract. I also changed MVAnalyseMulti and MVDegrain's so that they do not call for frames from AviSynth if not needed. The routines were always doing child->GetFrame whether the information was cached or not. I have achieved about a 10-20% improvement with the change.

Have fun!

Zep
11th August 2008, 01:55
Didn't seem to be too much reaction from last build.

OK, here is V1.9.6.1 Final.

http://rapidshare.com/files/136380190/MVTools_V1.9.6.1_Final.rar.html

This contains the fixes to MVMultiExtract. I also changed MVAnalyseMulti and MVDegrain's so that they do not call for frames from AviSynth if not needed. The routines were always doing child->GetFrame whether the information was cached or not. I have achieved about a 10-20% improvement with the change.

Have fun!


thanks! awesome work! will test it out now :)

mikeytown2
11th August 2008, 02:30
Trying out a couple of things with TempGaussMC_beta1 (http://home.arcor.de/dhanselmann/_stuff/?C=M;O=D), This is the code block that I'm using to replace the current MVAnalyse block around line 160 (used Ctrl-Q for block comments in AvsP)


# Get motion vectors
_pel = 2

#~ bvec3 = (use3) ? searchclip.MVAnalyse(isb=true, delta=3,truemotion=_tm,pel=_pel,sharp=_shrp,blksize=_bs,overlap=_ovlp,lambda=_lambda,pnew=_pnew,
#~ \ global=_global,search=_search,searchparam=_ME,pelsearch=_pelsrch,DCT=_DCT,plevel=_plevel,lsad=_lsad,idx=6) : nullclip # ,sadx264=3
#~ bvec2 = (use2) ? searchclip.MVAnalyse(isb=true, delta=2,truemotion=_tm,pel=_pel,sharp=_shrp,blksize=_bs,overlap=_ovlp,lambda=_lambda,pnew=_pnew,
#~ \ global=_global,search=_search,searchparam=_ME,pelsearch=_pelsrch,DCT=_DCT,plevel=_plevel,lsad=_lsad,idx=6) : nullclip # ,sadx264=3
#~ bvec1 = (use1) ? searchclip.MVAnalyse(isb=true, delta=1,truemotion=_tm,pel=_pel,sharp=_shrp,blksize=_bs,overlap=_ovlp,lambda=_lambda,pnew=_pnew,
#~ \ global=_global,search=_search,searchparam=_ME,pelsearch=_pelsrch,DCT=_DCT,plevel=_plevel,lsad=_lsad,idx=6) : nullclip # ,sadx264=3
#~ fvec1 = (use1) ? searchclip.MVAnalyse(isb=false,delta=1,truemotion=_tm,pel=_pel,sharp=_shrp,blksize=_bs,overlap=_ovlp,lambda=_lambda,pnew=_pnew,
#~ \ global=_global,search=_search,searchparam=_ME,pelsearch=_pelsrch,DCT=_DCT,plevel=_plevel,lsad=_lsad,idx=6) : nullclip # ,sadx264=3
#~ fvec2 = (use2) ? searchclip.MVAnalyse(isb=false,delta=2,truemotion=_tm,pel=_pel,sharp=_shrp,blksize=_bs,overlap=_ovlp,lambda=_lambda,pnew=_pnew,
#~ \ global=_global,search=_search,searchparam=_ME,pelsearch=_pelsrch,DCT=_DCT,plevel=_plevel,lsad=_lsad,idx=6) : nullclip # ,sadx264=3
#~ fvec3 = (use3) ? searchclip.MVAnalyse(isb=false,delta=3,truemotion=_tm,pel=_pel,sharp=_shrp,blksize=_bs,overlap=_ovlp,lambda=_lambda,pnew=_pnew,
#~ \ global=_global,search=_search,searchparam=_ME,pelsearch=_pelsrch,DCT=_DCT,plevel=_plevel,lsad=_lsad,idx=6) : nullclip # ,sadx264=3

mVectors=MVAnalyseMulti(refframes=3,truemotion=_tm,pel=_pel,sharp=_shrp,blksize=_bs,overlap=_ovlp,lambda=_lambda,pnew=_pnew,global=_global,search=_search,searchparam=_ME,pelsearch=_pelsrch,DCT=_DCT,plevel=_plevel,lsad=_lsad,idx=6)
bvec3 = (use3) ? mVectors.MVMultiExtract(0) : nullclip
bvec2 = (use2) ? mVectors.MVMultiExtract(1) : nullclip
bvec1 = (use1) ? mVectors.MVMultiExtract(2) : nullclip
fvec1 = (use1) ? mVectors.MVMultiExtract(3) : nullclip
fvec2 = (use2) ? mVectors.MVMultiExtract(4) : nullclip
fvec3 = (use3) ? mVectors.MVMultiExtract(5) : nullclip


It doesn't come out looking right... any thoughts on where I went wrong?

Also around line 240 there is a MVDegrain Code Block, any chance of replacing it like this?


# final temporal filter for stabilisation, motion-compensated
#~ stage2 = (tr2==0) ? stage1b
#~ \ : (tr2==1) ? stage1b.MVDegrain1(bvec1,fvec1, thSAD=_thSAD2,thSCD1=_SCth1,thSCD2=_SCth2,idx=8)
#~ \ : (tr2==2) ? stage1b.MVDegrain2(bvec1,fvec1,bvec2,fvec2, thSAD=_thSAD2,thSCD1=_SCth1,thSCD2=_SCth2,idx=8)
#~ \ : stage1b.MVDegrain3(bvec1,fvec1,bvec2,fvec2,bvec3,fvec3,thSAD=_thSAD2,thSCD1=_SCth1,thSCD2=_SCth2,idx=8)

stage2 = (tr2==0) ? stage1b
\ : (tr2==1) ? stage1b.MVDegrainMulti(mVectors,1,thSAD=_thSAD2,thSCD1=_SCth1,thSCD2=_SCth2,idx=8)
\ : (tr2==2) ? stage1b.MVDegrainMulti(mVectors,2,thSAD=_thSAD2,thSCD1=_SCth1,thSCD2=_SCth2,idx=8)
\ : stage1b.MVDegrainMulti(mVectors,3,thSAD=_thSAD2,thSCD1=_SCth1,thSCD2=_SCth2,idx=8)



As of right now both of the above code blocks run but it doesn't produce correct output. I have not tested the 2nd code block independent of the 1st one, which means the 2nd one could be valid.

Gavino
11th August 2008, 09:40
#~ bvec3 = (use3) ? searchclip.MVAnalyse(isb=true, delta=3, ...)
...
mVectors=MVAnalyseMulti(refframes=3,truemotion=_tm, ...)
It doesn't come out looking right... any thoughts on where I went wrong?

Unless last=searchclip at this point, it should bemVectors=searchclip.MVAnalyseMulti(...)


stage2 = (tr2==0) ? stage1b
\ : (tr2==1) ? stage1b.MVDegrainMulti(mVectors,1,thSAD=_thSAD2,thSCD1=_SCth1,thSCD2=_SCth2,idx=8)
\ : (tr2==2) ? stage1b.MVDegrainMulti(mVectors,2,thSAD=_thSAD2,thSCD1=_SCth1,thSCD2=_SCth2,idx=8)
\ : stage1b.MVDegrainMulti(mVectors,3,thSAD=_thSAD2,thSCD1=_SCth1,thSCD2=_SCth2,idx=8)

Perhaps this could now be written more concisely as

stage2 = (tr2==0) ? stage1b
\ : stage1b.MVDegrainMulti(mVectors,tr2,thSAD=_thSAD2,thSCD1=_SCth1,thSCD2=_SCth2,idx=8)

mikeytown2
11th August 2008, 10:17
@josey_wells
Got another idea that hopefully won't be too hard to do and will allow people more freedom in choosing vectors. Make the opposite of MVMultiExtract(). Allow us to make/reorder vector arrays by using MVMultiExtract() along with a new function that will pack them into a single variable. Around line 170 of TempGaussMC_beta1, MVDegrain1 uses bvec2,fvec2 instead of bvec1,fvec1. I'm sure this is one of many examples where this could be useful. Also in setting refframes in MVDegrainMulti, does that determine the strength of the filter or is this variable ignored for the most part now?

@Gavino
Thanks for finding the error, it now works :)

josey_wells
11th August 2008, 11:38
I have found a memory corruption problem in MVAnalyseMulti for YUY2 data created with the caching optimization. I have fixed it but am working on some other things at the moment also.

Does anyone have a vote for the most popular MVTools function besides MVAnalyse and MVDegrain to possibly be looked at?


@josey_wells
Got another idea that hopefully won't be too hard to do and will allow people more freedom in choosing vectors. Make the opposite of MVMultiExtract(). Allow us to make/reorder vector arrays by using MVMultiExtract() along with a new function that will pack them into a single variable.

That is a lot more difficult since when I do an extract now it is basically referencing back to the MVAnayluseMulti data. How about an MVMultiPairExtract(int idx1, int idx2) which will extract any two pair from an existing MVMultiExtract and form a subset. Thoughts?

Also in setting refframes in MVDegrainMulti, does that determine the strength of the filter or is this variable ignored for the most part now?

If refframes is unspecified it will use the full passes multivector. IE if refframes=3 for MVAnalyseMulti then a MVDegrain3 equivalent would be performed. If refframes is specified less than passed in multivector then it will peform a lower temporal denoising. IE refframes=2 would be MVDegrain2 and refframes=1 would be MVDegrain1

Boulder
11th August 2008, 12:06
Does anyone have a vote for the most popular MVTools function besides MVAnalyse and MVDegrain to possibly be looked at?How about MVCompensate or the two MVFlowFPS functions? I think MVCompensate is more resource-hungry than MVFlowFPS.

Andrey /MAG/
11th August 2008, 15:59
MVFlowFps.

I use MVTools generally for make smooth motion by increasing FPS.

Ranguvar
11th August 2008, 16:19
Definitely MVCompensate, and then MVFlowFPS =]

Fizick
11th August 2008, 16:26
Didée,
I do not miss your feature request.
Probably it may be implemented by addind new function:

FilteredClip=SomePreFilter(Clip)
vector=MVAnalyse(FilteredClip, idx=1)
vectorWithNewSAD=MVApply(vector, Clip, dct=DCTMode, pelclip=PelClipIfNeeded, idx=2)
showSAD=MVMask(Clip,vectorWithNewSAD, kind=1)


But this MVApply is rather complex to code, and I am still in passive mode :)

mikeytown2
11th August 2008, 19:25
MVMultiPairExtract is perfect AFAIK so a quick example would be...

mVec=MVAnalyseMulti(refframes=3)
fvec1 = mVec.MVMultiExtract(3)
fvec2 = mVec.MVMultiExtract(4)

fvec1_2 = mVec.MVMultiPairExtract(3,4) #this or
fvec1_2 = MVMultiPairExtract(fvec1,fvec2) #this?


fvec2_bvec2 = mVec.MVMultiPairExtract(4,1) #would this work?
bvec2_fvec2 = mVec.MVMultiPairExtract(1,4) #this should work


The second one allows more freedom in that you can use vectors that did not come from MVAnalyseMulti; that could also be it's downfall.


If you can do MVCompensate first then MVFlow/MVFlowFPS/MVFlowInter (assuming very similar code base). If only one Flow then MVFlowFPS.

Fizick
11th August 2008, 21:00
IMO, the any extraction (one line by one vector stream) may be currently done with old good vertical Crop() function, and any packing (such as pairing) - by appropriate StackVertical() :)
But generally I am not very excited with this new Multi syntax numerous variants....

josey_wells
11th August 2008, 21:14
OK here is new version which fixes the data corruption problem. I have done compares with YUY2 data and YV12 data using old MVAnalyse and new MVAnalyseMulti to prove that they produce identical motion vector streams.

I have also added the requested MVMultiPairExtract function with an example below to show usage


c=last
MVMulti=MVAnalyseMulti(refframes=3, idx=1)
MVMulti2=MVMulti.MVMultiPairExtract(1, 4) # bac2 and for2
bac2=MVMulti2.MVMultiExtract(0)
for2=MVMulti2.MVMultiExtract(1)

bac2a=MVMulti.MVMultiExtract(1)
for2a=MVMulti.MVMultiExtract(4)

l1=c.MVshow(for2)
l2=c.MVshow(for2a)

Compare(l1, l2)

http://rapidshare.com/files/136611306/MV1.9.6.2_1.rar.html

IMO, the any extraction (one line by one vector stream) may be currently done with old good vertical Crop() function, and any packing (such as pairing) - by appropriate StackVertical()

Crop does not insure that the analysis data which is passed in the vi information is copied correctly, and is why the Multi variants are needed.

Before any more functions are multithreaded I think I want to try one more change to MVAnalyse where the SAD Chroma U's and SAD Chroma V's are calculated on different threads. This may give a good improvement. Since refframes=1 would spin 2*2=4 threads in total and refframes=2 would spin 4*2=8 threads in total.

Also some feedback that this is worthwhile to other people besides myself which it really serves the purpose would be nice.

mikeytown2
12th August 2008, 00:13
Fizick has a good point, usually the less function names the better for documentation and usability in general... You could make MVMultiExtract take multiple ints, so with one it behaves as normal, with 2+ it acts like MVMultiPairExtract (this is my opinion, opinions can be wrong).



Also some feedback that this is worthwhile to other people besides myself which it really serves the purpose would be nice.

So far I've seen many speed improvements and I believe that the lessons learned here with threading might be applied to AviSynth's core along with other filters. This effort has started to tame some of the highest quality bobers out there, and for that I believe a lot of people are/will be grateful! These latest developments might be justification for some people to go purchase a 2 x 4 core machine.

josey_wells
12th August 2008, 02:48
Fizick has a good point, usually the less function names the better for documentation and usability in general... You could make MVMultiExtract take multiple ints, so with one it behaves as normal, with 2+ it acts like MVMultiPairExtract (this is my opinion, opinions can be wrong)

Since AviSynth doesn't allow variable number of arguments do you mean something like

MVMultiExtract(int index1, int index2, int index3, int index4) where the indexX is given a default illegal value like -1 to indicate it is not used

Boulder
12th August 2008, 03:39
So far I've seen many speed improvements and I believe that the lessons learned here with threading might be applied to AviSynth's core along with other filters. This effort has started to tame some of the highest quality bobers out there, and for that I believe a lot of people are/will be grateful! These latest developments might be justification for some people to go purchase a 2 x 4 core machine.Multithreaded MVAnalyse and MVDegrain have been very useful to me. When I mentioned some time ago that it would be nice if MVTools were multithreaded without SetMTMode, I never thought that the performance boost would be this big :) Motion estimation and compensation is utilized in many areas so all this will benefit many of us.

josey_wells
12th August 2008, 03:46
Does anyone have any performance numbers to post with regards to latest build showing performance improvement?

The extra threads for SAD were a bust since it increased kernel contention time too much. So the latest build will have the best MVAnalyse and MVDegrain performance unless inspiration strikes me.

I will try to implement the single MVMultiExtract tommorrow which will be used to pull single or multiple motion vectors.

Boulder
12th August 2008, 03:59
I'll try to find the time to run a few tests this evening, comparing the latest official build and your latest build.

AVIL
12th August 2008, 08:11
Hi,

Since AviSynth doesn't allow variable number of arguments do you mean something like

MVMultiExtract(int index1, int index2, int index3, int index4) where the indexX is given a default illegal value like -1 to indicate it is not used

Clouded's Average plugin or Corrector from Manao/Fizick are examples of plugins with variable number of arguments.

Leak
12th August 2008, 09:27
Clouded's Average plugin or Corrector from Manao/Fizick are examples of plugins with variable number of arguments.
Or even the AviSynth built-in (Un-)AlignedSplice or Interleave filters...

Gavino
12th August 2008, 09:46
... AviSynth doesn't allow variable number of arguments ...
It doesn't allow (or doesn't provide a means of writing) a script function with a variable number of arguments, but it's no problem for a plugin function, and there are numerous examples in the built-in filters (Splice, Interleave, StackHorizontal, etc).

In the signature string in env->AddFunction, you use + or * to indicate a variable number of repetitions, eg "i+" means one or more integer arguments.

josey_wells
12th August 2008, 18:22
OK here is final V19.6.2 for awhile unles problem is found.

http://rapidshare.com/files/136825400/MVTools_V1.9.6.2_Final.rar.html

Leak, Gavino, AVIL

Thank you for the clarification about multiple arguments.

This version removed MVMultiPairExtract and combines the functionality into MVMulitExtract which can be used to extract multiple or single motion data.

for example

MVMulti=MVMultiAnalyse(last, refframes=3)
bac3=MVMulti.MVMultiExtract(0)
MVMulti2=MVMulti.MVMultiExtract(1, 4) #bac2 & for2

indices must be ascending order

I also made a couple little speed tweaks which might get a couple .x% points.

remember MVDegrainMulti always expects an even number of Multiframes in the order of most backward to most forward.

Zep
13th August 2008, 14:57
OK here is final V19.6.2 for awhile unles problem is found.

http://rapidshare.com/files/136825400/MVTools_V1.9.6.2_Final.rar.html


Tested this a good bit and no crashes or bugs pop out at me yet :)


As for a general feedback your improvements are great for simple scripts and you do get a speed increase. The down side though is more complex scripts you get a huge speed decrease because on those scripts you really do need setMTmode(2,8) for other functions but 8 setMTmode threads just kills MVMultiAnalyse/MVDegrainMulti due to I guess massive overhead. (I can see 70 MVtools.dll threads in task manager VS just 8 with the old version)

on my quad it appears the sweet spot for something like

MVForBack = last.MVAnalyseMulti(refframes=3, pel=2, overlap=0, sharp=2,blksize=8,sadx264=3,idx=1)
last.MVDegrainMulti(MVForBack,thSAD=300,idx=1)

is setMTmode(2,3)


Anymore threads and it it starts to slow down so if your script has other functions that need SetMTmode 4 threads or more then one should use the old version. (at least this is what I am seeing)

thanks!

morsa
13th August 2008, 20:17
I'm getting color artifacts (color Blocks, mostly gree, as if they were digital video drops) using MCbob and MVflowFPS with the core2duo version.

Can anyone reproduce it?

(Same with P4 version and plain C version)

Tried this script:

clp=last
idx = 1
bw1_vec1 = clp.MVAnalyse(isb = true, truemotion=true, lambda=2000, searchparam=8, pel=4, idx=idx,dct=3, divide=1)
fw1_vec1 = clp.MVAnalyse(isb = false, truemotion=true, lambda=2000, searchparam=8, pel=4, idx=idx,dct=3, divide=1)
clp.MVFlowFps(bw1_vec1,fw1_vec1,num=50,idx=idx, ml= 200)

Fizick's latest is working fine though.

mikeytown2
13th August 2008, 21:33
@morsa Can you post screen shots, one with the latest MVTools 1.9.6.2 and one with 1.9.5.7? Also post or reference the code that your using if you have modified the source of MCBob in order to take advantage of multi threading.

morsa
14th August 2008, 01:18
So this means nobody tested it or this issue is just a problem I have on my core 2 Quad system.

I cannot post the images I'm using, and anyway it is not related to those images. I didn't modified anything in MCbob and the same problem happens with the little script I posted above.

mikeytown2
14th August 2008, 01:31
There is an issue with MVFlowFps!

Here is a simple script that everyone should be able to run


a = ColorBars().Trim(0,99)

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()

clp=last
idx = 1
bw1_vec1 = clp.MVAnalyse(isb = true, truemotion=true, lambda=2000, searchparam=8, pel=4, idx=idx,dct=3, divide=1)
fw1_vec1 = clp.MVAnalyse(isb = false, truemotion=true, lambda=2000, searchparam=8, pel=4, idx=idx,dct=3, divide=1)
clp.MVFlowFps(bw1_vec1,fw1_vec1,num=50,idx=idx, ml= 200)


Requires KenBurnsEffect() (http://forum.doom9.org/showthread.php?t=135776)

Frame 51 with 1.9.6.2
http://img388.imageshack.us/img388/8590/23702731qb9.th.png (http://img388.imageshack.us/my.php?image=23702731qb9.png)

Frame 51 with 1.9.5.7
http://img204.imageshack.us/img204/6193/72165764se3.th.png (http://img204.imageshack.us/my.php?image=72165764se3.png)


EDIT: this fails as well...

vectors=MVAnalyseMulti(refframes=1)
bw1_vec1=vectors.MVMultiExtract(0)
fw1_vec1=vectors.MVMultiExtract(1)
last.MVFlowFps(bw1_vec1,fw1_vec1)

Boulder
14th August 2008, 03:40
Does anyone have any performance numbers to post with regards to latest build showing performance improvement?I've done some testing and the performance gain has been 40-50% with a script that has two MVDegrainMulti calls and using pel=4.

josey_wells
14th August 2008, 03:44
Tested this a good bit and no crashes or bugs pop out at me yet :)


As for a general feedback your improvements are great for simple scripts and you do get a speed increase. The down side though is more complex scripts you get a huge speed decrease because on those scripts you really do need setMTmode(2,8) for other functions but 8 setMTmode threads just kills MVMultiAnalyse/MVDegrainMulti due to I guess massive overhead. (I can see 70 MVtools.dll threads in task manager VS just 8 with the old version)

on my quad it appears the sweet spot for something like

MVForBack = last.MVAnalyseMulti(refframes=3, pel=2, overlap=0, sharp=2,blksize=8,sadx264=3,idx=1)
last.MVDegrainMulti(MVForBack,thSAD=300,idx=1)

is setMTmode(2,3)


Anymore threads and it it starts to slow down so if your script has other functions that need SetMTmode 4 threads or more then one should use the old version. (at least this is what I am seeing)

thanks!

Threading efficiency can be guaged by how much time the OS is spending in the kernel. This can be turned on in the task manager. A high kernel percentage indicates thread contention.

I am currently running 35 threads with little to no kernel contention.

I have run applications spinning close to 100 threads which process efficiently. As long as threads are not fighting for resources or are run sequentially based on events a lot of threads is not a problem.

The SetMTMode puts critical sections in the GetFrame class of AviSynth. This causes all the threads to fight to get frames and thus lowers speed.

Nevertheless, I will add an MT boolean flag which will cause the MultiThreaded functions to process the threads sequentially via semaphores.

There is an issue with MVFlowFps!

That's interesting since that code was not changed in V1.9.6.2. I wonder if Fzick compiled with differnet settings.

However, I can't test this now as I am in the middle of some major updates covering the following:

1. A multitude of memory fragmentation and alignment problems have been fixed.
2. A bug in YUY2 planes have been fixed.
3. At more than one hundred of places delete was used where delete [] was needed.
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.
5. I want to redo the cache mechanism for idx since I believe it can be made clearner using the STL map class.
6. I have fixed several other stability problems. The worst being where a destructor was called twice after the object was detroyed.

I have greater than 120 hours in this now and my goal is to get to a stable baseline where more functions are ready to be multithreaded as time permits but are running at optimal efficiency and stability. Although I doubt this will ever be officially adopted and always remain a branch.

josey_wells
14th August 2008, 03:57
I've done some testing and the performance gain has been 40-50% with a script that has two MVDegrainMulti calls and using pel=4.

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.

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