Hello all,
I'm struggling to know what correct order of filters to conversion 60 to 30.
My script below:
Download spoiler.avsLanguage: avs
Import("C:\Program Files (x86)\AviSynth 2.5\plugins\deblink4.avs")
LoadPlugin("C:\Program Files (x86)\AviSynth 2.5\plugins\ExactDedup.dll")
LoadPlugin("C:\Program Files (x86)\AviSynth 2.5\plugins\mvtools2.dll")
LoadPlugin("C:\Program Files (x86)\AviSynth 2.5\plugins\mt_masktools-26.dll")
AVISource("video.avi").ConvertToRGB32().AssumeFPS(60,1).deblink4.ChangeFPS(30)
deblink4.avs=function deblink4(clip clp, float "ratio", int "level") {
ratio = default(ratio, 2.0 /3)
assert(ratio >= 0.0 && 1.0 >= ratio,
\ "[deblink4] 1.0 >= ratio >= 0.0, it was " + string(ratio))
level = default(level, round(ratio * 257))
assert(level >= 0 && 257 >= level,
\ "[deblink4] 257 >= level >= 0, it was " + string(level))
blink=clp.ng_blinkmask_new
m01=mt_logic(blink.selectevery(4,0),blink.selectevery(4,1),mode="or").converttorgb32
m23=mt_logic(blink.selectevery(4,2),blink.selectevery(4,3),mode="or").converttorgb32
f0=layer(clp.selectevery(4,0),clp.selectevery(4,1).mask(m01),level=level)
f1=layer(clp.selectevery(4,1),clp.selectevery(4,0).mask(m01),level=level)
f2=layer(clp.selectevery(4,2),clp.selectevery(4,3).mask(m23),level=(257-level) )
f3=layer(clp.selectevery(4,3),clp.selectevery(4,2).mask(m23),level=(257-level) )
interleave(f0,f1,f2,f3)
}
function deblink3(clip clp){
blink=clp.ng_blinkmask_new
m01=mt_logic(blink.selectevery(4,0),blink.selectevery(4,1),mode="or").converttorgb32
f0=layer(clp.selectevery(4,0),clp.selectevery(4,1).mask(m01))
f1=layer(clp.selectevery(4,1),clp.selectevery(4,0).mask(m01))
interleave(f0,f1,clp.selectevery(4,2),clp.selectevery(4,3))
}
function ng_blinkmask_new(clip c,int "ml"){
ml=default(ml,128)
src=c.ConvertToYv12
super=MSuper(src, pel=1)
fvec =MAnalyse(super, isb=false, blksize=4)
bvec =MAnalyse(super, isb=true , blksize=4)
fmask=Mmask(src,fvec,kind=1,ml=ml).mt_binarize(u=-128,v=-128)
bmask=Mmask(src,bvec,kind=1,ml=ml).mt_binarize(u=-128,v=-128)
eo0_to =fmask.selectevery(2,1)
oe_from=bmask.selectevery(2,1)
front =mt_logic(eo0_to,oe_from,mode="and")
oe_to =fmask.selectevery(2,2)
eo_from=bmask.selectevery(2,2)
back =mt_logic(oe_to,eo_from,mode="and")
ee_src=src.selecteven
ee_super=MSuper(ee_src, pel=1)
ee_fvec =MAnalyse(ee_super, isb=false, blksize=4)
ee_bvec =MAnalyse(ee_super, isb=true , blksize=4)
ee_fmask=Mmask(ee_src,ee_fvec,kind=1,ml=ml).mt_binarize(u=-128,v=-128)
ee_bmask=Mmask(ee_src,ee_bvec,kind=1,ml=ml).mt_binarize(u=-128,v=-128)
ee_to =ee_fmask.trim(1,0)
ee_from=ee_bmask
ee =mt_logic(ee_to,ee_from,mode="or")
oo_src=src.selectodd
oo_super=MSuper(oo_src, pel=1)
oo_fvec =MAnalyse(oo_super, isb=false, blksize=4)
oo_bvec =MAnalyse(oo_super, isb=true , blksize=4)
oo_fmask=Mmask(oo_src,oo_fvec,kind=1,ml=ml).mt_binarize(u=-128,v=-128)
oo_bmask=Mmask(oo_src,oo_bvec,kind=1,ml=ml).mt_binarize(u=-128,v=-128)
oo_to =oo_fmask.trim(1,0)
oo_from=oo_bmask
oo =mt_logic(oo_to,oo_from,mode="or")
#to e0-o1, from o1-e2, nothing e0-e2
even_blink=mt_logic(front,ee.mt_invert,mode="and")
#to o1-e2, from e2-o3, nothing o1-o3
odd_blink =mt_logic(back,oo.mt_invert,mode="and")
interleave(even_blink, odd_blink).selectevery(1,-1)
}
and
Download spoiler.avsLanguage: avs
Import("C:\Program Files (x86)\AviSynth 2.5\plugins\ng_deblink.avs")
LoadPlugin("C:\Program Files (x86)\AviSynth 2.5\plugins\ExactDedup.dll")
LoadPlugin("C:\Program Files (x86)\AviSynth 2.5\plugins\mvtools2.dll")
LoadPlugin("C:\Program Files (x86)\AviSynth 2.5\plugins\mt_masktools-26.dll")
AviSource("video.avi").ConvertToRGB32().ng_deblink(0.5).Selectodd
ng_deblink.avs=function ng_deblink(clip clp,
\ float "ratio",
\ int "level",
\ clip "blinkmask"
\){
#Version 10 2012.04.22
blink = default(blinkmask, clp.ng_blinkmask())
ratio = default(ratio, 2.0 /3)
assert(ratio >= 0.0 && 1.0 >= ratio,
\ "[ng_deblink] 1.0 >= ratio >= 0.0, it was " + string(ratio))
level = default(level, round(ratio * 257))
assert(level >= 0 && 257 >= level,
\ "[ng_deblink] 257 >= level >= 0, it was " + string(level))
m01=mt_logic(blink.SelectEvery(4,0),
\ blink.SelectEvery(4,1),
\ mode="or").ConvertToRGB32()
m23=mt_logic(blink.SelectEvery(4,2),
\ blink.SelectEvery(4,3),
\ mode="or").ConvertToRGB32()
f0=Layer(clp.SelectEvery(4,0),
\ clp.SelectEvery(4,1).Mask(m01),
\ level=level)
f1=Layer(clp.SelectEvery(4,1),
\ clp.SelectEvery(4,0).Mask(m01),
\ level=level)
f2=Layer(clp.SelectEvery(4,2),
\ clp.SelectEvery(4,3).Mask(m23),
\ level=(257-level) )
f3=Layer(clp.SelectEvery(4,3),
\ clp.SelectEvery(4,2).Mask(m23),
\ level=(257-level) )
Interleave(f0,f1,f2,f3)
}
function ng_blinkmask(clip clp,
\ bool "TEST",
\ bool "STABILIZE",
\ bool "SHARP",
\ bool "HYSTER",
\ int "inpand",
\ int "expand",
\ int "ml"
\){
#Version 10 2012.04.22
#BLINK
# Blinking is a block that alternates on/off each frame
# SelectEven would only see either the on or the off
#FLASH
# Flashing is a block that is only on for a single frame
# SelectEven might miss the flash
#SHAKE
# Shaking is a block that moves back/forth each frame
# SelectEven would only see one position
# The goal of this function is to make a blink mask for use with
# ng_deblink. For overly complicated scenes where a clean blinkmask
# can't be found, just use TASBlend. Uniform softness looks better
# than sharp artifacts.
# This function calculates flash and shake info for the test script,
# but those effects should be handled in different ways.
# Flash - choose frames to make sure the flash is in your final clip.
# Shake - SelectEvery(4,0,2,1,3) or SelectEvery(4,1,0,2,3)
# SelectEvery doesn't generally work because it messes with the fluidity
# of motion. But that won't be noticable on a shaking screen.
# Be careful if 2 frame blinking is present, as the selectevery can turn
# it into 1 frame blinking.
TEST = default( TEST, false)
STABILIZE = default(STABILIZE, true)
SHARP = default( SHARP, true)
HYSTER = default( HYSTER, false)
inpand = default( inpand, 1)
expand = default( expand, 1)
ml = default( ml, 128)
# The functions used to make the masks work in the YV12 colorspace. Once
# the masks are created they can be used in the RGB32 colorspace direcly
src=clp.ConvertToYV12()
# Blinking is located by looking for blocks that don't exist in
# consecutive frames. The motion vector will match blocks that exist in
# both frames. The blocks that aren't in both will end up with huge
# values that are picked out by the motion mask.
super = MSuper(src, pel=1)
fvec = MAnalyse(super, isb=false, blksize=4)
bvec = MAnalyse(super, isb=true , blksize=4)
fmask = Mmask(src, fvec, kind=1, ml=ml).mt_binarize()
bmask = Mmask(src, bvec, kind=1, ml=ml).mt_binarize()
blink = mt_logic(fmask, bmask, mode="and")
# Blinking usually occurs against a stable background. This is found
# by looking at blocks 2 frames apart. This distinguishes a blink from
# blocks that are just changing every frame.
ee_src = src.SelectEven()
ee_super = MSuper(ee_src, pel=1)
ee_fvec = MAnalyse(ee_super, isb=false, blksize=4)
ee_bvec = MAnalyse(ee_super, isb=true , blksize=4)
ee_fmask = Mmask(ee_src, ee_fvec, kind=1, ml=ml).mt_binarize()
ee_bmask = Mmask(ee_src, ee_bvec, kind=1, ml=ml).mt_binarize()
oo_src = src.SelectOdd()
oo_super = MSuper(oo_src, pel=1)
oo_fvec = MAnalyse(oo_super, isb=false, blksize=4)
oo_bvec = MAnalyse(oo_super, isb=true , blksize=4)
oo_fmask = Mmask(oo_src, oo_fvec, kind=1, ml=ml).mt_binarize()
oo_bmask = Mmask(oo_src, oo_bvec, kind=1, ml=ml).mt_binarize()
fmask_2 = Interleave(ee_fmask, oo_fmask)
bmask_2 = Interleave(ee_bmask, oo_bmask)
background = mt_logic(fmask_2.SelectEvery(1,1),
\ bmask_2.SelectEvery(1,-1),
\ mode="or")
stable_blink = mt_hysteresis(background.mt_invert, blink)
blink2 = (STABILIZE) ? stable_blink : blink
# Shrinking the blink mask can get rid of noise,
# too much will lose signal as well.
blink3 = blink2.mt_inpand(mode=mt_diamond(inpand))
# Using just pixels that changed helps sharpen the mask
diff = ng_diff(clp.SelectEvery(1,-1), clp)
diff_2 = mt_logic(diff, diff.SelectEvery(1,1), mode="and")
#Hysteresis
# Matches continuous blocks of pixels.
# Use with care, will match the whole screen on fades.
hyster_blink = mt_hysteresis(blink3, diff_2)
# Expand the mask to make up for shrinking it (or just use hysteresis)
blink4 = blink3.mt_expand(mode=mt_circle(expand))
sharp_blink = mt_logic(blink4, diff_2, mode="and")
blink5 = (HYSTER) ? hyster_blink :
\ (SHARP) ? sharp_blink : blink4
# A flash won't match blocks 1 or 2 frames away.
sub_flash = mt_logic(fmask_2, bmask_2, mode="and")
flash = mt_logic(blink, sub_flash, mode="and")
# A shake changes in one frame and changes back in the next.
# This isn't detected by the motion vectors because the blocks exist in
# both frames, they are just shifting around.
same = ng_same(clp.SelectEvery(1,-1), clp.SelectEvery(1,1))
shake = mt_logic(same, diff_2, mode="and")
(TEST) ? stackhorizontal(clp, mergeRGB(blink5, flash, shake))
\ : blink5.GreyScale()
}
function ng_diff(clip A, clip B, int "thr"){
thr=default(thr,0)
TAD=ng_TAD(A,B)
return mt_binarize(TAD, threshold=thr)
}
function ng_same(clip A, clip B, int "thr"){
thr=default(thr,0)
TAD=ng_TAD(A,B)
return mt_binarize(TAD, threshold=thr, upper=true)
}
function ng_TAD(clip A, clip B){
R=ng_AD(A .showRed("YV12"),B .showRed("YV12"))
G=ng_AD(A.showGreen("YV12"),B.showGreen("YV12"))
B=ng_AD(A .showBlue("YV12"),B .showBlue("YV12"))
return ng_plus(R, ng_plus(G, B))
}
function ng_AD(clip A, clip B){
return mt_lutxy(A,B,"x y - abs")
}
function ng_plus(clip A, clip B){
return mt_lutxy(A,B,"x y +")
}
Its ok?
I'm also sending a video sample to know which filters to use.
SAMPLE.AVI
Thank you
Claudio