Log in

View Full Version : Advanced AviSynth programming: Array4x4


LigH
18th September 2002, 11:33
Here is an example with self-declared functions and filter names via arguments for the Eval function.

Array4x4.avs

# YUY2 requires even sizes - clear bit 0
# (simulates "h = i && $FFFE", because "&&" requires boolean args)
Function CSBasedHalf(clip c, int i)
{
h = i/2
return IsYUY2(c) ? ((h % 2 == 1) ? (h-1) : h) : h
}

# add black/white edges
# (using subtitles; instead, I'd prefer setting single pixels...)
Function Frame(clip c)
{
return c.Subtitle("+",x=-2,y=3,size=10,text_color=$FFFFFF,halo_color=$808080)
\.Subtitle("+",x=c.width-3,y=3,size=10,text_color=$000000,halo_color=$808080)
\.Subtitle("+",x=-2,y=c.height+2,size=10,text_color=$000000,halo_color=$808080)
\.Subtitle("+",x=c.width-3,y=c.height+2,size=10,text_color=$FFFFFF,halo_color=$808080)
}

# execute custom command to each clip with arrayed arguments
Function TestClip(clip c, string cmd, string args)
{
w = c.width
h = c.height
s = cmd+"(c,"+args+")"
t = Eval(s)
b = Frame(t)
l = Crop(t,1,1,-1,-1)
return b.Layer(l,"fast",255,1,1).Subtitle(cmd,x=2,y=10,font="Arial Narrow",size=12,text_color=$FFFFFF).Subtitle(args,x=2,y=24,font="Arial",size=14,text_color=$FFFFFF)
}

# create a 4x4 array for different arguments on each clip part
Function Test4x4(clip c, string cmd, string pre, int min_x, int step_x, string mid, int min_y, int step_y, string post)
{
left2 = CSBasedHalf(c, c.width)
left1 = CSBasedHalf(c, left2)
left3 = left2+CSBasedHalf(c, c.width-left2)
width1 = left1
width2 = left2 - left1
width3 = left3 - left2
width4 = c.width - left3
top2 = CSBasedHalf(c, c.height)
top1 = CSBasedHalf(c, top2)
top3 = top2+CSBasedHalf(c, c.height-top2)
height1 = top1
height2 = top2 - top1
height3 = top3 - top2
height4 = c.height - top3
clip11 = c.Crop( 0, 0, width1, height1)
clip12 = c.Crop(left1, 0, width2, height1)
clip13 = c.Crop(left2, 0, width3, height1)
clip14 = c.Crop(left3, 0, width4, height1)
clip21 = c.Crop( 0, top1, width1, height2)
clip22 = c.Crop(left1, top1, width2, height2)
clip23 = c.Crop(left2, top1, width3, height2)
clip24 = c.Crop(left3, top1, width4, height2)
clip31 = c.Crop( 0, top2, width1, height3)
clip32 = c.Crop(left1, top2, width2, height3)
clip33 = c.Crop(left2, top2, width3, height3)
clip34 = c.Crop(left3, top2, width4, height3)
clip41 = c.Crop( 0, top3, width1, height4)
clip42 = c.Crop(left1, top3, width2, height4)
clip43 = c.Crop(left2, top3, width3, height4)
clip44 = c.Crop(left3, top3, width4, height4)
y = min_y
x = min_x
res11 = TestClip(clip11, cmd, pre+String(x)+mid+String(y)+post)
x = x + step_x
res12 = TestClip(clip12, cmd, pre+String(x)+mid+String(y)+post)
x = x + step_x
res13 = TestClip(clip13, cmd, pre+String(x)+mid+String(y)+post)
x = x + step_x
res14 = TestClip(clip14, cmd, pre+String(x)+mid+String(y)+post)
y = y + step_y
x = min_x
res21 = TestClip(clip21, cmd, pre+String(x)+mid+String(y)+post)
x = x + step_x
res22 = TestClip(clip22, cmd, pre+String(x)+mid+String(y)+post)
x = x + step_x
res23 = TestClip(clip23, cmd, pre+String(x)+mid+String(y)+post)
x = x + step_x
res24 = TestClip(clip24, cmd, pre+String(x)+mid+String(y)+post)
y = y + step_y
x = min_x
res31 = TestClip(clip31, cmd, pre+String(x)+mid+String(y)+post)
x = x + step_x
res32 = TestClip(clip32, cmd, pre+String(x)+mid+String(y)+post)
x = x + step_x
res33 = TestClip(clip33, cmd, pre+String(x)+mid+String(y)+post)
x = x + step_x
res34 = TestClip(clip34, cmd, pre+String(x)+mid+String(y)+post)
y = y + step_y
x = min_x
res41 = TestClip(clip41, cmd, pre+String(x)+mid+String(y)+post)
x = x + step_x
res42 = TestClip(clip42, cmd, pre+String(x)+mid+String(y)+post)
x = x + step_x
res43 = TestClip(clip43, cmd, pre+String(x)+mid+String(y)+post)
x = x + step_x
res44 = TestClip(clip44, cmd, pre+String(x)+mid+String(y)+post)
row1 = StackHorizontal(res11, res12, res13, res14)
row2 = StackHorizontal(res21, res22, res23, res24)
row3 = StackHorizontal(res31, res32, res33, res34)
row4 = StackHorizontal(res41, res42, res43, res44)
return StackVertical(row1, row2, row3, row4)
}


