PDA

View Full Version : NTSC tools: auto NTSC to PAL with 24p, 30p, 60i detection (v 0.93)


Mug Funky
29th July 2006, 06:28
okay, i re-read this thread:
http://forum.doom9.org/showthread.php?t=67161
a few days ago after being linked from the recent monty-python thread.

i remembered trying it out and seeing 30p pans get decimated as film, so i came up with this:

####
##
## 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", float "th_film", int "th_film2", int "th_prog", int "th_bob", float "tol", bool "show", int "mode", string "filter", bool "blend", int "deblocker", int "IVTCtype", int "precision")
{
speedup=default(speedup,false)
blend=default(blend,true)
th_film=default(th_film,.4)#.15)
th_film2=default(th_film2,5)
th_prog=default(th_prog,4)
th_bob=default(th_bob,8)
tol=default(tol,1.5)
show=default(show,false)
mode=default(mode,1)
filter=default(filter,"last")
deblocker=default(deblocker,0)
IVTCtype = default(IVTCtype,4) # 1 = telecide, 2 = tfm, 3 = tfm(pp=0), 4 = tdeint(mode=2), 5 = blindmatch ...formerly 2
precision = default(precision,1)


data=NTSCanalyse(c,th_film=th_film,th_prog=th_prog,th_film2=th_film2,tol=tol,precision=precision)
NTSCconvert(c,data,th_bob=th_bob,speedup=speedup,show=show,mode=mode,filter=filter,blend=blend,deblocker=deblocker, IVTCtype=IVTCtype)

c.height==576? deblocker==0? c : c.deblocker(quant=deblocker,ipp=true) : last
}

function NTSCanalyse (clip c, float "th_film", int "th_film2", int "th_prog", float "tol", int "precision", 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,.3)
global th_film2=default(th_film2,10)
#global th_prog=default(th_prog,2)
global th_prog=default(th_prog,30)
global tol=default(tol,.1)
global precision=default(precision,1)

#d = c.horizontalreduceby2().bob(1,0,height=c.height/2).converttoyv12()
d = c.bicubicresize(32*precision,c.height,1/3.,1/3.,16,0,c.width-32,c.height).separatefields().bicubicresize(32*precision,32*precision,1/3.,1/3.,0,8,32*precision,(c.height/2.)-16).converttoyv12()

global film_c = d
global film_d = d.selectevery(2,0)

global f01 = mt_lutxy(film_c.selecteven(),film_c.selectodd(),expr="x y - abs")#.mt_inpand(mode=mt_rectangle(0,2))

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.yplanemax(tol) <= th_prog ? 1 : 0")
film_d2 = frameevaluate(film_d1,"isprog= f01.yplanemax() <= th_prog ? 1 : 0")
film_d3 = frameevaluate(film_d2,"""
\ isfilm= filmnum!=current_frame? 0 : (b1f1.yplanemax() < th_film2) ? 1 :
\ (f02.yplanemax() < th_film2) && (b35.yplanemax() < th_film2) ? 1 :
\ (b02.yplanemax() < th_film2) && (f35.yplanemax() < th_film2) ? 1 :
\ (b13.yplanemax() < th_film2) && (f24.yplanemax() < th_film2) ? 1 :
\ (f13.yplanemax() < th_film2) && (b24.yplanemax() < th_film2) ? 1 :
\ (f24.yplanemax() < th_film2) && (b13.yplanemax() < th_film2) ? 1 :
\ (b24.yplanemax() < th_film2) && (f13.yplanemax() < th_film2) ? 1 : 0 """)

