Log in

View Full Version : array type and for loop in avisynth?


primitive
4th September 2003, 15:19
Greetings all. I'm working on an Avisynth script to use in my anime encodes and I was wondering if there was an array type or a for loop-like expression in Avisynth. I didn't find any mention of either in the documentation, but since I read somewhere in this forum that the documentation often lagged behind the reality I thought I'd ask.

stickboy
4th September 2003, 17:39
AviSynth 2.5x and earlier have no array type or explicit looping expression. If you need a loop, you usually can use a recursive function instead.

Exactly what do you want to do?

primitive
4th September 2003, 20:29
I'm writing a function that iterates over a clip, performs an operation on each frame, and uses the results to create a metric. I want the number of samples it takes from the clip in question to be user-defined. This means that I need something to hold the values for me while the script takes a look at each frame in the clip. It's nonsense for me to use variables like this:


s1 =
s2 =
s3 =
...
s128 =


because I can never be sure what the user is going to give for the number of desired samples. More important than the for loop is the array class, because even if I iterated over a series of frames I wouldn't have any place to put the values.

stickboy
5th September 2003, 05:32
Well, if you really want to, you could use strings as a poor-man's array.

First you'd write a recursive function with a string as its accumulator; something of the form:
# given an input n, this returns a string "1,2,...,n,"
function foo(int n, string "s")
{
s = default(s, "")
return (n > 0) ? foo(n - 1, String(n) + "," + s)
\ : s
}And then you could parse this string with another function:

# given a string "a0,a1,...,aN,", where a0,...,aN are numbers,
# this returns a0+a1+...+aN
function bar(string s, float "acc")
{
acc = default(acc, 0.0)
offset = FindStr(s, ",")
# FindStr returns 0 if not found
return (offset == 0) ? acc
\ : bar(MidStr(s, offset + 1),
\ acc + Value(LeftStr(s, offset - 1)))
}

# example usage
MessageClip(String(bar(foo(5))))

primitive
5th September 2003, 07:24
Wow, that's a neat trick that I never thought of, but sweet jesus is it ever a hack ;)

Thanks!

-p

oof
5th September 2003, 18:22
stickboy
You appear to be quite good at this and seem to enjoy
good puzzles.
I have one I've been trying to do for a long time. I finaly
cheated and used Unix AWK on it but I'd like an Avisynth script

I sometimes get videos with a duplicate frame every so often.
I want to eliminate one of the duplicate frames in each instance.
If there was a looping structure, I think I could do it.

Compare() doesnt seem to return anything - just makes a logfile
Conditional Filter or Script Clip look promising.

I think a recursive function that increments a frame number and uses DeleteFrame(n) might be close.

You have any tricky ideas ?

stickboy
5th September 2003, 18:45
How do you detect the duplicate frames? Do they occur on regular intervals?

What does your awk script look like? If AviSynth had an explicit iterative looping construct, what would your script look like?

oof
5th September 2003, 19:25
The Kluge consists of writing a compare log to a file with:

avisource( "movie.avi" )
v2 = trim( last, 1,0 )
Compare(last, v2, "", "compare.log", true)

then run AWK
$2 == 0 {print "DeleteFrame( " $1 " )" "\r" }

now we have another AVS which deletes all the desired frames.


If it was C I would write

output( Frame[ FIRST_FRAME ] ) ;
for( i = FIRST_FRAME + 1 ; i <= LAST_FRAME ; i++ )
{ if( Frame[ i ] != Frame[ i - 1 ] )
output( Frame[ i ] ;
/* Else skip this one */
}

Wilbert
5th September 2003, 21:55
No, idea what the smartest way is. Maybe the following works:

1) subtract frame j and j+1
2) if averageluma of the resulting frame is close to 128 (check that by using ScriptClip) => delete that frame

oof
5th September 2003, 22:34
This is a nasty one. DeleteFrame reqires a frame number.
What if you delete frame N ? How are they numbered after that ?
I deleted them High numbers first to avoid that.

Another problem with the Kluge method is that the first AVS that
does the compare won't execute on all frames unless you frames serve to something that reads all the frames. The only thing I could think of
was play it in Vdub. That takes 2 hours if it's a 2 hour movie.
If I had /dev/null I could send it there as an AVI, does window have a
null file ?
Anybody know of a frameclient that requests frames as fast as it can
go ? Another AVS might do.

I don't really NEED to do this, I just want to solve the puzzle.

stickboy
6th September 2003, 06:12
Hmmm... I need to think about this for a while. :)