Log in

View Full Version : MTi(), mvtools2, and MDePan


halsboss
26th January 2009, 14:34
Moved a couple of posts from the dev forum (didn't realise it was the dev forum until just now)...

1. Need guidance with MTi(), mvtools2, and MDePan. I'm sure I've seen stuff before but can't locate the answers.

The MVtools2 doco says use this for interlaced (non-MTi processing) of interlaced material (I have a DV source):-
function MDegrain2i2(clip source, int "overlap", int "dct") {
overlap=default(overlap,4) # overlap value (0 to 4 for blksize=8)
dct=default(dct,0) # use dct=1 for clip with light flicker
fields=source.AssumeBFF().SeparateFields() # separate by fields
super = fields.MSuper()
backward_vec2 = super.MAnalyse(isb = true, delta = 2, overlap=overlap, dct=dct)
forward_vec2 = super.MAnalyse(isb = false, delta = 2, overlap=overlap, dct=dct)
backward_vec4 = super.MAnalyse(isb = true, delta = 4, overlap=overlap, dct=dct)
forward_vec4 = super.MAnalyse(isb = false, delta = 4, overlap=overlap, dct=dct)
fields.MDegrain2(super, backward_vec2,forward_vec2,backward_vec4,forward_vec4,thSAD=400)
Weave()
}

which separates the fields the analyses use deltas of 2 and 4 (presumably so even-fields match and odd-fields match).
Can someone please confirm whether this is functionally equivalent to MT's MTi processing http://avisynth.org/mediawiki/MT :-

source1=last.AssumeBFF()
result=MTi(source1,"MDegrain2i2_insideMTi()")
function MDegrain2i2_insideMTi(clip source, int "overlap", int "dct") {
overlap=default(overlap,4) # overlap value (0 to 4 for blksize=8)
dct=default(dct,0) # use dct=1 for clip with light flicker
fields=source # separate by fields already done by MTi
super = fields.MSuper()
backward_vec2 = super.MAnalyse(isb = true, delta = 1, overlap=overlap, dct=dct)
forward_vec2 = super.MAnalyse(isb = false, delta = 1, overlap=overlap, dct=dct)
backward_vec4 = super.MAnalyse(isb = true, delta = 2, overlap=overlap, dct=dct)
forward_vec4 = super.MAnalyse(isb = false, delta = 2, overlap=overlap, dct=dct)
fields.MDegrain2(super, backward_vec2,forward_vec2,backward_vec4,forward_vec4,thSAD=400)
}

Also, in the same manner I wonder about Depan of interlaced material too... will this result in a "depanned" interlaced result ?
The mvtools2 documentation says

AssumeBFF().SeparateFields() # set correct fields order
vectors = MSuper().MAnalyse(isb = false)
globalmotion = MDepan(vectors, pixaspect=1.094, thSCD1=400)
DepanStabilize(data=globalmotion, cutoff=2.0, mirror=15, pixaspect=1.094)
Weave()

But I'm guessing that isn't functionally equivalent to this below since Manalyses are only getting 1/2 the fields to look at (MTi feeds each thread only even or odd fields exclusively)

source1=last.AssumeBFF()
result=MTi(source1,"MDepan_insideMTi()")
function MDepan_insideMTi(clip source) {
vectors = MSuper(source).MAnalyse(isb = false)
globalmotion = MDepan(vectors, pixaspect=1.094, thSCD1=400)
source.DepanStabilize(data=globalmotion, cutoff=2.0, mirror=15, pixaspect=1.094)
}

Any suggestions ?

2. Just a query re motion stablilization and the new V2 MDePan-

#MDepan(clip, clip vectors, bool "zoom", bool "rot", float "pixaspect", float "error", bool "info", string "log", float "wrong", float "zerow", int "range", int "thSCD1", int "thSCD2", bool "isse")
super=MSuper()
vectors = MAnalyse(super, isb=false, overlap=4)
globalmotion = MDepan(vectors, zoom=true, rot=true, pixaspect=1.094, thSCD1=400, range=2) #
DepanStabilize(data=globalmotion, cutoff=2.0, mirror=15, pixaspect=1.094) #1.094 for standard PAL

The example in the documentation uses Msuper and then only 1 MAnalyse which looks forward and then feeds the manalyse result into MDePan, am I using it right ? How does that relate to the range parameter; I'd thought MDePan would have to work over the super clip instead ?

Also, do people recommend using the range parameter and if so what values ? I'd assumed the larger the better, eg 2 or 3. And is this correct usage for a prefiltered clip ?

prefiltered = last.FFT3DFilter(sigma=3, interlaced=false, plane=4)
prefilteredSuper = MSuper(prefiltered, pel=2)
#super = MSuper(pel=2)
vectors = prefiltered.MAnalyse(prefilteredSuper, isb=false, overlap=4)
globalmotion = prefiltered.MDepan(vectors, zoom=true, rot=true, pixaspect=1.094, thSCD1=400) #1.094 for standard PAL
last.DepanStabilize(data=globalmotion, cutoff=2.0, mirror=15, pixaspect=1.094) #1.094 for standard PAL

Sagekilla
26th January 2009, 17:21
If you use MT() the results probably won't be the same. Reason? MT() and MTi() split the frame spatially. If you have a filter that produces output based on the -whole- frame then running it under MT() will affect it.

If you want my 2 cents: I'd recommend doing a dumb bob(), do all your processing, and throw those new fields away.

Fizick
26th January 2009, 19:03
halsboss,
1. You are right in all your guessings.

2. Your scripts are correct.
Range parameter value is not critical. Results will be same, but speed may vary a little.

Alex_ander
26th January 2009, 21:34
I always do as Sagekilla has just suggested, use bob (not necessarily dumb) instead of simple field separation, re-interlace after filtering. Strongly suspect it's more safe with that kind of processing (as with all denoisers). If a filter produces changes in pixel positions, those pixels shouldn't be limited in moving within just even or odd fields.

Sagekilla
26th January 2009, 22:34
Dumb bob usually works fine in most cases. Using a sharper and more accurate bobber can help depending on the filter but if you're pressed for speed, dumb bob never hurts :)

halsboss
26th January 2009, 22:43
OK, Thanks.
Will read up on Bobbing and reinterlacing. I reckon there's a thread on TFF/BFF and correct reinterlacing, somewhere.
Edit yes it's http://forum.doom9.org/showthread.php?p=1110741#post1110741 which shows how to reinterlace doubleframerate material. In my BFF case it's AssumeBFF().SeparateFields().SelectEvery(4,0,3).Weave()

Segakilla, I read MTi does separatefields rather than spatial split although that is still "bad" ?

Fizick, thanks for confirming that these aren't functionally equivalent :
I wonder about Depan of interlaced material too... will this result in a "depanned" interlaced result ?
The mvtools2 documentation says

AssumeBFF().SeparateFields() # set correct fields order
vectors = MSuper().MAnalyse(isb = false)
globalmotion = MDepan(vectors, pixaspect=1.094, thSCD1=400)
DepanStabilize(data=globalmotion, cutoff=2.0, mirror=15, pixaspect=1.094)
Weave()

But I'm guessing that isn't functionally equivalent to this below since Manalyses are only getting 1/2 the fields to look at (MTi feeds each thread only even or odd fields exclusively)

source1=last.AssumeBFF()
result=MTi(source1,"MDepan_insideMTi()")
function MDepan_insideMTi(clip source) {
vectors = MSuper(source).MAnalyse(isb = false)
globalmotion = MDepan(vectors, pixaspect=1.094, thSCD1=400)
source.DepanStabilize(data=globalmotion, cutoff=2.0, mirror=15, pixaspect=1.094)
}

Sagekilla
26th January 2009, 22:51
I'm pretty sure MTi() is basically an alias for: SeparateFields().MT().Weave()

halsboss
27th January 2009, 00:07
Thanks, Googled it and http://avisynth.org/mediawiki/index.php?title=MT&printable=yes says
function PseudoMTi(clip c,string filter)
{
a=eval("c.AssumeFieldBased().SeparateFields.selecteven()."+filter)
b=eval("c.AssumeFieldBased().SeparateFields.selectodd()."+filter)
interleave(a,b).weave()
}

Anyway, looks like I still need to do as you suggest with deinterlacing...

halsboss
27th January 2009, 00:12
Well, I hope I have this right re the deinterlacing and reinterlacing... anyone willing to constructively criticise ?
SetMTmode(mode=5,threads=4) # start with mode=5 forAVIsource http://forum.doom9.org/showthread.php?p=1067216#post1067216
SetMemoryMax(1024) #have 4Gb albeit in XP/win32
LoadPlugin("C:\Program Files\AviSynth 2.5\plugins-zzz\Yadifmod.dll")
LoadPlugin("C:\Program Files\AviSynth 2.5\plugins-zzz\NNEDI.dll")
LoadPlugin("C:\Program Files\AviSynth 2.5\plugins-zzz\DePan.dll")
LoadPlugin("C:\Program Files\AviSynth 2.5\plugins-zzz\AGC.dll")
LoadPlugin("C:\Program Files\AviSynth 2.5\plugins-zzz\fft3dfilter.dll")
LoadPlugin("C:\Program Files\AviSynth 2.5\plugins-zzz\degrainmedian.dll")
LoadPlugin("C:\Program Files\AviSynth 2.5\plugins-zzz\Convolution3d.dll")
LoadPlugin("C:\Program Files\AviSynth 2.5\plugins-zzz\WarpSharp.dll")
LoadPlugin("C:\Program Files\AviSynth 2.5\plugins-zzz\aWarpSharp.dll")
LoadPlugin("C:\Program Files\AviSynth 2.5\plugins-zzz\mt_masktools.dll")
LoadPlugin("C:\Program Files\AviSynth 2.5\plugins-zzz\mvtools2.dll")
LoadPlugin("C:\Program Files\AviSynth 2.5\plugins-zzz\Unfilter.dll")
LoadPlugin("C:\Program Files\AviSynth 2.5\plugins-zzz\AddgrainC.dll")
LoadPlugin("C:\Program Files\AviSynth 2.5\plugins-zzz\RemoveGrainSSE2.dll")
LoadPlugin("C:\Program Files\AviSynth 2.5\plugins-zzz\RepairSSE2.dll")
LoadPlugin("C:\Program Files\AviSynth 2.5\plugins-zzz\RemoveDirtSSE2.dll")
Import("C:\Program Files\AviSynth 2.5\LimitedSharpenFaster.avs")

AviSource("G:\CAPTURE\test\test.avi", audio=false)
AssumeFPS(25)
AssumeBFF()
Converttoyv12(interlaced=true) # do this here so not to break chroma during processing

SetMTmode(mode=2,threads=4)

# Deinterlace DV PAL 720x576 16:9 camcorder BFF material to double-framerate,
# process it with mvtools2 mdegrain or whatever,
# then reinterlace by throwing away the interpolated field.

# 1. Deinterlace first
# nnedi field=-2 requires assumeXff() be set first !
# yadifmod order=-1 requires assumeXff() be set first !
# yadifmod mode=1=doubleframerate
AssumeBFF()
yadifmod(mode=1, order=-1, edeint=nnedi(field=-2))

####
#### 2. processing of non-interlaced material goes in here, say degrain3
####

# 3. now reinterlace to BFF single-framerate by throwing away the interpolated top field
# see http://forum.doom9.org/showthread.php?p=1110741#post1110741
AssumeBFF()
SeparateFields()
SelectEvery(4,0,3)
Weave()

# 4. If I have it right, we can only Stabilize *AFTER* reinterlacing
# since to do otherwise would cause it to use the interpolated (top) field
# during the reinterlacing, which we don't want.
AssumeBFF()
SeparateFields()
vectors1 = MSuper().MAnalyse(isb = false)
globalmotion1 = MDepan(vectors1, zoom=true, rot=true, pixaspect=1.094, thSCD1=400)
# I wish I could figure out what cutoff and rotmax and prev and next *actually* meant :)
# Fizick said "Only high frequency vibration (above cutoff) will be stabilized."
DepanStabilize(data=globalmotion1, cutoff=0.5, rotmax=5, mirror=15, prev=3, next=3, pixaspect=1.094)
Weave()
AssumeBFF()

# 5. Finished. Now we have a reinterlaced, stablisised PAL 720x576 16:9 clip ready for HCenc
SetPlanarLegacyAlignment(True)
Distributor() # use this when using HC and SetMTmode, per http://forum.doom9.org/showthread.php?p=1063622#post1063622

## Misc functions used to compare clips from time to time
## eg for clips ORIGINAL and PROCESSED
## zzzBox4(ORIGINAL,"original",PROCESSED,"processed") ++ zzzBox4(PROCESSED,"processed",ORIGINAL,"original")
Function zzzBox2(Clip a, string asub, Clip b, string bsub) {
hClip = a.height()
wClip = a.width()
stackvertical(stackhorizontal(a.crop(0*wClip/2,0*hClip/2,-1*wClip/2,-1*hClip/2).subtitle(aSub,size=10), \
b.crop(1*wClip/2,0*hClip/2,-0*wClip/2,-1*hClip/2).subtitle(bSub,size=10)), \
stackhorizontal(b.crop(0*wClip/2,1*hClip/2,-1*wClip/2,-0*hClip/2).subtitle(bSub,size=10), \
a.crop(1*wClip/2,1*hClip/2,-0*wClip/2,-0*hClip/2).subtitle(aSub,size=10)))
}
Function zzzBox4(Clip a, string asub, Clip b, string bsub) {
hClip = a.height()
wClip = a.width()
stackvertical(stackhorizontal(a.crop(0*wClip/4,0*hClip/4,-3*wClip/4,-3*hClip/4).subtitle(aSub,size=10), \
b.crop(1*wClip/4,0*hClip/4,-2*wClip/4,-3*hClip/4).subtitle(bSub,size=10), \
a.crop(2*wClip/4,0*hClip/4,-1*wClip/4,-3*hClip/4).subtitle(aSub,size=10), \
b.crop(3*wClip/4,0*hClip/4,-0*wClip/4,-3*hClip/4).subtitle(bSub,size=10)), \
stackhorizontal(b.crop(0*wClip/4,1*hClip/4,-3*wClip/4,-2*hClip/4).subtitle(bSub,size=10), \
a.crop(1*wClip/4,1*hClip/4,-2*wClip/4,-2*hClip/4).subtitle(aSub,size=10), \
b.crop(2*wClip/4,1*hClip/4,-1*wClip/4,-2*hClip/4).subtitle(bSub,size=10), \
a.crop(3*wClip/4,1*hClip/4,-0*wClip/4,-2*hClip/4).subtitle(aSub,size=10)), \
stackhorizontal(a.crop(0*wClip/4,2*hClip/4,-3*wClip/4,-1*hClip/4).subtitle(aSub,size=10), \
b.crop(1*wClip/4,2*hClip/4,-2*wClip/4,-1*hClip/4).subtitle(bSub,size=10), \
a.crop(2*wClip/4,2*hClip/4,-1*wClip/4,-1*hClip/4).subtitle(aSub,size=10), \
b.crop(3*wClip/4,2*hClip/4,-0*wClip/4,-1*hClip/4).subtitle(bSub,size=10)), \
stackhorizontal(b.crop(0*wClip/4,3*hClip/4,-3*wClip/4,-0*hClip/4).subtitle(bSub,size=10), \
a.crop(1*wClip/4,3*hClip/4,-2*wClip/4,-0*hClip/4).subtitle(aSub,size=10), \
b.crop(2*wClip/4,3*hClip/4,-1*wClip/4,-0*hClip/4).subtitle(bSub,size=10), \
a.crop(3*wClip/4,3*hClip/4,-0*wClip/4,-0*hClip/4).subtitle(aSub,size=10)))
}
Function zzzBox8(Clip a, string asub, Clip b, string bsub) {
hClip = a.height()
wClip = a.width()
stackvertical(stackhorizontal(a.crop(0*wClip/8,0*hClip/8,-7*wClip/8,-7*hClip/8).subtitle(aSub,size=10), \
b.crop(1*wClip/8,0*hClip/8,-6*wClip/8,-7*hClip/8).subtitle(bSub,size=10), \
a.crop(2*wClip/8,0*hClip/8,-5*wClip/8,-7*hClip/8).subtitle(aSub,size=10), \
b.crop(3*wClip/8,0*hClip/8,-4*wClip/8,-7*hClip/8).subtitle(bSub,size=10), \
a.crop(4*wClip/8,0*hClip/8,-3*wClip/8,-7*hClip/8).subtitle(aSub,size=10), \
b.crop(5*wClip/8,0*hClip/8,-2*wClip/8,-7*hClip/8).subtitle(bSub,size=10), \
a.crop(6*wClip/8,0*hClip/8,-1*wClip/8,-7*hClip/8).subtitle(aSub,size=10), \
b.crop(7*wClip/8,0*hClip/8,-0*wClip/8,-7*hClip/8).subtitle(bSub,size=10)), \
stackhorizontal(b.crop(0*wClip/8,1*hClip/8,-7*wClip/8,-6*hClip/8).subtitle(bSub,size=10), \
a.crop(1*wClip/8,1*hClip/8,-6*wClip/8,-6*hClip/8).subtitle(aSub,size=10), \
b.crop(2*wClip/8,1*hClip/8,-5*wClip/8,-6*hClip/8).subtitle(bSub,size=10), \
a.crop(3*wClip/8,1*hClip/8,-4*wClip/8,-6*hClip/8).subtitle(aSub,size=10), \
b.crop(4*wClip/8,1*hClip/8,-3*wClip/8,-6*hClip/8).subtitle(bSub,size=10), \
a.crop(5*wClip/8,1*hClip/8,-2*wClip/8,-6*hClip/8).subtitle(aSub,size=10), \
b.crop(6*wClip/8,1*hClip/8,-1*wClip/8,-6*hClip/8).subtitle(bSub,size=10), \
a.crop(7*wClip/8,1*hClip/8,-0*wClip/8,-6*hClip/8).subtitle(aSub,size=10)), \
stackhorizontal(a.crop(0*wClip/8,2*hClip/8,-7*wClip/8,-5*hClip/8).subtitle(aSub,size=10), \
b.crop(1*wClip/8,2*hClip/8,-6*wClip/8,-5*hClip/8).subtitle(bSub,size=10), \
a.crop(2*wClip/8,2*hClip/8,-5*wClip/8,-5*hClip/8).subtitle(aSub,size=10), \
b.crop(3*wClip/8,2*hClip/8,-4*wClip/8,-5*hClip/8).subtitle(bSub,size=10), \
a.crop(4*wClip/8,2*hClip/8,-3*wClip/8,-5*hClip/8).subtitle(aSub,size=10), \
b.crop(5*wClip/8,2*hClip/8,-2*wClip/8,-5*hClip/8).subtitle(bSub,size=10), \
a.crop(6*wClip/8,2*hClip/8,-1*wClip/8,-5*hClip/8).subtitle(aSub,size=10), \
b.crop(7*wClip/8,2*hClip/8,-0*wClip/8,-5*hClip/8).subtitle(bSub,size=10)), \
stackhorizontal(b.crop(0*wClip/8,3*hClip/8,-7*wClip/8,-4*hClip/8).subtitle(bSub,size=10), \
a.crop(1*wClip/8,3*hClip/8,-6*wClip/8,-4*hClip/8).subtitle(aSub,size=10), \
b.crop(2*wClip/8,3*hClip/8,-5*wClip/8,-4*hClip/8).subtitle(bSub,size=10), \
a.crop(3*wClip/8,3*hClip/8,-4*wClip/8,-4*hClip/8).subtitle(aSub,size=10), \
b.crop(4*wClip/8,3*hClip/8,-3*wClip/8,-4*hClip/8).subtitle(bSub,size=10), \
a.crop(5*wClip/8,3*hClip/8,-2*wClip/8,-4*hClip/8).subtitle(aSub,size=10), \
b.crop(6*wClip/8,3*hClip/8,-1*wClip/8,-4*hClip/8).subtitle(bSub,size=10), \
a.crop(7*wClip/8,3*hClip/8,-0*wClip/8,-4*hClip/8).subtitle(aSub,size=10)), \
stackhorizontal(a.crop(0*wClip/8,4*hClip/8,-7*wClip/8,-3*hClip/8).subtitle(aSub,size=10), \
b.crop(1*wClip/8,4*hClip/8,-6*wClip/8,-3*hClip/8).subtitle(bSub,size=10), \
a.crop(2*wClip/8,4*hClip/8,-5*wClip/8,-3*hClip/8).subtitle(aSub,size=10), \
b.crop(3*wClip/8,4*hClip/8,-4*wClip/8,-3*hClip/8).subtitle(bSub,size=10), \
a.crop(4*wClip/8,4*hClip/8,-3*wClip/8,-3*hClip/8).subtitle(aSub,size=10), \
b.crop(5*wClip/8,4*hClip/8,-2*wClip/8,-3*hClip/8).subtitle(bSub,size=10), \
a.crop(6*wClip/8,4*hClip/8,-1*wClip/8,-3*hClip/8).subtitle(aSub,size=10), \
b.crop(7*wClip/8,4*hClip/8,-0*wClip/8,-3*hClip/8).subtitle(bSub,size=10)), \
stackhorizontal(b.crop(0*wClip/8,5*hClip/8,-7*wClip/8,-2*hClip/8).subtitle(bSub,size=10), \
a.crop(1*wClip/8,5*hClip/8,-6*wClip/8,-2*hClip/8).subtitle(aSub,size=10), \
b.crop(2*wClip/8,5*hClip/8,-5*wClip/8,-2*hClip/8).subtitle(bSub,size=10), \
a.crop(3*wClip/8,5*hClip/8,-4*wClip/8,-2*hClip/8).subtitle(aSub,size=10), \
b.crop(4*wClip/8,5*hClip/8,-3*wClip/8,-2*hClip/8).subtitle(bSub,size=10), \
a.crop(5*wClip/8,5*hClip/8,-2*wClip/8,-2*hClip/8).subtitle(aSub,size=10), \
b.crop(6*wClip/8,5*hClip/8,-1*wClip/8,-2*hClip/8).subtitle(bSub,size=10), \
a.crop(7*wClip/8,5*hClip/8,-0*wClip/8,-2*hClip/8).subtitle(aSub,size=10)), \
stackhorizontal(a.crop(0*wClip/8,6*hClip/8,-7*wClip/8,-1*hClip/8).subtitle(aSub,size=10), \
b.crop(1*wClip/8,6*hClip/8,-6*wClip/8,-1*hClip/8).subtitle(bSub,size=10), \
a.crop(2*wClip/8,6*hClip/8,-5*wClip/8,-1*hClip/8).subtitle(aSub,size=10), \
b.crop(3*wClip/8,6*hClip/8,-4*wClip/8,-1*hClip/8).subtitle(bSub,size=10), \
a.crop(4*wClip/8,6*hClip/8,-3*wClip/8,-1*hClip/8).subtitle(aSub,size=10), \
b.crop(5*wClip/8,6*hClip/8,-2*wClip/8,-1*hClip/8).subtitle(bSub,size=10), \
a.crop(6*wClip/8,6*hClip/8,-1*wClip/8,-1*hClip/8).subtitle(aSub,size=10), \
b.crop(7*wClip/8,6*hClip/8,-0*wClip/8,-1*hClip/8).subtitle(bSub,size=10)), \
stackhorizontal(b.crop(0*wClip/8,7*hClip/8,-7*wClip/8,-0*hClip/8).subtitle(bSub,size=10), \
a.crop(1*wClip/8,7*hClip/8,-6*wClip/8,-0*hClip/8).subtitle(aSub,size=10), \
b.crop(2*wClip/8,7*hClip/8,-5*wClip/8,-0*hClip/8).subtitle(bSub,size=10), \
a.crop(3*wClip/8,7*hClip/8,-4*wClip/8,-0*hClip/8).subtitle(aSub,size=10), \
b.crop(4*wClip/8,7*hClip/8,-3*wClip/8,-0*hClip/8).subtitle(bSub,size=10), \
a.crop(5*wClip/8,7*hClip/8,-2*wClip/8,-0*hClip/8).subtitle(aSub,size=10), \
b.crop(6*wClip/8,7*hClip/8,-1*wClip/8,-0*hClip/8).subtitle(bSub,size=10), \
a.crop(7*wClip/8,7*hClip/8,-0*wClip/8,-0*hClip/8).subtitle(aSub,size=10)))
}


edit: remembered link to non-MT mvtools1 version/queries... same results... http://forum.doom9.org/showthread.php?p=1043328#post1043328