film_d4 = frameevaluate(film_d3,"""
\ filmnum= (b1f1.averageluma() < th_film) ? current_frame :
\ (f02.averageluma() < th_film) && (b35.averageluma() < th_film) ? current_frame :
\ (b02.averageluma() < th_film) && (f35.averageluma() < th_film) ? current_frame :
\ (b13.averageluma() < th_film) && (f24.averageluma() < th_film) ? current_frame :
\ (f13.averageluma() < th_film) && (b24.averageluma() < th_film) ? current_frame :
\ (f24.averageluma() < th_film) && (b13.averageluma() < th_film) ? current_frame :
\ (b24.averageluma() < th_film) && (f13.averageluma() < 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", int "deblocker",int "IVTCtype")
{
# 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,0)
IVTCtype = default(IVTCtype,4) # 1 = telecide, 2 = tfm, 3 = tfm(pp=0), 4 = tdeint(mode=2)

outnum = speedup==true? 48000 : 50000
outden = speedup==true? 1001 : 1000

order = c.getparity()==true? 1 : 0

c = deblocker==0? c : c.deblocker(quant=deblocker,ipp=true)
d = c

#global bobbed = d.leakkernelbob(order=order,threshold=th_bob,sharp=true,twoway=true).assumeframebased()
global bobbed = d.tdeint(1,order,expand=4,mthreshl=th_bob)

NTSCconvert_60i = mode==1? bobbed.blendfps(outnum/float(outden),1.25).changefps(outnum,outden).resizetopal(false,false) : bobbed.salfps(outnum/float(outden),protection2=60).changefps(outnum,outden).resizetopal(false,false)
NTSCconvert_30p = mode==1? d.blendfps(outnum/float(outden),1.25).changefps(outnum/2,outden).resizetopal(false,false) : d.salfps(outnum/float(2*outden),protection2=50).resizetopal(false,false).changefps(outnum/2,outden)

IVTCtype==1? d.telecide(order=order,guide=1).decimate().resizetopal(false,false) :\
IVTCtype==2? d.tfm(order=order,pp=6,chroma=true).decimate().resizetopal(false,false) :\
IVTCtype==3? d.tfm(order=order,pp=0,chroma=false).decimate().resizetopal(false,false) :\
d.tdeint(2,-1,expand=4,tryweave=true,cthresh=3,mi=24,mthreshl=6).decimate().resizetopal(false,false)

eval(filter)
NTSCconvert_24pfilter = last

global NTSCconvert_24p = speedup==true?
\ NTSCconvert_24pfilter.changefps(outnum/2,outden) :
\ (blend==true)? NTSCconvert_24pfilter.blendfps(50,1.25).changefps(outnum,outden).interlace(order=1):
\ NTSCconvert_24pfilter.changefps(outnum,outden).interlace(order=1)

NTSCconvert_60i
eval(filter)

interlace(order=1)
global NTSCconvert_60i = last

#NTSCconvert_30p
#eval(filter)
#mode==1? last : last.interlace(order=1)
#global NTSCconvert_30p = last

#NTSCconvert_24p
#eval(filter)
#
#global NTSCconvert_24p = last


global NTSCconvert_data = data.assumetff().medianblurt(0,0,2).blendfps(outnum/float(outden*2)).changefps(outnum/2,outden)
#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)
global NTSCconvert_isgreen = mt_lutxy(NTSCconvert_green,NTSCconvert_data,yexpr="x y - abs",y=3,u=1,v=1)

scriptclip(NTSCconvert_24p,"yplanemax(NTSCconvert_isred)==0 ? NTSCconvert_24p : NTSCconvert_60i")
#scriptclip(NTSCconvert_24p,"yplanemax(NTSCconvert_isred)==0 ? NTSCconvert_24p : yplanemax(NTSCconvert_isgreen)==0 ? NTSCconvert_30p : NTSCconvert_60i")
speedup==true? last.assumefps(25,true).SSRC(48000) : last

show==true? overlay(last,data.changefps(outnum/2,outden)) : 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 NTSCtoFPS (clip c, clip data, int "num", int "den", bool "show")
{

show=default(show,false)

num=default(num,25000)
den=default(den,1000)

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)
matched = c.tfm(order=order,pp=6,micmatching=0).decimate()

global NTSCtoFPS_60i = bobbed.salfps(num/float(den),protection2=30,iterate=4)
global NTSCtoFPS_30p = c.salfps(num/float(den),protection2=30,iterate=4)
global NTSCtoFPS_24p = bobbed.decimate().salfps(num/float(den),protection2=30,iterate=4)

global NTSCtoFPS_data = data.changefps(num,den)

global NTSCtoFPS_red = blankclip(NTSCtoFPS_data,color=$ff0000)
global NTSCtoFPS_green = blankclip(NTSCtoFPS_data,color=$00ff00)

global NTSCtoFPS_isred = mt_lutxy(NTSCtoFPS_red,NTSCtoFPS_data,yexpr="x y - abs",y=3,u=1,v=1)
global NTSCtoFPS_isgreen = mt_lutxy(NTSCtoFPS_green,NTSCtoFPS_data,yexpr="x y - abs",y=3,u=1,v=1)

scriptclip(NTSCtoFPS_30p,"yplanemax(NTSCtoFPS_isred)==0 ? NTSCtoFPS_24p : yplanemax(NTSCtoFPS_isgreen)==0 ? NTSCtoFPS_30p : NTSCtoFPS_60i")

show==true? overlay(last,NTSCtoFPS_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)
}

function combblur(clip c, int threshold)
{
mt_merge(c.mt_convolution("1","1 2 1",y=3,u=3,v=3).mt_convolution("1","-1 6 -1",y=3,u=3,v=3),c,c.combmask(threshold,threshold,y=3,u=3,v=3).mt_expand(mode=mt_rectangle(0,1),y=3,u=3,v=3).mt_inflate(y=3,u=3,v=3),y=3,u=3,v=3)
}

now, it's not complete, but everything (i believe) is in place to make this a real ripper.

it probably needs to be optimised. while things are film it's quite fast (well, not really), but once things get 30p or 60i, things slow down a tad, especially when mocomp is on.

usage:

this is a client-server model, like mvtools and depan. this makes things less efficient, but it's all i could think of as a way to framerate-convert the results of film detection - make 3 different colours in a tiny 8x4 clip that represent the footage type, then changefps those to get to 48fps, then compare colours and treat the footage accordingly on the client end.

here's an example:


...source clip...

data=last.NTSCanalyse()

NTSCconvert(last,data) # or it could be last.NTSCconvert(data)

...filters...


or, since v0.91:

...source...
autoPAL()


to run filters:

...source...
data=last.ntscanalyse()
ntscfilter(last,data,"...filters...")


or:

...source...
autoPAL(speedup=true,filter="...filters...")


what you'll get is a 50i clip that's been sped up 4%, film style. audio is handled too, if there is any, so it should all be in sync.

requires:
-clouded's motionprotectedfps and motion package
-a nice deinterlacer like tdeint. field-matching is a good idea, as my script just works on the frames you give it.
-masktools v2

have fun y'all!

Mug Funky
30th July 2006, 17:16
updated to "ver 0.9". see first post...

i thought i'd give it a version number so it gives me a 1.0 to aim for, that does everything i want.

for now, it's giving very good output on "clone high". i'll have to make a burn and watch it on a TV now, just to see how it goes. i hope to see no artefacts whatsoever (though mocomped mode will probably show some, blend mode is just fine for animation).

kle500
31st July 2006, 22:23
Maybe a stupid question, but does this function works also on Pure NTSC Interlaced matterial?
Or i shall stick with (motionprotectedFPS) that i am currently using?
I am currently aimed to NTSC(i) -> PAL(i)

If the above function also works on 30i source, is this script good enough?

Oh..
I named a file (NTSCconvert.avsi), and placed into plugins.

Then i wrote this script and right now i encode the clip.

Mpeg2Source("test.d2v",idct=0)
TDeint(mode=1)
assumetff()
data=last.NTSCanalyse()
NTSCconvert(last,data)
ConvertToYUY2(interlaced=true)
lanczosresize(720,576)

Regards
George

Boulder
1st August 2006, 15:38
So this one could be (ab)used to do the conversion (restoring the PAL content as it is possible nowadays) I was looking for in the MP thread? I don't know when I shall have the time to try things out, but IIRC R24 didn't like being called more than once by a script :(

Mug Funky
1st August 2006, 16:05
eh... i probably posted that script too early. i've made quite a few changes over the last couple of days, on account of it apparently working completely differently on my home and work computers.

it's frustrating because if it gives a good result on something, i come back the next day and it's failing on the same sample. but it is getting there.

to recap:

- this script is for converting hybrid NTSC stuff to PAL in an optimal way.

- it converts everything to a 48 or 24fps intermediate clips, then speeds up the final output (including audio) to 25fps, and of course resizes it to 720x576. this means audio needs to be re-encoded or it'll be out of sync.

- it'll attempt to detect 3:2 telecine and output 25p for those sections. it'll also try to find 30p parts and 60i parts, and convert them separately (though the most current version simply treats nonfilm as 60i for safety).

- you can tell it to either field-blend or motion-compensate (via motionprotectedfps with a little more protection) the nonfilm parts. when finished, 30p will become 25p and 60i will become 50i.


@ boulder: if you give it blended stuff, it'll detect it as 60i unfortunately. it's not meant for un-doing standards conversions, but rather for doing them in as progressive-friendly a way as possible. though i can see the use of unblending stuff, as i just got a pile of DVD extras that were shot in PAL, converted to NTSC, then given to us to convert back to PAL. grrr.

@ kle500: good luck with that encode :) if it doesn't output script errors in grey subtitling, or simply crash avisynth, then you're lucky enough to have a computer it likes :) however, it'll still act strangely, but you're probably fine using it if there's no random seeking going on. if it fails, it'll lean toward 60i and you'll hopefully just get a normal field-blend at half the speed...

i should probably have mentioned it's not quite ready for serious encodes yet - i'm having to tweak it too much for each clip i try, and really what i want is a "one size fits all" script that handles everything without artefacts or suboptimal conversion. it's not there yet, but it's close (the one i've got but haven't posted yet is closer, and when it's reliable enough i'll post it).

current issues are:

- my home computer behaves differently with it, and it seems every day i need to rethink and rewrite parts for scant reason (at least in my mind). this is getting better though, so hopefully in a week or so it'll be stable.

- 60i is being detected as 30p or sometimes even film and ugly blurred fields result. only happens on the japanese intro to "desert punk" that i've seen, which has a mix of 30p and 60i and a little film. a workaround is to treat all nonfilm as 60i...

- film is sometimes detected too much, sometimes not enough, and curiously it doesn't change much when the film threshold is raised... i'm on it, but it sure is weird.

- scenechanges are very likely to be spotted as 60i even if they're not, and interlaced, blended scenechanges aren't exactly good for compression. should be theoretically easy to fix, but very fiddly in the current script.

- i know it can be sped up a lot - i've already replaced one of the mt_luts with a frameevaluate and it doesn't seem to have affected anything but speed (which is good). it may be possible to do all comparisons via frameevaluates, but it's all a matter of how long i can go without my brain imploding with those backward-forward inside-out conditional filters :)

Mug Funky
2nd August 2006, 12:04
ver 0.91 posted above... copypasta it into an avsi to run it. hopefully i didn't forget any helper functions, as i have hundreds and tend to forget others don't have them...

should be much much more stable, and quite a bit faster too (it's running at about 70% the speed of a standard deinterlace-resize-blendfps-reinterlace script, which is better than i expected).

converttopal() = 38fps
autopal() = ~26fps (speed varies between modes of course)

all with just mpeg2source(...) and assumetff in their paths.

IanB
2nd August 2006, 15:51
Any chance of a width friendly version and some comments?

buzzqw
2nd August 2006, 17:16
omg ! AWESOME script !! :thanks: :thanks:

BHH

P.S me too with IanB

thegame
2nd August 2006, 23:44
This seems really cool,But I was wondering,is there a PAL Tools version also,I have alot of PAL DVD's I would like to convert to NTSC.
thanks in advance
game

Mug Funky
3rd August 2006, 02:09
PAL only has 2 major footage types - interlaced and progressive (well, there's field-shifted film, but that doesn't come up often and can be handled with telecide).

but i'll consider modifying it to make it PAL friendly (and amending the current one to detect input height + fps to make sure it doesn't work on already PAL stuff).

on the width friendly script - i remember there was a way to break conditionalfilters over lines, but it involved inserting ascii codes into the script. maybe something i'll do later. for now ctrl+a and a text editor should do :)

i'll have to document it too, as those metrics are sort of messy.

i'm also considering giving it a more catchy name...

foxyshadis
3rd August 2006, 03:11
Just need a triple quote. :p Like:

scriptclip(source, """(counter==0 && !sc ? final : (counter==1 ? dupframe : source))#.subtitle(string(fs))
\ .subtitle("Bdiff:"+string(b_diff,"%1.2f")).subtitle("Avg:"+string(AverageLuma(single),"%1.2f"),align=9)
\ .subtitle("Cdiff:"+string(c_diff,"%1.2f"),align=4).subtitle("Avg:"+string(AverageLuma(single.trim(1,0)),"%1.2f"),align=6)
""")

(example ripped out of my old debugging version of fixblendivtc...)

Boulder
3rd August 2006, 11:26
@ boulder: if you give it blended stuff, it'll detect it as 60i unfortunately. it's not meant for un-doing standards conversions, but rather for doing them in as progressive-friendly a way as possible. though i can see the use of unblending stuff, as i just got a pile of DVD extras that were shot in PAL, converted to NTSC, then given to us to convert back to PAL. grrr.

I was thinking about altering the function so that the 60i sections would be treated with one function (available in that MP thread) and all the rest would get the Restore24 treatment.

Chances are that it would work just fine :) Still, I need to see a commented function first, and it might be that I still couldn't do the trick:p

EDIT: just did a small test on that sample clip of mine (originally 25p, now a blended one?) and it looks like it is recognized as interlaced so it doesn't work without modificating the analysing parts as well. Dang:( However, the 60i stuff converted back to PAL (without modding your function) looks really good at least on the PC, no jerkiness whatsoever.

Mug Funky
3rd August 2006, 11:34
haha! is it that long since i played with conditional filters? i swear the ascii thing was the only way to do it way back when (though i probably just didn't think of the triple-quotes).

now, one thing i'd like to crack is fade detection. i might have a go at it tonight - with any luck it wont slow the process down except in extreme cases, because it's already slower than i'd like it to be.

another thing i'd like is to refine the 30p/60i metric. maybe use a good old fashioned spatial comb mask? i also noticed the few frames before a piece of interlaced footage come to a complete stop can sometimes be detected as film. not sure whether this is actually noticable as spoiled motion, but i suspect it is (though on a TV it may well not be due to the inherent jumpiness of the scanlines and the very small amount of motion involved).

i've now tested this on about 10 different sources (anime, video, analog, digital, sharp, blurry, crawly, clean, etc) and it seems to be very robust. excellent :). this could finally mean that film with edits can be sped-up automatically without having to split and treat separately. once i get fade detection going it'll be ready for public consumption (and production work, which is after all what i wrote it for).

Mug Funky
7th August 2006, 11:59
updated to v 0.92

it's now working robustly enough to use in production :)

CruNcher
8th August 2006, 03:27
woot you got fade detection stable, so no combing anymore between transitions (those ugly lines) ? , i have to test this great work :)
autoPAL(speedup=false) would give me 24p right ?

Mug Funky
8th August 2006, 06:39
well, it'll give you PAL 50i...

speedup=true will give you 25p (for film) you could slow it back down to 24p, but then the hybrid parts would be in 48i which is probably not what you want if you're maintaining NTSC.

you could use NTSC120 though:

data=last.ntscanalyse()
ntsc120(last,data)
selectevery(5,0)

would give you 24p, but it's better to use straight TIVTC :)

Chainmax
20th August 2006, 22:37
I'm currently trying to repair an extremely badly done DVD transfer made from my elder brother's Bar Mitzvah. The people who did it really screwed up, the source was NTSC (probably interlaced as it was filmed on a VHS camcorder) and they converted it to PAL (which, as far as I can tell, is interlaced too). Would Restore24 help me out? If so, where can I download the latest package? If not, then I'd like to request Mug Funky to create the reciprocal of this function.

P.S: upon ripping in IFO mode, what I got was 4 M2V's and a VOB, all of which had to be loaded in DGIndex for the D2V to be created. While creating the D2V, DGIndex reported "Picture Error" and at the end it told me that the field order was corrected. Should I expect nasty surprises when trying to re-encode or did DGIndex solve it?

Mug Funky
21st August 2006, 02:28
hmm. it's not really possible to recover 60i from 50i unless motion-compensation has been used (and even then it'll lose quite a bit).

i recently scripted a "restore24 lite" for my own use (sadly some dearly loved old cartoons from the 80's came in as NTSC which had been converted from PAL, and i have to make them PAL again), but it seems to be outputting duped frames in isolated situations that i can't quite tie down yet. it's got promise though :) basically it takes a bobbed clip, spots a blend via edgemasking, then chooses the adjacent frame that is most similar to the current frame, then decimates by 1 in 6 to get back to PAL. it's probably not post-worthy yet, and at any rate is only good for 25p-to-60i-and-back-again stuff.

Chainmax
21st August 2006, 04:14
I could post a short sample encoded in Lagarith for you to look.

Mug Funky
21st August 2006, 05:32
not much point - i can tell you now there's not much hope of un-blending a 60i to 50i conversion.

clouded was working on something that looked promising (finding the blend pattern and using it to subtract frames from each other just the right amount to reverse the blending), but he's not been around for months. there are some experimental filters around that might help. i don't have a clue how to use them though...

Boulder
21st August 2006, 07:43
Try this one (by scharfis_brain):
mpeg2source("python.d2v")

x=leakkernelbob(order=1)

#blend two NTSC-fields together (50:50 blend)
a=x.trim(1,0).mergeluma(x,0.5).mergechroma(x,0.5)

#blend three NTSC field together (25:50:25 blend)
b1=x.deleteframe(0).mergeluma(x.duplicateframe(0),0.5).mergechroma(x.duplicateframe(0),0.5)
b=b1.mergeluma(x,0.5).mergechroma(x,0.5)

#concat them
interleave(b,a)

#blindly select them, to get progressive 25 fps
changefps(25)It probably could be tweaked, maybe choosing another smart bobber would give better results.

actionman133
21st August 2006, 13:26
another thing i'd like is to refine the 30p/60i metric.

Hey Mug Funky, have you managed to refine this? I haven't actually had time to play with your function so I don't know how well it works, but I thought I'd share an old algorithm I developed that at the very least will be food for thought (I hope!! lol)...

Consider frames 1-4. 1 and 2 are 30p, 3 and 4 are 60i. Assume TFF so that the letters run alphabetically. We want to find out which frames are progressive and which are interlaced.

Frame 1 2 3 4
A1 B1 c e
A2 B2 d f

For each pair of frames, you subtract the diagonal matches. Subtract (A1, B2) and (A2, B1) for the progressive frames. For the interlaced, Subtract (c, f) and Subtract (d, e). You then compare these pairs of subtractions. Since the fields are identical in 30p, the two subtractions should be very similar (slight errors arise with spatial shifting). This says the fields aren't changing, therefore it's progressive.

If there is any motion in the interlaced sequence, differences between the two subtractions should become very measurable. One subtraction will register more motion than the other, indicating that the fields are unique. Therefore it's 60i.

I'd post the script I wrote for it, but I think it's been lost over time... can't seem to find it.

Hope this helps, and if it doesn't... oh well...:D

Mug Funky
22nd August 2006, 06:23
that's actually very clever!

i think i'll give it a shot, however there's a couple of other things i need to fix first (30p detection and giving it separate treatment will take it up to the 1.0 release candidate level i think).

it's usable at the moment (and i have been using it quite a bit), but will occasionally pass through nonfilm frames as film, mainly on either fades (this is getting better though) and with certain types of motion (hopefully not noticable in these cases, but watching on a TV shows that it can be quite visible. lowering th_film fixes it though).

another issue is that if i turn 30p on (there's a commented chunk of code in there), film detection goes out of whack. this is very strange indeed as these things are handled in separate functions. maybe there's a shared global that i haven't noticed?

and i'm still getting a 1-frame lag it seems - in that the treatment for frame n is being applied to frame n+1. again, it's not very noticable (in fact i can't see it at all on a TV unless it's a fade from black or a very fast crossfade between film and interlaced).

once those issues are solved i'll try out your idea for 30p detection - it seems like it'd be quite robust, in that small stuff wont throw it off, meaning 1 setting should be fine for almost everything (which is what i'm aiming for - that other people can use this blindly as part of a batch encoding method).

actionman133
23rd August 2006, 18:55
Yes, it worked well in concept tests. One of my tests was with grainy and soft (due to poor focus) night footage from The Hire DVD featurettes. The sequence featured a BMW doing a 180, slight burnout on the spot (low motion), before speeding off. The camera follows the car the whole time from the other side of the road.

Decomb turned out worst, returning progressive frames all the way through it, particularly when the car was at a halt. SmartDecimate () fared better, returning a dozen or so progressive frames when the car was stationary. My test filter only returned one or two interlaced frames, and that was when there was so little motion, you couldn't see any interlacing anyway.

Also, Mug Funky, to add to your mega-function ;) , have you considered adding support for field-matched, but non-decimated telecine? Not the blended kind (3 clean, 2 blended - although it would be nice if you could support that too), but rather the '1 duplicate in 5' type. To detect and restore that to 24p would be great. I don't know if you've encountered it, but I've seen videos with 3:2 pulldown AND field-matched film content in the same clip. To take both into account would be cool.

Great work with this function, by the way. Ought to be a ripper when you finally get everything finished. I'm looking forward to it! :p

Mug Funky
24th August 2006, 03:23
hmm... 1 in 5 duped (like the output of telecide without any decimating?).

yeah, i've seen this before a fair bit. mostly low budget stuff (screener discs). it would be fairly simple to add that in - if a dup is found within 6 frames of another dup then you can assume it's one of these clips.

right now i'm using a "service clip" that's coloured red green or blue for film, 30p and 60i respectively, but there's plenty more colours in the rainbow - extra footage types can be added so long as they can be detected reliably. field-blending is one i'm considering - i have a separate function dealing with that, but it's being thrown off by large 12.5fps animated objects in front of a 25fps pan - i get dupes in the output :(. works near perfect for everything else though, at least on the She-Ra eps i've tested it on (the show was restored in PAL, so they had to go give us the NTSC tapes, didn't they?).

[edit]

@ actionman: i like your sig... lemme guess - you weigh in at 25mbps?

actionman133
24th August 2006, 06:16
@ actionman: i like your sig... lemme guess - you weigh in at 25mbps?

What do you take me for, a featherweight? I'm no Mini-DV wannabe! I'm 144 Mbps HDCAM! :D

Can't help you with field blending though, mate. Not my area...

I was actually working on a hybrid NTSC deinterlacing script as well, before I found this thread. It's major difference from yours is that will be manual - the user specifies frame ranges and specifies the content (between frames 'a' and 'l' is 30p, 'm' to 'q' is 60i, etc). It's designed for maximum quality - it even blends the duplicate fields in material that has undergone 3:2 pulldown.

It's designed to output to 120p, but to also consider decimation strategies, including blending and mo-comping (so far, it can decimate to 12, 15, 24, 30 and 60 fps flawlessly - if I up it to 240p, it could also do NTSC-PAL hybrid conversions like your function does). It's still in draft stages, and isn't too streamlined, but the concept is working. If you want, I can post the script here... obviously, it won't help you with detection, but perhaps the algorithms to recover and structure the frames may or may not give you some new ideas (I didn't think my 30p/60i detection would). Also some feedback about it wouldn't hurt, either. I don't know if I'm handling stray fields at the ends of 24p sequences properly, for example...

Mug Funky
25th August 2006, 02:44
hmm... on the 120p thing: take a look at the bottom half of my script :)


data=last.NTSCanalyse()
NTSC120(last,data)

will do it. it'll do it better once 30p detection is bug-free, but with a good enough deinterlacer thrown in there it'll look the same.

however, if your script can be taught to read the data clip NTSCanalyse makes, they could be easily combined, as NTSCanalyse pretty much just specifies what frames are what, and the other functions simply choose what to do about each kind of footage.

Mug Funky
1st September 2006, 12:23
posted 0.93...

the first post is too long so the changelog is here:

- (1/09/2006) updated to v0.93.
- partially re-wrote the engine. one of the metrics was comparing the wrong field... should be more robust and react quicker to footage changes.
- removed the hacky "if current frame is within 2 frames of the last film frame, then current frame is film" check. now film is (hopefully) properly detected on every frame. this will help with fades and interlaced talking-head footage (with slow-moving people).
- added pre-deblocking. i noticed deblocking beforehand was throwing off film detection on soft-telecined stuff, so i put a deblocker in NTSCconvert but not NTSCanalyse. that way soft-telecine should never be detected as nonfilm (ha!). turn it on with "deblock=true".
- i'll add more later - got a thumping headache.
- tweaked tfm settings slightly, though the occasional fade is still getting munged.


main reason for the update: Trinity Blood vol 1 :) that show has so so many fades in it, and they're all 30p. everything else is 24p, but the old NTSCtools were buggering up the fades most of the time. seems slow 30p fades of 24p content is a bit of an achilles heel for the old one (not to mention there was a pretty big bug that i hadn't spotted).

Mug Funky
26th October 2006, 04:51
again, 1st post is too long, so here's the changelog snipped out of it:


[edit / changelog]

- updated script. doesn't output field-shifted PAL anymore if film is detected. doesn't need bobbed input. added a couple of helper functions that i've been using forever anyway, changed a couple of metrics that were giving stupid results, made frame type thresholds tweakable via "th_film" and "th_prog" variables. i encourage anyone interested to play with this

- (2/08/2006) updated to v0.91.
- metrics (almost) completely rewritten, so field-comparisons are done odd-for-odd or even-for-even. this means the half-pel shift between fields doesn't come into play with film detection, so thresholds can be set much, much lower (0 for a perfect 3:2...). also a much faster bob can be used
- logic changed a little too - should be faster and more precise.
- 30p/60i discrimination in NTSCconvert is disabled for now - it assumes 60i for everything non-film.
- added "autopal()" so you don't need to type all that extra stuff if you're converting to PAL.
- added "NTSCfilter()" for running a denoiser or whatever on each footage type separately - interlaced gets bob-filter-unbob, 30p gets normal filter, film gets IVTC-filter-3:2 telecine, and output is (hopefully) the same as input but filtered.
- added "NTSC120()" to allow for making 120fps files. film gets 5 dupes, 30p gets 4 dupes, 60i gets 2 dupes, final output is progressive (to use with a frame-dropping encoder).
- added helper function "resizetoPAL()" which just does a 525 line to 625 line resize (rather than 480 to 576). you'll get ~4 pixels of black letterboxing on the top and bottom unless your input is 486 lines.
- (7/08/2006) updated to v0.92.
- added filter options to autopal and ntscconvert
- added fade detection. seems to work pretty well at the default. if it fails, TIVTC's postprocessing will take it, which leads to:
- changed tdeint to TFM for field-matching. it catches fades better, so if my script fails it'll catch it. also much faster now (~90% speed of old "converttopal")
- added blending mode... this is now default, simply because it's way easier at my end if audio doesn't need messing with. set "speedup=true" to go back to old behaviour, which is more desirable in a perfect world anyway. 1 in 12 field jitter wasn't my cup of tea either, but you can get that with "blend=false".
- added "interlace(int order)" helper function. this will prevent the last field being a dupe of the 2nd last, giving an ugly aliased final frame in ~50% of cases. hopefully it wont break anything.
- tweaked thresholds with focus on pure film live action and hybrid anime (ie. anything i can find around work and home).
- (26/10/2006) updated to v0.93c.
- 2 months of tweaking...
- added "IVTCtype" (int), enabling selection of telecide, tfm or tdeint mode 2 (default, for various reasons)
- now uses the latest Tdeint, so make sure you update or the script wont work. on the upside, the results look much better and fades are handled waay better.

Bugs/issues:
- switching between film and video seems to expose a seeking issue in DGdecode. only applies to soft-pulldowned clips (ie > 0% FILM). might show up as a tiny flash on some scenechanges, or possibly as a combed frame (probably not, as tdeint should catch it in default mode)
- code is messy. i need to copypasta this a function at a time and figure out what's not needed.


to do:

- add a 24p output mode for anyone who might need it. non-film will be blended or mocomped to 24p.

- gather stats on what "film conditions" occur most often, and rearrange the film decision line to exploit that (speed should increase, but probably not by much).

- put 30p/60i discrimination back in when it's stabler (right now if 30p is allowed film detection gets thrown off... wtf?)

- finalise default thresholds, and chase down any weirdnesses as i (or anyone else) find them.

- clean up the code, rename vars, make it readable (and understandable).

LogicDeLuxe
26th October 2006, 20:13
There is no function named "mt_lutxy".
Where do I get this from?

Alain2
26th October 2006, 20:21
Read the first post... requires:
-clouded's motionprotectedfps and motion package
-a nice deinterlacer like tdeint. field-matching is a good idea, as my script just works on the frames you give it.
-masktools v2

LogicDeLuxe
26th October 2006, 20:59
Read the first post...I did. Just got the wrong masktools. Now it works.

Thunderbolt8
19th November 2006, 03:50
ok, can I use this now to "convert" a ntsc dvd with 23,976 or 29,97 fps directly with all the other scripts and options of /avisynth and megui encoding process and make x264 files out of it ?

Mug Funky
19th November 2006, 15:38
if you're going x264, do you really need it in PAL? this script will output interlaced and x264 currently isn't fully interlace friendly (though it's getting there).

i'd recommend TIVTC or plain old Telecide + decimate if you're making x264 backups.

this script is something i've developed for work use and decided to share (because it rocks, but needs bugs spotted and fixed by more people than myself :)).

btw, i've just hacked tritical's new compile of smartdecimate (and the plugin version of vinverse) into my development version of this script and it's nearly doubled the speed without hurting anything :). i'll post it here once i've cleaned the code a bit (right now it's a huge mess)

DSP8000
30th November 2006, 03:13
@Mug_Funky

Any chance of providing PALTools version of the script.

I've got some MiniDV video that I'm trying to convert to NTSC.
I reread the whole PAL2NTSC posts & found some solutions that do the job good, but I'd like to try your PAL version of the script.

Also, maybe scharfis's got some suggestions on this matter as well.

@scharfis_brain,

can you please point me in the right direction for this conversion, I consider you "A Master of Deint/Interlacing issues" :thanks:

ficofico
9th December 2006, 16:52
Which script I need to recode my 30p videos from camera to 25p pal?

With autopal() I have error "no function named blend fps" Thanks.

Mug Funky
11th December 2006, 01:00
@ ficofico:

dependencies for autopal (that i can think of right now):

- masktools v2 (aka. mt_masktools)
- masktools
- motion.dll by clouded (mg262)

you'll need to find these for the script to work :)

@ DSP8000:

PAL video doesn't come in as many flavours as NTSC, so detecting telecine patterns etc is less relevant, though i can see that it'd be quite useful too. i haven't any plans to rewrite this for outputting NTSC, though it would be a simpler script and probably faster, so i might do it on a bored day :)

for now, a nice deinterlacer (tdeint + vinverse postprocessing is my current favourite) plus resize and motionprotectedfps or just blendfps should be enough for a pretty good conversion of 50i to 60i. sorry to be lazy about it, but my focus is on NTSC to PAL because that makes up 99% of my work. it's rare that i need to output NTSC, and most of the time a simple blend or progressive "slowdown" is enough. australia is PAL after all, and sadly we don't export as much content as we import...

DSP8000
11th December 2006, 05:15
@ DSP8000:

PAL video doesn't come in as many flavours as NTSC, so detecting telecine patterns etc is less relevant, though i can see that it'd be quite useful too. i haven't any plans to rewrite this for outputting NTSC, though it would be a simpler script and probably faster, so i might do it on a bored day

for now, a nice deinterlacer (tdeint + vinverse postprocessing is my current favourite) plus resize and motionprotectedfps or just blendfps should be enough for a pretty good conversion of 50i to 60i. sorry to be lazy about it, but my focus is on NTSC to PAL because that makes up 99% of my work. it's rare that i need to output NTSC, and most of the time a simple blend or progressive "slowdown" is enough. australia is PAL after all, and sadly we don't export as much content as we import...

That's cool, no probs, it would be nice if you put it together one day so we'll have a nice set of AutoPAL/NTSC Tools. I'll try your suggestion on TDeint+Vinverse today.

australia is PAL after all, and sadly we don't export as much content as we import...
I did PAL to NTSC conversion last week/ at work we had some corporate videos that the head office in Japan wanted them in NTSC. Came out very nice & they were very happy.

Looking forward to try your version of AutoNTSC/ whenever that may be.
I hope you get bored soon;)

Thanks for the pointers anyways.

DSP8000

Mug Funky
11th December 2006, 06:54
oh, i didn't notice the "location" part in your profile :)

yeah, it can be handy to have autoNTSC, but to be honest whenever i've had to make NTSC i've just done a blend :sly: give the NTSC people a taste of their own medicine. the default mode for autopal is blending anyway, but the advantage is being able to speed up the parts that can be sped up if need be.

Floatingshed
12th February 2009, 15:44
I'm loving NTSCtools, its doing a great job but for one small thing. I'm getting "Evaluate: System exception - Access violation ([scriptclip], line1) stamped on the top of the output video for a few frames. Does anyone know how to disable this please?
Thanks.

Mug Funky
13th February 2009, 06:53
oooh, that means something is failing for 1 of the detected types of frames (by default "film" or "other").

try "show=true" and tell me what colour the top-left corner is. from the look of things it may be buggering up on one of the plugins it uses (maybe mvtools, as i haven't updated this for mvtools2 with superclips and all that).

glad to hear it's coming in useful, somewhat. i haven't maintained this script since i moved jobs from being the fixer of problems to the cause of them :)

McCauley
13th February 2009, 10:53
Added to wiki (http://avisynth.org/mediawiki/External_filters#Frame_Rate_Conversion).

Regards
McCauley

Floatingshed
13th February 2009, 13:26
Thanks for the fast response. The colour in the top left is red. The error message is intermittent. I had it on frames 57 and 60 of a clip but when I re-loaded it was fine. Another clip had it on frames 0 and 5 but again it is difficult to recreate. There is no crash or problem loading into VDub, just an error message on the outputted video and it seems only to occur in the first few seconds of a clip.

Apart from this tiny problem this is an absolutely superb piece of work, I've never seen better NTSC-PAL conversion.

I do have a clip it doesn't like though! But that's another story and another post in the near future.

Thanks.

Floatingshed
13th February 2009, 22:41
Which version of MVTools was your function designed to work with? Maybe I could use that and see if the problem goes away?
Thanks.

Mug Funky
16th February 2009, 03:01
aaah, stupid me forgot that i used clouded's "motion" plugin to do the motion-compensated frame rate conversion (and i think i also used the "blendfps" component for the dumb-blend default mode). unfortunately this plugin is not maintained (hope clouded's alright, but he dropped off the forum years ago).

you can find the 12/12/05 version on warpenterprises' plugin page here:

http://avisynth.org/warpenterprises/

or download the plugin directly here:

http://avisynth.org/warpenterprises/files/motion_25_dll_20051212.zip

hopefully that should make it all work. i just quickly tested it on some awful NTSC VHS i got from a friend and it appears to be working (though it likes cleaner video and was falsely matching the analog black as film... ah well), though i seem to be using a newer version of the script. that doesn't necessarily mean it's better mind you...

Floatingshed
18th February 2009, 20:00
Downloaded it only to find that its the same version I have!
Still got the problem regardless of input clip. Loads fine, works beautifully but still outputs the error message on one or two frames.
Is it possible to switch off the subtitle-style error reporting in avisynth?
Thanks again.

Gavino
18th February 2009, 20:56
Is it possible to switch off the subtitle-style error reporting in avisynth?
No - and you shouldn't want to. You get errors reported this way when a run-time script (such as within ScriptClip) produces an error.

Since a run-time script can do different things on different frames, sometimes you only get the error on certain frames. But it still indicates a problem in the script that needs to be fixed.

IanB
18th February 2009, 21:14
@Floatingshed,

Actually, sort of yes. As Gavino points out "you shouldn't want to". The error "Evaluate: System exception - Access violation" is very serious. It means some code tried to access part of the address space that was not declared. If the rouge access is random that same code accessing any part of the address space that is declared will not trigger an error, it will silently just mess things up. So you really should find and replace the errant plugin.

To suppress the default error handling behaviour you can wrap the offending statement with a try/catch and script to deal with (or ignore) the problem.try {
statement # goes boom!
}
catch(err_msg) {
statements
...
}

Gavino
18th February 2009, 21:36
To suppress the default error handling behaviour you can wrap the offending statement with a try/catch and script to deal with (or ignore) the problem.
Yes, but note you would need to put the try/catch inside the failing run-time script, ie at the appropriate place inside NTSCTools. Putting it in the user-level script will not help.

Floatingshed
18th February 2009, 22:38
Thanks for your replies. However I understand very little of it. I can write simple scripts for my own use but something as complex as this is way beyond me. Mug Funky's script produces superb results apart from this small problem. The error never seems to occur on the same frame twice. This is really frustrating as I have a lot of material to process. Any more ideas very welcome. Thanks.

Floatingshed
18th February 2009, 22:41
though i seem to be using a newer version of the script. that doesn't necessarily mean it's better mind you...

Could I possibly try the newer version please?

Mug Funky
19th February 2009, 06:19
here's 0.96. i think the defaults have been tweaked slightly.

note that you have a choice of IVTC methods for "film" flagged frames. it's possible that's where the errors were popping up before, so if this new script doesn't help you could change "IVTCtype" to some other number (it says inside the script what each one does).

also, AFAIK this script is a bit slower but _should_ be better quality. bear in mind any tweaks i've made since i left madman have been sample-specific, and haven't been "general" solutions (at madman i was putting through ~60 DVDs a month, mostly on this script. where i am now i'm not even encoding, but colour grading, so i don't see much NTSC, and almost never need to convert it).

keep the old script on hand somewhere - rename it and turn the "avsi" into "avs" so it doesn't get autoloaded.

good luck :)

####
##
## NTSC tools 0.96, 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, clip "ext_match", bool "speedup", float "th_film", int "th_film2", int "th_prog", float "th_noise", int "th_noise2", int "th_bob", bool "show", int "mode", string "filter", bool "blend", int "deblocker", int "IVTCtype", int "precision", bool "find30p", int "reset", int "denoise",int "threads")
{
speedup=default(speedup,false)
ext_match=default(ext_match,c)
blend=default(blend,true)
th_film=default(th_film,.4)#.15)
th_film2=default(th_film2,5)
th_prog=default(th_prog,18) # 16 seems good

th_noise=default(th_noise,.5)
th_noise2=default(th_noise2,40)

th_bob=default(th_bob,8)
show=default(show,false)
mode=default(mode,1)
filter=default(filter,"last")
deblocker=default(deblocker,0)
IVTCtype = default(IVTCtype,3) # 1 = telecide, 2 = tfm, 3 = tfm(pp=0), 4 = tdeint(mode=2), 5 = smartdecimate ...formerly 2
precision = default(precision,1)
reset = default(reset,50)
denoise = default(denoise,0)

threads=default(threads,1)

find30p = default(find30p,false)

data= NTSCanalyse(ext_match,th_film=th_film,th_prog=th_prog, th_noise=th_noise,th_film2=th_film2,precision=precision,find30p=find30p,denoise=denoise)


threads<=1? NTSCconvert(c,data,th_bob=th_bob,speedup=speedup,show=show,mode=mode,filter=filter,blend=blend,deblocker=deblocker, IVTCtype=IVTCtype, reset=reset) :
\ mt(blackpal(c.changefps(25).framecount()),"""NTSCconvert(c,data,th_bob=th_bob,speedup=speedup,show=show,mode=mode,filter=filter,blend=blend,deblocker=deblocker, IVTCtype=IVTCtype, reset=reset)""",threads,8,true)



c.height==576? deblocker==0? c : c.converttoyv12(interlaced=true).deblocker(quant=deblocker,ipp=true) : last
}

function NTSCanalyse (clip c, float "th_film", int "th_film2", int "th_prog", int "precision", bool "show", bool "find30p", int "denoise", float "th_noise", int "th_noise2")
{
# 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 filmnum=-4
global ftype="60i"
global noise=1
global noise2=1

global th_film=default(th_film,.4)#.15)
global th_film2=default(th_film2,5)
global th_prog=default(th_prog,18) # 16 seems good

global th_noise=default(th_noise,.5)
global th_noise2=default(th_noise2,40)

precision=default(precision,1)
denoise = default(denoise,0)

find30p = default(find30p,false)

e = c.converttoyv12(interlaced=true)
d= denoise==0?
\ c.bicubicresize(32*precision,c.height,1/3.,1/3.,16,0,c.width-32,c.height).separatefields().bicubicresize(32*precision,32*precision,1/3.,1/3.,0,8,32*precision,(c.height/2.)-16).converttoyv12()
\ : c.bicubicresize(32*precision,c.height,1/3.,1/3.,16,0,c.width-32,c.height).separatefields().bicubicresize(32*precision,32*precision,1/3.,1/3.,0,8,32*precision,(c.height/2.)-16).converttoyv12().weave().temporalsoften(5,denoise,0).separatefields()

global film_c = d
global film_d = d.selectevery(2,0)

weavemask=e.mt_edge("0 -1 0 0 2 0 0 -1 -0 2",0,255,y=3,u=3,v=3)
separatemask=e.separatefields().mt_edge("0 -1 0 0 2 0 0 -1 -0 2",0,255,y=3,u=3,v=3).weave()

global f01 = mt_lutxy(weavemask,separatemask,expr="x y -").mt_inpand(mode=mt_rectangle(0,2))

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,""" ftype=="24p" ? NTSCanalyse_red : ftype=="30p" ? NTSCanalyse_green : NTSCanalyse_blue """)

film_d2 = find30p==true? frameevaluate(film_d1,""" ftype = f01.yplanemax() <= th_prog ? "30p" : ftype """) : frameevaluate(film_d1,"NOP")
film_d3 = frameevaluate(film_d2,"""
\ ftype = (noise2==1)? ftype : ftype != "24p"? "60i" : (b1f1.yplanemax() < th_film2) ? "24p" :
\ max(f02.yplanemax(),b35.yplanemax()) < th_film2 ? "24p" :
\ max(b02.yplanemax(),f35.yplanemax()) < th_film2 ? "24p" :
\ max(b13.yplanemax(),f24.yplanemax()) < th_film2 ? "24p" :
\ max(f13.yplanemax(),b24.yplanemax()) < th_film2 ? "24p" :
\ max(f24.yplanemax(),b13.yplanemax()) < th_film2 ? "24p" :
\ max(b24.yplanemax(),f13.yplanemax()) < th_film2 ? "24p" : "60i" """)

film_d4 = frameevaluate(film_d3,"""
\ ftype = (noise==1)? ftype : (b1f1.averageluma() < th_film) ? "24p" :
\ max(f02.averageluma(),b35.averageluma()) < th_film ? "24p" :
\ max(b02.averageluma(),f35.averageluma()) < th_film ? "24p" :
\ max(b13.averageluma(),f24.averageluma()) < th_film ? "24p" :
\ max(f13.averageluma(),b24.averageluma()) < th_film ? "24p" :
\ max(f24.averageluma(),b13.averageluma()) < th_film ? "24p" :
\ max(b24.averageluma(),f13.averageluma()) < th_film ? "24p" : "60i" """)

film_d5 = frameevaluate(film_d4,"""
\ noise= (b1f1.averageluma() > th_noise) ? 0 :
\ max(f02.averageluma(),b35.averageluma()) > th_noise ? 0 :
\ max(b02.averageluma(),f35.averageluma()) > th_noise ? 0 :
\ max(b13.averageluma(),f24.averageluma()) > th_noise ? 0 :
\ max(f13.averageluma(),b24.averageluma()) > th_noise ? 0 :
\ max(f24.averageluma(),b13.averageluma()) > th_noise ? 0 :
\ max(b24.averageluma(),f13.averageluma()) > th_noise ? 0 : 1 """)

film_d6 = frameevaluate(film_d5,"""
\ noise2= (b1f1.yplanemax() > th_noise2) ? 0 :
\ max(f02.yplanemax(),b35.yplanemax()) > th_noise2 ? 0 :
\ max(b02.yplanemax(),f35.yplanemax()) > th_noise2 ? 0 :
\ max(b13.yplanemax(),f24.yplanemax()) > th_noise2 ? 0 :
\ max(f13.yplanemax(),b24.yplanemax()) > th_noise2 ? 0 :
\ max(f24.yplanemax(),b13.yplanemax()) > th_noise2 ? 0 :
\ max(b24.yplanemax(),f13.yplanemax()) > th_noise2 ? 0 : 1 """)



show==true? overlay(c,film_d6) : film_d6

show==true? scriptclip(""" subtitle("max pixel difference = "+
\ string(max(b1f1.yplanemax(),
\ f02.yplanemax(),b35.yplanemax(),
\ b02.yplanemax(),f35.yplanemax(),
\ b13.yplanemax(),f24.yplanemax(),
\ f13.yplanemax(),b24.yplanemax(),
\ f24.yplanemax(),b13.yplanemax(),
\ b24.yplanemax(),f13.yplanemax()))+", max avg luma diff = "+
\ string(max(b1f1.averageluma(),
\ f02.averageluma(),b35.averageluma(),
\ b02.averageluma(),f35.averageluma(),
\ b13.averageluma(),f24.averageluma(),
\ f13.averageluma(),b24.averageluma(),
\ f24.averageluma(),b13.averageluma(),
\ b24.averageluma(),f13.averageluma()))
\ +", noise1 = "+string(noise)+", noise2 = "+string(noise2)) """) : last

}

function NTSCconvert (clip c, clip data, bool "speedup", int "th_bob", int "mode", bool "show", string "filter", bool "blend", int "deblocker",int "IVTCtype", int "reset")
{
# 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,0)
IVTCtype = default(IVTCtype,3) # 1 = telecide, 2 = tfm(chroma=true), 3 = tfm(), 4 = tdeint(mode=2) 5 = smartdecimate
reset = default(reset,50)

outnum = speedup==true? 48000 : 50000
outden = speedup==true? 1001 : 1000

order = c.getparity()==true? 1 : 0

d = deblocker==0? c : c.converttoyv12(interlaced=true).deblocker(quant=deblocker,ipp=true)
d = mode==1? d : d.converttoyv12(interlaced=true)

global bobbed = d.tdeint(1,order,expand=4,mthreshl=th_bob)
sdbob = d.tdeint(1,order,expand=4,mi=24,cthresh=8,mthreshl=th_bob,tryweave=true)

NTSCconvert_60i = mode==1? bobbed.vinverse().blendfps(outnum/float(outden),1.25).changefps(outnum,outden).resizetopal(false,false) : bobbed.vinverse().converttoyv12(interlaced=false).salfps(outnum/float(outden),protection2=60,reset=reset).changefps(outnum,outden).resizetopal(false,false)
NTSCconvert_30p = d.converttoyv12().vinverse().salfps(outnum/float(2*outden),protection2=50,reset=reset).resizetopal(false,false).changefps(outnum/2,outden)

IVTCtype==1? d.telecide(order=order,guide=1).decimate() :\
IVTCtype==2? d.tfm(order=order,pp=0,chroma=true).decimate() :\
IVTCtype==3? d.tfm(order=order,pp=0,chroma=false).decimate() :\
IVTCtype==4? d.tdeint(2,-1,expand=4,tryweave=true,cthresh=3,mi=24,mthreshl=8,chroma=true).decimate() :\
d.smartdecimate(24,60,bob=sdbob,tel=1.)

vinverse()
resizetopal(false,false)

eval(filter)
NTSCconvert_24pfilter = last

global NTSCconvert_24p = speedup==true?
\ NTSCconvert_24pfilter.changefps(outnum/2,outden) :
\ (blend==true)? NTSCconvert_24pfilter.blendfps(50,1.25).changefps(outnum,outden).interlace(order=1):
\ NTSCconvert_24pfilter.changefps(outnum,outden).interlace(order=1)

NTSCconvert_60i
eval(filter)

interlace(order=1)
global NTSCconvert_60i = last

NTSCconvert_30p
eval(filter)
#mode==1? last : last.interlace(order=1)
global NTSCconvert_30p = last


global NTSCconvert_data = data.assumetff().blendfps(outnum/float(outden*2),2.).changefps(outnum/2,outden)
#global NTSCconvert_data = data.changefps(outnum/2,outden)
#global NTSCconvert_data = data.assumetff().medianblurt(0,0,2).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)
global NTSCconvert_isgreen = mt_lutxy(NTSCconvert_green,NTSCconvert_data,yexpr="x y - abs",y=3,u=1,v=1)

mode==1? scriptclip(NTSCconvert_24p,"yplanemax(NTSCconvert_isred)==0 ? NTSCconvert_24p : NTSCconvert_60i") : scriptclip(NTSCconvert_24p,"yplanemax(NTSCconvert_isred)==0 ? NTSCconvert_24p : yplanemax(NTSCconvert_isgreen)==0 ? NTSCconvert_30p : NTSCconvert_60i")
speedup==true? last.assumefps(25,true).SSRC(48000) : last

show==true? overlay(last,data.changefps(outnum/2,outden)) : last
assumetff()

c.height==576? c : last
trim(0,c.changefps(outnum/2,outden).framecount())
}

Mug Funky
19th February 2009, 06:19
...and the support functions (please append this to the last lot in a .avsi file)

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,expand=4,mi=24,cthresh=8,mthreshl=8,tryweave=true).vinverse()#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 NTSCtoFPS (clip c, clip data, int "num", int "den", int "th_bob", bool "show", string "filter", int "deblocker",int "IVTCtype", int "reset")
{

num=default(num,24000)
den=default(den,1001)

th_bob=default(th_bob,2)
show=default(show,false)
filter = default(filter,"last")
deblocker = default(deblocker,0)
IVTCtype = default(IVTCtype,3) # 1 = telecide, 2 = tfm(chroma=true), 3 = tfm(), 4 = tdeint(mode=2) 5 = smartdecimate
reset = default(reset,50)

order = c.getparity()==true? 1 : 0

d = deblocker==0? c : c.converttoyv12(interlaced=true).deblocker(quant=deblocker,ipp=true)
d = d.converttoyv12(interlaced=true)

global bobbed = d.tdeint(1,order,expand=4,mthreshl=th_bob)
sdbob = d.tdeint(1,order,expand=4,mi=24,cthresh=8,mthreshl=th_bob,tryweave=true)

NTSCtoFPS_60i = bobbed.vinverse().converttoyv12(interlaced=false).salfps(num/float(den),protection2=60,reset=reset).changefps(num,den)
NTSCtoFPS_30p = d.converttoyv12().vinverse().salfps(num/float(den),protection2=50,reset=reset).changefps(num,den)

IVTCtype==1? d.telecide(order=order,guide=1).decimate() :\
IVTCtype==2? d.tfm(order=order,pp=0,chroma=true).decimate() :\
IVTCtype==3? d.tfm(order=order,pp=0,chroma=false).decimate() :\
IVTCtype==4? d.tdeint(2,-1,expand=4,tryweave=true,cthresh=3,mi=24,mthreshl=8,chroma=true).decimate() :\
d.smartdecimate(24,60,bob=sdbob,tel=1.)

vinverse()

eval(filter)

salfps(num/float(den),protection2=50).changefps(num,den)

global NTSCtoFPS_24p = last


NTSCtoFPS_60i
eval(filter)

global NTSCtoFPS_60i = last

NTSCtoFPS_30p
eval(filter)

global NTSCtoFPS_30p = last


global NTSCtoFPS_data = data.assumetff().blendfps(num/float(den),2.).changefps(num,den)

global NTSCtoFPS_red = blankclip(NTSCtoFPS_data,color=$ff0000)
global NTSCtoFPS_green = blankclip(NTSCtoFPS_data,color=$00ff00)
global NTSCtoFPS_blue = blankclip(NTSCtoFPS_data,color=$0000ff)

global NTSCtoFPS_isred = mt_lutxy(NTSCtoFPS_red,NTSCtoFPS_data,yexpr="x y - abs",y=3,u=1,v=1)
global NTSCtoFPS_isgreen = mt_lutxy(NTSCtoFPS_green,NTSCtoFPS_data,yexpr="x y - abs",y=3,u=1,v=1)

scriptclip(NTSCtoFPS_24p,"yplanemax(NTSCtoFPS_isred)==0 ? NTSCtoFPS_24p : yplanemax(NTSCtoFPS_isgreen)==0 ? NTSCtoFPS_30p : NTSCtoFPS_60i")

show==true? overlay(last,NTSCtoFPS_data) : last
assumetff()

c.height==576? c : 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)
}

function combblur(clip c, int threshold)
{
mt_merge(c.mt_convolution("1","1 2 1",y=3,u=3,v=3).mt_convolution("1","-1 6 -1",y=3,u=3,v=3),c,c.combmask(threshold,threshold,y=3,u=3,v=3).mt_expand(mode=mt_rectangle(0,1),y=3,u=3,v=3).mt_inflate(y=3,u=3,v=3),y=3,u=3,v=3)
}


function salblendfps(clip c, float fps, float "aperture")
{
aperture = default(aperture,1.)

c.changefps(8*fps).temporalsoften(round(8*aperture),255,255,24).selectevery(8,0)
}

Floatingshed
19th February 2009, 08:36
Great, thanks. Can't wait to get home and have a play. On a twelve hour Tx shift so it'll be a while!

Floatingshed
19th February 2009, 23:20
Oops, no joy at all:

Avisynth open failure
Evaluate: system exception - integer overflow
(C:\Program Files\AviSynth 2.5\plugins\vinverse.avsi, line 14)
(C:\Program Files\AviSynth 2.5\plugins\NTSC tools 0.96\ntsc096.avsi, line 189)
(C:\Program Files\AviSynth 2.5\plugins\NTSC tools 0.96\ntsc096.avsi, line 40)

Any thoughts?
Thanks.

edit... tried the dll of vinverse too, not sure which version is required. Same result.

Mug Funky
19th February 2009, 23:48
argh. another one :)

hang on, i don't have any good NTSC stuff to check this out on at the moment (just a couple of VHS captures for a friend - too jittery for meaningful results i think). i'll just simulate some.

if you could run autopal with "show=true", and let me know what colour the little spot in the top left is just on the frames that are failing. that way i'll know which part of the script to look at (red is for "i think this is film" and blue is for "this doesn't look like film, i'll treat it as 60i").

i'm also thinking of some possible speed boosts when using motion compensation, but please bear in mind i'm quite short of NTSC samples at the moment, especially stuff with mixed timebases (working with film is great - no need to worry about mixing things up - it's all progressive 25fps off the telecine)

[edit]
btw, i don't recommend using "threads" at the moment - it's broken and just there for testing. i forgot it was still in there

[edit 2]

@ floatingshed: dll version is required. make sure you move the avsi version out of the way so avisynth doesn't try to load both. though they should both work, the dll is faster.

[edit 3]

poos. i can't replicate this bug. apologies. i'll go check the date-stamps on my plugins and we can compare, k?

[edit 4]

plugins: (dated yyyy-mm-dd)

decomb521.dll (dated 2004-5-18)
leakkerneldeint.dll (dated 2005-1-18)
tdeint.dll (dated 2007-01-22)
vinverse.dll (dated 2006-11-04)
Motion_12Dec05.dll (dated, obviously, 2005-12-12)
SmartDecimate.dll (dated 2006-10-25)

also, there's a couple of script functions used internally that weren't included in the package maybe. "blackpal" simply makes black pal video of the desired length. "salfps" is called when motion-compensated conversion is used (by default it's off).

here they are:

function salFPS(
\ clip input, float FPS,
\ int "mode", int "protection", int "protection2",
\ int "iterate", int "reset", int "initialise", bool "interlaced")
{
mode = default(mode, warp)#warpfast)
protection = default(protection, 80)
protection2 = default(protection2, 32)
iterate = default(iterate, 2)
reset = default(reset, 50)
initialise = default(initialise, 6)
interlaced = default(interlaced,false)

originalFPS = input.framerate()
input

mp = FindMotion(iterate = iterate, reset = reset,
\ initialise = initialise)
p = MotionFPS(FPS,mode,Motion = mp)
maskp = mp.SumStretchFPSMask(FPS, protection)

mn = FindMotion(iterate = iterate, reset = reset,
\ initialise = initialise, from = next)
n = MotionFPS(FPS,mode,Motion = mn, source = next)
maskn = mn.SumStretchFPSMask(FPS, protection, source = next)

maskp
assumeFPS(originalFPS)

tehmask=last.CombineFPS(FPS, maskp, maskn)
last.CombineFPS(FPS, maskp, maskn.Invert())
bilinearresize(width*8, height*8)
crop(0, 0, input.width(), input.height())
fity2uv()
mpro=last

tehmask
mt_deflate()
mt_binarize(protection2,false)
temporalsoften(1,255,255,255)
mt_binarize(80,false)
mt_expand(mode=mt_circle(3))
mt_inflate()
bicubicresize(width*8, height*8,1,0)
crop(0, 0, input.width(), input.height())
fity2uv()
tehmask=last
mt_merge(p, n, mpro, u=3, v=3)

interlaced==false? mt_merge(last,input.blendfps(FPS,aperture=FPS/float(input.framerate())),tehmask, u=3,v=3) :
\ mt_merge(last.changefps(FPS,false).selectevery(1,0,0),input.blendfps(2*FPS,aperture=FPS/float(input.framerate())),tehmask, u=3,v=3).interlace()
#merge(last,tehmask.greyscale(),.5)
}


function blackPAL (int "length", int "colour")
{
length = default(length,250)
colour = default(colour,$000000)

blankclip(width=720,height=576,fps=25000,fps_denominator=1000,pixel_type="yv12",length=length,audio_rate=48000,stereo=true,color=colour)
}




best of luck!... my plugins folder is in a bit of a shambles, so i'll have to clean this all up and re-release at some point just to be fair to anybody actually trying to use it :)

Floatingshed
20th February 2009, 08:08
Morning!
The colour in the corner of error frames is red using version 0.93.
I can't load version 0.96 into VDub without getting the failure error (above).
A couple of plugins needed different versions. Result: Same errors as before (minus the mention of vinverse):

Avisynth open failure
Evaluate: system exception - integer overflow
(, line 14)
(C:\Program Files\AviSynth 2.5\plugins\Autopal096.avsi, line 189)
(C:\Program Files\AviSynth 2.5\plugins\Autopal096.avsi, line 40)

Floatingshed
27th February 2009, 18:21
@: mugfunky

Any more thoughts? Thanks.

Mug Funky
2nd March 2009, 08:28
eeks. um... maybe post a sample? red spot means frames detected as film. so something's going wrong there. the only problem is it works at my end :(

sorry about the late reply. work is mad - sometimes i've got time to post, other times i'm here until the wee hours.

Floatingshed
4th March 2009, 23:16
I'm not sure that a sample would help as the problem is not dependent on the clip, it occurs with every piece of video that I load!

Great shame that it won't work for me it seems so promising.

Mug Funky
5th March 2009, 01:08
i do recall getting random errors with smartdecimate at one point. i can't remember what stopped them.

however, i see here in v0.96 the default IVTC type is TFM (tritical's TIVTC package). in v.093 there was no choice between IVTC methods used.

sooooo....

maybe try change "IVTCtype" to 1, 4 or 5 (these types are neuron2's telecide, tritical's tDeint and smartdecimate respectively).

if this stops the errors then we've narrowed the problem down to TFM.

if this makes no difference to the errors, i need to look harder

posting your script would help too - maybe something is being used as input that's messing with it (like directshowsource giving odd values or colourspaces, who knows?)

Boulder
21st June 2009, 19:38
I've got Carl Sagan's Cosmos CE DVD box, which I'd like to clean up and transfer to PAL for viewing on my very old TV set which doesn't support NTSC. The source consists of hybrid material so I thought that AutoPAL would do the transfer job for me nice and easy. However, the latest version only causes an Avisynth error message: "AssumeFPS: FPS value is out of range." The error message points to lines 40, 190 and 466 in the avsi file.

The initial version works just fine.

Mug Funky
23rd June 2009, 13:33
hmm. looks like there is enough demand for this that i should get off my proverbial and fix this... sorry guys.

i'm on a fresh computer at the mome, so i'll see if i can wrench this script into working order. this is what happens when you keep a backup of your plugins folder with you wherever you go... dependencies go unnoticed.

yotsu
23rd June 2009, 13:48
MugFunky do you think you can help me on this :

http://forum.doom9.org/showthread.php?t=147947

?

Mug Funky
23rd June 2009, 14:04
@ yotsu: i'll focus on making this one work first :)... but i can't see this doing anything that the methods being suggested in that thread can't do... my script assumes the video is a mix between perfect 3:2 sections and interlaced sections. with messy stuff like that vid appears to be, it'll most likely go 3:2 treatment with flashes of 60i treatment, giving you something somewhat smoother than just an IVTC, but interlaced and still not correct compared to a tailored solution.

@ everyone:

by using the "copy all plugins to temp folder, then copy them back one by one according to avs error messages", i've got it down to these plugins and these versions are needed.

i've only tried the default settings. it'll probably need other stuff if you start tweaking (btw, it was designed to work best on defaults for a sausage-factory style workflow, so tweakage will probably not help much).

- Decomb521.dll (2004-05-18)
- DGDecode.dll (2006-11-29)
- medianblur.dll (2005-01-19)
- Motion_12Dec05.dll (2005-12-12)
- mt_masktools.dll (2006-06-06)
- TDeint.dll (2007-01-22)

if this doesn't work with the script in the first post in this thread, it must be something weird, like a CPU dependency in one of the plugins.