Professional Documents
Culture Documents
# v1.06.1 2008-10-10
# Read the documentation for all the required info to know how to use this
function
function AnimeIVTC (clip i, int "mode", int "aa", int "precision", int "killcomb",
bool "mt"\
, int "decimate", float "cdeblendmthr", float "dupthr", float
"mrestorebf", int "mrestoredup", int "mrestoremthr"\
, string "iregion", string "oregion", string "postconv", string
"wavaudio"\
, bool "denoise", int "block", bool "showmetrics", float "hybriddup",
float "vidthresh", int "pass" \
, int "bob", string "edimode", int "degrain", int "omode", int "mix"\
, int "istart1", int "iend1", int "istart2", int "iend2" \
, int "estart1", int "eend1", int "estart2", int "eend2", int
"estart3", int "eend3" \
, int "pstart1", int "pend1", int "pstart2", int "pend2" \
, int "overlap", int "pel", int "search", bool "nnedipel", string
"denoiseri", string "denoiserp"\
, int "check", bool "reduce", bool "horizontal" \
, int "aastr", float "dark", int "thin", int "sharp", int "smooth",
bool "stabilize", int "tradius", int "aapel", int "aaov", int "aablk", string
"aatype"){
#General arguments
assert(defined(mode), "Specify a mode... please read the documentation. If you are
not sure if you have pure interlaced, use any mode + check=1")
assert(mode == 1 || mode == 2 || mode == 3 || mode == 4 || mode == 5 || mode == 6
|| mode == 7, "Please use mode = 1, 2, 3, 4, 5, 6 or 7")
precision = default ( precision, 3 )
aa = (mode==7 || defined(check)) ? 0 : default ( aa, 5 )
killcomb = default ( killcomb, 1 )
mt = default ( mt, false )
#aa=4
aastr = default ( aastr, 255 ) # antialiasing strength
dark = default ( dark, 0.2 ) # strokes darkening strength
thin = default ( thin, 80 ) # Presharpening
sharp = default ( sharp, 300 ) # Postsharpening
smooth = default ( smooth, 100 ) # Postsmoothing
stabilize= default ( stabilize, true ) # Use post stabilization with Motion
Compensation
Tradius = default ( Tradius, 2 ) # 2 = MVDegrain2 / 3 = MVDegrain3 /// 28 =
MVDegrain28
aapel = default ( aapel, 1 ) # accuracy of the motion estimation (Value can
only be 1, 2 or 4. 1 means a precision to the pixel. 2 means a precision to half a
pixel, 4 means a precision to quarter a pixel, produced by spatial interpolation
(better but slower).)
aaov = default ( aaov, 4 ) # block overlap value (horizontal). Must be even
and less than block size. (Higher = more precise & slower)
aablk = default ( aablk, 8 ) # Size of a block (horizontal). It's either 4, 8
or 16 ( default is 8 ). Larger blocks are less sensitive to noise, are faster, but
also less accurate.
aatype = default ( aatype, "Sangnom" ) # Use Sangnom() or EEDI2() for anti-
aliasing
#VFR arguments
denoise = default ( denoise, true )
block = default ( block, 16 )
showmetrics = default ( showmetrics, false )
hybriddup = default ( hybriddup, 1.1 )
vidthresh = default ( vidthresh, 1.1 )
pass = (mode==5 || mode==7) ? default ( pass, 1 ) : default ( pass, 0 )
#30i arguments
bob = default ( bob, 3 )
edimode = default ( edimode, "eedi2" )
degrain = default ( degrain, 1 )
assert(mode==1 || mode==2 || mode==5 || mode==6 || mode==7 || defined(omode),
"Please select an output framerate with omode = 1 or 2")
assert(mode==1 || mode==2 || mode==5 || mode==6 || mode==7 || defined(mix),
"Please tell how to deal with the 30i sections with mix = 1 to 22")
omode= (defined(check) || mode==1 || mode==2) ? 3 : default(omode, 3)
mix=defined(check) ? 23 : default(mix, 23)
#If frame numbers are not entered... yay, that was fun to do
assert(mix != 1 || (defined(istart1) && defined(iend1) && defined(estart1)
&& defined(eend1)),
"Please enter the frame # for istart1, iend1, estart1
and eend1")
assert(mix != 2 || (defined(istart1) && defined(iend1) && defined(estart1)
&& defined(eend1) && defined(istart2) && defined(iend2)),
"Please enter the frame # for istart1,
iend1, estart1, eend1, istart2 and iend2")
assert(mix != 3 || (defined(istart1) && defined(iend1) && defined(estart1)
&& defined(eend1) && defined(istart2) && defined(iend2) && defined(estart2)
&& defined(eend2)), "Please enter the frame # for
istart1, iend1, estart1, eend1, istart2, iend2, estart2 and eend2")
assert(mix != 4 || (defined(estart1) && defined(eend1) && defined(istart1)
&& defined(iend1) && defined(estart2) && defined(eend2)),
"Please enter the frame # for estart1,
eend1, istart1, iend1, estart2 and eend2")
assert(mix != 5 || (defined(estart1) && defined(eend1) && defined(istart1)
&& defined(iend1)),
"Please enter the frame # for estart1, eend1, istart1
and iend1")
assert(mix != 6 || (defined(estart1) && defined(eend1) && defined(istart1)
&& defined(iend1) && defined(estart2) && defined(eend2) && defined(istart2)
&& defined(iend2)), "Please enter the frame # for
estart1, eend1, istart1, iend1, estart2, eend2, istart2 and iend2")
assert(mix != 7 || (defined(estart1) && defined(eend1) && defined(istart1)
&& defined(iend1) && defined(estart2) && defined(eend2) && defined(istart2)
&& defined(iend2) && defined(estart3) && defined(eend3)), "Please enter the
frame # for estart1, eend1, istart1, iend1, estart2, eend2, istart2, iend2,
estart3 and eend3")
assert(mix != 8 || (defined(pstart1) && defined(pend1) && defined(estart1)
&& defined(eend1)),
"Please enter the frame # for pstart1, pend1, estart1
and eend1")
assert(mix != 9 || (defined(pstart1) && defined(pend1) && defined(estart1)
&& defined(eend1) && defined(pstart2) && defined(pend2)),
"Please enter the frame # for pstart1,
pend1, estart1, eend1, pstart2 and pend2")
assert(mix != 10 || (defined(pstart1) && defined(pend1) && defined(estart1)
&& defined(eend1) && defined(pstart2) && defined(pend2) && defined(estart2)
&& defined(eend2)), "Please enter the frame # for
pstart1, pend1, estart1, eend1, pstart2, pend2, estart2 and eend2")
assert(mix != 11 || (defined(estart1) && defined(eend1) && defined(pstart1)
&& defined(pend1) && defined(estart2) && defined(eend2)),
"Please enter the frame # for estart1,
eend1, pstart2, pend2, estart2 and eend2")
assert(mix != 12 || (defined(estart1) && defined(eend1) && defined(pstart1)
&& defined(pend1)),
"Please enter the frame # for estart1, eend1, pstart2
and pend2")
assert(mix != 13 || (defined(estart1) && defined(eend1) && defined(pstart1)
&& defined(pend1) && defined(estart2) && defined(eend2) && defined(pstart2)
&& defined(pend2)), "Please enter the frame # for
estart1, eend1, pstart1, pend1, estart2, eend2, pstart2 and pend2")
assert(mix != 14 || (defined(estart1) && defined(eend1) && defined(pstart1)
&& defined(pend1) && defined(estart2) && defined(eend2) && defined(pstart2)
&& defined(pend2) && defined(estart3) && defined(eend3)), "Please enter the
frame # for estart1, eend1, pstart1, pend1, estart2, eend2, pstart2, pend2,
estart3 and eend3")
assert(mix != 15 || (defined(estart1) && defined(eend1) && defined(istart1)
&& defined(iend1) && defined(estart2) && defined(eend2) && defined(pstart1)
&& defined(pend1)), "Please enter the frame # for
estart1, eend1, istart1, iend1, estart2, eend2, pstart1 and pend1")
assert(mix != 16 || (defined(istart1) && defined(iend1) && defined(estart1)
&& defined(eend1) && defined(pstart1) && defined(pend1) && defined(estart2)
&& defined(eend2)), "Please enter the frame # for
istart1, iend1, estart1, eend1, pstart1, pend1, estart2 and eend2")
assert(mix != 17 || (defined(estart1) && defined(eend1) && defined(istart1)
&& defined(iend1) && defined(estart2) && defined(eend2) && defined(pstart1)
&& defined(pend1) && defined(estart3) && defined(eend3)), "Please enter the
frame # for estart1, eend1, istart1, iend1, estart2, eend2, pstart1, pend1,
estart3 and eend3")
assert(mix != 18 || (defined(istart1) && defined(iend1) && defined(estart1)
&& defined(eend1) && defined(pstart1) && defined(pend1)),
"Please enter the frame # for istart1,
iend1, estart1, eend1, pstart1 and pend1")
assert(mix != 19 || (defined(pstart1) && defined(pend1) && defined(estart1)
&& defined(eend1) && defined(istart1) && defined(iend1)),
"Please enter the frame # for pstart1,
pend1, estart1, eend1, istart1 and iend1")
assert(mix != 20 || (defined(estart1) && defined(eend1) && defined(pstart1)
&& defined(pend1) && defined(estart2) && defined(eend2) && defined(istart1)
&& defined(iend1)), "Please enter the frame # for
estart1, eend1, pstart1, pend1, estart2, eend2, istart1 and iend1")
assert(mix != 21 || (defined(pstart1) && defined(pend1) && defined(estart1)
&& defined(eend1) && defined(istart1) && defined(iend1) && defined(estart2)
&& defined(eend2)), "Please enter the frame # for
pstart1, pend1, estart1, eend1, istart1, iend1, estart2 and eend2")
assert(mix != 22 || (defined(estart1) && defined(eend1) && defined(pstart1)
&& defined(pend1) && defined(estart2) && defined(eend2) && defined(istart1)
&& defined(iend1) && defined(estart3) && defined(eend3)), "Please enter the
frame # for estart1, eend1, pstart1, pend1, estart2, eend2, istart1, iend1,
estart3 and eend3")
#Field blended/DHT
decimate = default ( decimate, 4 )
#cdeblend
cdeblendmthr = default ( cdeblendmthr, 0.3 )
#mrestore
mrestorebf = default ( mrestorebf, 0.6 )
mrestoredup = default ( mrestoredup, 0 )
mrestoremthr = default ( mrestoremthr, 0 )
#Norm conversion
iregion = default ( iregion, "NTSC" )
oregion = default ( oregion, iregion )
assert(iregion=="NTSC" || iregion=="PAL", "Invalid region, please use NTSC or
PAL")
assert(oregion=="NTSC" || oregion=="PAL", "Invalid region, please use NTSC or
PAL")
tnum = (oregion=="NTSC") ? 24000 : 25000
tden = (iregion=="NTSC") ? 1001 : 1000
regionconv = (iregion=="NTSC" && oregion=="NTSC") ? 1 : (iregion=="NTSC" &&
oregion=="PAL") ? 2 : (iregion=="PAL" && oregion=="PAL") ? 3 : (iregion=="PAL" &&
oregion=="NTSC") ? 4 : NOP()
postconv = default ( postconv, "bleh" )
assert(postconv=="NTSC" || postconv=="PAL" || postconv=="bleh", "Invalid region,
please use NTSC or PAL")
i = defined(wavaudio) ? audiodub(i,wavsource(wavaudio)) : i
omode = (regionconv==2 || regionconv==4) ? 1 : (mode==6) ? 2 : omode
#Lil' helpers
check = default ( check, 11 )
reduce = default ( reduce, false )
horizontal = default ( horizontal, false )
errormsgs = blankclip(pixel_type="YV12")
####################
#Field matching
#IVTC for mode 1 & 3, bob for mode 2 & 4, IVTC + stats.txt output for mode 5
ht = (precision==0) ? i.tfm(slow=2) :
\ (precision==1) ? i.tfm(slow=2,clip2=i.tdeint(2)) :
\ (precision==2) ? i.tfm(slow=2,clip2=i.tdeint(2,edeint=i.nnedi(-2))) :
\ (precision==3) ? i.tfm(slow=2,clip2=i.tdeint(2,edeint=i.nnedi(-
2),emask=i.tmm(1))) :
\ errormsgs.subtitle("Please use precision = 0, 1, 2 or 3")
####################
#CFR decimation
####################
####################
#HT decimation
htdecim = matched.tdecimate()
####################
#Decimate bobbed stream based on user settings
derrmsg = errormsgs.subtitle("Decimate=1, 2 or 3 are meant for NTSC to NTSC only")
d1 = (regionconv==1) ? matched.selectevery(5,0,2) : derrmsg
d2 = (regionconv==1) ? matched.selectevery(5,1,3) : derrmsg
d3 = (regionconv==1) ? matched.selectevery(5,2,4) : derrmsg
d4prep = defined(dupthr) ?
matched.cdeblend(mthresh=cdeblendmthr,omode=1).dup(dupthr).requestlinear(clim=30)
:
\
matched.cdeblend(mthresh=cdeblendmthr,omode=1).requestlinear(clim=30)
d4 = (regionconv==1) ? d4prep.tdecimate(1,3,5) :
\ (regionconv==2) ? d4prep.tdecimate(1,7,12) :
\ (regionconv==3) ? d4prep.tdecimate(1,3,6) :
\ (regionconv==4) ? d4prep.tdecimate(1,13,25) : NOP()
d5 =
matched.mrestore(tnum,tden,0,mrestorebf,true,mrestoredup,mthr=mrestoremthr,dclip=i
.bob().reduceflicker(strength=1),cache=20)
dhtdecim = (decimate==1) ? d1 :
\ (decimate==2) ? d2 :
\ (decimate==3) ? d3 :
\ (decimate==4) ? d4 :
\ (decimate==5) ? d5 : errormsgs.subtitle("Please use decimate = 0 to 5")
#IVTCed clip
ivtced = (mode == 1 || mode == 3) ? htdecim :
\ (mode == 2 || mode == 4) ? dhtdecim :
\ (mode==6) ? matched : nop() #Will be done later via
VFR decimation
####################
#Credits
####################
####################
#Interlaced
#Smart-bobbing
b0 = i.tdeint(1)
b1 = i.tdeint(1,edeint=i.nnedi(-2))
b2 = i.tdeint(1,edeint=i.nnedi(-2),emask=i.tmm(1))
b3 = i.tempgaussmc_beta1mod(mt=mt,edimode=edimode,tr2=degrain)
b4 = i.mcbob()
bobbed = (bob==0) ? b0 : (bob==1) ? b1 : (bob==2) ? b2 : (bob==3) ? b3 :
(bob==4) ? b4 : errormsgs.subtitle("Please use bob = 0 to 4")
compbob = interleave( b0.subtitle("bob=0",align=9),
\ b1.subtitle("bob=1",align=9),
\ b2.subtitle("bob=2",align=9),
\ b3.subtitle("bob=3",align=9),
\ b4.subtitle("bob=4",align=9))
####################
#Progressive
#Blend deinterlace the 24t background while doing minimal damage on the 30p
credits
blendbg=i.daa()
####################
#Framerate conversion
#Clean detection clip for MVAnalyse, if requested
bobbed
mvdeni = defined(denoiseri) ? eval(denoiseri) : last
blendbg
mvdenp = defined(denoiserp) ? eval(denoiserp) : last
####################
#Splicing restored sections
#Choose how to deal with the pure interlaced sections based on the desired output
framerate
credi = (omode==1) ? fpsconvi : (omode==2) ? bobbed :
errormsgs.subtitle("Please use omode = 1 or 2")
credp = (omode==1) ? fpsconvp : (omode==2) ? blendbg :
errormsgs.subtitle("Please use omode = 1 or 2")
#Prepare the IVTCed clip for splicing with the deinterlaced 30i
usee1 = (mix != 23) ? true : false
usee2 = (mix==3 || mix==4 || mix==6 || mix==7 || mix==10 || mix==11 || mix==13 ||
mix==14 || mix==15 || mix==16 || mix==17 || mix==20 || mix==21 || mix==22) ? true
: false
usee3 = (mix==7 || mix==14 || mix==17 || mix==22) ? true : false
e1 = (usee1 && omode==2) ? ivtced.trim(estart1,eend1).changefps(maxfps) :
\ (usee1 && omode==1) ? ivtced.trim(estart1,eend1) : nop()
#Splice
spliced=(mix==1) ? c1 + e1 : \
(mix==2) ? c1 + e1 + c2 : \
(mix==3) ? c1 + e1 + c2 + e2 : \
(mix==4) ? e1 + c1 + e2 : \
(mix==5) ? e1 + c1 : \
(mix==6) ? e1 + c1 + e2 + c2 : \
(mix==7) ? e1 + c1 + e2 + c2 + e3 : \
(mix==8) ? p1 + e1 : \
(mix==9) ? p1 + e1 + p2 : \
(mix==10) ? p1 + e1 + p2 + e2 : \
(mix==11) ? e1 + p1 + e2 : \
(mix==12) ? e1 + p1 : \
(mix==13) ? e1 + p1 + e2 + p2 : \
(mix==14) ? e1 + p1 + e2 + p2 + e3 : \
(mix==15) ? e1 + c1 + e2 + p1 : \
(mix==16) ? c1 + e1 + p1 + e2 : \
(mix==17) ? e1 + c1 + e2 + p1 + e3 : \
(mix==18) ? c1 + e1 + p1 : \
(mix==19) ? p1 + e1 + c1 : \
(mix==20) ? e1 + p1 + e2 + c1 : \
(mix==21) ? p1 + e1 + c1 + e2 : \
(mix==22) ? e1 + p1 + e2 + c1 + e3 : \
NOP()
####################
#Final clip at the desired CFR with framerate post-conversion, if requested
####################
#Kill combing
toprocess = (mode==1 || mode==2 || omode==1) ? finalcfr : (mode==5) ? matched :
(omode==2) ? spliced : i
dec0=(check!=11 && check!=5) ? errormsgs : toprocess
dec1=(check!=11 && check!=5) ? errormsgs : toprocess.vinverse()
dec2=(check!=11 && check!=5) ? errormsgs : toprocess.vinverseD()
dec = (killcomb==0) ? dec0 :
\ (killcomb==1) ? dec1 :
\ (killcomb==2) ? dec2 :
\ errormsgs.subtitle("Please use killcomb = 0, 1 or 2")
####################
#Anti-aliasing
aa0=dec
aa1=dec.ediaa()
aa2=dec.daa()
aa3=dec.maa()
aa4=dec.sharpaamcmod(aastr=aastr, ds=dark, shpre=thin, shpost=sharp,
smpost=smooth, tradius=tradius, mt=mt, MC=stabilize, pel=aapel, ov=aaov,
blk=aablk, aatype=aatype)
####################
#Final clip with VFR decimation
#Anti-aliasing with edge masking by martino, mask using "sobel" taken from
Kintaro's useless filterscripts and modded by thetoof for spline36
function maa(clip input, int "mask") {
mask = input.mt_edge("sobel",7,7,5,5).mt_inflate()
aa_clip=input.spline36Resize(width(input)*2,height(input)*2).TurnLeft().SangNom().
TurnRight().SangNom().spline36Resize(width(input),height(input)).MergeChroma(input
)
return mt_merge(input,aa_clip,mask) }
w=width(orig)
h=height(orig)
m=logic( orig.DEdgeMask(0,255,0,255,"5 10 5 0 0 0 -5 -10 -5",
divisor=4,Y=3,U=3,V=3)
\ ,orig.DEdgeMask(0,255,0,255,"5 0 -5 10 0 -10 5 0 -5",
divisor=4,Y=3,U=3,V=3)
\ ,"max").greyscale().levels(0,0.8,128,0,255,false)
preaa=(ShPre==0 && ds==0) ? orig : (ShPre==0) ? orig.Toon(ds) : (ds==0) ?
orig.Warpsharp(depth=ShPre) : orig.Toon(ds).Warpsharp(depth=ShPre)
aa= (aatype=="Sangnom") ?
preaa.spline36resize(w*2,h*2).TurnLeft().SangNom(aa=aastr).TurnRight().SangNom(aa=
aastr).spline36resize(w,h) : (aatype=="EEDI2") ? preaa.ediaa() :
blankclip(pixel_type="YV12").subtitle("Please use Sangnom or EEDI2 for aatype")
postsh=(ShPost==0 && SmPost==0) ? aa :
aa.LimitedSharpenFaster(edgemode=1,strength=ShPost,overshoot=1,soft=SmPost)
merged=mt_merge(orig,postsh,m,Y=3,U=3,V=3)
sD=mt_makediff(orig,merged)
fv3 = orig.MVAnalyse(isb=false,delta=3,pel=pel,overlap=ov,blksize=blk,idx=21)
fv2 = orig.MVAnalyse(isb=false,delta=2,pel=pel,overlap=ov,blksize=blk,idx=21)
fv1 = orig.MVAnalyse(isb=false,delta=1,pel=pel,overlap=ov,blksize=blk,idx=21)
bv1 = orig.MVAnalyse(isb=true, delta=1,pel=pel,overlap=ov,blksize=blk,idx=21)
bv2 = orig.MVAnalyse(isb=true, delta=2,pel=pel,overlap=ov,blksize=blk,idx=21)
bv3 = orig.MVAnalyse(isb=true, delta=3,pel=pel,overlap=ov,blksize=blk,idx=21)
allv = mt ?
orig.MVAnalyseMulti(refframes=tradius,pel=pel,overlap=ov,blksize=blk,idx=21) :
nop()
fiz = (tradius==1) ? sD.MVDegrain1(bv1,fv1,idx=22) : (tradius==2) ?
sD.MVDegrain2(bv1,fv1,bv2,fv2,idx=22) : (tradius==3) ?
sD.MVDegrain3(bv1,fv1,bv2,fv2,bv3,fv3,idx=22) :
blankclip(pixel_type="yv12").subtitle("You must use MT=true with josey_wells'
branch of MVTools to use a higher tradius than 3")
sDD = (MT) ? sD.MVDegrainMulti(allv,idx=22) : fiz
reduc = 0.4
sDD = mt_lutxy(sD,sDD,"x 128 - abs y 128 - abs < x y ?").mergeluma(sDD,1.0-reduc)