#### ## ## NTSC tools 0.93, by Sal, aka Mug ## ## takes an NTSC clip, finds Film, 30p and 60i parts and gives them special treatment ## use it to convert to PAL with 4% speed-up (ie 23.976 to 25 fps) ## #### function AutoPAL (clip c, bool "speedup", int "th_film", int "th_prog", float "th_fade", int "th_bob", float "tol", bool "show", int "mode", string "filter", bool "blend", bool "deblocker", int "quant") { speedup=default(speedup,false) blend=default(blend,true) th_film=default(th_film,4) th_prog=default(th_prog,4) th_fade=default(th_fade,.8) th_bob=default(th_bob,2) tol=default(tol,.5) show=default(show,false) mode=default(mode,1) filter=default(filter,"last") deblocker=default(deblocker,false) quant=default(quant,6) data=NTSCanalyse(c,th_film=th_film,th_prog=th_prog,th_fade=th_fade,tol=tol) NTSCconvert(c,data,th_bob=th_bob,speedup=speedup,show=show,mode=mode,filter=filter,blend=blend,deblocker=deblocker,quant=quant) c.height==576? deblocker==true? c.deblocker(quant=quant,ipp=true) : c : last } function NTSCanalyse (clip c, int "th_film", int "th_prog", float "th_fade", float "tol", bool "show") { # output clip is teeny coloured clip in same space as input # red = FILM # green = progressive # blue = interlaced show=default(show,false) order = c.getparity()==true? 1 : 0 global isfade=true global filmnum=-4 global progtele=0 global th_film=default(th_film,4) global th_prog=default(th_prog,2) global th_fade=default(th_fade,1.5) global tol=default(tol,.5) d = c.horizontalreduceby2().bob(1,0,height=c.height/2).converttoyv12() global film_c = d global film_d = d.selectevery(2,0) global f01 = mt_lutxy(film_d,film_c.selectevery(2,1),expr="x y - abs") global f02 = mt_lutxy(film_c.selectevery(2,0), film_c.selectevery(2,2),expr="x y - abs") global f13 = mt_lutxy(film_c.selectevery(2,1), film_c.selectevery(2,3),expr="x y - abs") global b1f1 = mt_lutxy(film_c.selectevery(2,-1), film_c.selectevery(2,1),expr="x y - abs") global b02 = mt_lutxy(film_c.selectevery(2,0), film_c.selectevery(2,-2),expr="x y - abs") global f24 = mt_lutxy(film_c.selectevery(2,2), film_c.selectevery(2,4),expr="x y - abs") global b13 = mt_lutxy(film_c.selectevery(2,-1), film_c.selectevery(2,-3),expr="x y - abs") global b24 = mt_lutxy(film_c.selectevery(2,-2), film_c.selectevery(2,-4),expr="x y - abs") global f35 = mt_lutxy(film_c.selectevery(2,3), film_c.selectevery(2,5),expr="x y - abs") global b35 = mt_lutxy(film_c.selectevery(2,-3), film_c.selectevery(2,-5),expr="x y - abs") global NTSCanalyse_red = blankclip(film_d,width=8,height=4,color=$ff0000) global NTSCanalyse_green = blankclip(film_d,width=8,height=4,color=$00ff00) global NTSCanalyse_blue = blankclip(film_d,width=8,height=4,color=$0000ff) film_d1 = scriptclip(NTSCanalyse_blue,"isfilm==1? NTSCanalyse_red : isprog==1? NTSCanalyse_green : NTSCanalyse_blue") film_d2 = frameevaluate(film_d1,"isprog= f01.yplaneminmaxdifference(0) <= th_prog ? 1 : 0") film_d3 = frameevaluate(film_d2,"isfilm= current_frame == filmnum ? 1 : 0") film_d4 = frameevaluate(film_d3,""" \ filmnum= (b1f1.yplanemax(tol) < th_film) && (b1f1.averageluma() < th_fade) ? current_frame : \ (f02.yplanemax(tol) < th_film) && (f02.averageluma() < th_fade) && (b35.yplanemax(tol) < th_film) ? current_frame : \ (b02.yplanemax(tol) < th_film) && (b02.averageluma() < th_fade) && (f35.yplanemax(tol) < th_film) ? current_frame : \ (b13.yplanemax(tol) < th_film) && (b13.averageluma() < th_fade) && (f24.yplanemax(tol) < th_film) ? current_frame : \ (f13.yplanemax(tol) < th_film) && (f13.averageluma() < th_fade) && (b24.yplanemax(tol) < th_film) ? current_frame : \ (f24.yplanemax(tol) < th_film) && (f24.averageluma() < th_fade) && (b13.yplanemax(tol) < th_film) ? current_frame : \ (b24.yplanemax(tol) < th_film) && (b24.averageluma() < th_fade) && (f13.yplanemax(tol) < th_film) ? current_frame : filmnum """) show==true? overlay(c,film_d4) : film_d4 } function NTSCconvert (clip c, clip data, bool "speedup", int "th_bob", int "mode", bool "show", string "filter", bool "blend", bool "deblocker", int "quant") { # mode 1 = blend non-film frames to 50i # mode 2 = try to motion-compensate non-film frames to 25p or 50i speedup=default(speedup,true) th_bob=default(th_bob,2) blend=default(blend,true) mode=default(mode,1) show=default(show,false) filter = default(filter,"last") deblocker = default(deblocker,false) quant = default(quant,6) outnum = speedup==true? 48000 : 50000 outden = speedup==true? 1001 : 1000 order = c.getparity()==true? 1 : 0 c = deblocker==true? c.deblocker(quant=quant,ipp=true) : c global bobbed = c.leakkernelbob(order=order,threshold=th_bob,sharp=true,twoway=true).assumeframebased()# NTSCconvert_60i = mode==1? bobbed.blendfps(outnum/float(outden),1.25).changefps(outnum,outden).resizetopal(false,false).interlace(order=1) : bobbed.salfps(outnum/float(outden),protection2=60).changefps(outnum,outden).resizetopal(false,false).interlace(order=1) #.assumetff().separatefields().selectevery(4,0,3).weave() NTSCconvert_30p = mode==1? c.blendfps(outnum/float(outden),1.25).changefps(outnum/2,outden).resizetopal(false,false) : c.salfps(outnum/float(2*outden),protection2=30).resizetopal(false,false).changefps(outnum,outden).interlace(order=1) #.interlace(order=1) # NTSCconvert_24p = speedup==true? \ c.tfm(order=order,pp=2,micmatching=0).decimate().resizetopal(false,false).changefps(outnum/2,outden) : \ (blend==true)? c.tfm(order=order,pp=2,micmatching=0).decimate().resizetopal(false,false).blendfps(50,1.25).changefps(outnum,outden).interlace(order=1): \ c.tfm(order=order,pp=2,micmatching=0).decimate().resizetopal(false,false).changefps(outnum,outden).interlace(order=1) NTSCconvert_60i eval(filter) global NTSCconvert_60i = last NTSCconvert_30p eval(filter) global NTSCconvert_30p = last NTSCconvert_24p eval(filter) global NTSCconvert_24p = last global NTSCconvert_data = data.changefps(outnum/2,outden) global NTSCconvert_red = blankclip(NTSCconvert_data,color=$ff0000) global NTSCconvert_green = blankclip(NTSCconvert_data,color=$00ff00) global NTSCconvert_blue = blankclip(NTSCconvert_data,color=$0000ff) global NTSCconvert_isred = mt_lutxy(NTSCconvert_red,NTSCconvert_data,yexpr="x y - abs",y=3,u=1,v=1) scriptclip(NTSCconvert_24p,"yplanemax(NTSCconvert_isred)==0 ? NTSCconvert_24p : NTSCconvert_60i") speedup==true? last.assumefps(25,true).SSRC(48000) : last show==true? overlay(last,NTSCconvert_data) : last assumetff() c.height==576? c : last } function NTSCfilter (clip c, clip data, string filter, bool "show") { show=default(show,false) order = c.getparity()==true? 1 : 0 bobbed = c.assumeframebased().leakkernelbob(order=order,threshold=2) bobbed.selecteven() eval(filter) evn=last bobbed.selectodd() eval(filter) odd=last interleave(evn,odd) interlace(order=order) global NTSCfilter_60i = last c eval(filter) global NTSCfilter_30p = last c.tdeint(2,1,tryweave=true,cthresh=2,mi=24,mtnmode=1,mthreshl=2).decimate() eval(filter) changefps(c.framerate*2).interlace(order=order) global NTSCfilter_24p = last global NTSCfilter_data = data global NTSCfilter_red = blankclip(NTSCfilter_data,color=$ff0000) global NTSCfilter_green = blankclip(NTSCfilter_data,color=$00ff00) global NTSCfilter_isred = mt_lutxy(NTSCfilter_red,NTSCfilter_data,yexpr="x y - abs",y=3,u=1,v=1) global NTSCfilter_isgreen = mt_lutxy(NTSCfilter_green,NTSCfilter_data,yexpr="x y - abs",y=3,u=1,v=1) scriptclip(NTSCfilter_30p,"yplanemax(NTSCfilter_isred)==0 ? NTSCfilter_24p : yplanemax(NTSCfilter_isgreen)==0 ? NTSCfilter_30p : NTSCfilter_60i") show==true? overlay(last,NTSCfilter_data) : last } function NTSC120 (clip c, clip data, bool "show") { show=default(show,false) order = c.getparity()==true? 1 : 0 bobbed = c.tdeint(1,order,tryweave=true,cthresh=4,mi=24,mtnmode=1,mthreshl=8)#leakkernelbob(order=order,threshold=2) global NTSCfilter_60i = bobbed.changefps(120000,1001) global NTSCfilter_30p = c.changefps(120000,1001) global NTSCfilter_24p = bobbed.decimate().changefps(120000,1001) global NTSCfilter_data = data.changefps(120000,1001) global NTSCfilter_red = blankclip(NTSCfilter_data,color=$ff0000) global NTSCfilter_green = blankclip(NTSCfilter_data,color=$00ff00) global NTSCfilter_isred = mt_lutxy(NTSCfilter_red,NTSCfilter_data,yexpr="x y - abs",y=3,u=1,v=1) global NTSCfilter_isgreen = mt_lutxy(NTSCfilter_green,NTSCfilter_data,yexpr="x y - abs",y=3,u=1,v=1) scriptclip(NTSCfilter_30p,"yplanemax(NTSCfilter_isred)==0 ? NTSCfilter_24p : yplanemax(NTSCfilter_isgreen)==0 ? NTSCfilter_30p : NTSCfilter_60i") show==true? overlay(last,NTSCfilter_data) : last } function resizetopal (clip c, bool "soft", bool "speedup") { soft=default(soft,false) speedup=default(speedup,true) soft==false? c.addborders(0,2,0,2).lanczosresize(c.width,576,0,2+(c.height-483.84)/2,c.width,483.84) : c.addborders(0,2,0,2).bicubicresize(c.width,576,1,0,0,2+(c.height-483.84)/2,c.width,483.84) speedup==true? last.assumefps(25,true).SSRC(48000) : last c.height==576? c : last } function interlace (clip interlace_c, int "order") { order=default(order,1) interlace_d= interlace_c.framecount()%2==0? interlace_c : interlace_c.assumefps(interlace_c.framerate)++interlace_c.selectevery(interlace_c.framecount,interlace_c.framecount-1).assumefps(interlace_c.framerate) order==1? interlace_d.assumeframebased().assumetff().separatefields().selectevery(4,0,3).weave() : \ interlace_d.assumeframebased().assumebff().separatefields().selectevery(4,0,3).weave() } function deblocker (clip c,int "quant",int "th",int "radius", bool "deblock",bool "depump",bool "conv",bool "ipp",int "modh", int "modv") { quant=default(quant,8) th=default(th,3) radius=default(radius,8) deblock=default(deblock,true) depump=default(depump,false) conv=default(conv,false) ipp=default(ipp,false) modh=default(modh,20) modv=default(modv,40) c = (c.width*c.height%256==0)? c : mod16(c)#.limiter() blurd = (conv==true)?c.wideblur(4,conv): (depump==true)? c.bilinearresize(4*(c.width/8),4*(c.height/8)) : c.bilinearresize(4*(c.width/8),4*(c.height/8)).bicubicresize(c.width,c.height,1,0) highpass=(conv==true)?mt_makediff(blurd,c,y=3,u=3,v=3): (depump==true)? mt_makediff(blurd.bicubicresize(c.width,c.height,1,0),c,y=3,u=3,v=3) : mt_makediff(blurd,c,y=3,u=3,v=3) deblocked=(deblock==true) ? highpass.blindpp(quant=quant,cpu=4,ipp=ipp,moderate_h=modh,moderate_v=modv) : highpass nopump=mt_makediff(blurd,deblocked,y=3,u=3,v=3) depumped=blurd.temporalsoften(2,th,th,32,2)#.removedirt() pump=(conv==true)?mt_makediff(depumped,deblocked,y=3,u=3,v=3):mt_makediff(depumped.bicubicresize(c.width,c.height,1,0),deblocked,y=3,u=3,v=3) (depump==true) ? pump : nopump (c.width*c.height%256==0)? last : unmod16(last) }