You can enter any other arguments or text before (pre), between (mid) or after (post) both parameters, like in this calling example:

Bars_4x4.avs

SetMemoryMax(16)
LoadPlugin("H:\PROGRA~1\GKNOT\mpeg2dec.dll")
Import("Array4x4.avs")
Test4x4(ColorBars(352,288), "TemporalSmoother", "", 2, 1, ",", 1, 2, "")


The result shall look like this picture:

Guest
18th September 2002, 13:01
And your point is...?

int 21h
18th September 2002, 13:19
I think he means to share this snippet of code so that others can use them in their .avs files.

Koepi
18th September 2002, 13:33
I'm a bit lost, too, the script looks nice and mighty, but can you use a clip instead of the colour bars, too?
I think this could be useful to test some filter settings and compare them all on the same image to see for example which one gives the best trade-off between e.g. noise and blur and so on.

Am I right there?

Best regards,
Koepi

Guest
18th September 2002, 13:34
A statement of the problem and how his approach solves it would have been welcome.

bb
18th September 2002, 13:44
Cool script. I'll use it for some tests.
A better explanation would have been nice; I had to read the source to understand what it does.

bb

LigH
18th September 2002, 19:02
@ neuron2:

Indeed, I forgot to mention that this is no problem report, instead it is a success report I would like to share with you: I found many questions how Eval() works - here is one answer. So 'int 21h' is absolutely right.

@ Koepi:

Of course, you can use any clip; I just used ColorBars because I don't know which clip everyone owns to repeat and compare the results. It worked fine with AVS scripts using MPEG2DEC to serve an MPEG2 video (*.d2v), as well as AVIs as source.

And furthermore, you shall be able to visualise the results of any filter which has several parameters and where it would be hard to decide how to chose both at the same time.

Defiler
19th September 2002, 02:51
If I wanted to change the "step" variables to type float, so that I can use smaller increments.. is that going to break anything? I only scanned the last function briefly, but it seems like that would be fine.

LigH
19th September 2002, 07:25
@ Defiler:

Good idea! Of course, that's an enhancement I was thinking of, too; currently, I only needed integer parameters, but float parameters would be required for other functions, so it might be indeed better to use a more flexible parameter type for both the min and step arguments; maybe 'val' shall be fine here, in case some function throws an error when it expects integer arguments? Untested, yet...

LigH
22nd September 2002, 10:55
Second edition released:

http://www.ligh.de/software/Array4x4.rar

New: alternative version to change one argument each in two functions, and "val" argument type. Examples included.

E-Male
22nd September 2002, 14:05
I tried your script, but it doesn´t work for me

Script error: there is no function named "String"
Array4x4.avs, line
66 (bars, old version)
83 (bars)
159 (gamma)

any ideas?
thx
e-male

LigH
22nd September 2002, 17:59
Originally posted by E-Male
Script error: there is no function named "String"

Well... I'm afraid that this script requires a certain minimum AviSynth version; I developed it with AviSynth 2.05 - according to the documentation, "String(val)" is indeed a function which is only implemented in AviSynth Versions 2.x!

E-Male
22nd September 2002, 20:33
updated avisynth and it work
thx