avisynth docu

277
AVISYNTH Documentation

Upload: dprahut

Post on 18-Nov-2014

184 views

Category:

Documents


7 download

TRANSCRIPT

Page 1: avisynth docu

AVISYNTH Documentation

Page 2: avisynth docu

Table of ContentsAVISYNTH Documentation.............................1

Packages main index......................................8Introduction....................................................8AVSLib Packages...........................................8The array package...........................................9

Required packages.....................................9Modules.....................................................9

The array :: core module.....................10Required modules...........................10Functions........................................10Constants........................................11

Variables..............................................11ArrayCreate....................................12ArrayDelete....................................12ArrayDelimiterGet..........................13ArrayDelimiterReset......................13ArrayDelimiterSet..........................14ArrayFill.........................................14ArrayGet.........................................15ArrayGetString...............................15ArrayGetValueRegisterNewHandler........................................................16ArrayGetValueResetDefaultHandler........................................................16ArrayInsert......................................17ArrayLen........................................17ArrayRange....................................18ArraySet..........................................19ArraySetValueRegisterNewHandler........................................................19ArraySetValueResetDefaultHandler........................................................20

The array :: functions module.............21Required modules...........................21Functions........................................21Constants........................................21Variables.........................................21ArrayAverage.................................22ArrayClamp....................................22ArrayEqual.....................................22ArrayGreater...................................23ArrayGreaterOrEqual.....................23ArrayLess.......................................24ArrayLessOrEqual..........................24ArrayNegate...................................25ArrayNot.........................................25ArrayNotEqual...............................26ArrayProduct..................................26ArraySpline....................................27ArrayStDev.....................................27

ArraySumProduct...........................28The array :: operators module.............29

Required modules...........................29Functions........................................29Constants........................................29Variables.........................................29ArrayOpArray................................30ArrayOpArrayFunc........................31ArrayOpFunc..................................32ArrayOpValue.................................33ArraySum.......................................34

The array :: powseries module............35Required modules...........................35Functions........................................35Constants........................................35Variables.........................................35ArrayPowSeries..............................36ArrayPowSeriesA...........................36ArrayPowSeriesAA........................36PowSeriesA....................................37PowSeriesAA.................................38

The array :: properties module............39Required modules...........................39Functions........................................39Constants........................................39Variables.........................................39ArrayContains................................40ArrayElmCount..............................40ArrayIndexOf.................................41ArrayMax.......................................41ArrayMin........................................42

The array :: slices module...................43Required modules...........................43Functions........................................43Constants........................................43Variables.........................................43ArrayDelRange...............................44ArrayDeplex...................................45ArrayGetRange...............................46ArrayInsRange................................46ArrayJoin........................................47ArrayPlex........................................48ArraySetRange...............................49ArraySplit.......................................50

The array :: transforms module...........51Required modules...........................51Functions........................................51Constants........................................51Variables.........................................51ArrayDistinct..................................52

Page 3: avisynth docu

ArrayElmSwap...............................52ArrayInvert.....................................53ArrayReduce...................................53ArrayRotate....................................54ArraySort........................................55

The base package..........................................56Required packages...................................56Modules...................................................56

The base :: constants module..............57Required modules...........................57Functions........................................57Constants........................................57Variables.........................................58

The base :: conversion module............59Required modules...........................59Functions........................................59Constants........................................59Variables.........................................59CBool..............................................60CClip..............................................61CFloat.............................................62CInt.................................................63CString............................................64

The base :: core module......................65Required modules...........................65Functions........................................65Constants........................................65Variables.........................................65ImportIf..........................................66IsCallable........................................66Null.................................................67Self..................................................67Throw.............................................67Typename.......................................68Undef..............................................68VarType...........................................69

The base :: version module.................70Required modules...........................70Functions........................................70Constants........................................70Variables.........................................70AvslibVersion.................................71AvslibVersionNumber....................71AvslibVersionString........................71

The bool package..........................................72Required packages...................................72Modules...................................................72

The bool :: core module......................73Required modules...........................73Functions........................................73Constants........................................73Variables.........................................73

And.................................................74And2...............................................74Not..................................................75Or....................................................75Or2..................................................76Xor2................................................76

The clip package...........................................77Required packages...................................77Modules...................................................77

The clip :: arrays module.....................78Required modules...........................78Functions........................................78Constants........................................78Variables.........................................78JointFPS..........................................79JointPixelType................................80

The clip :: core module.......................81Required modules...........................81Functions........................................81Constants........................................81Variables.........................................81ColorSpace.....................................82IsPixelType.....................................82MakeRGBColor..............................82SafeHeight......................................83SafeWidth.......................................83SplitRGBColor...............................84

The debug package.......................................85Required packages...................................85Modules...................................................85

The debug :: core module....................86Required modules...........................86Functions........................................86Constants........................................86Variables.........................................86ArrayPrint.......................................87ArrayPrintCP..................................87Break..............................................88BreakIf............................................88Print................................................89

The debug :: logging module..............90Required modules...........................90Functions........................................90Constants........................................91Variables.........................................91DebugLog.......................................92GetDebugFile.................................92GetDebugMode..............................93SetDebugFile..................................93SetDebugMode...............................93

The numeric package....................................94Required packages...................................94

Page 4: avisynth docu

Modules...................................................94The numeric :: core module................95

Required modules...........................95Functions........................................95Constants........................................95Variables.........................................95Clamp.............................................96Count..............................................96DegToRad ......................................96Dif2.................................................97Div2................................................97IsEven.............................................97IsOdd..............................................98Max.................................................98Max2...............................................98Min.................................................99Min2...............................................99Mod2..............................................99Product..........................................100Product2........................................100RadToDeg.....................................100Sum...............................................101Sum2.............................................101

The numeric :: curves2d module.......102Required modules.........................102Functions......................................102Constants......................................102Variables.......................................102Circle............................................103Ellipsis..........................................103Hyperbola.....................................104Line...............................................104Line1pt..........................................105Line2pt..........................................105Parabola........................................105

The numeric :: functions module......106Required modules.........................106Functions......................................106Constants......................................106Variables.......................................106ArcCos..........................................107ArcCosh........................................107ArcCot..........................................107ArcCot..........................................108ArcSin...........................................108ArcSinh.........................................108ArcTan..........................................109ArcTanh........................................109Cosh..............................................109Cot................................................110Coth..............................................110Exp10............................................110

ExpBs............................................111Log10............................................111LogBs............................................111Sinh...............................................112Tan................................................112

The numeric :: powseries module.....113Required modules.........................113Functions......................................113Constants......................................113Variables.......................................113Factorial........................................114Polynomial....................................114PowSeries.....................................115

The numeric :: rounding module.......117Required modules.........................117Functions......................................117Constants......................................117Variables.......................................117CeilBs...........................................118FloorBs.........................................118FRound.........................................119IntBs..............................................119RoundBs.......................................120RoundEven...................................120RoundOdd....................................121

The numeric :: statistics module.......122Required modules.........................122Functions......................................122Constants......................................122Variables.......................................122Average.........................................123StDev............................................123SumSquare....................................123

The string package......................................124Required packages.................................124Modules.................................................124

The string :: core module..................125Required modules.........................125Functions......................................125Constants......................................125Variables.......................................125IsQuoted.......................................126QuoteNoexpr................................126StrCompare...................................127StrFill............................................127StrLeft...........................................128StrMid...........................................128StrQuote........................................129StrRight........................................129StrUnquote....................................130ZStrip............................................130

The string :: search module...............131

Page 5: avisynth docu

Required modules.........................131Functions......................................131Constants......................................131Variables.......................................131StrFind..........................................132StrReplace....................................133

The string :: sprintf module...............134Required modules.........................134Functions......................................134Constants......................................134Variables.......................................134StrPrint..........................................135

The filters package......................................137Required packages.................................137Modules.................................................137

The filters :: animate module............138Required modules.........................138Functions......................................138Constants......................................138Variables.......................................138LineAnim......................................139PolygonAnim................................141MoveOverlay................................144ResizeOverlay..............................146

The filters :: channels module...........147Required modules.........................147Functions......................................147Constants......................................147Variables.......................................147ChannelIndex................................148IsRGB24Channels........................148IsRGB32Channels........................148IsRGBChannels............................149IsYUVChannels............................149IsYUY2Channels..........................149IsYV12Channels..........................150MergeARGB.................................150MergeRGB...................................150MergeVideoChannels...................151MergeYUV...................................151ShowBlue.....................................152ShowGreen...................................152ShowRed......................................152ShowU..........................................153ShowV..........................................153ShowY..........................................154SplitVideoChannels......................154

The filters :: edit module...................155Required modules.........................155Functions......................................155

Constants...........................................155Variables.......................................155

EditDelete.....................................156EditInsert......................................157EditJoin.........................................158EditReplace..................................159EditTrim.......................................161

The filters :: frames module..............163Required modules.........................163Functions......................................163Constants......................................163Variables.......................................163FrameFilter...................................164FrameFilterReader........................166

The filters :: multiedit module...........168Required modules.........................168Functions......................................168Constants......................................168Variables.......................................168EditTrimRange.............................169

The filters :: resize module................170Required modules.........................170Functions......................................170Constants......................................170Variables.......................................170GetDefaultResizer........................171Resize...........................................172ResizeToFit...................................173ResizeToTarget.............................174SetDefaultResizer.........................175

The filters :: stack module.................176Required modules.........................176Functions......................................176Constants......................................176Variables.......................................176Stack.............................................177StackToFit.....................................178

The filters :: utility module...............179Required modules.........................179Functions......................................179Constants......................................179Variables.......................................179ConvertToTarget...........................180FilterChain....................................180FilterVarChain..............................181ScaleToPC....................................181ScaleToTV....................................182

Installation Instructions..............................183Downloading the right version of AVSLib...............................................................183Installing AVSLib...................................183

Standard (recommended) installation procedure...........................................183Manual installation procedure...........183

Page 6: avisynth docu

Using AVSLib........................................183Solving installation problems................184

Uninstalling AVSLib...................................184Standard (recommended) installation procedure...............................................184Manual installation procedure...............184

FAQs...........................................................185General questions...................................185

1. What is AVSLib?...........................1852. What makes AVSLib different from other plugins I have found for Avisynth?...........................................................1853. What are the licencing terms of AVSLib?............................................1854. Where can I download the latest version of AVSLib?...........................1855. Where can I find documentation for AVSLib?............................................1856. What are the plans for the future?. 185

Installation.............................................1861. How do I install AVSLib?.............1862. How do I install multiple versions of AVSLib?............................................1863. I want a partial install of AVSLib, how can it be accomplished?.............1864. How do I know what version of AVSLib I have installed in my system?...........................................................1865. How do I uninstall AVSLib?.........186

Usage.....................................................1871. Are there any limitations in AVSLib?...........................................................1872. Will these limitations be removed in a future version of AVSLib?................1873. Are there any recommendations regarding the use of AVSLib features?...........................................................1874. I try to run a script containing calls to AVSLib functions and I get the "I don't know what xxx means" error from Avisynth. What's going wrong?........1875. I get unexpected errors pointing to array operator functions (ArrayOpValue / ArrayOpFunc / ArrayOpArray / ArrayOpArrayFunc). Didn't you tested them for errors?.....1876. My animation gets out of the clip area. What's going wrong?................1887. VirtualDub either crashes or displays a "sctip open failed!" messagebox when I try to run a script containing AVSLib commands. What's going wrong?.....188

8. I made a script using arrays but I always get a "__left_str: string has > 1024 chars" message when I try to run it. What's going wrong?.....................1889. I try to use the EditJoin filter with a custom join function but I get an "invalid arguments to function..." error? What's going wrong?.........................188

Support...................................................1891. I want to submit a bug report. What should I do?.......................................1892. I want a feature not included in AVSLib. How can I request it?.........1893. Where can I find support about using AVSLib?............................................1894. I have a question about AVSLib. Where do I seek for an answer?........1895. Where can I contact the developers of AVSLib?............................................189

Contribution...........................................1901. I want to participate on AVSLib development. How can I do this?......1902. I want to contribute texts or script examples to AVSLib documentation. How can I do this?.............................190

Structure of the AVSLib library..................191Library Structure....................................191

Library Specifications.......................191Naming conventions..........................192Reserved names.................................192Reserved actions................................192

Examples....................................................1931. Stack clips in a matrix........................193Apply a swap transition.........................1963. Create a simple movie intro clip........1984. Make a palette clip with all Avisynth named colors..........................................1995. Load a text file with arbitrary clips....2026. Create an enhanced movie intro clip..2047. Stack clip frames in a matrix.............206

8. Load, convert and join arbitrary clips...........................................................208

9. Make an animated draw of a curve with random orbits.........................................21110. Loop through filter settings..............22111. Loop through filter settings - revisited...............................................................22312. Load, convert and join with transition effect arbitrary clips...............................22613. Multi-color mask creation and manipulation..........................................23014. Create an expanding rotating circle of

Page 7: avisynth docu

rotating stars...........................................23415. Per frame filtering, a position + size + color animation......................................24216. Per frame filtering, exporting specific frame(s)..................................................248

Tutorials......................................................255Understanding containers......................255

Implementation selections.................255Impact of selections on functionality256What containers can do for you........258Hints for effective use.......................259

Container operators................................260Introduction.......................................260Array operators..................................260

ArrayOpValue...............................260ArrayOpFunc................................261ArrayOpArray..............................262ArrayOpArrayFunc......................263ArraySum.....................................264

Usage (what to do and what not to do)...........................................................265

Understanding editing filters.................267Introduction.......................................267The editing model.............................267Assembling the parts of the final result...........................................................269User-supplied functions....................270A generic example of a user-supplied function.............................................270

Understanding animation filters.............272Introduction.......................................272Animation coordinate system............272The significance of masks.................272Usage tips and examples...................273

Using the loader module to build Avisynth script libraries........................................274

Introduction.......................................274Module internals................................274Package internals...............................275Library internals................................275Library organisation..........................277

Page 8: avisynth docu

Packages main index

IntroductionAVSlib is organised in an hierarcy of packages and modules that allow script authors to selectively load only the modules that are needed.

Thus, faster loading times and fewer namespace collisions can be achieved. In addition, the script author does not need to worry for any modules' dependencies, since each module will load by itself any other modules that it requires.

This is achieved by the use of the special loader module, toghether with appropriate definitions at the start of each package and module. See the Using the "loader.avsi" module to build Avisynth script libraries tutorial for more details.

AVSLib PackagesName Description

array The array package contains modules that implement the array container type and all its associated operations (creation, manipulation, etc.).

base The base package contains modules that provide basic extensions to Avisynth script language as well as basic components of other AVSLib modules.

bool The bool package contains modules that extend standard Avisynth operations on variables of boolean type.

clip The clip package contains modules that extend standard Avisynth operations on variables of clip type.

debug The debug package contains modules that provide debuging facilities for script developers.

deprecated

The deprecated package contains modules created for backwards compatibility purposes.

The modules provide functions defined in previous AVSLib versions that are now deprecated and will be removed some time in the future.

Note that no module of this package is included in the prebuilt library configurations (those that can be passed to LoadLibrary()) and thus they must be explicitly loaded by the script developer.

filters The filters package contains modules that implement various useful filters (clip transformation functions); for example animation, editing, resizing and stacking filters.

numeric The numeric package contains modules that extend standard Avisynth operations on variables of numeric type (ints and floats).

string The string package contains modules that extend standard Avisynth operations on variables of string type.

Page 9: avisynth docu

The array packageThe array package contains modules that implement the array container type and all its associated operations (creation, manipulation, etc.).

Required packagesThe array package requires modules from the following packages (see the specific modules' documentation for actual dependencies): base, numeric, string.

ModulesName Description

core This module provides functions, constants and global variables for the performance of core array operations, such as creating and deleting arrays, getting and setting an array element, defining action handlers for array values, etc.

functions This module provides functions, constants and global variables for the performance of common array operations such as comparisons, negation, product, average, etc.

operators This module provides functions, constants and global variables for the implementation of array operators, the core mechanism for performing operations on arrays.

powseries This module provides functions, constants and global variables for the implementation of additional power series functions, besides the core one (PowSeries()).

properties This module provides functions, constants and global variables for getting / setting common array properties such as whether (or how many times) a value is contained in an array, etc.

slices This module provides functions, constants and global variables for the implementation of operations on array slices (ie subranges) such as selection, deletion, replacement, etc.

transforms This module provides functions, constants and global variables for the implementation of array transformations such as inversion, sorting, etc.

Page 10: avisynth docu

The array :: core moduleThe array :: core module provides functions, constants and global variables for the performance of core array operations, such as creating and deleting arrays, getting and setting an array element, defining action handlers for array values, etc.

Required modulesbase :: core, string :: core

FunctionsName Description

ArrayCreate() Returns a new array from the supplied arguments, in the order provided. The function accepts up to 60 arguments...

ArrayDelete() Deletes an element from the array passed as argument and returns the resulting array...

ArrayDelimiterGet() Returns the current array elements delimiter...

ArrayDelimiterReset() Assigns the library's default value as the array elements delimiter and updates internal library variables. Returns the previous setting...

ArrayDelimiterSet() Assigns a new array elements delimiter and updates internal library variables. Returns the previous setting...

ArrayFill() Returns an array consisting of a number of copies of a value (each copy can be independently manipulated)...

ArrayGet() Retrieves an element from the array, with specified index and returns its value...

ArrayGetString() Retrieves and returns the string representation of an array's element, ...

ArrayGetValueRegisterNewHandler() Assigns a new array value-retrieve handler function for use by array routines...

ArrayGetValueResetDefaultHandler() Resets the array value-retrieve handler function to the default AVSLib handler...

ArrayInsert() Inserts new_value before array[index] and returns the ...

ArrayLen() Returns the length of the array, ie the number of elements stored inside it...

ArrayRange() Returns a subrange of an array...

ArraySet() Assigns a new value to a specified array element...

ArraySetValueRegisterNewHandler() Assigns a new array value-set handler function for use by array routines...

ArraySetValueResetDefaultHandler() Resets the array value-set handler function to the default AVSLib

Page 11: avisynth docu

handler...

ConstantsNone

VariablesName DescriptionArrayGetValueHandler Holds the name of the handler function for retrieving a value from an array's element.

ArraySetValueHandler Holds the name of the handler function for setting an array element to a new value.

Page 12: avisynth docu

ArrayCreateModule: array :: core

Definition:ArrayCreate (val "elm01", val "elm02", val "elm03", val "elm04", ... , val "elm60")

Description:

Returns a new array from the supplied arguments, in the order provided.

The function accepts up to 60 arguments. For arrays with > 60 elements one must use multiple function calls for 60 elements' blocks and join the blocks with the ArrayJoin or ArrayInsRange functions.

Notes and conditions on arguments relations:

If none argument is supplied, the function returns an empty array (ie an array with zero elements).

Examples:a1 = ArrayCreate(2, 4, 3.5, 4.12, 12.01) c1 = AviSource( ... ) c2 = AviSource( ... ) c3 = AviSource( ... ) c4 = AviSource( ... ) a2 = ArrayCreate(c1, c1.Levels(0,1,255,0,200), c2, c3, c4, c4.Tweak(hue=10))

ArrayDeleteModule: array :: core

Definition:ArrayDelete(string array, int "index")

Description:

Deletes an element from the array passed as argument and returns the resulting array.

Arguments: array: The array to operate on.

"index" (Optional, defaults to ArrayLen(array) - 1, ie the last array element): The index of the array element to delete.

Examples:ar1 = "2, 3, 5, 7" ar2 = "true, true, false, true" ar3 = "This,is,a,dog." ar1 = ArrayDelete(ar1) # ar1 is now "2, 3, 5" ar2 = ArrayDelete(ar2, 2) # ar2 is now "true, true, true" ar3 = ar3.ArrayDelete(2) # ar3 is now "This,is,dog."

Page 13: avisynth docu

ArrayDelimiterGetModule: array :: core

Definition:ArrayDelimiterGet()

Description:

Returns the current array elements delimiter.

Examples:cur_dlm = ArrayDelimiterGet() # do a custom action based on this value pos = FindStr(arr, cur_dlm)

ArrayDelimiterResetModule: array :: core

Definition:ArrayDelimiterReset()

Description:

Assigns the library's default value as the array elements delimiter and updates the corresponding internal library variables. Returns the previous setting.

Note that this is a global setting affecting immediately all subsequent operations on arrays.

Examples:old = ArrayDelimiterReset() ... # do some action that assumes default settings and # then restore the old value ... dummy = ArrayDelimiterSet(old) # assign to dummy to avoid assigning to last

Page 14: avisynth docu

ArrayDelimiterSetModule: array :: core

Definition:ArrayDelimiterSet(string delimiter)

Description:

Assigns delimiter as the new array elements delimiter and updates the corresponding internal library variables. Returns the previous setting.

Note that this is a global setting affecting immediately all subsequent operations on arrays.

Examples:old = ArrayDelimiterSet(" | ") ... # do some action and then restore the old value ... dummy = ArrayDelimiterSet(old) # assign to dummy to avoid assigning to last

ArrayFillModule: array :: core

Definition:ArrayFill(val base, int count, bool "strict")

Description:

Returns an array consisting of count copies of base (each copy can be independently manipulated).

If count == 0, a null string is returned.

The "strict" optional parameter when set to false makes the function to return a null (zero length) array when a negative count value is passed (the default behavior is to throw an error).

Examples:a1 = ArrayFill(1, 5) # a1 == "1,1,1,1,1" clp = AviSource(...) a2 = ArrayFill(clp, 4) # a2 now contains 4 copies of clp, each one independent of clp a2 = a2.ArraySet(0, a2.ArrayGet(0).Tweak(hue=20)) a2 = a2.ArraySet(3, a2.ArrayGet(0).Tweak(cont=2)) # a2 1st and 4th elements are now different from the others a3 = ArrayFill(2.35, 0) # a3 == "" (empty array) # this will halt script with an error a4 = ArrayFill("abc", -1) # this will return a null array (same result as a3, above) a5 = ArrayFill("abc", -1, false)

Page 15: avisynth docu

ArrayGetModule: array :: core

Definition:ArrayGet(string array, int index)

Description:

Retrieves an element from the array, with index index and returns its value.

This is the equivalent of the var = array[index] statement used in many programming languages, where valid indexes are in the range [0..ArrayLen(array)-1].

Examples:a1 = "0.5, 1.0, 1.5, 2.0, 2.5" num = ArrayGet(a1, 0) # num == 0.5 c1 = AVISource(...) a2 = ArrayCreate(c1, c1.Trim(0, -50), c1.Trim(50, -50), c1.Tweak(hue=120)) cl = a2.ArrayGet(1) # get the 2nd element of a2 fc = cl.Framecount # cl is a clip; fc == 50

ArrayGetStringModule: array :: core

Definition:ArrayGetString(string array, int index)

Description:

Retrieves and returns the string representation of an array's element, as it is stored internally to the array; no attempt is made to evaluate the element by passing its string representation to Eval().

This function is intended primarily for extension developers.

Examples:a1 = "0.5,1.0,1.5,2.0,2.5" s1 = a1.ArrayGetString(0) # s1 == "0.5" c1 = AVISource(...) a2 = ArrayCreate(c1, c1.Trim(0, -50), c1.Trim(50, -50), c1.Tweak(hue=120)) s2 = a2.ArrayGetString(1) # assuming this is the 1st clip array created by the script # s2 == "__acp__2" return Eval(s2) # the script will return the second element of a2, ie c1.Trim(0, -50).

Page 16: avisynth docu

ArrayGetValueRegisterNewHandlerModule: array :: core

Definition:ArrayGetValueRegisterNewHandler(string new_handler)

Description:

Makes new_handler the new array value-retrieve handler function by assigning it to the ArrayGetValueHandler global variable.

Returns the previous value of the variable.

The assignment is made only if the passed argument is callable, as decided by the IsCallable() library function.

Note that this is a global setting affecting immediately all subsequent operations on arrays.

Examples:function my_array_get_handler(...) {...} ... oldhandler = ArrayGetValueRegisterNewHandler("my_array_get_handler") # perform your custom array operations here ... # if afterwards you want the previous behavior, reset the old handler dummy = ArrayGetValueRegisterNewHandler(oldhandler)

ArrayGetValueResetDefaultHandlerModule: array :: core

Definition:ArrayGetValueResetDefaultHandler()

Description:

Resets the array value-retrieve handler function to the default AVSLib handler by assigning it to the ArrayGetValueHandler global variable.

Returns the previous value of the variable.

Note that this is a global setting affecting immediately all subsequent operations on arrays.

Examples:

function my_array_get_handler(...) {...} ... oldhandler = ArrayGetValueRegisterNewHandler("my_array_get_handler") # perform your custom array operations here ... # if afterwards you want the default behavior, reset the handler dummy = ArrayGetValueResetDefaultHandler()

Page 17: avisynth docu

ArrayInsertModule: array :: core

Definition:ArrayInsert(string array, val new_value, int "index")

Description:

Inserts new_value before array[index] and returns the resulting array. ..

As a result the array is expanded, new_value is positioned at array[index] and all subsequent elements's indexes are increased by one.

If (optional) index is ommited, then new_value is appended to the end of array (same as providing an index with value equal to array.ArrayLen()).

Examples:

a1 = ArrayCreate(AVISource(.1.), AVISource(.2.)) a1 = a1.ArrayInsert(AVISource(.3.)) a1 = a1.ArrayInsert(AVISource(.4.), 0) # a1 now contains clips {(.4.),(.1.),(.2.),(.3.)}

ArrayLenModule: array :: core

Definition:ArrayLen(string array)

Description:

Returns the length of array, ie the number of elements stored inside it.

Examples:

a1 = "0.5, 1.0, 1.5, 2.0, 2.5" items = a1.ArrayLen() # items == 5 a2 = "" itm2 = a2.ArrayLen() # itm2 == 0

Page 18: avisynth docu

ArrayRangeModule: array :: core

Definition:ArrayRange(val start, val end, val "step", int "npoints")

Description:

Returns an array with values covering the range [start..end] either with a specified step or with a specified number of points (when the optional npoints parameter is specified).

Arguments:

start: The start value of the range (int or float).

end: The end value of the range (int or float).

"step" (Optional, defaults to 1): The step value to add in each successive step until end is reached.

"npoints" (Optional): The number of points (array elements) to divide the specified range ([start..end]).

Notes and conditions on arguments relations:

1] step and npoints cannot be specified together (the function will throw an error).

2] When step is defined and the values of start and step are such that end cannot exactly be reached by succesively addind step to start then the maximum valid value < end will be the last element of the returned array.

This is of importance when float values are used, since then small approximation errors inherent to float arithmetic may result in arrays with one less element than the number expected by the arguments. If this happens, add a small number to end (for example 0.0001) in order to get the expected number of array elements.

Examples:

a1 = ArrayRange(0, 10) # a1 == "0,1,2,3,4,5,6,7,8,9,10" a2 = ArrayRange(0, 10, 2) # a2 == "0,2,4,6,8,10" a3 = ArrayRange(0, 10, 3) # a3 == "0,3,6,9" a4 = ArrayRange(0, 10, npoints=5) # a4 == "0,2.5,5.0,7.5,10.0"

Page 19: avisynth docu

ArraySetModule: array :: core

Definition:ArraySet(string array, int index, val new_value)

Description:

Assigns new_value to the array element with index index and returns the resulting array.

This is the equivalent of the array[index] = value statement used in many programming languages, where valid indexes are in the range [0..ArrayLen(array)-1].

Examples:

a1 = "2.3,4,5,1.2,3" a1 = a1.ArraySet(4, 12) # a1 == "2.3,4,5,1.2,12" a1 = a1.ArraySet(1, 0.2) # a1 == "2.3,0.2,5,1.2,12"

ArraySetValueRegisterNewHandlerModule: array :: core

Definition:ArraySetValueRegisterNewHandler(string new_handler)

Description:

Makes new_handler the new array value-set handler function by assigning it to the ArraySetValueHandler global variable.

Returns the previous value of the variable.

The assignment is made only if the passed argument is callable, as decided by the IsCallable() library function.

Note that this is a global setting affecting immediately all subsequent operations on arrays.

Examples:

function my_array_set_handler(...) {...} ... oldhandler = ArraySetValueRegisterNewHandler("my_array_set_handler") # perform your custom array operations here ... # if afterwards you want the previous behavior, reset the old handler dummy = ArraySetValueRegisterNewHandler(oldhandler)

Page 20: avisynth docu

ArraySetValueResetDefaultHandlerModule: array :: core

Definition:ArraySetValueResetDefaultHandler()

Description:

Resets the array value-set handler function to the default AVSLib handler by assigning it to the ArraySetValueHandler global variable.

Returns the previous value of the variable.

Note that this is a global setting affecting immediately all subsequent operations on arrays.

Examples:

function my_array_set_handler(...) {...} ... oldhandler = ArraySetValueRegisterNewHandler("my_array_set_handler") # pdrform your custom array operations here ... # if afterwards you want the default behavior, reset the handler dummy = ArraySetValueResetDefaultHandler()

Page 21: avisynth docu

The array :: functions moduleThe array :: functions module provides functions, constants and global variables for the performance of common array operations such as comparisons, negation, product, average, etc.

Required modulesbase :: core, numeric :: core, array :: core, array :: operators

FunctionsName Description

ArrayAverage() Returns the (statistical) average of all array elements...

ArrayClamp() Applies the Clamp function to all array elements and returns the result...

ArrayEqual() Returns true if all corresponding elements of the arrays ...

ArrayGreater() Returns true if all elements of array1 are greater than the corresponding ...

ArrayGreaterOrEqual() Returns true if all elements of array1 are greater or equal than ...

ArrayLess() Returns true if all elements of array1 are less than ...

ArrayLessOrEqual() Returns true if all elements of array1 are less or equal than ...

ArrayNegate() Inverses the sign of all elements of array (the same as multiplying...

ArrayNot() Applies the Not function to all array elements ...

ArrayNotEqual() Returns true if all corresponding elements of array1 ...

ArrayProduct() Returns the product of all array elements...

ArraySpline() Returns an array with elements the spline (y value) of ...

ArrayStDev() Returns the standard deviation of array elements...

ArraySumProduct() Returns the sum of the products of all pairs of the corresponding elements ...

ConstantsNone

VariablesNone

Page 22: avisynth docu

ArrayAverageModule: array :: functions

Definition:ArrayAverage(string array)

Description:

Returns the (statistical) average of all array elements.

Examples:

a1 = "6, 5, 7, 9, 4, 8" avg = ArrayAverage(a1) # avg is now 6.5000, ie 39/6

ArrayClampModule: array :: functions

Definition:ArrayClamp(string array, val low_limit, val high_limit)

Description:

Applies the Clamp function to all array elements and returns the resulting array.

Examples:

ax = "3, 5, -8, 12, 4, 2, 10" ac = ax.ArrayClamp(2, 7) # same as ArrayClamp(ax, 2, 7) # ac is now "3, 5, 2, 7, 4, 2, 7"

ArrayEqualModule: array :: functions

Definition:ArrayEqual(string array1, string array2)

Description:

Returns true if all corresponding elements of the arrays passed as arguments are equal (ie array1[i] == array2[i] for all i).

Examples:

a1 = "0.5, 1.0, 1.5, 2.0, 2.5" a2 = "0.5, 1.0, -1.5, 2.0, 2.5" a3 = a1 b1 = ArrayEqual(a1, a2) # b1 == false b2 = ArrayEqual(a1, a3) # b2 == true

Page 23: avisynth docu

ArrayGreaterModule: array :: functions

Definition:ArrayGreater(string array1, string array2)

Description:

Returns true if all elements of array1 are greater than the corresponding elements of array2 (ie array1[i] > array2[i] for all i).

Examples:

a1 = "2,3,6,8,12,5,4" a2 = "1,2,5,7,11,4,3" a3 = "2,2,5,7,12,5,4" b1 = a1.ArrayGreater(a2) # b1 == true b2 = a1.ArrayGreater(a3) # b2 == false

ArrayGreaterOrEqualModule: array :: functions

Definition:ArrayGreaterOrEqual(string array1, string array2)

Description:

Returns true if all elements of array1 are greater or equal than the corresponding elements of array2 (ie array1[i] >= array2[i] for all i).

Examples:

a1 = "2,3,6,8,12,5,4" a2 = "10,2,5,7,21,4,13" a3 = "2,2,5,7,12,5,4" b1 = a1.ArrayGreaterOrEqual(a2) # b1 == false b2 = a1.ArrayGreaterOrEqual(a3) # b2 == true

Page 24: avisynth docu

ArrayLessModule: array :: functions

Definition:ArrayLess(string array1, string array2)

Description:

Returns true if all elements of array1 are less than the corresponding elements of array2 (ie array1[i] < array2[i] for all i).

Examples:

a1 = "2,3,6,8,12,5,4" a2 = "1,2,5,7,11,4,3" a3 = "2,2,5,7,12,5,4" b1 = a2.ArrayLess(a1) # b1 == true b2 = a2.ArrayLess(a3) # b2 == false

ArrayLessOrEqualModule: array :: functions

Definition:ArrayLessOrEqual(string array1, string array2)

Description:

Returns true if all elements of array1 are less or equal than the corresponding elements of array2 (ie array1[i] <= array2[i] for all i).

Examples:

a1 = "2,3,6,8,12,5,4" a2 = "10,2,5,7,21,4,13" a3 = "2,2,5,7,12,5,4" b1 = a3.ArrayLessOrEqual(a1) # b1 == true b2 = a3.ArrayLessOrEqual(a2) # b2 == false

Page 25: avisynth docu

ArrayNegateModule: array :: functions

Definition:ArrayNegate(string array)

Description:

Inverses the sign of all elements of array (the same as multiplying with -1) and returns the resulting array.

Examples:

a1 = "2,3,5,1.45,-23,-2.4,4" a2 = a1.ArrayNegate() # a2 == "-2,-3,-5,-1.45,23,2.4,-4" a3 = ArrayOpArray(a1, a2, "+") # a3 contains all zeros [a1 + (-a1) = 0]

ArrayNotModule: array :: functions

Definition:ArrayNot(string array)

Description:

Applies the Not function to all array elements (ie performs a NOT to array elements) and returns the resulting array.

Examples:

a1 = "true,true,false,true" a2 = a1.ArrayNot() # a2 == "false,false,true,false"

Page 26: avisynth docu

ArrayNotEqualModule: array :: functions

Definition:ArrayNotEqual(string array1, string array2)

Description:

Returns true if all corresponding elements of array1 and array2 are not equal (ie array1[i] != array2[i] for all i).

Examples:

a1 = "2,3,4,5,6,7" a2 = "2,3,5,-6,7,8" a3 = "3,4,-5,6,-7,8" b1 = a1.ArrayNotEqual(a2) b1 == false b2 = a1.ArrayNotEqual(a3) b2 == true b3 = ArrayNotEqual(a2, a3) b3 == false

ArrayProductModule: array :: functions

Definition:ArrayProduct(string array)

Description:

Returns the product of all array elements.

Examples:

a1 = "1,2,-3,4,-2,5" pr = a1.ArrayProduct() # pr == 240 a2 = "0.1,0.2,-3.5,4,-2.0,5.2" pf = a2.ArrayProduct() # pf == 2.912

Page 27: avisynth docu

ArraySplineModule: array :: functions

Definition:ArraySpline(string x_array, string point_curve, bool "cubic")

Description:

Returns an array with elements the spline (y value) of each respective x_array's element.

point_curve must be an array of x,y coordinates, as in Spline standard Avisynth function.

Examples:

clp = AVISource(...) ovr = AVISource(...) fr = "25,50,75,100" x = "50,100,240,290" crv = "20,30,80,240,160,120,320,70" y = x.ArraySpline(crv, true) anm = PolygonAnim(clp, ovr, fr, x, y)

ArrayStDevModule: array :: functions

Definition:ArrayStDev(string array)

Description:

Returns the standard deviation of array elements.

array must contain only numbers, else the function will throw an error or the results will be unpredictable.

Examples:

a1 = "1, 1, 2, 0, 1" sd = a1.ArrayStDev() # sd == 0.7071

Page 28: avisynth docu

ArraySumProductModule: array :: functions

Definition:ArraySumProduct(string array1, string array2)

Description:

Returns the sum of the products of all pairs of the corresponding elements of array1 and array2.

In effect (taking into account that an array is the representation of a vector) the function is the equivalent of the internal product of two vectors.

Examples:

a1 = "0.5, 1.0, 1.5, 2.0, 2.5" ip = ArraySumProduct(a1, a1) # ip == 13.75

Page 29: avisynth docu

The array :: operators moduleThe array :: operators module provides functions, constants and global variables for the implementation of array operators, the core mechanism for performing operations on arrays.

Required modulesstring :: core, array :: core

FunctionsName Description

ArrayOpArray() Performs an operation between corresponding elements of two arrays ...

ArrayOpArrayFunc() Performs an operation of a function onto all pairs of corresponding elements of two arrays...

ArrayOpFunc() Performs an operation of a function onto all elements of an array ...

ArrayOpValue() Performs an operation of a value with all elements of an array ...

ArraySum() Returns the sum of all array elements as it is deduced by applying a ...

ConstantsNone

VariablesNone

Page 30: avisynth docu

ArrayOpArrayModule: array :: operators

Definition:ArrayOpArray(string array1, string array2, string operation)

Description:

Performs an operation between corresponding elements of two arrays (ie array1[i] op array2[i]) and returns the resulting array.

Arguments:

array1: The array who's elements will be the left operand of the operation.

array2: The array who's elements will be the right operand of the operation.

operation: The string representation of the operation to be performed between array1 and array2 pairs of elements. All Avisynth operations that are valid for the specific type of elements are supported ("+", "-", "*", "/", "%", "==", "!=", ">=", "<=", "<", ">", "&&", "||", etc.)

Notes and conditions on arguments relations:

1] The type of array1 and of array2 elements must be compatible with respect to the chosen operation.

2] When performing division with ints Avisynth truncates the result to an int. If you want float results, make either array1 or array2 elements floats (you can use a call like this: ArrayOpFunc(my_array, "Float") ).

Examples:

a1 = "2,3,5,-6,7,8" a2 = "3,4,-5,6,-7,8" c1 = AVISource(...) ... c6 = AVISource(...) a3 = ArrayCreate(c1, c2, c3) a4 = ArrayCreate(c4, c5, c6) r1 = ArrayOpArray(a1, a2, "+") # r1 == "5,7,0,0,0,16" r2 = ArrayOpArray(a1, a2, "-") # r2 == "-1,-1,10,-12,14,0" r3 = ArrayOpArray(a1, a2, "<=") # r3 == "true,true,false,true,false,true" r4 = ArrayOpArray(a3, a4, "+") # r4 contains clips {(c1+c4),(c2+c5),(c3+c6)}

Page 31: avisynth docu

ArrayOpArrayFuncModule: array :: operators

Definition:ArrayOpArrayFunc(string array1, string array2, string func, string "args")

Description:

Performs an operation of a function onto all pairs of corresponding elements of two arrays (ie func(array1[i], array2[i], ...)) and returns the resulting array. Arguments:

array1: The array who's elements will be the first argument of func.

array2: The array who's elements will be the second argument of func.

func: The name of a function that accepts two required arguments and possibly an arbitrary number of optional arguments (see args, below).

"args" (Optional, defaults to ""): A string in the form of a function call argument list (ie a comma delimited list of values) containing additional arguments to be passed to the func function.

Notes and conditions on arguments relations:

1] func must accept two required argument with types compatible to array1 and array2 elements' type(s). The arguments must be the first in func's argument list. An arbitrary number of other (possibly optional) arguments is allowed, but if any of them is not optional it must always be specified in args.

2] The types of array1 and array2 elements need not be the same. The only requirement is that func can accept them.

3] The args argument list string can only contain value literals and global names (expressions of them are supported also). Use the String() function to convert local variables to value literals.

Examples:

Function xrot(int x, int y, float angle) { return Round(x*Cos(angle) - y*Sin(angle)) } Function yrot(int x, int y, float angle) { return Round(x*Sin(angle) + y*Cos(angle)) } # lets define a curve and rotate it by 30 degrees xs = "0,40,80,120,160,200,240" ys = "0,40,120,220,280,320,340" xs_30 = ArrayOpArrayFunc(xs, ys, "xrot", String(Pi()/6)) ys_30 = ArrayOpArrayFunc(xs, ys, "yrot", String(Pi()/6)) ... # function to extract a number of frames from a clip Function mytrim(clip c, int frames) { return c.Trim(0, -frames) } # lets create arrays of clips and frames # and then perform a batch Trim on all clips ac = ArrayCreate(AVISource(.1.), ..., AVISource(.8.)) fn = "400,300,400,500,1200,600,400,900" ac_trim = ArrayOpArrayFunc(ac, fn, "mytrim") # done

Page 32: avisynth docu

ArrayOpFuncModule: array :: operators

Definition:ArrayOpFunc(string array, string func, string "args")

Description:

Performs an operation of a function onto all elements of an array (ie func(array[i], ...)) and returns the resulting array.

Arguments:

array: The array who's elements will be the first argument of func.

func: The name of a function that accepts one required argument and possibly an arbitrary number of optional arguments (see args, below).

"args" (Optional, defaults to ""): A string in the form of a function call argument list (ie a comma delimited list of values) containing additional arguments to be passed to the func function.

Notes and conditions on arguments relations:

1] func must accept one required argument with type compatible to array elements' type(s). The argument must be first in func's argument list. An arbitrary number of other (possibly optional) arguments is allowed, but if any of them is not optional it must always be specified in args.

2] The args argument list string can only contain value literals and global names (expressions of them are supported also). Use the String() function to convert local variables to value literals.

Examples:

Function my_y(int x) { return Round(10 + 0.5*x - 0.1*Pow(x, 2)) } ax = ArrayRange(0, 700, 50) ay = ax.ArrayOpFunc("my_y") # filter a set of clips Function my_f(clip c, float f_hue) { return c.ConvertToYV12().BilinearResize( \ 720, 480).Tweak(hue=f_hue) } ac1 = ArrayCreate(AVISource(.1.), AVISource(.2.), ...) ac2 = ac1.ArrayOpFunc("my_f", "25") # set f_hue to 25

Page 33: avisynth docu

ArrayOpValueModule: array :: operators

Definition:ArrayOpValue(string array, val scalar, string operation, bool "array_first")

Description:

Performs an operation of a value with all elements of an array (ie value op array[i] or array[i] op value) and returns the resulting array.

Arguments:

array: The array who's elements will be the one (defaults to left) operand of the operation.

scalar: The single value which will be the other (defaults to right) operand of the operation.

operation: The string representation of the operation to be performed between each array element and scalar. All Avisynth operations that are valid for the specific types of operands are supported ("+", "-", "*", "/", "%", "==", "!=", ">=", "<=", "<", ">", "&&", "||", etc.)

"array_first" (Optional, defaults to true): Bool flag that controls the order of the operands of the operation.

When true or ommited, the array element will be the left operand and the scalar the right one. When false, the order is reversed.

This is of importance for operations that are not symmetrical, such as for example division ("/"), modulo ("%"), certain comparison operations (">", "<", ">=", "<="), etc.

Notes and conditions on arguments relations:

1] The type of array elements and of scalar must be compatible with respect to the chosen operation.

2] When performing division with ints Avisynth truncates the result to an int. If you want float results, make either array elements or scalar a float.

Examples:

a1 = "3.2, 4.1, 3.3, -0.23" a2 = a1.ArrayOpValue(0.4, "+") # a2 == "3.6,4.5,3.7,0.17" a3 = a1.ArrayOpValue(4, "<=") # a3 == "true,false,true,true" # now we will invert the order of operands # which is the same as changing the operation to ">=" a3 = a1.ArrayOpValue(4, "<=", false) # a3 == "false,true,false,false" # clips can also be added ac1 = ArrayCreate(AVISource(.1.), AVISource(.2.), ...) clp = AVISource(...) # add clp in front of every clip contained in ac1 ac2 = ac1.ArrayOpValue(clp, false) # add clp both in front and at end of every clip contained in ac1 ac3 = ac1.ArrayOpValue(clp, false).ArrayOpValue(clp)

Page 34: avisynth docu

ArraySumModule: array :: operators

Definition:ArraySum(string array, string "elm_func", string "elm_args", string "sum_func", string "sum_args")

Description:

Returns the sum of all array elements as it is deduced by applying a user-defined function for the evaluation of each array element and another one for the summing of the resulting values.

In effect the function is the equivalent of taking the integral of an array.

Arguments:

array: The array who's elements will be summed.

"elm_func" (Optional, defaults to "Self"): The function to evaluate each array element and return a value to be used by sum_func. The default function simply returns element unchanged.

"elm_args" (Optional, defaults to ""): A string in the form of a function call argument list (ie a comma delimited list of values) containing additional arguments to be passed to the elm_func function.

"sum_func" (Optional, defaults to "Sum2"): The function to evaluate the sum of values produced by the application of elm_func on each array element. The default function simply adds the values by using the "+" operator.

"sum_args" (Optional, defaults to ""): A string in the form of a function call argument list (ie a comma delimited list of values) containing additional arguments to be passed to the sum_func function.

Notes and conditions on arguments relations:

1] elm_func must accept one required argument with type compatible to array elements' type(s). The argument must be first in elm_func's argument list. An arbitrary number of other (possibly optional) arguments is allowed, but if any of them is not optional it must always be specified in elm_args.

2] sum_func must accept two required arguments with types compatible to the type(s) of the result of application of elm_func to array's elements. The arguments must be first in sum_func's argument list. An arbitrary number of other (possibly optional) arguments is allowed, but if any of them is not optional it must always be specified in sum_args.

3] Both the elm_args and sum_args argument list strings can only contain value literals and global names (expressions of them are supported also). Use the String() function to convert local variables to value literals.

Examples:

a1 = "0.5, 1.0, 1.5, 2.0, 2.5" num = a1.ArraySum() # num == 7.5 # sum an array of clips a2 = ArrayCreate(AVISource(.1.), ..., AVISource(.20.)) fin_clip = a2.ArraySum() # same as (.1.)+(.2.)+... # filter and then sum an array of clips Function myfilter(clip c) { return c.ConvertToYUY2().Tweak(cont=1.2) } flt_clip = a2.ArraySum(elm_func="myfilter") # filter and then sum an array of clips # blending with Dissolve(...,10) blflt_clip = a2.ArraySum(elm_func="myfilter", \ sum_func="Dissolve", sum_args="10")

Page 35: avisynth docu

The array :: powseries moduleThe array :: powseries module provides functions, constants and global variables for the implementation of additional power series functions, besides the core one (PowSeries()).

Required modulesstring :: core, array :: core, array :: operators

FunctionsName Description

ArrayPowSeries() Applies the PowSeries function to all array elements and returns th...

ArrayPowSeriesA() Applies the PowSeriesA function to all array elements and returns ...

ArrayPowSeriesAA() Applies the PowSeriesAA function to all array elements and return...

PowSeriesA() Returns a power series of x with coefficients supplied by an array...

PowSeriesAA() Returns a power series of x with coefficients and powers supplied by ...

ConstantsNone

VariablesNone

Page 36: avisynth docu

ArrayPowSeriesModule: array :: powseries

Definition:ArrayPowSeries( string x_array, string coef_func, string power_func, int start_index, int end_index, int "increment", string "coef_args", string "power_args")

Description:

Applies the PowSeries function to all array elements and returns the resulting array.

Examples:

function mycoef(int i) { return Pow(2, i) / Factorial(i) } function mypow(int i) { return 2 * i + 1 } ax = ArrayRange(0.1, 1.0, 0.1) ay = ax.ArrayPowSeries("mycoef", "mypow", 0, 4)

ArrayPowSeriesAModule: array :: powseries

Definition:ArrayPowSeriesA(string x_array, string coefs_array, val "start_power", val "increment")

Description:

Applies the PowSeriesA function to all array elements and returns the resulting array.

Examples:

coefs = "3, 0.2, -0.04, 0.0002" ax = "0,50,100,150,200" ay = ax.ArrayPowSeriesA(coefs)

ArrayPowSeriesAAModule: array :: powseries

Definition:ArrayPowSeriesAA(string x_array, string coefs_array, string powers_array)

Description:

Applies the PowSeriesAA function to all array elements and returns the resulting array.

Examples:

coefs = "0.6, 0.03, -0.0025" powers = "1, 3, 5" ax = "0,50,100,150,200" ay = ax.ArrayPowSeriesAA(coefs, powers)

Page 37: avisynth docu

PowSeriesAModule: array :: powseries

Definition:PowSeriesA(val x, string coefs_array, val "start_power", val "increment")

Description:

Returns a power series of x with coefficients supplied by an array and powers of defined start and increment.

It is provided as a simpler alternative for series with small number of terms to the more generic PowSeries function.

Arguments:

x: The value of which the power series will be calculated.

coefs_array: The array holding the power series coefficients.

"start_power" (Optional, defaults to 0): The starting power of the series.

"increment" (Optional, defaults to 1): The increment between successive powers of the series.

Notes and conditions on arguments relations:

1] If coefs_array has zero elements the function returns zero.

Examples:

# Calculate the power series 0.5*x + 3.23*x3 - 2.5*x5 for x = 5.4 coefs = "0.5, 3.23, -2.5" f1 = PowSeriesA(5.4, coefs, 1, 2) # Calculate the power series 3 + 2*x - 4*x2 + x3 for x = 2.5 coefs2 = "3, 2, -4, 1" f2 = PowSeriesA(2.5, coefs2) # Calculate the power series 1.3*x-0.5 + 0.2*x0.7 - 2.3*x1.9 # for x = 3 coefs3 = "1.3, 0.2, -2.3" f3 = PowSeriesA(3, coefs3, -0.5, 1.2)

Page 38: avisynth docu

PowSeriesAAModule: array :: powseries

Definition:PowSeriesAA(val x, string coefs_array, string powers_array)

Description:

Returns a power series of x with coefficients and powers supplied by (two) respective arrays.

It is provided as a simpler alternative for series with small number of terms to the more generic PowSeries function.

Arguments:

x: The value of which the power series will be calculated.

coefs_array: The array holding the power series coefficients.

powers_array: The array holding the powers of the series.

Notes and conditions on arguments relations:

1] coefs_array and powers_array must have the same number of elements.

Examples:

# Calculate the power series 0.5*x + 3.23*x3 - 2.5*x5 for x = 5.4 coefs = "0.5, 3.23, -2.5" powers = "1, 3, 5" f1 = PowSeriesAA(5.4, coefs, powers) # Calculate the power series 1.3*x-0.52 + 0.22*x2.34 - 2.3*x12.91 # for x = 3.3 coefs2 = "1.3, 0.22, -2.3" powers2 = "-0.52, 2.34, 12.91" f2 = PowSeriesAA(3.3, coefs2, powers2)

Page 39: avisynth docu

The array :: properties moduleThe array :: properties module provides functions, constants and global variables for getting / setting common array properties such as whether (or how many times) a value is contained in an array, etc.

Required modulesbase :: core, base :: conversion, array :: core, array :: operators

FunctionsName Description

ArrayContains() Returns true if array contains at least one element with ...

ArrayElmCount() Returns the number of array elements with value value...

ArrayIndexOf() Returns the (first) index of array that contains the specified value...

ArrayMax() Returns the bigger value stored inside array...

ArrayMin() Returns the smaller value stored inside array...

ConstantsNone

VariablesNone

Page 40: avisynth docu

ArrayContainsModule: array :: properties

Definition:ArrayContains(string array, val value)

Description:

Returns true if array contains at least one element with value value, false otherwise.

Examples:

ar = ArrayCreate(4, 3, 2, 12, 3, 5) b1 = ar.ArrayContains(4) # b1 == true b2 = ar.ArrayContains(3) # b2 == true b3 = ar.ArrayContains(7) # b3 == false

ArrayElmCountModule: array :: properties

Definition:ArrayElmCount(string array, val value)

Description:

Returns the number of array elements with value value.

Examples:

a = ArrayCreate(3,4,3,3,1,5,4,3,2) n1 = a.ArrayElmCount(3) # n1 == 4 n2 = a.ArrayElmCount(4) # n2 == 2

Page 41: avisynth docu

ArrayIndexOfModule: array :: properties

Definition:ArrayIndexOf(string array, val value, int "start_from")

Description:

Returns the (first) index of array that contains the specified value.

The start_from optional argument (defaults to 0) determines the index from which searching will start.

If no match is found the function returns -1.

Examples:

a = ArrayCreate(2,3,4,5,2,4) n1 = a.ArrayIndexOf(2) # n1 == 0 n2 = a.ArrayIndexOf(4) # n2 == 2 n3 = a.ArrayIndexOf(2,1) # n3 == 4 n4 = a.ArrayIndexOf(0) # n4 == -1

ArrayMaxModule: array :: properties

Definition:

ArrayMax(string array)

Description:

Returns the bigger value stored inside array.

Examples:

a1 = "0.5, 1.0, 1.5, 2.0, 2.5" a2 = a1.ArraySet(3, 3.7) mx1 = ArrayMax(a1) # mx1 == 2.5 mx2 = a2.ArrayMax() # mx2 == 3.7

Page 42: avisynth docu

ArrayMinModule: array :: properties

Definition:ArrayMin(string array)

Description:

Returns the smaller value stored inside array.

Examples:

a1 = "0.5, 1.0, 1.5, 2.0, 2.5" a2 = a1.ArraySet(3, -3.7) mx1 = ArrayMin(a1) # mx1 == 0.5 mx2 = a2.ArrayMin() # mx2 == -3.7

Page 43: avisynth docu

The array :: slices moduleThe array :: slices module provides functions, constants and global variables for the implementation of operations on array slices (ie subranges) such as selection, deletion, replacement, etc.

Required modulesbase :: core, string :: core, array :: core

FunctionsName Description

ArrayDelRange() Deletes a range of elements from the array passed as argument and ...

ArrayDeplex() Demultiplexes the array passed as argument and returns the speficied subarray (to multiplex ...

ArrayGetRange() Retrieves a range of elements (a subarray) from array ...

ArrayInsRange() Inserts the elements of newval_array before array[index] and returns the ...

ArrayJoin() Joins the arrays passed as arguments (arr01, arr02, ...) serially, ...

ArrayPlex() Multiplexes the arrays passed as arguments (arr01, arr02, ...) and ...

ArraySetRange() Assigns new values to a range of elements (subarray) of array and ...

ArraySplit() Splits array to a specified number of parts or to parts with specified length ...

ConstantsNone

VariablesNone

Page 44: avisynth docu

ArrayDelRangeModule: array :: slices

Definition:ArrayDelRange(string array, int "start_index", int "end_index")

Description:

Deletes a range of elements from the array passed as argument and returns the resulting array.

Arguments:

array: The array to operate on.

"start_index" (Optional, defaults to 0, ie the first array element): The index of the array element to start deleting from.

"end_index" (Optional, defaults to ArrayLen(array), ie one position past the last array element): The index of the array element to stop deleting (this element is not deleted).

Examples:

a1 = "0.5, 1.0, 1.5, 2.0, 2.5" a2 = a1.ArrayDelRange() # a2 == "" (empty array) a3 = a1.ArrayDelRange(0, 2) # a3 == "1.5,2,2.5" a4 = a1.ArrayDelRange(3) # a4 == "0.5,1,1.5" a5 = a1.ArrayDelRange(end_index=3) # a5 == "2,2.5"

Page 45: avisynth docu

ArrayDeplexModule: array :: slices

Definition:ArrayDeplex(string array, int index, int num_plexed_arrays)

Description:

Demultiplexes the array passed as argument and returns the speficied subarray (to multiplex arrays use ArrayPlex).

Arguments:

array: The array to operate on.

index: The index of the demultiplexed subarray of array to return as result. Must be in the range [0..num_plexed_arrays).

num_plexed_arrays: The number of multiplexed subarrays that array holds.

Notes and conditions on arguments relations:

Demultiplexing is performed by dividing array into blocks of num_plexed_arrays elements and taking the index element of each block, appending it to the resulting array.

In effect the function treats array as a matrix of num_plexed_arrays columns and returns its index column.

Examples:

coords = "10,20,30,70,50,120,70,140,90,100,110,80" # assuming coords is a [x,y] matrix (2x6), get x and y ax = coords.ArrayDeplex(0, 2) # ax == "10,30,50,70,90,110" ay = coords.ArrayDeplex(1, 2) # ay == "20,70,120,140,100,80" ... # assuming coords is a [x,y,z] matrix (3x4), get z z = coords.ArrayDeplex(2, 3) # z == "30,120,90,80"

Page 46: avisynth docu

ArrayGetRangeModule: array :: slices

Definition:ArrayGetRange(string array, int "start_index", int "end_index")

Description:

Retrieves a range of elements (a subarray) from array and returns it as a new array. The function returns all elements contained in [start_index..end_index) ie the element array[end_index] is not returned.

Arguments:

array: The array to retrieve the element range (subarray) from.

"start_index" (Optional, defaults to 0): The starting index of the element range that will be retrieved.

"end_index" (Optional, defaults to array. ArrayLen()): The ending index of the element range that will be retrieved.

Examples:

a1 = "0.5, 1.0, 1.5, 2.0, 2.5" a2 = a1.ArrayGetRange() # a2 == a1 a3 = a1.ArrayGetRange(0, 2) # a3 == "0.5,1" a4 = a1.ArrayGetRange(3) # a4 == "2,2.5" a5 = a1.ArrayGetRange(end_index=3) # a5 == "0.5,1,1.5"

ArrayInsRangeModule: array :: slices

Definition:ArrayInsRange(string array, string newval_array, int "index")

Description:

Inserts the elements of newval_array before array[index] and returns the resulting array.

As a result the array is expanded, newval_array's elements are positioned at array[index] - array[index + ArrayLen(newval_array) - 1] and all subsequent elements's indexes are increased by ArrayLen(newval_array).

If (optional) index is ommited, then newval_array's elements are appended to the end of array (same as providing an index with value equal to array. ArrayLen()).

Examples:

a1 = ArrayCreate(AVISource(.1.), AVISource(.2.), , AVISource(.3.)) a2 = ArrayCreate(AVISource(.4.), AVISource(.5.)) a3 = a1.ArrayInsRange(a2, 1) # a3 now contains clips {(.1.),(.4.),(.5.),(.2.),(.3.)} a4 = a1.ArrayInsRange(a2) # a4 now contains clips {(.1.),(.2.),(.3.),(.4.),(.5.)}

Page 47: avisynth docu

ArrayJoinModule: array :: slices

Definition:ArrayJoin(string "arr01", string "arr02", string "arr03", string "arr04", ... , string "arr20")

Description:

Joins the arrays passed as arguments (arr01, arr02, ...) serially, in the order specified, into one array. Returns the resulting array.

Notes and conditions on arguments relations:

1] If none argument is supplied, the function returns an empty array (ie an array with zero elements).

Examples:

a1 = ArrayCreate(AVISource(.1.), AVISource(.2.), AVISource(.3.)) a1 = a1.ArrayInsert(AVISource(.4.), 0) # a1 now contains clips {(.4.),(.1.),(.2.),(.3.)} a2 = a1.ArrayInvert() # a2 now contains clips {(.3.),(.2.),(.1.),(.4.)} a3 = ArrayJoin(a1, a2) # a3 now contains clips {(.4.),(.1.),(.2.),(.3.),(.3.),(.2.),(.1.),(.4.)} a4 = ArrayJoin(a2, a1) # a4 now contains clips {(.3.),(.2.),(.1.),(.4.),(.4.),(.1.),(.2.),(.3.)}

Page 48: avisynth docu

ArrayPlexModule: array :: slices

Definition:ArrayPlex(string arr01, string arr02, string "arr03", string "arr04", ... , string "arr20")

Description:

Multiplexes the arrays passed as arguments (arr01, arr02, ...) and returns the resulting array. [1]

Multiplexing is performed by taking sequentially one element of each array and appending it to the resulting array. In effect the function creates a matrix with each array being a column of the matrix, in the order that they are passed to the function.

Examples:

ax = ArrayRange(0, 500, 50) # y coordinates ay = "0,100,160,210,240,250,260,250,240,220,190" # (x,y) coordinates coords = ArrayPlex(ax, ay) # coords == "0,0,50,100,100,160,150,210,..." # or in a more visually evident arrangement # "0,0,\ # 50,100,\ # 100,160,\11` # ..."

[1]: The function can handle up to 20 arguments. This number is chosen as a good balance between usability and speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array package.

Page 49: avisynth docu

ArraySetRangeModule: array :: slices

Definition:ArraySetRange(string array, string newval_array, int "start_index", int "end_index")

Description:

Assigns new values to a range of elements (subarray) of array and returns the resulting array. The function sets all elements contained in [start_index..end_index) ie the element array[end_index] is not set.

Arguments:

array: The array to set the element range (subarray) of.

newval_array: The array with the new values that array's element range will be assigned to.

"start_index" (Optional, defaults to 0): The starting index of the element range that will be set.

"end_index" (Optional, defaults to array.ArrayLen()): The ending index of the element range that will be set.

Notes and conditions on arguments relations:

1] newval_array need not have the same number of elements as the selected subarray of array. However, if that happens the new array will have different length (number of elements) from the original.

Examples:

a1 = "1,2,3,4,5,6,7,8,9" a2 = a1.ArraySetRange("10,11,12", 3, 6) # a2 == "1,2,3,10,11,12,7,8,9" a3 = a1.ArraySetRange("10,11,12", 3, 4) # a2 == "1,2,3,10,11,12,5,6,7,8,9" a4 = a1.ArraySetRange("10,11,12", 3, 9) # a2 == "1,2,3,10,11,12" a5 = a1.ArraySetRange("10,11,12", 1, 6).ArraySet("-1,-2", 4, 6) # a5 == "1,10,11,12,-1,-2,9"

Page 50: avisynth docu

ArraySplitModule: array :: slices

Definition:

ArraySplit(string array, int index, int "chunks", int "chunksize")

Description:

Splits array to a specified number of parts or to parts with specified length (ie number of elements) and returns the requested part.

Arguments:

array: The array to split.

index: The zero-based index of the array part to return.

If chunks is specified, index must be in the range [0..chunks - 1].

If chunksize is specified, index must be in the range [0..Ceil(ArrayLen(array) / chunksize) - 1].

"chunks" (Optional): The number of parts to split array to.

"chunksize" (Optional): The number of elements that each array part should have.

Notes and conditions on arguments relations:

1] Exactly one of the chunks, chunksize arguments must be specified. If none or both are specified the function will throw an error.

2] If chunks is specified all parts except the last will have Floor(ArrayLen(array) / chunks) elements.

3] If chunksize is specified all parts except the last will have chunksize elements.

4] In any case the last part will contain the remaining array elements (which number may be equal to that of the other parts for certain combinations of array length and chunks or chunksize but in general will not).

Examples:

a1 = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16" # Splitting a 17-element array in 5 chunks yields # four 3-element arrays and a last 5-element array.

a2 = a1.ArraySplit(0, 5) # a2 == "0,1,2" a3 = a1.ArraySplit(2, 5) # a3 == "6,7,8" a4 = a1.ArraySplit(4, 5) # a4 == "12,13,14,15,16"

# Splitting a 17-element array with chunksize 4 yields # four 4-element arrays and a last 1-element array.

a5 = a1.ArraySplit(0, chunksize=4) # a5 == "0,1,2,3" a6 = a1.ArraySplit(2, chunksize=4) # a6 == "8,9,10,11" a7 = a1.ArraySplit(4, chunksize=4) # a7 == "16"

Page 51: avisynth docu

The array :: transforms moduleThe array :: transforms module provides functions, constants and global variables for the implementation of array transformations such as inversion, sorting, etc.

Required modulesbase :: core, string :: core, numeric :: statistics, array :: core, array :: operators, array :: slices

FunctionsName Description

ArrayDistinct() Returns the subset of array with only distinct elements in it. The resulting...

ArrayElmSwap() Returns a new array with the elements in indices index1, index2 interchanged (ie array[index1] ...

ArrayInvert() Inverts the indexes of the elements of array (the last element ...

ArrayReduce() Removes elements from array, wherever the corresponding flags array element has a value equal t...

ArrayRotate() Rotates the indexes of the elements of array (ie it shifts all elements ...

ArraySort() Sorts array, using the quick sort algorithm ...

ConstantsNone

VariablesNone

Page 52: avisynth docu

ArrayDistinctModule: array :: transforms

Definition:ArrayDistinct(string array, string "cmp_func", string "cmp_args", string "avg_func", string "avg_args")

Description:

Returns the subset of array with only distinct elements in it. The resulting array is always returned in ascending sort order (ie a[i] < a[i+1] for all i).

Arguments:

array: The array from which distinct elements are sought.

cmp_func (optional): A custom comparison function which must accept two val arguments at the start of its list and return -1,0,1 if arg1 < arg2, arg1 == arg2, arg1 > arg2, respectively.

cmp_args (optional): Any extra arguments needed by cmp_func as a string.

avg_func (optional): A custom average function (to be used by the sorting algorithm) which must accept two val arguments at the start of its list and return the average value of them.

avg_args (optional): Any extra arguments needed by avg_func as a string.

Examples:

a1 = ArrayCreate(1,2,3,2,3,3,5,6,7,8,5,5,6) a2 = a1.ArrayDistinct() # a2 == "1,2,3,5,6,7,8"

ArrayElmSwapModule: array :: transforms

Definition:ArrayElmSwap(string array, int index1, int index2)

Description:

Returns a new array with the elements in indices index1, index2 interchanged (ie array[index1] now holds the value of array[index2] at the original array and vice versa).

Examples:

a1 = ArrayCreate(1,2,3,4) a2 = a1.ArrayElmSwap(0,1) # a2 == "2,1,3,4" a3 = a2.ArrayElmSwap(2,3) # a3 == "2,1,4,3" a4 = a3.ArrayElmSwap(0,3) # a4 == "4,1,3,2"

Page 53: avisynth docu

ArrayInvertModule: array :: transforms

Definition:ArrayInvert(string array)

Description:

Inverts the indexes of the elements of array (the last element becomes first and so on) and returns the resulting array.

Examples:

a1 = ArrayCreate(AVISource(.1.), AVISource(.2.)) a1 = a1.ArrayInsert(AVISource(.3.)) a1 = a1.ArrayInsert(AVISource(.4.), 0) # a1 now contains clips {(.4.),(.1.),(.2.),(.3.)} a2 = a1.ArrayInvert() # a2 now contains clips {(.3.),(.2.),(.1.),(.4.)}

ArrayReduceModule: array :: transforms

Definition:ArrayReduce(string array, string flags)

Description:

Removes elements from array, wherever the corresponding flags array element has a value equal to zero. Returns the modified array.

Notes and conditions on arguments relations:

1] Both array and flags arrays must have the same length, else the function will throw an error.

Examples:

a1 = ArrayCreate(2.5, 3.12, 0.34, 2.15, 4, 5.1) flags = ArrayCreate(1, -1, 0, 2, 0, 0) a3 = a1.ArrayReduce(flags) # a3 == "2.5, 3.12, 2.15"

Page 54: avisynth docu

ArrayRotateModule: array :: transforms

Definition:ArrayRotate(string array, int num_indexes)

Description:

Rotates the indexes of the elements of array (ie it shifts all elements either left or right and puts the overflowed elements' block at the opposite side of the array). Returns the resulting array.

Arguments:

array: The array to rotate.

num_indexes: The number of indexes (ie positions) to rotate array elements.

If > 0 the rotation is made towards the end of the array (the elements are right-shifted and the last block is moved to array's start). If < 0 the rotation is made towards the start of the array (the elements are left-shifted and the first block is moved to array's end).

Notes and conditions on arguments relations:

1] If num_indexes > array.ArrayLen() the modulo of the division with array.ArrayLen() is used.

Examples:

a1 = "1,2,3,4,5,6,7,8,9,10" a2 = a1.ArrayRotate(4) # a2 == "7,8,9,10,1,2,3,4,5,6" a3 = a1.ArrayRotate(-4) # a3 == "5,6,7,8,9,10,1,2,3,4" a4 = a1.ArrayRotate(12) # a4 == "9,10,1,2,3,4,5,6,7,8"

Page 55: avisynth docu

ArraySortModule: array :: transforms

Definition:ArraySort(string array, bool "ascending", string "cmp_func", string "cmp_args", string "avg_func", string "avg_args")

Description:

Sorts array, using the quick sort algorithm [1].

Arguments:

array: The array to sort.

ascending (Optional, defaults to true): Boolean flag to determine the sort order (ascending or descending).

cmp_func (Optional, defaults to standard Avisynth comparison operators (>, <)): The name of a custom user function for comparing array elements.

cmp_args (Optional, defaults to "": Additional arguments (as a string) for the custom compare function.

avg_func (Optional, defaults to Average()): The name of a custom user function for averaging array elements.

avg_args: (Optional, defaults to "": Additional arguments (as a string) for the custom average function.

Notes and conditions on arguments relations:

1] Both cmp_func and avg_func must accept two array elements (of the appropriate type) as their first two arguments in their argument list.

2] cmp_func must return one of the -1, 0, 1 when elm1 < elm2, elm1 == elm2, elm1 > elm2, respectively.

Examples:

a1 = ArrayCreate(1, 3, 5, 8, 12, -4, 0, 2) a2 = a1.ArraySort() # a2 == "-4, 0, 1, 2, 3, 5, 8, 12" a3 = a1.ArraySort(false) # a3 == "12, 8, 5, 3, 2, 1, 0, -4"

Page 56: avisynth docu

The base packageThe base package contains modules that provide basic extensions to Avisynth script language as well as basic components of other AVSLib modules.

Required packagesNone

ModulesName Description

constants This module provides global constants commonly used in Avisynth scripts.

conversion This module provides functions, constants and global variables for the implementation of conversions between standard Avisynth types.

core This module provides functions, constants and global variables for the implementation of basic (core) capabilities of AVSLib.

version This module provides functions, constants and global variables for the implementation of AVSLib version reporting capabilities.

Page 57: avisynth docu

The base :: constants moduleThe base :: constants module provides global constants commonly used in Avisynth scripts.

Required modulesNone

FunctionsNone

ConstantsName Description

TAB The tab character (string constant).

CRLF The CR/LF line break pair (string constant).

FRATE_NTSC NTSC video framerate

FRATE_PAL PAL video framerate

FRATE_FILM Film (movie) framerate

FRATE_IMAX IMax film framerate

ASRAT_TV Television aspect ratio

ASRAT_TVWIDE Wide TV aspect ratio

ASRAT_ANIM Animation film aspect ratio

ASRAT_ACFLAT1 Academy Flat 1 aspect ratio

ASRAT_ACFLAT2 Academy Flat 2 aspect ratio

ASRAT_SCOPE Cinescope aspect ratio

WSIZE_NTSC NTSC video pixel width

HSIZE_NTSC NTSC video pixel height

OSIZE_NTSC NTSC video pixel height including overscan lines

WSIZE_PAL PAL video pixel width

HSIZE_PAL PAL video pixel height

OSIZE_PAL PAL video pixel height including overscan lines

Page 58: avisynth docu

Name Description

CS_MINW_RGB Minimum RGB clip's width (progressive & interlaced). Also the multiple-of base of valid RGB clips' widths.

CS_MINW_YUY2 Minimum YUY2 clip's width (progressive & interlaced). Also the multiple-of base of valid YUY2 clips' widths.

CS_MINW_YV12 Minimum YV12 clip's width (progressive & interlaced). Also the multiple-of base of valid YV12 clips' widths.

CS_MINH_RGB Minimum progressive RGB clip's height. Also the multiple-of base of valid progressive RGB clips' heights.

CS_MINH_YUY2 Minimum progressive YUY2 clip's height. Also the multiple-of base of valid progressive YUY2 clips' heights.

CS_MINH_YV12 Minimum progressive YV12 clip's height. Also the multiple-of base of valid progressive YV12 clips' heights.

CS_MINI_RGB Minimum interlaced RGB clip's height. Also the multiple-of base of valid interlaced RGB clips' heights.

CS_MINI_YUY2 Minimum interlaced YUY2 clip's height. Also the multiple-of base of valid interlaced YUY2 clips' heights.

CS_MINI_YV12 Minimum interlaced YV12 clip's height. Also the multiple-of base of valid interlaced YV12 clips' heights.

VariablesNone

Page 59: avisynth docu

The base :: conversion moduleThe base :: conversion module provides functions, constants and global variables for the implementation of conversions between standard Avisynth types.

Required modulesbase :: core

FunctionsName Description

CBool() Converts any variable to a bool type variable. The conversion follows the rules...

CClip() Converts any variable to a clip type variable. The conversion follows ...

CFloat() Converts any variable to a float type variable. The conversion follows the rules...

CInt() Converts any variable to an int type variable. The conversion follows the rules...

CString() Converts any variable to a string type variable. The function behaves like the...

ConstantsNone

VariablesNone

Page 60: avisynth docu

CBoolModule: base :: conversion

Definition:CBool(val "x", bool "force")

Description:

Converts any variable to a bool type variable. The conversion follows the rules of the table below:

Type of xResult

true false

clip x.Framecount > 0 x.Framecount == 0

float x <> 0.0 x == 0.0

int x > 0 x == 0

bool x unchanged

string x <> "" x == ""

Arguments:

"x": The variable to convert.

"force" (Optional, defaults to false): If true and x is an fined variable (ie Defined(x) returns false) then the function returns false. Else the function propagates the undefined variable to the caller, ie it returns an undefined value.

Examples:i1 = 0 i2 = 12 f1 = 2.34 s1 = "test" s2 = "" u = Undef() b1 = CBool(i1) # b1 == false b2 = CBool(i2) # b2 == true b3 = CBool(f1) # b3 == true b4 = CBool(s1) # b4 == true b5 = CBool(s2) # b5 == false b6 = CBool(u) # Defined(b6) == false b7 = CBool(u, true) # b7 == false

Page 61: avisynth docu

CClipModule: base :: conversion

Definition:CClip(val "x", bool "force")

Description:

Converts any variable to a clip type variable. The conversion follows the rules of the table below [1]:

Type of x Result

clip x unchanged

float x unchanged

int

BlankClip().SubTitle(String(x))bool

string

Arguments:

"x": The variable to convert.

"force" (Optional, defaults to false): If true and x is an undefined variable (ie Defined(x) returns false) then the function returns BlankClip(). Else the function propagates the undefined variable to the caller, ie it returns an undefined value.

Examples:

f = 4.231 c = AVISource( ... ) s = "a test string" c1 = CClip(f) c2 = CClip(c) # c2 == c c3 = CClip(s)

Page 62: avisynth docu

CFloatModule: base :: conversion

Definition:

CFloat(val "x", bool "force")

Description:

Converts any variable to a float type variable. The conversion follows the rules of the table below:

Type of x Result

clip 0.0

float x unchanged

int Float(x)

bool if x == true 1.0, else 0.0

string Float(Value(x))

Arguments:

"x": The variable to convert.

"force" (Optional, defaults to false): If true and x is an undefined variable (ie Defined(x) returns false) then the function returns 0.0. Else the function propagates the undefined variable to the caller, ie it returns an undefined value.

Examples:

i = 12 b = true s = "2.1" f1 = CFloat(i) # f1 == 12.0 f2 = CFloat(b) # f2 == 1.0 f3 = CFloat(s) # f3 == 2.1

Page 63: avisynth docu

CIntModule: base :: conversion

Definition:CInt(val "x", bool "force")

Description:

Converts any variable to an int type variable. The conversion follows the rules of the table below:

Type of x Result

clip 0

float Int(x)

int x unchanged

bool if x == true 1, else 0

string Int(Value(x))

Arguments:

"x": The variable to convert.

"force" (Optional, defaults to false): If true and x is an undefined variable (ie Defined(x) returns false) then the function returns 0.0. Else the function propagates the undefined variable to the caller, ie it returns an undefined value.

Examples:

f = 12.62 b = false s = "2.1" i1 = CInt(f) # i1 == 12 i2 = CInt(b) # i2 == 0 i3 = CInt(s) # i3 == 2

Page 64: avisynth docu

CStringModule: base :: conversion

Definition:CString(val "x", bool "force")

Description:

Converts any variable to a string type variable. The function behaves like the String() standard Avisynth function, except that it can accept undefined variables also.

Arguments:

"x": The variable to convert.

"force" (Optional, defaults to false): If true and x is an undefined variable (ie Defined(x) returns false) then the function returns "". Else the function propagates the undefined variable to the caller, ie it returns an undefined value.

Examples:

f = 12.62 b = false u = Undef() s1 = CString(f) # s1 == "12.62" s2 = CString(b) # i2 == "false" s3 = CString(u) # Defined(s3) == false s4 = CString(u, true) # s4 == ""

Page 65: avisynth docu

The base :: core moduleThe base :: core module provides functions, constants and global variables for the implementation of basic (core) capabilities of AVSLib.

Required modulesNone

FunctionsName Description

ImportIf() Conditionaly imports into the script one of two files based on the value of condition (file path_true...

IsCallable() Returns true if its argument can be called (ie it is a function)...

Null() Returns a null (zero) value appropriate for the type of its argument (ie either a zero-length clip, ...

Self() Returns its argument unchanged...

Throw() Throws an error (causing immediate termination of script execution), optionally showing a ...

Typename() Returns a distinct string value depending on the type of the variable passed as argument...

Undef() Returns an "undefined" value...

VarType() Returns a distinct integer value depending on the type of the variable passed as argument...

ConstantsName Description

MAX_INT Maximum positive int value supported by Avisynth

MIN_INT Minimum negative int value supported by Avisynth

VariablesNone

Page 66: avisynth docu

ImportIfModule: base :: core

Definition:ImportIf(bool condition, string path_true, string "path_false")

Description:

Conditionaly imports into the script one of two files based on the value of condition (file path_true if condition == true, or file path_false if condition == false) [1].

Examples:

clp1 = AVISource(…) clp2 = ImportIf(clp1.IsYUV, ""yuv_mask.avs"", ""rgb_mask.avs"")

IsCallableModule: base :: core

Definition:IsCallable(string func)

Description:

Returns true if its argument can be called (ie it is a function).

Be aware of possible side effects if the argument function modidies globals and can be called without arguments, since it is actually called in order to find if it is callable.

The function is a modification - to allow its use as a "silent" (ie not throwing any error) callability test - of stickboy's JDL_FunctionDefined, which on turn was based on the initial idea of mf for testing specific strings in Avisynth error messages in order to extract useful information (see the related thread in doom9 forum for details).

Examples:

function user_func(int x) { return 2*x-5 } b1 = IsCallable("user_func") # b1 == true b2 = IsCallable("notexist_func") # b2 == false

Page 67: avisynth docu

NullModule: base :: core

Definition:Null(val "template")

Description:

Returns a null (zero) value appropriate for the type of its argument (ie either a zero-length clip, or zero, or false or an empty string). If no argument is given it returns an undefined variable, as Undef does.

Examples:

c = AVISource(...) d = 1.3 e = ...a condition... ? c : Null(c) f = Null(d) # same as f = 0.0

SelfModule: base :: core

Definition:Self(val x)

Description:

Returns its argument unchanged. [1]

Examples:

x = 2.3 y = Self(x) # y == 2.3 s = "a test string" z = Self(s) # y == "a test string"

ThrowModule: base :: core

Definition:

Throw(string "error_msg")

Description:

Throws an error (causing immediate termination of script execution), optionally showing a custom error message.

Examples:

b = ...something... # the line below will stop script if b > 10 t = b > 10 ? Throw("this is an error") : 5

Page 68: avisynth docu

TypenameModule: base :: core

Definition:Typename(val x)

Description:

Returns a distinct string value depending on the type of the variable passed as argument (the standard Avisynth type's name, in lowercase).

Examples:

v0 = VarType(Undef()) # v0 == "undefined" v1 = Typename(BlankClip()) # v1 == "clip" v2 = Typename(3) # v2 == "int" v3 = Typename(2.35) # v3 == "float" v4 = Typename(true) # v4 == "bool" v5 = Typename("this is a string") # v5 == "string"

UndefModule: base :: core

Definition:Undef()

Description:

Returns an "undefined" value.

Intended usage is to set an already-defined variable to an "undefined" state.

Initially a reverb of stickboy's Undefined function to accommodate the different coding conventions used in AVSLib, now (from AVSLib version 1.1.0) the function has a new implementation without "private" arguments. This will also result in a different error text if one ever tries to pass an argument to it.

Examples:

v = Undef() b = Defined(v) # b == false

Page 69: avisynth docu

VarTypeModule: base :: core

Definition:VarType(val x)

Description:

Returns a distinct integer value depending on the type of the variable passed as argument (0 for undefined variables, 1 for clip, 2 for int, 3 for float, 4 for bool, 5 for string).

Useful for branching code execution based on argument's type.

Examples:

v0 = VarType(Undef()) # v0 == 0 v1 = VarType(BlankClip()) # v1 == 1 v2 = VarType(3) # v2 == 2 v3 = VarType(2.35) # v3 == 3 v4 = VarType(true) # v4 == 4 v5 = VarType("this is a string") # v5 == 5

Page 70: avisynth docu

The base :: version moduleThe base :: version module provides functions, constants and global variables for the implementation of AVSLib version reporting capabilities.

Required modulesNone

FunctionsName Description

AvslibVersion() Returns a clip with AVSLib's version and copyright information...

AvslibVersionNumber() Returns the AVSLib's version number as a float...

AvslibVersionString() Returns a string with the AVSLib's version number...

ConstantsName Description

AVISYNTH_NUM_MAJOR The first digit in Avisynth's version number, as an int.

AVISYNTH_NUM_MINOR The second digit in Avisynth's version number, as an int.

AVISYNTH_NUM_PATCH The third digit in Avisynth's version number, as an int.

AVSLIB_NUM_MAJOR The first digit in AVSLib's version number, as an int.

AVSLIB_NUM_MINOR The second digit in AVSLib's version number, as an int.

AVSLIB_NUM_PATCH The third digit in AVSLib's version number, as an int.

VariablesNone

Page 71: avisynth docu

AvslibVersionModule: base :: version

Definition:AVSLibVersion()

Description:

Returns a clip with AVSLib's version and copyright information.

Examples:

AVSLibVersion()

AvslibVersionNumberModule: base :: version

Definition:AVSLibVersionNumber()

Description:

Returns the AVSLib's version number as a float.

Examples:

f = AVSLibVersionNumber() flag = f > 1.0 ? true : false

AvslibVersionStringModule: base :: version

Definition:AVSLibVersionString()

Description:

Returns a string with the AVSLib's version number.

Examples:

BlankClip().SubTitle(AVSLibVersionString())

Page 72: avisynth docu

The bool packageThe bool package contains modules that extend standard Avisynth operations on variables of boolean type.

Required packagesThe bool package requires modules from the following packages (see the specific modules' documentation for actual dependencies): base.

ModulesName Description

core This module provides functions, constants and global variables for the implementation of basic operations on boolean variables.

Page 73: avisynth docu

The bool :: core moduleThe bool :: core module provides functions, constants and global variables for the implementation of basic operations on boolean variables.

Required modulesbase :: core

FunctionsName Description

And() Returns the result of the AND of its arguments...

And2() Returns the result of the AND of its arguments...

Not() Returns the result of the NOT of its argument...

Or() Returns the result of the OR of its arguments...

Or2() Returns the result of the OR of its arguments...

Xor2() Returns the result of the XOR (exclusive or) of its arguments...

ConstantsNone

VariablesNone

Page 74: avisynth docu

AndModule: bool :: core

Definition:And(val x1, val "x2", val "x3", val "x4", ... , val "x20")

Description:

Returns the result of the AND of its arguments. [1]

Possible usage includes combination of multiple tests in Assert() statements, bitwise flags testing, etc.

Examples:

d = And(true, true, false) # d == false a = And(1 < 2, 2 < 3, d == false) # a == true

[1]: The function can handle up to 20 arguments. This number is chosen as a good balance between usability and speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array package.

And2Module: bool :: core

Definition:

And2(val x1, val x2)

Description:

Returns the result of the AND of its arguments. [1]

Examples:

d = And2(w > t, w == 4) #d == true since both arguments are true bool expressions

[1]: The function is provided as a building block of more complex functions, particularly for operations on arrays. See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum functions.

Page 75: avisynth docu

NotModule: bool :: core

Definition:Not(val x)

Description:

Returns the result of the NOT of its argument. [1]

Examples:

b = true c = Not(b) # c == false

[1]: The function is provided as a building block of more complex functions, particularly for operations on arrays. See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum functions.

OrModule: bool :: core

Definition:Or(val x1, val "x2", val "x3", val "x4", ... , val "x20")

Description:

Returns the result of the OR of its arguments. [1]

Possible usage includes combination of multiple tests in Assert() statements, combination of bitwise flags in one value, etc.

Examples:

b1 = Or(true, true, false, false) # b1 == true b2 = Or(1 == 0, 2 < 1, 3 == Factorial(2)) # b2 == false b3 = Or(b1, b1 == b2, false) # b3 == true

[1]: The function can handle up to 20 arguments. This number is chosen as a good balance between usability and speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array package.

Page 76: avisynth docu

Or2Module: bool :: core

Definition:

Or2(val x1, val x2)

Description:

Returns the result of the OR of its arguments. [1]

Examples:

b1 = Or2(true,true) # b1 == true b2 = Or2(true,false) # b2 == true b3 = Or2(false,true) # b3 == true b4 = Or2(false,false) # b4 == false

[1]: The function is provided as a building block of more complex functions, particularly for operations on arrays. See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum functions.

Xor2Module: bool :: core

Definition:Xor2(val x1, val x2)

Description:

Returns the result of the XOR (exclusive or) of its arguments. [1]

Examples:

b1 = Xor2(true,true) # b1 == false b2 = Xor2(true,false) # b2 == true b3 = Xor2(false,true) # b3 == true b4 = Xor2(false,false) # b4 == false

[1]: The function is provided as a building block of more complex functions, particularly for operations on arrays. See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum functions.

Page 77: avisynth docu

The clip packageThe clip package contains modules that extend standard Avisynth operations on variables of clip type.

Required packagesThe clip package requires modules from the following packages (see the specific modules' documentation for actual dependencies): base, numeric, string, array.

ModulesName Description

arrays This module provides functions, constants and global variables for performing specific to clip arrays operations.

core This module provides functions, constants and global variables for performing basic operations related to clips.

Page 78: avisynth docu

The clip :: arrays moduleThe clip :: arrays module provides functions, constants and global variables for performing specific to clip arrays operations.

Required modulesbase :: conversion, numeric :: core, string :: core, array :: core, array :: operators, array :: transforms, array :: properties

FunctionsName Description

JointFPS() Returns the most common (ie with maximum occurence) framerate of a clip array...

JointPixelType() Returns the most common (ie with maximum occurence) pixel type of a clip array...

ConstantsNone

VariablesNone

Page 79: avisynth docu

JointFPSModule: clip :: arrays

Definition:JointFPS(string clips)

Description:

Returns the most common (ie with maximum occurence) framerate of a clip array.

Between framerates with the same occurence, the function favors those with the smaller value; for example if an array of 5 clips has fps [24,24,25,30,30] the function will return 24.

Examples:

# assuming ar is a clip array with 2 24-fps clips, 3 29.97-fps clip # and 2 59.94-fps clips (7 clips in total): fp = JointFPS(ar) # fp == 29.97 notes = $notes

Page 80: avisynth docu

JointPixelTypeModule: clip :: arrays

Definition:JointPixelType(string clips, bool "lowercase")

Description:

Returns the most common (ie with maximum occurence) pixel type of a clip array.

The function first honors total RGB/YUV occurence and then specific occurences of RGB/YUV subtypes.

In addition, when equal number of specific RGB/YUV subtypes is encountered, it favors YV12 over YUY2 and RGB32 over RGB24, as well as YUY2 over RGB32 (when total RGB == total YUV).

Thus:

• If most clips are in RGB/YUV it returns the RGB/YUV pixel_type with the maximum occurence (favoring YV12 and RGB32 when YUV/RGB subtypes' occurences are equal in number).

• If RGB clips == YUV clips, the specific subtype with the maximum occurence is returned (favoring by this order: YV12 > YUY2 > RGB32 > RGB24 when all subtypes have the same occurence).

Arguments:

clips: The clip array.

lowercase (Optional, defaults to false): If true then the returned string is in lowercase.

Examples:

# assuming ar is a clip array with 3 RGB32, 1 RGB24 # and 3YUY2 clips (7 clips in total): pt = JointPixelType(ar) # pt == "RGB32" # assuming ar2 is a clip array with 3 RGB32, 1 RGB24 # 2 YV12 and 3 YUY2 clips (9 clips in total): pt2 = JointPixelType(ar2) # pt2 == "YUY2" # assuming ar3 is a clip array with 3 RGB32, 1 RGB24 # 3 YV12 and 1 YUY2 clips (8 clips in total): pt3 = JointPixelType(ar3) # pt3 == "YV12" # assuming ar4 is a clip array with 3 RGB32, 1 RGB24 # 2 YV12 and 2 YUY2 clips (8 clips in total): pt4 = JointPixelType(ar4) # pt4 == "RGB32"

Page 81: avisynth docu

The clip :: core moduleThe clip :: core module provides functions, constants and global variables for performing basic operations related to clips.

Required modulesnumeric :: rounding, array :: core

FunctionsName Description

ColorSpace() Returns the colorspace of base as a string in the format used by Overlay()...

IsPixelType() Returns true if pixel_type is a valid pixel type string (as it is used by many Avisynth filters)...

MakeRGBColor() Returns an RGB color value, mapping appropriately the red, green, blue values (modul...

SafeHeight() Returns (by rounding) the closest to target_height safe height...

SafeWidth() Returns (by rounding) the closest to target_width safe width...

SplitRGBColor() Returns an (R, G, B) integer array, mapping appropriately the rgb_color RGB color value to red, green, blu...

ConstantsNone

VariablesNone

Page 82: avisynth docu

ColorSpaceModule: clip :: core

Definition:ColorSpace(clip base)

Description:

Returns the colorspace of base as a string in the format used by Overlay().

The return value is one of "RGB32", "RGB24", "YUY2" and "YV12"

Examples:

c = BlankClip().ConvertToYUY2() s = c.ColorSpace() # s == "YUY2"

IsPixelTypeModule: clip :: core

Definition:IsPixelType(string pixel_type, bool "extended")

Description:

Returns true if pixel_type is a valid pixel type string (as it is used by many Avisynth filters).

If 'extended is true, the value "RGB" is also considered to be a valid pixel type (it is used by the Show{Red/Green/Blue/Alpha} filters).

Examples:

b = IsPixelType("rgb32") # b == true c = IsPixelType("brown") # c == false

MakeRGBColorModule: clip :: core

Definition:MakeRGBColor(int red, int green, int blue)

Description:

Returns an RGB color value, mapping appropriately the red, green, blue values (modulo 256).

Examples:

c1 = MakeRGBColor(0, 0, 0) # c1 == black c2 = MakeRGBColor(255, 255, 255) # c2 == white c3 = MakeRGBColor(0, 0, 255) # c3 == blue c4 = MakeRGBColor(256, 256, 512) # c4 == black

Page 83: avisynth docu

SafeHeightModule: clip :: core

Definition:SafeHeight(clip c, int target_height, bool "interlaced")

Description:

Returns (by rounding) the closest to target_height safe height.

Safe here means that the returned height is compatible with the format of clip c, taking into account interlacing-imposed constrains (if interlaced is supplied and is true).

Examples:

c = AVISource(…).ConvertToYV12() h = SafeHeight(c, 399) # h == 400

SafeWidthModule: clip :: core

Definition:SafeWidth(clip c, int target_width)

Description:

Returns (by rounding) the closest to target_width safe width.

Safe here means that the returned width is compatible with the format of clip c [1].

Examples:

c = AVISource(…).ConvertToYV12() w = SafeWidth(c, 397) # w == 396

Page 84: avisynth docu

SplitRGBColorModule: clip :: core

Definition:SplitRGBColor(int rgb_color)

Description:

Returns an (R, G, B) integer array, mapping appropriately the rgb_color RGB color value to red, green, blue values. The array values are in the range [0..255].

Notes and conditions on arguments relations:

rgb_color must be a valid RGB color value in the range [$000000..$FFFFFF] for the function to return correct results.

Examples:

a1 = SplitRGBColor($ff00ff) # c1 == "255,0,255" a2 = SplitRGBColor(MakeRGBColor(100,20,245)) # a2 == "100,20,245"

Page 85: avisynth docu

The debug packageThe debug package contains modules that provide debuging facilities for script developers.

Required packagesThe debug package requires modules from the following packages (see the specific modules' documentation for actual dependencies): base, numeric, string, array.

ModulesName Description

core This module provides functions, constants and global variables for the implementation of basic debuging operations such as breaking and printing diagnostic messages and variables' values.

logging This module provides functions, constants and global variables for the implementation of a conditional (based on current debug level) output of debuging information to log files.

Page 86: avisynth docu

The debug :: core moduleThe debug :: core module provides functions, constants and global variables for the implementation of basic debuging operations such as breaking and printing diagnostic messages and variables' values.

Required modulesbase :: core, array :: core, array :: operators, array :: slices

FunctionsName Description

ArrayPrint() Returns a clip with the values of the elements contained in array ...

ArrayPrintCP() Returns a clip with the values of the elements contained in array ...

Break() Stops script execution and displays the values of the variables passed as ...

BreakIf() Stops script execution if condition is true and displays the values ...

Print() Returns a clip with the values of the variables passed as arguments printed in ...

ConstantsName Description

PRN_WSIZE Width of the standard clip returned by Print(), ArrayPrint() and ArrayPrintCP() functions.

PRN_HSIZE Height of the standard clip returned by Print(), ArrayPrint() and ArrayPrintCP() functions.

PRN_LSIZE Height of each (text) line of the standard clip returned by Print(), ArrayPrint() and ArrayPrintCP() functions.

PRN_LINES Number of lines contained in the standard clip returned by Print(), ArrayPrint() and ArrayPrintCP() functions.

VariablesName Description

PrintBase A PRN_WSIZE x PRN_HSIZE, 1 sec clip that is used internally by the module's routines to print out information passed in by the caller. Note that by changing it, the output of Print(), ArrayPrint() and ArrayPrintCP() functions will be affected.

Page 87: avisynth docu

ArrayPrintModule: debug :: core

Definition:ArrayPrint(string array)

Description:

Returns a clip with the values of the elements contained in array printed in separate lines (one line for each element). [1]

Examples:

... # check if script variables have correct values # by embedding the following lines of code ar = ArrayCreate(c1, c2, c3, offset_x, offset_y, eff) return ArrayPrint(ar) ...

[1]: Note that if the string representation of a variable's value is very long it may be clipped.

ArrayPrintCPModule: debug :: core

Definition:ArrayPrintCP(string array, int "columns")

Description:

Returns a clip with the values of the elements contained in array printed in separate lines (one line for each element). [1]

The function always return a clip with the height[2] of the clip stored in the PrintBase global variable.

If the number of elements is such that the output cannot be fit into one page, additional pages (ie frames) are added to the clip.

In addition the elements may be printed in more than one columns per page, if columns is suplied and > 1.

Examples:

... # check if a lot of script variables have correct values # by embedding the following lines of code ar = ArrayCreate(var1, var2, ..., var50) return ArrayPrintCP(ar) # if we wanted one 'page' then we could use # return ArrayPrintCP(ar, 2) ...

[1]:Note that if the string representation of a variable's value is very long it may be clipped. [2]:All debug printing functions return a clip with the width of the clip stored in the PrintBase global variable.

Page 88: avisynth docu

BreakModule: debug :: core

Definition:Break(val "x01", val "x02", val "x03", val "x04", ... , val "x20")

Description:

Stops script execution and displays the values of the variables passed as arguments in the standard Avisynth dialog box separated by "|" characters, after the string "User break:"

Examples:

v1 = 3.24 v2 = "test string" v3 = true ... Break(v1, v2, v3) # script stops here ...

BreakIfModule: debug :: core

Definition:BreakIf(bool condition, val "x01", val "x02", val "x03", val "x04", ... , val "x20")

Description:

Stops script execution if condition is true and displays the values of the variables passed as arguments (x01 - x20) in the standard Avisynth dialog box separated by "|" characters, after the string "Conditional break:"

Examples:

apath = ... c = AVISource(apath) d = SomeFilter(c) # script will stop only if d.Framecount < c.Framecount BreakIf(d.Framecount < c.Framecount, d.Framecount, c.Framecount, apath) ...

Page 89: avisynth docu

PrintModule: debug :: core

Definition:Print(val x01, val "x02", val "x03", val "x04", ... , val "x36")

Description:

Returns a clip with the values of the variables passed as arguments printed in separate lines (one line for each variable).

Note that if the string representation of a variable's value is very long it may be clipped.

Examples:

c = BlankClip(length=12) n = 24 f = 20.3456 b = 3*n - 15 <= 6*Log(f) s = "hello world!" return Print(c, n, f, b, s)

Page 90: avisynth docu

The debug :: logging moduleThe debug :: logging module provides functions, constants and global variables for the implementation of a conditional (based on current debug level) output of debuging information to log files.

Required modulesnumeric :: core, string :: core, string :: sprintf

FunctionsName Description

DebugLog() Outputs debuging information in a log file ...

GetDebugFile() Gets the filename of the current debug log file used by DebugLog()...

GetDebugMode() Gets the value of the current debug mode (level). See DebugLog() for further details...

SetDebugFile() Sets the filename of the current debug log file used by DebugLog()...

SetDebugMode() Sets the value of the current debug mode (level). See DebugLog() for further details...

Page 91: avisynth docu

ConstantsName Description

DBG_NODEBUG SetDebugMode() related constant. Specifies that debug logging (from DebugLog()) will not be performed. This constant if passed directly to DebugLog() will cause the respective call to always print information to the log file.

DBG_LEVEL_1 SetDebugMode() related constant. Specifies that user level 1 debug logging will be performed. Pass this constant to DebugLog() calls within your script which print the less detailed level of information to the log file.

DBG_LEVEL_2 SetDebugMode() related constant. Specifies that user level 2 debug logging will be performed. Pass this constant to DebugLog() calls within your script which print basic to moderately detailed level of information to the log file.

DBG_LEVEL_3 SetDebugMode() related constant. Specifies that user level 3 debug logging will be performed. Pass this constant to DebugLog() calls within your script which print moderately to detailed level of information to the log file.

DBG_LEVEL_4

SetDebugMode() related constant. Specifies that user level 4 debug logging will be performed. Pass this constant to DebugLog() calls within your script which print a detailed level of information to the log file. You can define more user-level constants if desired by succesively adding 1, 2,3, ..., etc. to this constant.

DBG_LIBRARY SetDebugMode() related constant. Avisynth libraries and plugins developers should derive their library-specific debug constants by adding to this number an appropriate integer offset (less than DBG_RESERVED - DBG_LIBRARY).

DBG_RESERVED

SetDebugMode() related constant. Debug level values equal or above DBG_RESERVED are reserved for AVSLib's own use.

Note: The above scheme may change at the future to allow the user a more granular control of what among different libraries should be logged.

VariablesNone

Page 92: avisynth docu

DebugLogModule: debug :: logging

Definition:DebugLog(int debug_level, string format, val "p01", val "p02", val "p03", val "p04", ..., val "p50" )

Description:

Outputs debuging information in a log file [1].

If the supplied debug_level is >= current debug mode (level) the function uses StrPrint() to insert the values of any defined variable arguments (p01, …, p50) into the string format and write it to the log file using WriteFileEnd. Else the function does nothing.

Examples:

fmt = "Processed clip is %i frames long, %ix%i and %f fps." c = AVISource(…) SetDebugMode(2) … # this equals to a NOP (1 > 2) DebugLog(1, fmt, c.FrameCount, c.Width, c.Height, c.Framerate) … # this will output to log file DebugLog(2, fmt, c.FrameCount, c.Width, c.Height, c.Framerate)

[1]:The main use of DebugLog is to trace the values of variables and function / filter arguments during code execution by carefully placing calls to DebugLog inside script code.

Descriptive format strings (for example ones that name the function, the variable, etc) greatly help the interpretation of log file contents.

GetDebugFileModule: debug :: logging

Definition:

GetDebugFile()

Description:

Gets the filename of the current debug log file used by DebugLog().

Examples:

#TODO in a later version of AVSLib.

Page 93: avisynth docu

GetDebugModeModule: debug :: logging

Definition:GetDebugMode()

Description:

Gets the value of the current debug mode (level). See DebugLog() for further details.

Examples:

# TODO in a later version of AVSLib.

SetDebugFileModule: debug :: logging

Definition:SetDebugFile(string path)

Description:

Sets the filename of the current debug log file used by DebugLog().

Examples:

# TODO in a later version of AVSLib.

SetDebugModeModule: debug :: logging

Definition:SetDebugMode(int mode)

Description:

Sets the value of the current debug mode (level). See DebugLog() for further details.[1]

Examples:

# TODO in a later version of AVSLib. [1]:AVSLib defines a number of constants for use with debug mode related functions. See the associated module's documentation for details.

Page 94: avisynth docu

The numeric packageThe numeric package contains modules that extend standard Avisynth operations on variables of numeric type (ints and floats).

Required packagesThe numeric package requires modules from the following packages (see the specific modules' documentation for actual dependencies): base.

ModulesName Description

core This module provides functions, constants and global variables for performing basic operations related to numeric types.

curves2d This module provides functions, constants and global variables for calculating points' coordinates on 2D curves.

functions This module extends the set of Avisynth numeric functions with new members (inverse and hyperbolic trigonometric functions, base-n exponentials and logarithms, etc.).

powseries This module extends the set of Avisynth numeric functions with power series, polynomial and factorial functions.

rounding This module extends the set of Avisynth numeric functions with base-n rounding functions.

statistics This module extends the set of Avisynth numeric functions with statistical functions.

Page 95: avisynth docu

The numeric :: core moduleThe numeric :: core module provides functions, constants and global variables for performing basic operations related to numeric types.

Required modulesbase :: core

FunctionsName Description

Clamp() Returns either x unchanged or one of the low_limit /...

Count() Returns the count of its arguments (ie the number of defined arguments in the ...

DegToRad() Returns the result of conversion of its degrees argument to radians...

Dif2() Returns the difference of its arguments...

Div2() Returns the quotient of the division of its arguments...

IsEven() Returns true if x is an even integer (a multiple of two),...

IsOdd() Returns true if x is an odd integer (not a multiple of two),...

Max() Returns the bigger of its (up to 20) arguments...

Max2() Returns the bigger of its (only two) arguments...

Min() Returns the smaller of its (up to 20) arguments...

Min2() Returns the smaller of (only two) its arguments...

Mod2() Returns the remainder of the division of its arguments...

Product() Returns the product of its (up to 20) arguments...

Product2() Returns the product of its (only two) arguments...

RadToDeg() Returns the result of conversion of its radians argument to degrees...

Sum() Returns the sum of its (up to 20) arguments...

Sum2() Returns the sum of its (only two) arguments...

ConstantsNone

VariablesNone

Page 96: avisynth docu

ClampModule: numeric :: core

Definition:Clamp(val x, val low_limit, val high_limit)

Description:

Returns either x unchanged or one of the low_limit / high_limit limiting values specified.

In other words it clamps x inside the interval [low_limit..high_limit].

Examples:

v = 2.8 w1 = Clamp(v, 2, 3) # w1 == 2.8 w2 = Clamp(v, 1, 2) # w2 == 2.0 w3 = Clamp(v, 3, 4) # w3 == 3.0

CountModule: numeric :: core

Definition:Count(val "x1", val "x2", val "x3", val "x4", ... , val "x20")

Description:

Returns the count of its arguments (ie the number of defined arguments in the function's argument list). [1]

Examples:

n = Count(1, 3, 5, 7) # n == 4 v1 = 3.24 v2 = Undef() n = Count(1, 3, v1, v2) # n == 3

[1]: The function can handle up to 20 arguments. This number is chosen as a good balance between usability and speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array package.

DegToRad Module: numeric :: core

Definition:DegToRad(float degrees)

Description:

Returns the result of conversion of its degrees argument to radians.

Examples:

r1 = DegToRad(180) r2 = DegToRad(360) # r1 == Pi and r2 == 2*Pi

Page 97: avisynth docu

Dif2Module: numeric :: core

Definition:Dif2(val x1, val x2)

Description:

Returns the difference of its arguments. [1]

Examples:

v = Dif2(5, 3) # v == 2 w = Dif2(-5, 3) # v == -8

[1]: The function is provided as a building block of more complex functions, particularly for operations on arrays. See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum functions.

Div2Module: numeric :: core

Definition:Div2(val x1, val x2)

Description:

Returns the quotient of the division of its arguments. [1]

Examples:

v = Div2(5, 2) # v == 2 because both args are ints w = Div2(5.0, 2) # v == 2.5 because 5.0 forces float division

[1]: The function is provided as a building block of more complex functions, particularly for operations on arrays. See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum functions.

IsEvenModule: numeric :: core

Definition:IsEven(int x)

Description:

Returns true if x is an even integer (a multiple of two), false otherwise.

Examples:

b1 = IsEven(3) # b1 == false b2 = IsEven(16) # b2 == true

Page 98: avisynth docu
Page 99: avisynth docu

IsOddModule: numeric :: core

Definition:IsOdd(int x)

Description:

Returns true if x is an odd integer (not a multiple of two), false otherwise.

Examples:

b1 = IsOdd(3) # b1 == true b2 = Isodd(16) # b2 == false

MaxModule: numeric :: core

Definition:Max(val x1, val "x2", val "x3", val "x4", ... , val "x20")

Description:

Returns the bigger of its arguments. [1]

Examples:

v = Max(1.1, 2.34, 3.05, -4, 0.9, 3) # v == 3.05 w = Max(-1.1, -2.34, 0, -4, -0.9) # w == 0

[1]: The function can handle up to 20 arguments. This number is chosen as a good balance between usability and speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array package.

Max2Module: numeric :: core

Definition:Max2(val x1, val x2)

Description:

Returns the bigger of its arguments. [1]

Examples:

v = Max2(1.1, 2.34) # v == 2.34 w = Max2(-1.1, -2.34) # w == -1.1

[1]: The function is provided as a building block of more complex functions, particularly for operations on arrays. See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum functions.

Page 100: avisynth docu

MinModule: numeric :: core

Definition:Min(val x1, val "x2", val "x3", val "x4", ... , val "x20")

Description:

Returns the smaller of its arguments. [1]

Examples:

v = Min(1.1, 2.34, 3.05, -4, 0.9, 3) # v == -4 w = Min(-1.1, -2.34, 0, -4, -0.9) # w == -4

[1]: The function can handle up to 20 arguments. This number is chosen as a good balance between usability and speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array package.

Min2Module: numeric :: core

Definition:Min2(val x1, val x2)

Description:

Returns the smaller of its arguments. [1]

Examples:

v = Min2(1.1, 2.34) # v == 1.1 w = Min2(-1.1, -2.34) # w == -2.34

[1]: The function is provided as a building block of more complex functions, particularly for operations on arrays. See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum functions.

Mod2Module: numeric :: core

Definition:Mod2(val x1, val x2)

Description:

Returns the remainder of the division of its arguments. [1]

Examples:

v = Mod2(7, 3) # v == 1 w = Mod2(1.1, 0.5) # w == 0.1

[1]: The function is provided as a building block of more complex functions, particularly for operations on arrays. See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum functions.

Page 101: avisynth docu

ProductModule: numeric :: core

Definition:Product(val x1, val "x2", val "x3", val "x4", ... , val "x20")

Description:

Returns the product of its arguments. [1]

Examples:

v = Product(3, 4, 6) # v is now 72 t = Product(0.5, 0.4, v) # t is now 14.4 z = Product(0.1, 0.2, v, t, t + v, t - v, 0.5) # z is now 51,597.80

[1]: The function can handle up to 20 arguments. This number is chosen as a good balance between usability and speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array package.

Product2Module: numeric :: core

Definition:Product2(val x1, val x2)

Description:

Returns the product of its arguments. [1]

Examples:

p = Product2(3, 4) # p is now 12 s = Product2(0.5, p) # s is now 6

[1]: The function is provided as a building block of more complex functions, particularly for operations on arrays. See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum functions.

RadToDegModule: numeric :: core

Definition:RadToDeg(float radians)

Description:

Returns the result of conversion of its radians argument to degrees.

Examples:

d1 = RadToDeg(Pi) d2 = RadToDeg(2*Pi) # d1 == 180 and d2 == 360

Page 102: avisynth docu

SumModule: numeric :: core

Definition:Sum(val x1, val "x2", val "x3", val "x4", ... , val "x20")

Description:

Returns the sum of its arguments. [1]

Examples:

sm1 = Sum(2, 2, 3, 5, 1, 4) # sm1 == 17 sm2 = Sum(clip1, clip2, clip3) # clips can also be summed sm3 = Sum("ab", "cde", "f") # sm3 == "abcdef"

[1]: The function can handle up to 20 arguments. This number is chosen as a good balance between usability and speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array package.

Sum2Module: numeric :: core

Definition:Sum2(val x1, val x2)

Description:

Returns the sum of its arguments. [1]

Examples:

sm1 = Sum2(2, 2) # sm1 == 4 sm2 = Sum2(clip1, clip2) # clips can also be summed sm3 = Sum2("ab", "cd") # sm3 == "abcd"

[1]: The function is provided as a building block of more complex functions, particularly for operations on arrays. See the documentation of the array package and the ArrayOpFunc, ArrayOpArrayFunc and ArraySum functions.

Page 103: avisynth docu

The numeric :: curves2d moduleThe numeric :: curves2d module provides functions, constants and global variables for calculating points' coordinates on 2D curves.

Required modulesNone

FunctionsName Description

Circle() Returns the y-value of x so that the point (x,y) lies on a circle ...

Ellipsis() Returns the y-value of x so that the point (x,y) lies on an ellipsis ...

Hyperbola() Returns the y-value of x so that the point (x,y) lies on a hyperbola parallel to x axis ...

Line() Returns the y-value of x so that the point (x,y) lies on a line defined by its ...

Line1pt() Returns the y-value of x so that the point (x,y) lies on a line defined by its ...

Line2pt() Returns the y-value of x so that the point (x,y) lies on a line defined by two...

Parabola() Returns the y-value of x so that the point (x,y) lies on a parabola parallel to x axis, with ed...

ConstantsNone

VariablesNone

Page 104: avisynth docu

CircleModule: numeric :: curves2d

Definition:Circle(float x, float radius, bool "up_part", float "xc", float "yc")

Description:

Returns the y-value of x so that the point (x,y) lies on a circle defined by its radius and its center (xc,yc).

If xc or yc are not provided they default to zero.

up_part determines whether the point will be on the upper or lower semi-circle. If up_part is true or omitted it will on the upper semi-circle (ie >= yc), else on the lower (ie < yc).

Examples:

y_u = Circle(Pi()/4, 1) # y_u == Pi()/4 y_d = Circle(Pi()/4, 1, false) # y_d == -Pi()/4 y = Circle(5, 5, xc=5, yc=-5) # y == 0

EllipsisModule: numeric :: curves2d

Definition:Ellipsis(float x, float a, float b, bool "up_part", float "xc", float "yc")

Description:

Returns the y-value of x so that the point (x,y) lies on an ellipsis defined by long axis half-length a, short axis half-length b and its center (xc,yc).

If xc or yc are not provided they default to zero.

up_part determines whether the point will be on the upper or lower part of the curve. If up_part is true or omitted it will on the upper part (ie >= yc), else on the lower (ie < yc).

Examples:

# TODO in a later version of AVSLib.

Page 105: avisynth docu

HyperbolaModule: numeric :: curves2d

Definition:Hyperbola(float x, float a, float b, bool "up_part", float "xc", float "yc")

Description:

Returns the y-value of x so that the point (x,y) lies on a hyperbola parallel to x axis defined by long axis half-length a, short axis half-length b and its center (xc,yc).

If xc or yc are not provided they default to zero.

up_part determines whether the point will be on the upper or lower part of the curve. If up_part is true or omitted it will on the upper part (ie >= yc), else on the lower (ie < yc).

Notes and conditions on arguments relations:

1) If x >= xc + a the function returns the y-value that corresponds to a point on the right branch of the hyperbola.

2) If x <= xc - a the function returns the y-value that corresponds to a point on the left branch of the hyperbola.

3) If x does not satisfy the above two conditions (does not correspond to a point in any branch, the function throws an error.

4) Exchange x,y to get a hyperbola with axis parallel to y axis.

Examples:

# TODO in a later version of AVSLib.

LineModule: numeric :: curves2d

Definition:Line(float x, float slope, float intercept)

Description:

Returns the y-value of x so that the point (x,y) lies on a line defined by its slope and intercept.

Examples:

y1 = Line(2, 1, 0) # y = 1x + 0 = x == 2 y2 = Line(2, 0.5, 4) # y = 0.5x + 4 == 5

Page 106: avisynth docu

Line1ptModule: numeric :: curves2d

Definition:Line1pt(float x, float x1, float y1, float slope)

Description:

Returns the y-value of x so that the point (x,y) lies on a line defined by its slope and a given point (x1,y1).

Examples:

y1 = Line1pt(2, 0, 1, 0.5) # y = 0.5x + 1 == 2 y2 = Line1pt(0, 1, 1, -1) # y = -x + 2 == 2

Line2ptModule: numeric :: curves2d

Definition:Line2pt(float x, float x1, float y1, float x2, float y2)

Description:

Returns the y-value of x so that the point (x,y) lies on a line defined by two given points (x1,y1) and (x2,y2).

Examples:

y1 = Line2pt(2, 0, 1, 4, 3) # y = 0.5x + 1 == 2 y2 = Line2pt(0, 1, 1, 3, -1) # y = -x + 2 == 2

ParabolaModule: numeric :: curves2d

Definition:Parabola(float x, float a, bool "up_part", float "xc", float "yc")

Description:

Returns the y-value of x so that the point (x,y) lies on a parabola parallel to x axis, with edge located at distance a from its focus and its center located at (xc,yc).

If xc or yc are not provided they default to zero.

up_part determines whether the point will be on the upper or lower part of the curve. If up_part is true or omitted it will on the upper part (ie >= yc), else on the lower (ie < yc).

Notes and conditions on arguments relations:

1) If x >= xc the function returns the y-value that corresponds to a parabola opening towards the right x semi-axis; else the y-value that corresponds to a parabola opening towards the left x semi-axis.

2) Exchange x,y to get a hyperbola with axis parallel to y axis.

Examples:

# TODO in a later version of AVSLib.

Page 107: avisynth docu

The numeric :: functions moduleThe numeric :: functions module extends the set of Avisynth numeric functions with new members (inverse and hyperbolic trigonometric functions, base-n exponentials and logarithms, etc.).

Required modulesnumeric :: core

FunctionsName Description

ArcCos() Returns the inverse cosine of its argument...

ArcCosh() Returns the inverse hyperbolic cosine of its argument...

ArcCot() Returns the inverse cotangent of its argument...

ArcCoth() Returns the inverse hyperbolic cotangent of its argument...

ArcSin() Returns the inverse sine of its argument...

ArcSinh() Returns the inverse hyperbolic sine of its argument...

ArcTan() Returns the inverse tangent of its argument...

ArcTanh() Returns the inverse hyperbolic tangent of its argument...

Cosh() Returns the hyperbolic cosine of its argument...

Cot() Returns the cotangent of its argument...

Coth() Returns the hyperbolic cotangent of its argument...

Exp10() Returns the base-10 exponent of x (ie 10x)...

ExpBs() Returns the base-base exponent of x (ie (base)x)...

Log10() Returns the base-10 logarithm of x (ie Log10(x))...

LogBs() Returns the base-base logarithm of x (ie logbase(x))...

Sinh() Returns the hyperbolic sine of its argument...

Tan() Returns the tangent of its argument...

Tanh() Returns the hyperbolic tangent of its argument...

ConstantsNone

VariablesNone

Page 108: avisynth docu

ArcCosModule: numeric :: functions

Definition:ArcCos(float x)

Description:

Returns the inverse cosine of its argument.

Examples:

v = ArcCos(0.5403) # v == 1.0000 v = ArcCos(Pi/4) # v == 0.6675

ArcCoshModule: numeric :: functions

Definition:ArcCosh(float x)

Description:

Returns the inverse hyperbolic cosine of its argument.

Examples:

v = ArcCosh(1.5431) # v == 1.0000 v = ArcCosh(3.7622) # v == 2,0000

ArcCotModule: numeric :: functions

Definition:ArcCot(float x)

Description:

Returns the inverse cotangent of its argument.

Examples:

v = ArcCot(0.6421) # v == 1.0000 v = ArcCot(-0.4577) # v == 2.000

Page 109: avisynth docu

ArcCotModule: numeric :: functions

Definition:ArcCot(float x)

Description:

Returns the inverse cotangent of its argument.

Examples:

v = ArcCot(0.6421) # v == 1.0000 v = ArcCot(-0.4577) # v == 2.000

ArcSinModule: numeric :: functions

Definition:ArcSin(float x)

Description:

Returns the inverse sine of its argument.

Examples:

v = ArcSin(0.84147) # v == 1.0000 v = ArcSin(0.5) # v == 0.5236

ArcSinhModule: numeric :: functions

Definition:ArcSinh(float x)

Description:

Returns the inverse hyperbolic sine of its argument.

Examples:

v = ArcSinh(1.1752) # v == 1.000 v = ArcSinh(3.6269) # v == 2.0000

Page 110: avisynth docu

ArcTanModule: numeric :: functions

Definition:ArcTan(float x)

Description:

Returns the inverse tangent of its argument.

Examples:

v = ArcTan(1.5574) # v == 1.0000 v = ArcTan(2) # v == 1.1071

ArcTanhModule: numeric :: functions

Definition:ArcTanh(float x)

Description:

Returns the inverse hyperbolic tangent of its argument.

Examples:

v = ArcTanh(0.7616) # v == 1.0000 v = ArcTanh(Pi/4) # v == 1.0593

CoshModule: numeric :: functions

Definition:Cosh(float x)

Description:

Returns the hyperbolic cosine of its argument.

Examples:

v = Cosh(1) # v == 1.5431 v = Cosh(2) # v == 3.7622

Page 111: avisynth docu

CotModule: numeric :: functions

Definition:Cot(float x)

Description:

Returns the cotangent of its argument.

Examples:

v = Cot(1) # v == 0.6421 v = Cot(2) # v == -0.4577

CothModule: numeric :: functions

Definition:Coth(float x)

Description:

Returns the hyperbolic cotangent of its argument.

Examples:

v = Coth(1) # v == 1.3130 v = Coth(2) # v == 1.0373

Exp10Module: numeric :: functions

Definition:Exp10(float x)

Description:

Returns the base-10 exponent of x (ie 10x).

Examples:

e1 = Exp10(1) # e1 == 10 e2 = Exp10(3) # e2 == 1000

Page 112: avisynth docu

ExpBsModule: numeric :: functions

Definition:ExpBs(float x, float base)

Description:

Returns the base-base exponent of x (ie (base)x). The base argument can take any value allowed by Pow function.

Examples:

e1 = ExpBs(1, 2.5) # e1 == 2.5 e2 = ExpBs(2, 3) # e2 == 9

Log10Module: numeric :: functions

Definition:Log10(float x)

Description:

Returns the base-10 logarithm of x (ie Log10(x)).

Examples:l1 = Log10(10) # l1 == 1 l2 = Log10(1000) # l2 == 3

LogBsModule: numeric :: functions

Definition:LogBs(float x, float base)

Description:

Returns the base-base logarithm of x (ie logbase(x)). The base argument can take any allowed real value.

Examples:

l1 = LogBs(2.5, 2.5) # l1 == 1 l2 = LogBs(9, 3) # l2 == 2

Page 113: avisynth docu

SinhModule: numeric :: functions

Definition:Sinh(float x)

Description:

Returns the hyperbolic sine of its argument.

Examples:

v = Sinh(1) # v == 1.1752 v = Sinh(2) # v == 3.6269

TanModule: numeric :: functions

Definition:Tan(float x)

Description:

Returns the tangent of its argument.

Examples:

v = Tan(1) # v == 1.5574 v = Tan(2) # v == -2.1850

Page 114: avisynth docu

The numeric :: powseries moduleThe numeric :: powseries module extends the set of Avisynth numeric functions with power series, polynomial and factorial functions.

Required modulesNone

FunctionsName Description

Factorial() Returns the factorial of x (ie x!)...

Polynomial() Returns an arbitrary polynomial of x...

PowSeries() Returns an arbitrary power series of x...

ConstantsNone

VariablesNone

Page 115: avisynth docu

FactorialModule: numeric :: powseries

Definition:Factorial(int x)

Description:

Returns the factorial of x (ie x!).

Examples:

n1 = Factorial(3) # n1 == 6 n2 = Factorial(5) # n2 == 120

PolynomialModule: numeric :: powseries

Definition:Polynomial(float x, string coef_func, int start_index, int end_index, int "increment", string "coef_args")

Description:

Returns an arbitrary polynomial of x.

The polynomial is generated by summing the terms coef_func(index, coef_args) * Pow(x, index)) for all indexes in the range [start_index .. end_index), ie end_index is not included.

The function is a special case of the more general PowSeries function, where the power_func argument is the Self function.

See PowSeries for an explanation of the arguments.

Examples:

# Calculate the polynomial (2 + bn)*x2n starting from n=0 and taking 10 terms for value of x = 5.4 and b = 2.3 function mycoef(int i, float b) { return 2 + b * Int(i / 2) } # Since i increases at step of 2, i/2 will increase at steps of 1 p1 = Polynomial(5.4, "mycoef", 0, 20, 2, String(2.3))

Page 116: avisynth docu

PowSeriesModule: numeric :: powseries

Definition:PowSeries(float x, string coef_func, string power_func, int start_index, int end_index, int "increment", string "coef_args", string "power_args")

Description:

Returns an arbitrary power series of x.

The power series is generated by summing the terms coef_func(index, coef_args) * Pow(x, power_func(index, power_args)) for all indexes in the range [start_index .. end_index), ie end_index is NOT included.

coef_func and power_func user-functions must accept an integer (the index of the series term) as their first argument. Optionally, they can accept other arguments, which can be passed as strings (containing the intermediate commas) with the "coef_args" and "power_args" arguments.

Arguments:

x: The value of which the power series will be calculated.

coef_func: The name of the function that produces the coefficients of the series. coef_args argument.

power_func: The name of the function that produces the powers of the series.

start_index: The index of the first term of the series.

end_index: The first index after the end of the series (that is, no term will be generated for that index).

"increment" (Optional, defaults to 1): The increment between successive indexes of the series.

"coef_args" (Optional, defaults to ""): Additional arguments to pass to the coef_func function.

"power_args" (Optional, defaults to ""):

Notes and conditions on arguments relations:

1. start_index must be <= end_index. In the special case where these two are equal the function returns zero.

2. If coef_args or power_args contain string arguments, the later must be surrounded with double quotes before entering them into the arguments. Use StrQuote for this purpose.

3. Since coef_func and power_func are the first constituents of the constructed string for Eval() you can perform simple operations with constants and globals inside those strings, such as multiplication and addition (eg. set coef_func to "2 + funcname").

Page 117: avisynth docu

Examples:

# Calculate the power series (2n/n!)*x(2n+1) # for n=0 to 19 and value of x = 1.4 function mycoef(int i) { return Pow(2, i) / Factorial(i) } function mypow(int i) { return 2 * i + 1 } f1 = PowSeries(1.4, "mycoef", "mypow", 0, 20) # Calculate the power series (2/n!)*x2n for n=4 to 16, # with step 2 and value of x = 0.5 f2 = PowSeries(0.5, "2 / Factorial", "2 * Self", 4, 18, 2) # Calculate the power series [Sin(n*pi()*x/a)/(2n)]*x(2n+1)/b # for n=-10 to 10 (included) and value of # x = 0.75 with a = 10 and b = Pi() function mycoef(int i, float x, float a) { return Sin(i*Pi()*x/a) / Pow(2, i) } function mypow(int i, float b) { return (2 * i + 1)/b } f3 = PowSeries(0.75, "mycoef", "mypow", -10, 11, 1, "0.75, 10", "Pi()")

Page 118: avisynth docu

The numeric :: rounding moduleThe numeric :: rounding module extends the set of Avisynth numeric functions with base-n rounding functions.

Required modulesnumeric :: core

FunctionsName Description

CeilBs() An extension to the Ceil standard Avisynth function for arbitrary (integer) base base...

FloorBs() An extension to the Floor standard Avisynth function for arbitrary (integer) base base...

FRound() Returns x rounded to decimals accuracy, taking care not to overflow during the intermediate cal...

IntBs() An extension to the Int standard Avisynth function for arbitrary (integer) base base...

RoundBs() An extension to the Round standard Avisynth function for arbitrary (integer) base base...

RoundEven() Returns the closest even integer to its argument...

RoundOdd() Returns the closest odd integer to its argument...

ConstantsNone

VariablesNone

Page 119: avisynth docu

CeilBsModule: numeric :: rounding

Definition:CeilBs(float x, int "base")

Description:

An extension to the Ceil standard Avisynth function for arbitrary (integer) base base.[1] It returns the base-base ceiling of x (ie the smallest integral multiple of base that is greater or equal to x).

Examples:

f1 = CeilBs(3.3, 2) # f1 == 4.0 f2 = CeilBs(7.3, 3) # f2 == 9.0 f3 = CeilBs(7.3, 1) # f3 == 8.0

[1]: Like the Ceil standard Avisynth function, CeilBs is non-symmetrical around the axis origin and periodic.

Consequently, the following equalities hold:

Ceil(x) = k, x in (k-1..k] for every k in Z CeilBs(x, b) = kb, x in ((k-1)*b..k*b] for every k in Z

FloorBsModule: numeric :: rounding

Definition:FloorBs(float x, int "base")

Description:

An extension to the Floor standard Avisynth function for arbitrary (integer) base base.[1] It returns the base-base floor of x (ie the largest integral multiple of base that is less or equal to x).

Examples:

f1 = FloorBs(3.3, 2) # f1 == 2.0 f2 = FloorBs(7.3, 3) # f2 == 6.0 f3 = FloorBs(7.3, 1) # f3 == 7.0

[1]:Like the Floor standard Avisynth function, FloorBs is non-symmetrical around the axis origin and periodic.

Consequently, the following equalities hold:

Floor(x) = k, x in [k..k+1) for every k in Z FloorBs(x, b) = kb, x in [k*b..(k+1)*b) for every k in Z

Page 120: avisynth docu

FRoundModule: numeric :: rounding

Definition:FRound(float x, int decimals)

Description:

Returns x rounded to decimals accuracy, taking care not to overflow during the intermediate calculations. The result is a float number.

Note that when using negative decimals it is possible to zero the result if x < 0.5*Pow(10,-decimals).

Examples:

f1 = 2.345613 f2 = FRound(f1, 2) # f2 == 2.34 f3 = 2132.345 f4 = FRound(f3, -2) # f4 == 2100

IntBsModule: numeric :: rounding

Definition:IntBs(float x, int "base")

Description:

An extension to the Int standard Avisynth function for arbitrary (integer) base base.[1] It returns the base-base truncated integer of x (ie the largest integral multiple of base with absolute value less or equal to Abs(x)).

Examples:

f1 = IntBs(3.3, 2) # f1 == 2.0 f2 = IntBs(7.3, 3) # f2 == 6.0 f3 = IntBs(7.3, 1) # f3 == 7.0

[1]:Like the Int standard Avisynth function, IntBs is symmetrical around the axis origin and not periodic.

Consequently, the following equalities hold:

Int(x) = Ceil(x), x < 0 | Floor(x), x > 0 IntBs(x, b) = CeilBs(x, b), x < 0 | FloorBs(x, b), x > 0

Page 121: avisynth docu

RoundBsModule: numeric :: rounding

Definition:RoundBs(float x, int "base")

Description:

An extension to the Round standard Avisynth function for arbitrary (integer) base base.[1] It returns the base-base rounded integer of x (ie the integral multiple of base that has absolute difference from x less or equal to base/2). [2]

Examples:

f1 = RoundBs(3.3, 2) # f1 == 4.0 f2 = RoundBs(7.3, 3) # f2 == 6.0 f3 = RoundBs(7.3, 1) # f3 == 7.0

[1]:Like the Round standard Avisynth function, RoundBs is symmetrical around the axis origin and not periodic.

Consequently, the following equalities hold:

Round(x) = k, x in (k-0.5..k+0.5) for every k in Z RoundBs(x, b) = kb, x in ((k-0.5)*b..(k+0.5)*b) for every k in Z

[2]:The current implementation will overflow if x is near (ie less or equal than base) the maximum / minimum integer limits. This limitation may be removed in a subsequent version.

RoundEvenModule: numeric :: rounding

Definition:RoundEven(float x)

Description:

Returns the closest even integer to its argument.

Rounding is made such that the previous odd integer (even - 1) rounds to even, ie all values inside the interval [even - 1..even + 1) round to even.

Examples:

re1 = RoundEven(7.0) # re1 == 8 re2 = RoundEven(8.999999) # re2 == 8 re3 = RoundEven(9.0) # re3 == 10

Page 122: avisynth docu

RoundOddModule: numeric :: rounding

Definition:RoundOdd(float x)

Description:

Returns the closest odd integer to its argument.

Rounding is made such that the previous even integer (odd - 1) rounds to odd, ie all values inside the interval [odd - 1..odd + 1) round to odd.

Examples:

ro1 = RoundOdd(6.0) # ro1 == 7 ro2 = RoundOdd(7.999999) # ro2 == 7 ro3 = RoundOdd(8.0) # ro3 == 9

Page 123: avisynth docu

The numeric :: statistics moduleThe numeric :: statistics module extends the set of Avisynth numeric functions with statistical functions.

Required modulesbase :: core, numeric :: core

FunctionsName Description

Average() Returns the (statistical) average of its arguments...

StDev() Returns the (statistical) standard deviation of its arguments...

SumSquare() Returns the sum of squares of its arguments (ie each argument is raised to a power of 2 ...

ConstantsNone

VariablesNone

Page 124: avisynth docu

AverageModule: numeric :: statistics

Definition:Average(val x1, val "x2", val "x3", val "x4", ... , val "x20")

Description:

Returns the (statistical) average of its arguments. [1]

Examples:

avg = Average(6, 5, 7, 9, 4, 8) # avg == 6.5000, ie 39/6

[1]: The function can handle up to 20 arguments. This number is chosen as a good balance between usability and speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array package.

StDevModule: numeric :: statistics

Definition:StDev(val x1, val "x2", val "x3", val "x4", ... , val "x20")

Description:

Returns the (statistical) standard deviation of its arguments. [1]

Examples:

sd1 = StDev(2, 2, 3, 5, 1, 4) # sd1 == 1.4720 sd2 = StDev(3, 1, 3, 5, 2, 4) # sd1 == 1.4142

[1]: The function can handle up to 20 arguments. This number is chosen as a good balance between usability and speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array package.

SumSquareModule: numeric :: statistics

Definition:SumSquare(val x1, val "x2", val "x3", val "x4", ... , val "x20")

Description:

Returns the sum of squares of its arguments (ie each argument is raised to a power of 2 before contributing to the sum). [1]

Examples:

ss1 = SumSquare(2, 2, 3, 5, 1, 4) # ss1 == 59 ss2 = SumSquare(3, 1, 3, 5, 2, 4) # ss2 == 64

[1]: The function can handle up to 20 arguments. This number is chosen as a good balance between usability and speed. If more arguments are needed use an array and the ArraySum function, or a suitable function of the array package.

Page 125: avisynth docu

The string packageThe string package contains modules that extend standard Avisynth operations on variables of string type.

Required packagesThe string package requires modules from the following packages (see the specific modules' documentation for actual dependencies): base, numeric, array.

ModulesName Description

core This module provides functions, constants and global variables for performing basic operations related to the string (and array) type.

search This module provides functions, constants and global variables for performing extended string searching and replacement operations.

sprintf This module provides StrPrint, a string formatting function with sprintf-like interface.

Page 126: avisynth docu

The string :: core moduleThe string :: core module provides functions, constants and global variables for performing basic operations related to the string (and array) type.

Required modulesbase :: core

FunctionsName Description

IsQuoted() Returns true if x starts and ends with a " character...

QuoteNoexpr() Returns its argument string either quoted if it fails to evaluate (and thus it is not ...

StrCompare() Compares strings s1 and s2 and returns -1,0,1 if s1 < s2, s1 == s2, s1 > s2, respectively...

StrFill() Returns a string consisting of count repetitions of s...

StrLeft() A replacement of LeftStr standard Avisynth function. For Avisynth versions up to 2.55 offers the ability ...

StrMid() A replacement of MidStr standard Avisynth function. For Avisynth versions up to 2.55 offers the ability to...

StrQuote() Returns its argument with one " character added at the begining and at the end...

StrRight() A replacement of RightStr standard Avisynth function. For Avisynth versions up to 2.55 offers the ability ...

StrUnquote() Returns its argument with one " character at the begining and one at the end ...

ZStrip() Returns fpnum stripped from leading and trailing zeros if fpnum ...

ConstantsName Description

CHAR_SET The active character set. Used for case-sensitive search and replace by the string :: search module's functions.

VariablesNone

Page 127: avisynth docu

IsQuotedModule: string :: core

Definition:IsQuoted(string x)

Description:

Returns true if x starts and ends with a " character.

Note that for zero-length and one-length strings it returns false.

Examples:

s = StrQuote("test string") b1 = IsQuoted(s) # b1 == true t = "test string" b2 = IsQuoted(t) # b2 == false u = Chr(34) # a single " character b3 = IsQuoted(u) # b3 == false

QuoteNoexprModule: string :: core

Definition:QuoteNoexpr(string x)

Description:

Returns its argument string either quoted if it fails to evaluate (and thus it is not a valid expression or global identifier's name) or unchanged if it succeeds to evaluate.

Its intended usage is constructing proper strings for passing to Eval() but be aware of possible side effects if its argument contains an exression or a function that assigns to globals and not just a variable name.

This function is used by the array package.

Examples:

global nb_exp = 2 s = QuoteNoexpr("nb_exp") # s == 'nb_exp' t = QuoteNoexpr("nbnoexp") # t == '"nbnoexp"'

Page 128: avisynth docu

StrCompareModule: string :: core

Definition:StrCompare(string s1, string s2, bool "ignorecase", string "comparefunc")

Description:

Compares strings s1 and s2 and returns -1,0,1 if s1 < s2, s1 == s2, s1 > s2, respectively.

Arguments:

ignorecase (Optional, defaults to True): Set it to false to perform a case-sensitive comparison.

comparefunc (Optional, defaults to standard Avisynth string comparison): A user-defined function that accepts up to three arguments (the same as StrCompare, ie s1, s2 and (optionally) ignorecase and returns the same values as StrCompare. Use it whenever a non-standard comparison has to be performed.

Examples:

v1 = StrCompare("aviSynth", "Avisynth") # v1 == 0 v2 = StrCompare("aviSynth", "Avisynth", true) # v2 == 1

StrFillModule: string :: core

Definition:StrFill(string s, int count, bool "strict")

Description:

Returns a string consisting of count repetitions of s.

If count == 0, a null string is returned.

The strict optional parameter when set to false makes the function to return a null string when a negative count value is passed (the default behavior is to throw an error).

Examples:

s = StrFill("a", 12) # s == "aaaaaaaaaaaa" t = StrFill("abc", 3) # t == "abcabcabc" u = StrFill("abc", 0) # u == "" # this will halt script with an error v = StrFill("abc", -1) # this will return a null string (same result as u, above) v = StrFill("abc", -1, false)

Page 129: avisynth docu

StrLeftModule: string :: core

Definition:StrLeft(string s, int length)

Description:

A replacement of LeftStr standard Avisynth function. For Avisynth versions up to 2.55 offers the ability to handle twice as large strings than the standard function; for later versions it has the same functionality.

Arguments:

The arguments are those of the associated standard Avisynth function.

Examples:

s1 = StrLeft("\avisynth", 5) s2 = StrLeft("\avisynth", 3) # s1 == "avisy", s2 == "avi"

StrMidModule: string :: core

Definition:StrMid(string s, int start, int "length")

Description:

A replacement of MidStr standard Avisynth function. For Avisynth versions up to 2.55 offers the ability to handle twice as large strings than the standard function; for later versions it has the same functionality.

Arguments:

The arguments are those of the associated standard Avisynth function.

Examples:

s1 = StrMid("\avisynth", 1, 5) s2 = StrMid("\avisynth", 6, 3) # s1 == "avisy", s2 == "nth"

Page 130: avisynth docu

StrQuoteModule: string :: core

Definition:StrQuote(string x)

Description:

Returns its argument with one " character added at the begining and at the end.

Examples:

s = "this is a string" q = StrQuote(s) # q == '"this is a string"'

StrRightModule: string :: core

Definition:StrRight(string s, int length)

Description:

A replacement of RightStr standard Avisynth function. For Avisynth versions up to 2.55 offers the ability to handle twice as large strings than the standard function; for later versions it has the same functionality.

Arguments:

The arguments are those of the associated standard Avisynth function.

Examples:

s1 = StrRight("\avisynth", 5) s2 = StrRight("\avisynth", 3) # s1 == "synth", s2 == "nth"

Page 131: avisynth docu

StrUnquoteModule: string :: core

Definition:StrUnquote(string x)

Description:

Returns its argument with one " character at the begining and one at the end stripped (if both they exist). " characters inside the string are left untouched.

Examples:

s = Chr(34) + "test string" + Chr(34) l1 = StrLen(s) # l1 == 13, s == '"test string"' t = StrUnquote(s) l2 = StrLen(t) # l2 == 11, t == "test string"

ZStripModule: string :: core

Definition:ZStrip(string fpnum)

Description:

Returns fpnum stripped from leading and trailing zeros if fpnum is a valid string representation of a number, else fpnum unchanged.

Examples:

# strings 1 and 3 are valid numbers, 2 is not s1 = ZStrip("2.304000") # s1 == "2.304" s2 = ZStrip("24-10-003") # s2 == "24-10-003" s3 = ZStrip("023.30240") # s3 == "23.3024"

Page 132: avisynth docu

The string :: search moduleThe string :: search module provides functions, constants and global variables for performing extended string searching and replacement operations.

Required modulesstring :: core, array :: core

FunctionsName Description

StrFind() A generic substring search function that can return all positions of occurrence of sought inside base...

StrReplace() A generic substring replacement function that can replace all occurrences of sought inside base...

ConstantsNone

VariablesNone

Page 133: avisynth docu

StrFindModule: string :: search

Definition:StrFind(string base, string sought, int "index", bool "ignorecase")

Description:

A generic substring search function that can return all positions of occurrence of sought inside base (as an array) or a specific occurrence (as a zero-based index of the array).

Both case-sensitive and case-insensitive searches are supported, controlled by the ignorecase argument.

Notes and conditions on arguments relations:

1] The function defaults to case-sensitive searches and to returning all positions of sought. If only the first occurence is wanted the index argument must explicilty contain a zero value.

Examples:

a1 = StrFind("abbcdefabcd", "b") a1 == "2,3,9" (an array) a2 = StrFind("abbcdefabcd", "B") a2 == 0 (case-sensitive is the default) a3 = StrFind("abbcdefabcd", "b", 0) a3 == 2

Page 134: avisynth docu

StrReplaceModule: string :: search

Definition:StrReplace(string base, string sought, string rep, int "index", bool "ignorecase", bool "recurse")

Description:

A generic substring replacement function that can replace all occurrences of sought inside base with rep or the zero-based index'th specific occurrence.

Both case-sensitive and case-insensitive replacements are supported, controlled by the ignorecase argument.

Also, recursive replacements are supported (where the new string after substitution of sought by rep is searched from the begining for occurence of sought), controlled by the recurse argument.

Notes and conditions on arguments relations:

If recurse is true the rep string must not contain sought as a substring, because this would led to infinite recursion. The function will immediately throw an error if such a condition is detected.

Examples:

s1 = StrReplace("abbcacbd", "ab", "a", recurse=true) # s1 == "acacbd" s2 = StrReplace("abbcacbd", "ab", "a") # s2 == "abcacbd" s3 = StrReplace("aBbcabBcaBd", "aB", "A", ignorecase=true, recurse=true) # s3 == "AcAcAd" s4 = StrReplace("aBbcabBcaBd", "aB", "A", recurse=true) # s4 == "AbcabBcAd"

Page 135: avisynth docu

The string :: sprintf moduleThe $package :: $module module provides StrPrint, a string formatting function with sprintf-like interface.

Required modulesbase :: core, numeric :: core, string :: core, string :: search, array :: core, array :: slices, array :: operators, array :: transforms

FunctionsName Description

StrPrint() An sprintf-like string formatting function...

ConstantsNone

VariablesNone

Page 136: avisynth docu

StrPrintModule: string :: sprintf

Definition:StrPrint(string format, val "p01", val "p02", val "p03", val "p04", ..., val "p50")

Description:

An sprintf-like string formatting function.

It permits incorporation of string representations of up to 50 variables into a pre-built expression (the format string).

It also allows the incorporation of format characters (tabs, linebreaks, etc.).

Very useful for creating subtitles, log entries and function calls or other code strings to be passed to the Eval() standard avisynth function or other Avisynth, plugin or user functions (for example: to build RPN expressions for the xxxLut functions of MaskTools).

Arguments:

format: String containing variable substitution placeholders which will be replaced by an appropriate string representation of the corresponding variable's value (in all cases except %q as a string without double quotes). The substitution placeholders have the form:

• %b: interpret variable as a bool (replace with "true" or "false"). • %c: interpret variable as a clip; replace with its framecount. • %f: interpret variable as a float (replace with its value, stripping trailing zeros with ZStrip()). • %g: interpret variable as a clip; store it as an auto-global and replace with the auto-global's name [1]. • %i: interpret variable as an integer. • %q: interpret variable as a string; quote it with double quotes before replacing. • %s: interpret variable as a string. • %v: interpret variable as having any possible type and replace appropriately after determining it. Clips are

treated as if %c was specified.

Total number of variables (and thus substitution placeholders) accepted is 50.

In addition, the following formating placeholders have a special meaning (and may be present in any number):

• %%: Replace with a % character. • \n: Replace with a line feed character. • \r: Replace with a carriage return character. • \t: Replace with a tab character.

p01, p02, ..., p50 (Optional): The variables that will supply values for replacing the substitution placeholders of the format string. "

Notes and conditions on arguments relations:

1) All substitution and formatting placeholders' strings are case sensitive.

2) The number of variables must correspond exactly to the number of substitution placeholders contained in the format string else the function will throw an error.

3) If some of the variables supplied to the function are not defined, they will be treated as non-existent; this is a feature but it means that you must be careful because substitution of placeholders in the format string is performed with the order that defined arguments are supplied to the function.

4) You can use the function to perform only formatting substitutions if no variables are supplied and the format string contains only formatting placeholders.

Page 137: avisynth docu

Examples:

fmt = "Current source is a %ix%i %f fps %s clip ." c = AVISource(…) ct = c.IsRGB ? ""RGB"" : (c.IsYUY2 ? ""YUY2"" : ""YV12"") rst = StrPrint(fmt, c.Width, c.Height, c.Framerate, ct) return BlankClip().Subtitle(rst)

[1]: %g is useful for creating parameter strings to be passed at array operator functions, in order to convert a local clip variable to a global variable. The mechanism used to do so is the same as the one used for the implementation of AVSLib's array type.

Page 138: avisynth docu

The filters packageThe filters package contains modules that implement various useful filters (clip transformation functions); for example animation, editing, resizing and stacking filters.

Required packagesThe filters package requires modules from the following packages (see the specific modules' documentation for actual dependencies): base, numeric, string, array, clip.

ModulesName Description

animate This module provides functions, constants and global variables for the implementation of animation filters.

channels This module provides functions, constants and global variables for performing operations to clip channels (extraction, merging, etc.).

edit

This module provides functions, constants and global variables for the implementation of editing filters (which allow insertion, deletion, replacement, joining, trimming, etc. of clips). In particular, the ability to specify arbitrary user-functions for the joining of edited clip's parts allows batch application of transitions and other effects (titles, etc.).

frames This module provides functions, constants and global variables for the implementation of custom per frame (runtime) filters. The module's filters thus play the role of runtime filters factory functions.

multiedit This module provides functions, constants and global variables for the implementation of multirange editing filters.

resize This module provides functions, constants and global variables for the implementation of generic resizing filters.

stack This module provides functions, constants and global variables for the implementation of generic video stacking filters.

utility This module provides functions, constants and global variables for the implementation of general purpose and utility filters that are not classified elsewhere.

Page 139: avisynth docu

The filters :: animate moduleThe filters :: animate module provides functions, constants and global variables for the implementation of animation filters.

Required modulesbase :: core, base :: conversion, string :: core, string :: search, string :: sprintf, array :: core, array :: operators, clip :: core, filters :: resize

FunctionsName Description

LineAnim() Animates a clip between a start and an end frame while in parallel it overlays it on a base ...

PolygonAnim() Animates a clip between each segment of a sequence of frames while in parallel overlays it ...

MoveOverlay() Continuously animates a clip's position and opacity between a start and end frame, while in parallel overlays it ...

ResizeOverlay() Continuously animates a clip's size between a start and end frame, while in parallel overlays it ...

ConstantsNone

VariablesNone

Page 140: avisynth docu

LineAnimModule: filters :: animate

Definition:LineAnim(clip base, clip ovl, int "f_start", int "f_end", int "x_start", int "x_end", int "y_start", int "y_end", float "op_start", float "op_end", int "w_start", int "w_end", int "h_start", int "h_end", clip "mask", string "mode", bool "greymask", string "output", bool "ignore_conditional", bool "pc_range")

Description:

Animates a clip between a start and an end frame while in parallel it overlays it on a base clip using the Overlay() standard Avisynth function. The clip is animated along with it's mask (a full white as default, if none specified), thus allowing the application of any overlay mode supported by Overlay().

The filter accepts all arguments of the Overlay() filter, thus providing a general purpose animation interface for two-point (ie linear) position, opacity and size animation between two frames.

Arguments:

base: The base clip on top of which the animated ovl clip will be overlayed.

ovl: The clip to animate and overlay on top of base clip. If "mask" is not supplied, the function creates a default full opaque (white) mask equal to the dimensions of the ovl clip.

"f_start" (Optional, defaults to 0): The frame from which the animation will start.

"f_end" (Optional, defaults to base.Framecount-1): The frame where the animation will end.

"x_start" (Optional, defaults to Round(ovl.Width/2)): The starting position of the center [1] of the animated ovl clip on the horizontal (x) axis.

Thus if x_start is not specified the left side of ovl clip will be, taking into account possible scaling, on top of the left side of base clip (same behavior with Overlay).

"x_end" (Optional, defaults to x_start): The ending position of the center of the animated ovl clip on the horizontal (x) axis.

"y_start" (Optional, defaults to Round(ovl.Height/2)): The starting position of the center [1] of the animated ovl clip on the vertical (y) axis.

Thus if y_start is not specified the top side of ovl clip will be, taking into account possible scaling, on top of the top side of base clip (same behavior with Overlay).

"y_end" (Optional, defaults to y_start): The ending position of the center of the animated ovl clip on the vertical (y) axis.

"op_start" (Optional, defaults to 1.0): The starting opacity value of the animated ovl clip.

"op_end" (Optional, defaults to op_start): The ending opacity value of the animated ovl clip.

"w_start" (Optional, defaults to ovl.Width): The starting width of the animated ovl clip.

"w_end" (Optional, defaults to ovl.Width): The ending width of the animated ovl clip.

"h_start" (Optional, defaults to ovl.Height): The starting height of the animated ovl clip.

"h_end" (Optional, defaults to ovl.Height): The ending height of the animated ovl clip.

"mask", "mode", "greymask", "output", "ignore_conditional", "pc_range": They have the same functionality as in the Overlay() standard Avisynth function. See the Avisynth documentation for details.

Page 141: avisynth docu

Notes and conditions on arguments relations:

1) From version 1.1.0 and onwards, the implementation of the filter is based on ScriptClip(), thus allowing smaller memory footprint and consequently more complex animations than the previous versions (which were using the Animate() filter).

2) The filter uses internally the Resize filter in order to execute clip resizing when needed. To control which specific Avisynth resizer will be used by the filter place a call to SetDefaultResizer with appropriate parameters before calling the filter.

Examples:

# zoom-in a clip, sliding it top-left to bottom-right # animate the first 200 frames bc = AVISource(...) # a 720x480, 600 frames clip oc = AVISource(...) # a 360x240 clip # start size: 24x16, end size: 320x240 anim = LineAnim(bc, oc, 0, 200, 12, 360+180, 8, 240+120, \ 0.0, 1.0, 24, 360, 16, 240) ... # stretch a clip, sliding it top to bottom # animate all clip frames bc = AVISource(...) # a 720x480, 600 frames clip oc = AVISource(...) # a 360x240 clip anim = LineAnim(bc, oc, x_start=360, y_start=60, y_end=240, \ w_start=720, h_start=120, w_end=180, h_end=480)

[1]: Animation filters (currently LineAnim and PolygonAnim) treat parameters specifying overlay clip's (x,y) position as if they correspond to its center and not to its top-left corner as Overlay() does.

While this may seems odd, it does make the calculation of (x,y) paths simpler because in the general case size will also be animated. If this convention was not used then at any path point a correction would had to be made for the changing size of the animated clip at both x and y.

See the tutorial "Understanding animation filters" for details. [2]: Further examples can be found at the Example Scripts section of the documentation.

Page 142: avisynth docu

PolygonAnimModule: filters :: animate

Definition:PolygonAnim(clip base, clip ovl, string f_array, val "x_array", val "y_array", val "op_array", val "w_array", val "h_array", val "mask", val "mode", val "greymask", string "output", val "ignore_conditional", val "pc_range")

Description:

Animates a clip between each segment of a sequence of frames while in parallel it overlays it on a base clip using the Overlay() standard Avisynth filter. The clip is animated on each segment along with it's corresponding mask (a full white as default, if none specified), thus allowing the application of any overlay mode supported by Overlay().

The filter accepts all arguments of the Overlay() filter, either as arrays or as single values. In the first case each frame segment has distinct values for the associated parameter; in the later case all frame segments share the same value for the associated parameter.

Thus, the filter provides a general purpose animation interface for multi-point linear (ie polygonal) position, opacity and size animation within a set of frames.

Arguments:

base: The base clip on top of which the animated ovl clip will be overlayed.

ovl: The clip to animate and overlay on top of base clip. If "mask" is not supplied, the function creates a default full opaque (white) mask equal to the dimensions of the ovl clip.

f_array: An array of ints defining the frame numbers of the end-points of each animation segment. f_array must have at least two elements.

The frame numbers must be placed in strict ascending order (ie f_array[i] < f_array[i+1] for every i) and they must all be in the range [0..base.Framecount-1].

"x_array" (Optional, defaults to Round(ovl.Width/2)): Either an array of ints with the same number of elements as f_array if varying ovl x-placement is wanted, or a single value if constant x-placement is wanted.

In the first case the x-placement of ovl is linearly animated in each segment between the specified end-point values.

In every case x_array specifies the starting position of the center [1] of the animated ovl clip on the horizontal (x) axis.

Thus if x_array is not specified the left side of ovl clip will be, taking into account possible scaling, on top of the left side of base clip (same behavior with Overlay).

"y_array" (Optional, defaults to Round(ovl.Height/2)): Either an array of ints with the same number of elements as f_array if varying ovly-placement is wanted, or a single value if constant y-placement is wanted.

In the first case the y-placement of ovl is linearly animated in each segment between the specified end-point values.

In every case y_array specifies the starting position of the center [1] of the animated ovl clip on the vertical (y) axis.

Thus if y_array is not specified the top side of ovl clip will be, taking into account possible scaling, on top of the top side of base clip (same behavior with Overlay).

"op_array" (Optional, defaults to 1.0): Either an array of floats with the same number of elements as f_array if varying ovl opacity is wanted, or a single value if constant opacity is wanted.

In the first case the opacity of ovl is linearly animated in each segment between the specified end-point values.

"w_array" (Optional, defaults to ovl.Width): Either an array of ints with the same number of elements as f_array if varying ovl width is wanted, or a single value if constant width is wanted.

Page 143: avisynth docu

In the first case the width of ovl is linearly animated in each segment between the specified end-point values.

"h_array" (Optional, defaults to ovl.Height): Either an array of ints with the same number of elements as f_array if varying ovl height is wanted, or a single value if constant height is wanted.

In the first case the height of ovl is linearly animated in each segment between the specified end-point values.

"mask" (Optional, defaults to full white mask): Either an array of clips with one less element than f_array if a distinct mask on each animation segment is wanted, or a single value if only one mask for the entire animation is wanted.

When distinct masks are provided, they are applied on a per segment basis, ie the transformation is discontinuous: mask[i] is applied on segment[i], ie on frames [f_array[i]..f_array[i+1]), mask[i+1] on segment[i+1], ie on frames [f_array[i+1]..f_array[i+2]), etc., without any smoothing transition between them.

"mode" (Optional, defaults to "blend"): Either an array of strings with one less element than f_array if a distinct overlay mode on each animation segment is wanted, or a single value if only one overlay mode for the entire animation is wanted.

When distinct modes are provided, they are applied on a per segment basis, ie the transformation is discontinuous: mode[i] is applied on segment[i], ie on frames [f_array[i]..f_array[i+1]), mode[i+1] on segment[i+1], ie on frames [f_array[i+1]..f_array[i+2]), etc., without any smoothing transition between them.

See the Overlay() documentation for the allowed values of this argument.

"greymask" (Optional, defaults to true): Either an array of bools with one less element than f_array if a distinct greymask setting on each animation segment is wanted, or a single value if only one greymask setting for the entire animation is wanted.

When distinct greymask settings are provided, they are applied on a per segment basis, ie the transformation is discontinuous: greymask[i] is applied on segment[i], ie on frames [f_array[i]..f_array[i+1]), greymask[i+1] on segment[i+1], ie on frames [f_array[i+1]..f_array[i+2]), etc., without any smoothing transition between them.

"output" (Optional, defaults to input colorspace): Has the same functionality as the corresponding argument in the Overlay() standard Avisynth function and accepts the same values.

See the Overlay() documentation for the allowed values of this argument.

"ignore_conditional" (Optional, defaults to false): Either an array of bools with one less element than f_array if a distinct ignore_conditional setting on each animation segment is wanted, or a single value if only one ignore_conditional setting for the entire animation is wanted.

When distinct ignore_conditional settings are provided, they are applied on a per segment basis, ie the transformation is discontinuous: ignore_conditional[i] is applied on segment[i], ie on frames [f_array[i]..f_array[i+1]), ignore_conditional[i+1] on segment[i+1], ie on frames [f_array[i+1]..f_array[i+2]), etc., without any smoothing transition between them.

"pc_range": (Optional, defaults to false): Either an array of bools with one less element than f_array if a distinct pc_range setting on each animation segment is wanted, or a single value if only one pc_range setting for the entire animation is wanted.

When distinct pc_range settings are provided, they are applied on a per segment basis, ie the transformation is discontinuous: pc_range[i] is applied on segment[i], ie on frames [f_array[i]..f_array[i+1]), pc_range[i+1] on segment[i+1], ie on frames [f_array[i+1]..f_array[i+2]), etc., without any smoothing transition between them.

Notes and conditions on arguments relations:

1. The last point of each segment is the first point of the next one, thus for n segments (edges) n+1 values are required for end-point settings arrays (such as f_array, x_array, etc.) while n values are required for segment properties arrays (such as mask, mode, etc.).

2. From version 1.1.0 and onwards, the implementation of the filter is based on ScriptClip(), thus allowing smaller memory footprint and consequently more complex animations than the previous versions (which were using the Animate() filter).

3. The filter uses internally the Resize filter in order to execute clip resizing when needed. To control which specific Avisynth resizer will be used by the filter place a call to SetDefaultResizer with appropriate parameters before calling the filter.

Page 144: avisynth docu

Examples:

# zoom-in a clip, sliding it from top-left to center # and then slide it top-right, to dissapear bc = AVISource(...) # a 720x480, 600 frames clip oc = AVISource(...) # a 360x240 clip f_arr = "0,100,200" xy_path = ArrayCreate(6,4, 360,240, 720+180,-120) x_arr = xy_path.ArrayDeplex(0, 2) y_arr = xy_path.ArrayDeplex(1, 2) wh_size = "12,8, 360,240, 360,240" w_arr = wh_size.ArrayDeplex(0, 2) h_arr = wh_size.ArrayDeplex(1, 2) op_arr = "0,1,1" result = PolygonAnim(bc, oc, f_arr, x_arr, y_arr, op_arr, w_arr, h_arr) ... # move a clip top->bottom->top and in parallel # stretch it on the left-right direction bc = AVISource(...) # a 720x480, 600 frames clip oc = AVISource(...) # a 360x240 clip f_arr = "0,150,300,450,599" x_arr = 360 # x is const, no need for array y_arr = "120,240,360,240,120" wh_size = "360,240, 720,120, 360,240, 720,120, 360,240" w_arr = wh_size.ArrayDeplex(0, 2) h_arr = wh_size.ArrayDeplex(1, 2) op_arr = 1 # opacity is const, no need for array # use add mode here result = PolygonAnim(bc, oc, f_arr, x_arr, y_arr, op_arr, w_arr, h_arr, mode="add")

[1]: Animation filters (currently LineAnim and PolygonAnim) treat parameters specifying overlay clip's (x,y) position as if they correspond to its center and not to its top-left corner as Overlay() does.

While this may seems odd, it does make the calculation of (x,y) paths simpler because in the general case size will also be animated. If this convention was not used then at any path point a correction would had to be made for the changing size of the animated clip at both x and y.

Page 145: avisynth docu

MoveOverlayModule: filters :: animate

Definition:MoveOverlay(clip base, clip ovl, int "f_start", int "f_end", int "x_start", int "x_end", int "y_start", int "y_end", float "opac_start", float "opac_end", clip "mask", string "mode", bool "greymask", string "output", bool "ignore_conditional", bool "pc_range")

Description:

Continuously animates a clip's position and opacity [1] between a start and end frame, while in parallel overlays it on a base clip. The clip is animated along with it's mask (a full white as default, if none specified), thus allowing the application of any overlay mode supported by Overlay().

Arguments:

base: The base clip on top of which the size animated ovl clip will be overlayed.

ovl: The clip to animate its size and overlay on top of base clip.

"f_start" (Optional, defaults to 0): The frame from which the animation will start.

"f_end" (Optional, defaults to base.Framecount-1): The frame where the animation will end.

"x_start" (Optional, defaults to Round(ovl.Width/2)): The starting position of the center [2] of the animated ovl clip on the horizontal (x) axis.

Thus if x_start is not specified the left side of ovl clip will be, taking into account possible scaling, on top of the left side of base clip (same behavior with Overlay).

"x_end" (Optional, defaults to x_start): The ending position of the center of the animated ovl clip on the horizontal (x) axis.

"y_start" (Optional, defaults to Round(ovl.Height/2)): The starting position of the center [2] of the animated ovl clip on the vertical (y) axis.

Thus if y_start is not specified the top side of ovl clip will be, taking into account possible scaling, on top of the top side of base clip (same behavior with Overlay).

"y_end" (Optional, defaults to y_start): The ending position of the center of the animated ovl clip on the vertical (y) axis.

"op_start" (Optional, defaults to 1.0): The starting opacity value of the animated ovl clip.

"op_end" (Optional, defaults to op_start): The ending opacity value of the animated ovl clip.

"mask", "mode", "greymask", "output", "ignore_conditional", "pc_range": They have the same functionality as in the Overlay() standard Avisynth function. See the Avisynth documentation for details.

Page 146: avisynth docu

Examples:

bs = AVISource(...) ov = AVISource(...) # Move from 10,10 to 320,240 # change occures between frames 20 and 100 ovs = MoveOverlay(bs, ov, 20, 100, 10, 320, 10, 240) # zoom out from 960x720 to 320x240 # scale base clip to double size to avoid clipping # (will feed result to PolygonAnim to animate position) ovp = ResizeOverlay(bs, ov, 10, 100, 960, 320, 720, 240, 2.0)

[1]: This is an intermediate filter used by LineAnim and PolygonAnim filters. Nevertheless it may be useful on certain occasions and thus it is provided as a "public" AVSLib filter. [2]: Animation filters treat parameters specifying overlay clip's (x,y) position as if they correspond to its center and not to its top-left corner as Overlay() does.

While this may seems odd, it does make the calculation of (x,y) paths simpler because in the general case size will also be animated. If this convention was not used then at any path point a correction would had to be made for the changing size of the animated clip at both x and y.

Page 147: avisynth docu

ResizeOverlayModule: filters :: animate

Definition:ResizeOverlay(clip base, clip ovl, int "f_start", int "f_end", int "w_start", int "w_end", int "h_start", int "h_end", bool "pcrange")

Description:

Continuously animates a clip's size [1] between a start and end frame, while in parallel overlays it on a base clip. The overlay is done such that the center of the overlayed clip is always on the center of the base clip, irrespectively of its size. [2]

Arguments:

base: The base clip on top of which the size animated ovl clip will be overlayed.

ovl: The clip to animate its size and overlay on top of base clip. Note that unlike other animation functions, such as LineAnim and PolygonAnim, no mask is used.

"f_start" (Optional, defaults to 0): The frame from which the size animation will start.

"f_end" (Optional, defaults to base.Framecount-1): The frame where the size animation will end.

"w_start" (Optional, defaults to ovl.Width): The starting width of the animated ovl clip.

"w_end" (Optional, defaults to ovl.Width): The ending width of the animated ovl clip.

"h_start" (Optional, defaults to ovl.Height): The starting height of the animated ovl clip.

"h_end" (Optional, defaults to ovl.Height): The ending height of the animated ovl clip.

"pcrange" (Optional, defaults to false): Has the same functionality as the pc_range argument of the Overlay() standard Avisynth function.

Notes and conditions on arguments relations:

1] The filter uses internally the Resize filter in order to execute clip resizing when needed. To control which specific Avisynth resizer will be used by the filter place a call to SetDefaultResizer with appropriate parameters before calling the filter.

Examples:

bs = AVISource(...) ov = AVISource(...) # zoom in from 10x10 to 320x240 # change occures between frames 10 and 100 ovs = ResizeOverlay(bs, ov, 10, 100, 10, 320, 10, 240) # zoom out from 960x720 to 320x240 ovp = ResizeOverlay(bs, ov, 10, 100, 960, 320, 720, 240)

[1]: This is an intermediate filter used by LineAnim and PolygonAnim filters. Nevertheless it may be useful on certain occasions and thus it is provided as a "public" AVSLib filter. [2]: The filter uses internally the generic Resize filter. Currently, there is no option to specify a resizer in the argument list and thus resizer selection (if other than the default) must be performed through explicit calls to the SetDefaultResizer() helper function before invoking the filter.

Page 148: avisynth docu

The filters :: channels moduleThe filters :: channels module provides functions, constants and global variables for performing operations to clip channels (extraction, merging, etc.).

Required modulesbase :: core, base :: conversion, array :: core, array :: operators, clip :: core

FunctionsName Description

ChannelIndex() Returns the index in a clip channels' array of the specified in ch channel ...

IsRGB24Channels() Returns true if the array channels contains the channels of a RGB24 clip...

IsRGB32Channels() Returns true if the array channels contains the channels of a RGB32 clip...

IsRGBChannels() Returns true if the array channels contains the channels of a RGB (either RGB24 or RGB32) clip...

IsYUVChannels() Returns true if the array channels contains the channels of a YUV (either YUY2 or YV12) clip...

IsYUY2Channels() Returns true if the array channels contains the channels of a YUY2 clip...

IsYV12Channels() Returns true if the array channels contains the channels of a YV12 clip...

MergeARGB() A filter for Avisynth versions up to 2.55 providing equivalent functionality with the corresponding filter of Avisynt...

MergeRGB() A filter for Avisynth versions up to 2.55 providing equivalent functionality with the corresponding filter of Avisynt...

MergeVideoChannels() Merges the clips of channels' array channels into a single clip...

MergeYUV() Merges clips clipY, clipU and clipV into a signle YUV clip...

ShowBlue() A filter for Avisynth versions up to 2.55 providing equivalent functionality with the corresponding filter of Avisynth...

ShowGreen() A filter for Avisynth versions up to 2.55 providing equivalent functionality with the corresponding filter of Avisynth...

ShowRed() A filter for Avisynth versions up to 2.55 providing equivalent functionality with the corresponding filter of Avisynth...

ShowU() A YUV filter analogus to the Show{Red/Green...

ShowV() A YUV filter analogus to the Show{Red/Green/Blue}...

ShowY() A YUV filter analogus to the Show{Red/Green/Blue}...

SplitVideoChannels() Splits a clip into an array containing the individual clip's channels (R, G, B[, A] or Y, U, V depending on clip's colorspace) ...

ConstantsNone

VariablesNone

Page 149: avisynth docu

ChannelIndexModule: filters :: channels

Definition:ChannelIndex(string ch)

Description:

Returns the index in a clip channels' array [1] of the specified in ch channel.

The ch argument must be a signle character string containing one of A, R, G, B, Y, U, V.

Examples:

redid = ChannelIndex("R") clp_red = channels.ArrayGet(redid)

[1]:See the SplitVideoChannels() function's documentation for further details.

IsRGB24ChannelsModule: filters :: channels

Definition:IsRGB24Channels(string channels)

Description:

Returns true if the array channels contains the channels of a RGB24 clip.[1]

Examples:

# TODO in a later version of AVSLib. [1]:See the SplitVideoChannels() function's documentation for further details.

IsRGB32ChannelsModule: filters :: channels

Definition:IsRGB32Channels(string channels)

Description:

Returns true if the array channels contains the channels of a RGB32 clip.[1]

Examples:

# TODO in a later version of AVSLib.

1]:See the SplitVideoChannels() function's documentation for further details.

Page 150: avisynth docu

IsRGBChannelsModule: filters :: channels

Definition:IsRGBChannels(string channels)

Description:

Returns true if the array channels contains the channels of a RGB (either RGB24 or RGB32) clip.[1]

Examples:

# TODO in a later version of AVSLib. [1]:See the SplitVideoChannels() function's documentation for further details.

IsYUVChannelsModule: filters :: channels

Definition:IsYUVChannels(string channels)

Description:

Returns true if the array channels contains the channels of a YUV (either YUY2 or YV12) clip.[1]

Examples:

# TODO in a later version of AVSLib. [1]:See the SplitVideoChannels() function's documentation for further details.

IsYUY2ChannelsModule: filters :: channels

Definition:IsYUY2Channels(string channels)

Description:

Returns true if the array channels contains the channels of a YUY2 clip.[1]

Examples:

# TODO in a later version of AVSLib. [1]:See the SplitVideoChannels() function's documentation for further details.

Page 151: avisynth docu

IsYV12ChannelsModule: filters :: channels

Definition:IsYV12Channels(string channels)

Description:

Returns true if the array channels contains the channels of a YV12 clip.[1]

Examples:

# TODO in a later version of AVSLib. [1]:See the SplitVideoChannels() function's documentation for further details.

MergeARGBModule: filters :: channels

Definition:MergeARGB(clip clipA, clip clipR, clip clipG, clip clipB)

Description:

A filter for Avisynth versions up to 2.55 providing equivalent functionality with the corresponding filter of Avisynth 2.56 and later.

The filter is a thin wrapper around the RGB Manipulate plugin developed by tsp. The later provides the core functionality of RGB channels manipulation.

Arguments:

See the Avisynth 2.56 or later documentation for argument information.

Examples:

# See the Avisynth 2.56 or later documentation for examples.

MergeRGBModule: filters :: channels

Definition:MergeRGB(clip clipR, clip clipG, clip clipB, string "pixel_type")

Description:

A filter for Avisynth versions up to 2.55 providing equivalent functionality with the corresponding filter of Avisynth 2.56 and later.

The filter is a thin wrapper around the RGB Manipulate plugin developed by tsp. The later provides the core functionality of RGB channels manipulation.

Arguments:

See the Avisynth 2.56 or later documentation for argument information.

Examples:

# See the Avisynth 2.56 or later documentation for examples.

Page 152: avisynth docu

MergeVideoChannelsModule: filters :: channels

Definition:MergeVideoChannels(string channels)

Description:

Merges the clips of channels' array channels into a single clip.

channels must be in a compatible format with that returned by SplitVideoChannels().

Examples:

"ch = SplitVideoChannels(AVISource(…)) … # process individual channels and update ch elements … proc_clip = MergeVideoChannels(ch)

MergeYUVModule: filters :: channels

Definition:MergeYUV(clip clipY, clip clipU, clip clipV)

Description:

Merges clips clipY, clipU and clipV into a signle YUV clip.

Output colorspace is determined by clipY (YUY2 if RGB/YUY2, YV12 if YV12).[1]

Notes and conditions on arguments relations:

1]: Given (w,h) dimensions of clipY, clipU and clipV dimensions must be (w/2,h) if clipY is RGB / YUY2, (w/2,h/2) if clipY is YV12.

Examples:

# See the MergeRGB() and MergeARGB() documentation for examples. [1]:All clip values are treated as pc range (they do not downscale when converting from RGB). See ShowY(), ShowU() , ShowV() documentation for details.

Page 153: avisynth docu

ShowBlueModule: filters :: channels

Definition:ShowBlue(clip c, string "pixel_type")

Description:

A filter for Avisynth versions up to 2.55 providing equivalent functionality with the corresponding filter of Avisynth 2.56 and later.

The filter is a thin wrapper around the RGB Manipulate plugin developed by tsp. The later provides the core functionality of RGB channels manipulation.

Arguments:

See the Avisynth 2.56 or later documentation for argument information.

Examples:

#See the Avisynth 2.56 or later documentation for examples.

ShowGreenModule: filters :: channels

Definition:ShowGreen(clip c, string "pixel_type")

Description:

A filter for Avisynth versions up to 2.55 providing equivalent functionality with the corresponding filter of Avisynth 2.56 and later.

The filter is a thin wrapper around the RGB Manipulate plugin developed by tsp. The later provides the core functionality of RGB channels manipulation.

Arguments:

See the Avisynth 2.56 or later documentation for argument information.

Examples:

#See the Avisynth 2.56 or later documentation for examples.

ShowRedModule: filters :: channels

Definition:ShowRed(clip c, string "pixel_type")

Description:

A filter for Avisynth versions up to 2.55 providing equivalent functionality with the corresponding filter of Avisynth 2.56 and later.

The filter is a thin wrapper around the RGB Manipulate plugin developed by tsp. The later provides the core functionality of RGB channels manipulation.

Arguments:

See the Avisynth 2.56 or later documentation for argument information.

Examples:

#See the Avisynth 2.56 or later documentation for examples.

Page 154: avisynth docu

ShowUModule: filters :: channels

Definition:ShowU(clip c, string "pixel_type")

Description:

A YUV filter analogus to the Show{Red/Green/Blue} RGB filters. It returns the c clip's U channel as a clip with pixel_type colorspace (or the original if no pixel_type is specified) [1].

Examples:

c = ColorBars().ConvertToYV12() # get U channel as a full [0..255] range RGB clip c_u = c.ColorUYV(levels="tv->pc").ShowU("RGB32")

[1]:YUV channels do not upscale if an RGB[32/24] pixel type is requested.

To return a full [0.255] range from an ordinary CCIR YUV clip you will have to manually perform ColorYUV(levels="tv->pc") before extracting the channels.

ShowVModule: filters :: channels

Definition:ShowV(clip c, string "pixel_type")

Description:

A YUV filter analogus to the Show{Red/Green/Blue} RGB filters. It returns the c clip's V channel as a clip with pixel_type colorspace (or the original if no pixel_type is specified) [1].

Examples:

c = ColorBars().ConvertToYUY2() # get V channel as a full [0..255] range RGB clip c_u = c.ColorUYV(levels="tv->pc").ShowV("RGB32")

[1]:YUV channels do not upscale if an RGB[32/24] pixel type is requested.

To return a full [0.255] range from an ordinary CCIR YUV clip you will have to manually perform ColorYUV(levels="tv->pc") before extracting the channels.

Page 155: avisynth docu

ShowYModule: filters :: channels

Definition:ShowY(clip c, string "pixel_type")

Description:

A YUV filter analogus to the Show{Red/Green/Blue} RGB filters. It returns the c clip's Y channel as a clip with pixel_type colorspace (or the original if no pixel_type is specified) [1].

Examples:

c = ColorBars().ConvertToYV12() # get Y channel as a full [0..255] range RGB clip c_u = c.ColorUYV(levels="tv->pc").ShowY("RGB32")

[1]:YUV channels do not upscale if an RGB[32/24] pixel type is requested.

To return a full [0.255] range from an ordinary CCIR YUV clip you will have to manually perform ColorYUV(levels="tv->pc") before extracting the channels.

SplitVideoChannelsModule: filters :: channels

Definition:SplitVideoChannels(clip c, string "pixel_type")

Description:

Splits clip c into an array containing the individual clip's channels (R, G, B[, A] or Y, U, V depending on c's colorspace) and (at index 0) a pixel type string description (thus the array returned is a mixed-type array).[1]

The optional pixel_type argument can be used to convert c to a different colorspace on the fly before returning the channels.

To access the channels inside the array it is best to use the ChannelIndex() helper function.

Examples:

#open a clip and split into channels converting to YV12 ch = SplitVideoChannels(AVISource(…), "YV12") # process the Y channel #don't forget to update the array yid = ChannelIndex("Y") ch.ArraySet(yid, ch.ArrayGet(yid).Levels(…)) # do further processing ... # merge channels when done rst = MergeVideoChannels(ch)

[1]:Batch processing of the entire array is still possible. Simply make the custom function to accept a val (ie any) Avisynth type and process an element only if IsClip returns true.

Page 156: avisynth docu

The filters :: edit moduleThe filters :: edit module provides functions, constants and global variables for the implementation of editing filters (which allow insertion, deletion, replacement, joining, trimming, etc. of clips).

In particular, the ability to specify arbitrary user-functions for the joining of edited clip's parts allows batch application of transitions and other effects (titles, etc.).

Required modulesbase :: core, numeric :: core, string :: core

FunctionsName Description

EditDelete() Deletes a specified number of frames from a clip, starting at a specified frame position...

EditInsert() Inserts a specified number of frames of an insert clip to a base clip, starting at a ...

EditJoin() Joins up to 50 clips sequentially. In particular, the ability to specify arbitrary user-functions...

EditReplace() Replaces a specified number of frames of a base clip with a specified number of frames ...

EditTrim() Returns a portion of a clip. It is intended as a replacement of the Trim standard Avisynth filter...

ConstantsName Description

EDOP_ADD Join clip parts after editing using UnallignedSplice (+).

EDOP_ALGN Join clip parts after editing using AllignedSplice (++).

EDOP_DISS Join clip parts after editing using Dissolve().

EDOP_USER Join clip parts after editing using a user-specified function.

VariablesNone

Page 157: avisynth docu

EditDeleteModule: filters :: edit

Definition:EditDelete(clip base, int frame, int "del_frames", int "op", string "extra_info")

Description:

Deletes a specified number of frames from a clip, starting at a specified frame position. The resulting clip will always have <= length from the base clip.

Arguments:

base: The clip to delete frames from.

frame: The frame-number to start deleting frames (ie the first frame to delete).

"del_frames" (Optional, defaults to base.Framecount ie to the end of clip): The number of frames to delete from base.

The value of del_frames is always clamp-ed between zero and base.Framecount. Thus negative values have the same effect as zero (nothing is deleted).

"op" , "extra_info" (Optional): Both have the same semantics as in EditReplace() function.

Examples:

# load a clip to c and then make it 200 frames long c = AVISource( ... ).EditTrim(0, 200) # now operate on c; use OOP notation # delete 10 frames starting from 0 (-10 decrease, 190 total) d1 = c.EditDelete(0, 10) # delete 40 frames starting from 80 (-40 decrease, 160 total) # use Dissolve() to join result parts with overlap=5 d2 = c.EditDelete(0, 10, EDOP_DISS, "5") # delete all frames to the end starting from 100 (-100 decrease, 100 total) d3 = c.EditDelete(100)

Page 158: avisynth docu

EditInsertModule: filters :: edit

Definition:EditInsert(clip base, clip inclip, int frame, int "ins_frames", int "op", string "extra_info")

Description:

Inserts a specified number of frames of an insert clip to a base clip, starting at a specified frame position. The resulting clip will always have >= length from base clip.

Arguments:

base: The clip to insert frames to.

inclip: The clip to insert frames from.

frame: The frame-number to start inserting frames (the first frame of inclip will correspond to this number in the resulting clip).

"ins_frames" (Optional, defaults to inclip.Framecount): The number of frames to insert from inclip (always starting from the begining of it).

The value of ins_frames is always clamp-ed between zero and inclip.Framecount.

Specifying zero for this argument is the same as ommiting it.

"op" , "extra_info" (Optional): Both have the same semantics as in EditReplace() function.

Examples:

# load a clip to c and d and then make them 200 frames long c = AVISource( ... ).EditTrim(0, 200) d = AVISource( ... ).EditTrim(0, 200) # now operate on c; use OOP notation # insert 10 frames of d starting from 0 (+10 increase, 210 total) i1 = c.EditInsert(d, 0, 10) # insert 50 frames of d starting from 50 (+50 increase, 250 total) # use Dissolve() to join result parts with overlap=5 i2 = c.EditInsert(d, 50, 50, EDOP_DISS, "5") # insert entire d at the end of c (+200 increase, 400 total) i3 = c.EditInsert(d, c.Framecount)

Page 159: avisynth docu

EditJoinModule: filters :: edit

Definition:EditJoin(clip c1, clip c2, clip "c3", clip "c4", .... , clip "c50", int "op", string "extra_info")

Description:

Joins up to 50 clips sequentially.

In particular, the ability to specify arbitrary user-functions for the joining allows batch application of transitions and other effects (titles, etc.).

Arguments:

c1, c2, ... , "c50" (Except c1, c2 all other are optional): The clips to join together.

"op" , "extra_info" (Optional): Both have the same semantics as in EditReplace() function.

Examples:

# load a clip to c and d and then make them 200 frames long c = AVISource( ... ).EditTrim(0, 200) d = AVISource( ... ).EditTrim(0, 200) # now join them (result is 400 frames long) j1 = EditJoin(c, d) # lets do something fancier # Blends last 10 frames of 1st clip with first 10 frames of 2nd # (this make the result 10 frames shorter than the sum of the clips) function my_join(clip c1, clip c2) { sc = c1.EditTrim(0, -10) ec = c2.EditTrim(10) mc = Overlay(c1.EditTrim(-10), c2.EditTrim(0, 10), opacity=0.5) return sc + mc + ec } # join using my_join (result is 390 frames long) j2 = EditJoin(c, d, op=EDOP_USER, extra_info="my_join")

Page 160: avisynth docu

EditReplaceModule: filters :: edit

Definition:EditReplace(clip base, clip inclip, int frame, int "ins_frames", int "rep_frames", int "op", string "extra_info")

Description:

Replaces a specified number of frames of a base clip with a specified number of frames of an insert clip, starting at a specified frame position. The operation is the sum of a "Trim" and an "Insert" and thus the resulting clip may have different length from base clip.

Arguments:

base: The clip to replace frames from.

inclip: The clip to insert frames of (ie the clip that contains the replacement frames).

frame: The frame-number to start replacing from (the frame corresponding to this number is excluded from the resulting clip).

The value of frame is clamp-ed between zero and base.Framecount. Thus, values <= 0 result in replacement starting from the start of base clip and values >= base.Framecount in addition of inclip (trimmed to ins_frames length) to the end of base.

"ins_frames" (Optional, defaults to inclip.Framecount): The number of frames to insert from inclip (always starting from the begining of it).

The value of ins_frames is always clamp-ed between zero and inclip.Framecount.

Specifying zero for this argument is the same as ommiting it.

"rep_frames" (Optional, defaults to processed value of ins_frames): The number of base clip frames to replace.

The value of rep_frames is always clamp-ed between zero and Max(0, base.Framecount - frame), ie maximum available frames after frame. Thus, if the replacement is requested near the end of base clip, the replaced frames may be less than ins_frames.

Specifying zero for this argument is the same as ommiting it.

"op" (Optional): The operation to perform for joining the resulting clip parts after trimming the initial clips.

Accepts one of the EDOP_xxx constants, defined at the filters::edit module. If not supplied, defaults to EDOP_ADD, ie join with UnallignedSplice(), the "+" clip operator.

"extra_info" (Optional, defaults to ""): Additional information to pass when the op argument is one of EDOP_DISS (join with Dissolve()) or EDOP_USER (join with a user-supplied function).

In the first case it must be a string representation of an integer, which has the same meaning as the overlap argument in the Dissolve() standard Avisynth function.

In the second case it must be the name of the user-supplied function.

Page 161: avisynth docu

Examples:

# load a clip to c and d and then make them 200 frames long c = AVISource( ... ).EditTrim(0, 200) d = AVISource( ... ).EditTrim(0, 200) # now operate on c; use OOP notation # replace 90 frames starting from 0 with 10 frames of d (-80 decrease, 120 total) r1 = c.EditReplace(d, 0, 10, 90) # replace 50 frames starting from 100 with 50 frames from d (same length, 200 total) r2 = c.EditReplace(d, 100, 50) # replace all frames to the end starting from 120 with entire d (+120 increase, 320 total) r3 = c.EditReplace(d, 120)

Page 162: avisynth docu

EditTrimModule: filters :: edit

Definition:EditTrim(clip base, int fstart, int "fend", int "fcount")

Description:

Returns a portion of a clip. It is intended as a replacement of the Trim standard Avisynth function, providing a more flexible and easier to use behavior.

Arguments:

base: The clip to trim.

fstart: The frame to start trimming from.

Negative values are allowed and specify the offset from the end of the clip (ie -10 means " start from the frame 10 positions before the end of clip").

"fend" (Optional, defaults to base.Framecount): The frame to end trimming. The end frame does not get included in the result ie the function always returns the frame interval [fstart..fend).

Negative values are allowed and specify the offset from the end of the clip (ie -10 means "stop at frame 10 positions before the end of clip").

"fcount" (Optional, defaults to zero): The number of frames to include in the result. Accepts only values >= 0 (when zero a null clip (length=0) is returned).

Notes and conditions on arguments relations:

1. fend and fcount are mutually exclusive. If both are supplied the function throws an error.

2. If both fend and fcount are ommited the function returns all frames from fstart to the end of clip.

3. If after processing negative indices and converting fcount (if supplied) to an equivalent fend value, fstart >= fend the function returns a null clip (length=0).

4. If fend is set to zero the function returns a null clip (length=0), since then the processed fstart will be >= fend (see note above).

Page 163: avisynth docu

Examples:

# load a clip to c and then make it a 200 frames clip c = AVISource( ... ).EditTrim(0, 200) # now operate on c; use OOP notation fc = c.Framecount # get frames from 20 to 100, number 20-99 (100 is not included) t0 = c.EditTrim(20, 100) # get the first frame only t1 = c.EditTrim(0, 1) # get the last frame only t2 = c.EditTrim(-1) # same as c.EditTrim(fc-1, fc) # get 5 frames from the end, number 195-199 t3 = EditTrim(c, -5) # get 15 frames starting 5 frames from the end # actually only 5 frames will be retrieved, number 195-199 t4 = c.EditTrim(-5, fcount=15) # get frames from 20 before end up to 10 frames before end, number 180-189 t5 = c.EditTrim(-20, -10) # get 100 frames from -300 before end, number (-100)-(-1) # since no frame of c is in that range a null clip (length=0) is returned t6 = c.EditTrim(-300, fcount=100) # this is also happens if a zero fcount is supplied or fstart==fend t7 = c.EditTrim(25, fcount=0) t8 = c.EditTrim(25, 25)

Page 164: avisynth docu

The filters :: frames moduleThe filters :: frames module provides functions, constants and global variables for the implementation of multirange editing filters.

Required modulesbase :: core, string :: core, string :: search, string :: sprintf, array :: core, array :: operators, filters :: utility

FunctionsName Description

FrameFilter() Applies a (filter) script to each frame of clip orig. The script has in its disposal all runtime variables and functions (current_frame, AverageLuma, etc.) plus the following text-substitution literals...

FrameFilterReader() Applies a (filter) script to each frame of a clip like FrameFilter() but in addition allows use of (any number of) ConditionalReader-style text files for setting auto-generated global variables inside the script...

ConstantsNone

VariablesNone

Page 165: avisynth docu

FrameFilterModule: filters :: frames

Definition:FrameFilter(clip orig, string script, val "p1", val "p2", val "p3", val "p4", ..., val "p50", string "vars", bool "show", bool "after_frame")

Description:

Applies a (filter) script to each frame of clip orig. The script has in its disposal all runtime variables and functions (current_frame, AverageLuma, etc.) plus the following text-substitution literals:

• Any number of the literals ${var1}, ${var2}, ..., for specifying named arguments to the script. They are substituted with StrReplace inside the script string and are supplied by the vars argument array.[1]

• Up to 50 positional arguments (%? placeholders, as defined in StrPrint). They are supplied by the filter's p1,...,p50 arguments.[2]

For any text-substitution literal contained inside the script, there must be a corresponding p1...p50 argument or element of the vars array, else the filter will fail with a ScriptClip error message.

Arguments:

orig: The clip on which ScriptClip with the script resulting from substitution of arguments on script will be called.

script: The runtime script on which textual substitution with filter's variable's arguments will be performed. The script will then be passed internally by the filter to the ScriptClip standard Avisynth filter.

Typically script will be a multiline string surrounded by triple double quotes ("""); this allows to write naturally double quoted strings inside the script, as one does in a normal Avisynth script; but this is not enforced.

"p1", ..., "p50" (optional, default to none): Positional arguments to be passed to script. Their values will be substituted to the script text with the aid of StrPrint. Positional means that the arguments have to be supplied with the same order that StrPrint-compatible %? placeholders appear inside the script's text.

vars (optional, defaults to none): An array of values/variables/globals to be passed to script. They will replace all occurences of the correspondind ${varI} literals (I being their 1-based index in the array; be aware that AVSLib arrays are zero-based indexed) inside script.

Names of globals should be quoted inside the vars array in order to be treated as variables and not as values; use StrQuote when inserting the element to the array.

show and after_frame (optional): They have the same meaning as in ScriptClip standard Avisynth filter. See the later's documentation for details.

Page 166: avisynth docu

Examples:

... LoadModule("avslib", "base", "constants") LoadModule("avslib", "filters", "frames") # a not-so-elegant dynamic brightness adjustment ( target_luma, threshold, filename ) FF_DYNAMIC_BRIGHTNESS = """ target_luma = %i th = %i logfile = %q avg_luma = AverageLuma() excess_luma = avg_luma - target_luma logfile != "" \ ? WriteFile(logfile, "current_frame", "TAB", "avg_luma", "TAB", "excess_luma", "TAB", "th") \ : last Abs(excess_luma) > th ? Tweak(bright=-Sign(excess_luma)*(Abs(excess_luma) - th)) : last """ clp = AviSource(...) FrameFilter(clp, FF_DYNAMIC_BRIGHTNESS, 46, 4, "dyn-bri_log.txt")

[1]: "named" arguments can be contained any times desired inside script. All occurences will be replaced in one step, with the same textual value, as it is supplied by the corresponding element of vars. [2]: If you need to include a positional argument more than one time inside the script you will either have to assign it once to a local script variable and use the variable afterwards or supply it at the p1,...,p50 part of the filter's argument list as many times and in the correct order as defined inside script.

Page 167: avisynth docu

FrameFilterReaderModule: filters :: frames

Definition:

FrameFilterReader(clip orig, string script, string filenames, val "p1", val "p2", val "p3", val "p4", ..., val "p50", string "vars", bool "show", bool "after_frame")

Description:

An extension of the FrameFilter filter. Applies a (filter) script to each frame of clip orig. The script has in its disposal:

• all runtime variables and functions (current_frame, AverageLuma, etc.), plus • all the text-substitution literals accepted by FrameFilter, plus • the text-substitution literals ${read1}, ${read2}, ..., ${readN}, N == filenames.ArrayLen.

The later are replaced by FrameFilterReader with the actual auto-generated global variables' names whose values are set internally by the filter from external files passed in (their path) as elements of filenames with ConditionalReader. [1]

For any text-substitution literal contained inside the script, there must be a corresponding p1...p50 argument or element of the vars or filenames arrays, else the filter will fail.

Arguments:

filenames is a CR/LF delimited array of filenames (each filename in a single line). Thus, it is the same as a multi-line string.

It contains the names of files with ConditionalReader-compatible format that set the variables corresponding to the ${readI} literals. The type and value of each ${readI} can be anything that suits your script and is supported by ConditionalReader; it just has to be the same type as that declared in the text file.

orig, script, "p1", ..., "p50", vars, show and after_frame: See the documentation of FrameFilter.

Notes and conditions on arguments relations:

1] If filenames == "", ConditionalReader will not be used by FrameFilterReader. A call with a zero-length filenames array is the same as calling FrameFilter (provided there are no ${readI} literals in the script).

Page 168: avisynth docu

Examples:

... LoadModule("avslib", "array", "core") LoadModule("avslib", "filters", "frames") # a simple per-frame filter mixer ( filtered ) FF_MIX = """ filtered = %q ${read1} > 0 ? Eval(filtered.ArrayGetString(${read1} - 1)) : last """ src = AviSource(...) ft1 = src.Levels(0,0.95,250,0,255).SubTitle("ft1") # SubTitle() is for illustration ft2 = src.Levels(0,1.05,255,10,252).SubTitle("ft2") ft3 = src.Levels(10,1.15,255,0,255).SubTitle("ft3") FrameFilterReader(src, FF_MIX, "mix.txt", ArrayCreate(ft1, ft2, ft3)) # a sample mix.txt contents (ignore # at the begining): # type int # default 0 # R 10 35 1 # R 45 48 2 # R 49 53 1 # R 105 123 3

[1]: ${readI} literals can be contained any times desired inside script. All occurences will be replaced in one step, with the same textual value, as it is supplied by the corresponding text file (through the auto-generated global variables).

Page 169: avisynth docu

The filters :: multiedit moduleThe filters :: multiedit module provides functions, constants and global variables for the implementation of multirange editing filters.

Required modulesbase :: core, array :: operators, filters :: edit

FunctionsName Description

EditTrimRange() Trims a number of ranges of frames from clip c and returns them as a single clip. Joining of ranges is performed by the EditJoin filter, supporting all of its features...

ConstantsNone

VariablesNone

Page 170: avisynth docu

EditTrimRangeModule: filters :: multiedit

Definition:EditTrimRange(clip c, string fs, val "fe", int "op", string "extra_info")

Description:

Trims a number of ranges of frames from clip c and returns them as a single clip. Joining of ranges is performed by the EditJoin filter, supporting all of its features.

Selected ranges can have the same or different lengths, depending on the values of fs, fe and (possibly) on custom joining user-code. [1]

Arguments:

c: The clip to extract frame ranges from.

fs: An array of frame numbers indicating the start of the frame ranges to be extracted.

fe (optional): An array or a single value (a scalar) indicating the first frame past the end of ranges to be extracted.

If fe is a scalar value, it is interpreted as the number of frames to extract from each range. Thus, the ith range selected will be [fs(i)..fs(i)+fe).

If fe is not provided it defaults to a scalar value equal to 1. Thus, the ith range selected will be [fs(i)..fs(i)+1), ie only the frames contained in fs will be selected.

If fe is an array, it must have the same length as fs and then each element of fe is interpreted as the first frame past the end of the corresponding range. Thus, the ith range selected will be [fs(i)..fe(i)).

op, extra_info (optional): See the documentation of the EditJoin filter.

Examples:

clp = AviSource(...) ... # select frames [12..21]+[345..354]+[1024..1033]+[4356..4365] # use AllignedSplice (++) to join fs = "12,345,1024,4356" sel1 = clp.EditTrimRange(fs, 10, EDOP_ALGN) ... # select just the frames 12+345+1024+4356 # use UnallignedSplice (+) to join fs = "12,345,1024,4356" sel2 = clp.EditTrimRange(fs) ... # select frames [12..339]+[345..811]+[1024..3566]+[4356..6744] # join parts using Dissolve(p1, p2, 10) fs = "12,345,1024,4356" fe = "340,812,3567,6745" sel3 = clp.EditTrimRange(fs, fe, EDOP_DISS, "10")

[1]: For selecting single-frame ranges or constant-size ranges without any special join operation, the use of the standard Avisynth filters SelectEvery / SelectRangeEvery may be more appropriate.

Page 171: avisynth docu

The filters :: resize moduleThe filters :: resize module provides functions, constants and global variables for the implementation of generic resizing filters.

Required modulesstring :: core, string :: sprintf, numeric :: rounding, array :: properties, clip :: core

FunctionsName Description

GetDefaultResizer() Returns the current default resizer that is used by the Resize... family of filters...

Resize() A generic resize filter. Uses any of the standard Avisynth resize filters, either set previously by a call to ...

ResizeToFit() Resizes clip c such that it fits inside the rectangle specified by width target_w and height target_h...

ResizeToTarget() Resizes base clip to the same dimensions that target clip has, ...

SetDefaultResizer() Sets the default resizer that is used by the Resize... family of filters when the...

ConstantsName Description

RTF_ZOOM A ResizeToFit() filter-specific constant. Orders that the clip to be resized will be zoomed (in or out) to match the desired dimensions. Clip's aspect ratio will be preserved, but black bars to fill the remaining space, if any, may appear.

RTF_CROP A ResizeToFit() filter-specific constant. Orders that the clip to be resized will be zoomed so that it covers the entire area set by the desired dimensions; parts that fall out will be cropped. Clip's aspect ratio will be preserved.

RTF_STRETCH A ResizeToFit() filter-specific constant. Orders that the clip to be resized will be stretched to fit exactly the desired dimensions. Clip's aspect ratio may change as a result.

VariablesNone

Page 172: avisynth docu

GetDefaultResizerModule: filters :: resize

Definition:GetDefaultResizer(bool "with_params")

Description:

Returns the current default resizer that is used by the Resize... family of filters when the resizer parameter does not explicitly be supplied to them.

If with_params is true then any additional parameters used by the resizer are returned as well, in the order supplied to SetDefaultResizer(), making the return value an array [1]. Else a single string is returned.

Examples:

oldrsz = GetDefaultResizer(true) … items = oldrsz.ArrayLen dummy = SetDefaultResizer(oldrsz.ArrayGet(0), (items > 1 ? oldrsz.ArrayGet(1) : Undef()), (items > 2 ? oldrsz.ArrayGet(2) : Undef()))

[1]: If the current resizer does not require any additional parameters an array of length 1 (ie a simple string) is returned.

Page 173: avisynth docu

ResizeModule: filters :: resize

Definition:Resize(clip c, int target_width, int target_height, float "src_left", float "src_top", float "src_width", float "src_height", string "resizer", val "rsz_param1", val "rsz_param2", bool "interlaced")

Description:

A generic resize filter. Uses any of the standard Avisynth resize filters, either set previously by a call to SetDefaultResizer() or directly requested through the resizer argument.

Useful when full flexibility regarding the specific resizer used is wanted (for example in library functions or modules). Moreover, since it is implemented in C++, the speed penalty from using the filter compared to a standard Avisynth resizer is negligible.

Arguments:

c, target_width, target_height and (optional) src_left, src_top, src_width, src_height: Same as the corresponding standard Avisynth ResizeXXX filters' arguments.

resizer, rsz_param1, rsz_param2 (Optional): See the SetDefaultResizer() documentation.

interlaced (Optional, defaults to false): Set it to true if the clip c is an interlaced one.

Notes and conditions on arguments relations:

1] The filter always returns a clip with the correct width and height for its colorspace (taking also into account the value of interlaced argument), regardless of the values of target_width, target_height. This makes it especially suitable for size animation, since it does not produces errors for intermediate values of those parameters.

2] If a very small width or height (down to zero) is requested, the filter does not throw an error as the standard Avisynth resizers do, but instead it uses Crop to achieve the requested dimensions (zero results in the least dimension supported by the clip's colorspace). Condition 1] above applies also in this case.

The actual (width,height) threshold values where a call to Crop is triggered are (12,8), respectively. These are higher by 4 from the minimum allowable values of standard Avisynth resizers in order to provide improved resistance in generation of errors from GetResamplingPattern when very steep resize ratios are requested from resizers with large support value.

3] The library default resizer (the one that is used when no resizer argument is passed to the filter and no calls to SetDefaultResizer() have been made previously) is BilinearResize.

Examples:

c = AVISource(…) # resize with current / default resizer d = c.Resize(720, 480) # do a bicubic resize (b=0, c=1/2) e = c.Resize(720, 480, resizer="Bicubic", rsz_param1=0, rsz_param2=1/2) ... # make bicubic, b=0, c=1/2 the default dummy = SetDefaultResizer("Bicubic", 0, 1/2) f = c.Resize(720, 480) # now f == e

Page 174: avisynth docu

ResizeToFitModule: filters :: resize

Definition:

ResizeToFit(clip c, int target_w, int target_h, int "mode", string "resizer", val "rsz_param1", val "rsz_param2", bool "interlaced")

Description:

Resizes clip c such that it fits inside the rectangle specified by width target_w and height target_height.

There are three possible resize modes (zoom, crop, stretch) that are selected by using proper values for the mode argument (one of the constants RTF_ZOOM, RTF_CROP, RTF_STRETCH defined at the filters::resize module).

Default mode is zoom (the clip is zoomed so that it fits in at least one of its dimensions to the target rectangle). This mode may make the result to have black borders (either horizontal or vertical). Aspect ratio is retained.

In crop mode the clip completely covers the target rectangle possibly leaving out some parts by cropping. Aspect ratio is retained.

In stretch mode the clip may change aspect ratio since then it is forced to fit the target rectangle in both dimensions.

Arguments:

c: The clip to be resized.

target_w: The target width to resize the clip. If it is zero, then the clip's width will remain unaltered.

target_h: The target height to resize the clip. If it is zero, then the clip's height will remain unaltered.

mode (optional): Controls the way that clip c will be resized to fit the target dimensions (see above).

resizer, rsz_param1, rsz_param2, interlaced (optional): Have the same function as the Resize() filter.

Notes and conditions on arguments relations:

1] If target_w, target_h do not have a value appropriate for the clip's colorspace the filter will throw an error.

2] In both zoom and crop modes the clip is centered to the target rectangle. Thus two black bars will appear (zoom mode) and two slices will be croped out (crop mode) in either side of the specific clip dimension chosen by the filter.

3] The filter uses internally the Resize filter in order to execute clip resizing when needed. To control which specific Avisynth resizer will be used by the filter place a call to SetDefaultResizer with appropriate parameters before calling the filter.

Examples:

clp = AVISource(...) # zoom to fit inside a 360x240 rectangle; use Lanczos4Resize c1 = clp.ResizeToFit(360, 240, resizer="lanczos4") # from now on use Spline36Resize old = SetDefaultResizer("spline36") # crop to fit inside a 360x240 rectangle c2 = clp.ResizeToFit(360, 240, RTF_CROP) # stretch to fit inside a 360x240 rectangle c3 = clp.ResizeToFit(360, 240, RTF_STRETCH) # stack results Stack(ArrayCreate(c1, c2, c3), 2, 2)

Page 175: avisynth docu

ResizeToTargetModule: filters :: resize

Definition:ResizeToTarget(clip base, clip target, string "resizer", val "rsz_param1", val "rsz_param2", bool "interlaced")

Description:

Resizes base clip to the same dimensions that target clip has, possibly with a colorspace conversion.

The later is done only if calling the Resize filter to adjust dimensions would crash Avisynth (at least on some versions) or would result in an error dialog box. This on turn depends both on base's and target's colorspaces and on target's dimensions.

Arguments:

resizer, rsz_param1, rsz_param2, interlaced (optional): Have the same function as the Resize() filter.

Notes and conditions on arguments relations:

1] The filter uses internally the Resize filter in order to execute clip resizing when needed. To control which specific Avisynth resizer will be used by the filter place a call to SetDefaultResizer with appropriate parameters before calling the filter.

2] If target is a badly cropped (for its colorspace) source or if a wrong interlaced argument is passed to the filter, the final dimensions of the returned clip may deviate slightly from the dimensions of target clip, due to the behavior of the Resize filter. This is however a condition that is not encountered in normal use situations.

Examples:

c = AVISource(...) #default to lanczos resizing with Avisynth-default taps dummy = SetDefaultResizer("lanczos") d = AVISource(...) d = d.ResizeToTarget(c) # d now has same dimensions as c (with the only possible # exception of c being a badly cropped source)

Page 176: avisynth docu

SetDefaultResizerModule: filters :: resize

Definition:SetDefaultResizer(string resizer, val "rsz_param1", val "rsz_param2")

Description:

Sets the default resizer that is used by the Resize... family of filters when the resizer parameter does not explicitly be supplied to them.

Thus, SetDefaultResizer is the master mechanism for the user to control which resizer a filter will use; simply place a call to SetDefaultResizer with adequate arguments before calling the resizing filter.

Note that since Resize is used internally by many AVSLib filters (such as for example LineAnim, StackToFit, etc.), setting the resizer with SetDefaultResizer affects any subsequent calls to those filters in the script.

Arguments:

resizer: The name of the resizer. One of "Bicubic", "Bilinear", "Lanczos", "Lanczos4", "Spline16", "Spline32", "Gauss" or "Point" ie the first part of a specific Avisynth resize filter. Passing the entire filter name of the resizer is also supported.

rsz_param1, rsz_param2 (Optional): Additional parameters needed by the resizer (for example b, c for BicubicResize, taps from LanczosResize, etc.); see Avisynth documentation for details.

Notes and conditions on arguments relations:

1] After a call to SetDefaultResizer, all subsequent invocations of any of the Resize... family of filters (and thus any filter also that uses them internally) will use the resizer specified, until the next call to SetDefaultResizer (unless of course specific values are passed to them as arguments).

2] The initial library default for resizer is "Bilinear". This is the resizer that will be used if no call to SetDefaultResizer has been made inside the script.

Examples:

#default to bicubic resizing with b=0, c=1/2 dummy = SetDefaultResizer("Bicubic", 0, 1/2) # now call a filter that uses Resize clip2 = clip1.ResizeToFit(720, 480, RTF_ZOOM)

Page 177: avisynth docu

The filters :: stack moduleThe filters :: stack module provides functions, constants and global variables for the implementation of generic video stacking filters.

Required modulesbase :: core, base :: conversion, array :: core, array :: slices, array :: operators, array :: transforms, array :: properties, string :: core, string :: sprintf, clip :: core, clip :: arrays, filters :: resize

FunctionsName Description

Stack() Stacks the clips contained in clips array to a nrows x ncols matrix ...

StackToFit() Stacks the clips contained in clips array to a rectangular matrix such as the resulting clip has target_w width and target_h height. The clips...

ConstantsNone

VariablesNone

Page 178: avisynth docu

StackModule: filters :: stack

Definition:Stack(string clips, int nrows, int ncols)

Description:

Stacks the clips contained in clips array to a nrows times ncols matrix [1].

Notes and conditions on arguments relations:

1] If the number of clips array elements is less than the product of nrows with ncols the filter fills the remaining cells with black clips.

2] If the number of clips array elements is greater than the product of nrows with ncols the filter discards the last excess elements of clips array.

Examples:

c1 = AVISource(…) c2 = AVISource(…) c3 = AVISource(…) c4 = AVISource(…) a = ArrayCreate(c1,c2,c3,c4, c2,c1,c4,c3, c3,c4,c1,c2, c4,c3,c2,c1) return Stack(a, 4, 4)

[1]: All clips must have same properties (width, height, fps, etc.) else a related Avisynth error will be thrown.

Page 179: avisynth docu

StackToFitModule: filters :: stack

Definition:StackToFit(string clips, int target_w, int target_h, int "mode", string "pixel_type", clip "audio", string "resizer", val "rsz_param1", val "rsz_param2", bool "interlaced")

Description:

Stacks the clips contained in clips array to a rectangular matrix such as the resulting clip has target_w width and target_h height. The clips contained in clips array are enlarged or shrinked as necessary.

Clips are converted to the dominant colorspace, unless a specific setting is enforced by the pixel_type argument.

The output clip has the audio of the first clip, unless a clip is passed in by the audio argument.

Clips must have the same framerate, else an error occurs. They can though have different dimensions.

Arguments:

mode (optional): Has the same function as the ResizeToFit() filter for each individual clip in the matrix [1].

resizer, rsz_param1, rsz_param2, interlaced (optional): Have the same function as the Resize() filter.

Notes and conditions on arguments relations:

1] The filter uses internally the Resize filter in order to execute clip resizing when needed. To control which specific Avisynth resizer will be used by the filter place a call to SetDefaultResizer with appropriate parameters before calling the filter.

Examples:

clp = ArrayCreate(AVISource(.), ..., AVISource(.)) ... stack in a 720x480 clip, without changing aspect ratio or cropping black areas between clips may appear c1 = StackToFit(clp, 720, 480, RTF_ZOOM) stack in a 720x480 clip, without changing aspect ratio and without allowing for black areas between clips; take audio from 2nd clip c2 = StackToFit(clp, 720, 480, RTF_CROP, audio=clp.ArrayGet(1)))

[1]: Each clip of the array resizes individually within the bounds calculated by the partitioning of the target_w x target_h rectangle to cells with mode supplied by the mode argument (zoom, crop, stretch - default is zoom). Thus, clips are allowed to have different dimensions and aspect ratios.

Page 180: avisynth docu

The filters :: utility moduleThe filters :: utility module provides functions, constants and global variables for the implementation of multirange editing filters.

Required modulesbase :: core, clip :: core, array :: core

FunctionsName Description

ConvertToTarget() Converts a clip to a target clip's colorspace...

FilterChain() Applies a filter successively on a clip (thus, implements a chain of filters), each time with the same arguments, a specified number of times...

FilterVarChain() Applies a filter successively on a clip (thus, implements a chain of filters), possibly with different arguments for each specific subgroup of the chain, a specified number of times...

ScaleToPC() Scales a clip to PC range ([0..255]) if it is YUV. Else returns it unchanged...

ScaleToTV() Scales a clip to CCIR range ([16..235]) if it is YUV. Else returns it unchanged...

ConstantsNone

VariablesNone

Page 181: avisynth docu

ConvertToTargetModule: filters :: utility

Definition:

ConvertToTarget(clip base, clip target)

Description:

Converts base to target's colorspace.

Examples:

ct = AVISource(...).ConvertToYV12 cb = AVISource(...) cb = cb.ConvertToTarget(ct) # now cb is YV12

FilterChainModule: filters :: utility

Definition:FilterChain(clip c, string filter, int times, string "fparams")

Description:

Applies filter with arguments (c, fparams) times times. fparams must contain the arguments to be passed to filter as an argument list (separated with commas).

Notes and conditions on arguments relations:

1]: If fparams is not supplied or is "" then filter is called with clip c as its sole argument.

2]: If times is zero or less the filter returns c unmodified.

3]: The first filter's argument (clip c) must not be included in fparams.

Examples:

# make a large gaussian blur by applying Blur 100 times clp = clp.FilterChain("Blur", 100, "1.57") # Reduce by 16 clp = clp.FilterChain("Reduceby2", 4)

Page 182: avisynth docu

FilterVarChainModule: filters :: utility

Definition:FilterVarChain(clip c, string filter, string var_times, string var_params)

Description:

Applies filter with varying arguments on each call with a varying number of times for each call.

Arguments:

c: The clip to apply filter to.

filter: The filter to apply to clip c. It can be a built-in or plugin filter or any user-defined function.

var_times: An array whose elements is the number of times to apply filter with the parameters contained at the corresponding var_params array's element.

var_params: A CR/LF delimited array (ie a multiline Avisynth string) containing at each line the arguments to be passed to filter as an argument list (separated with commas).

Notes and conditions on arguments relations:

1]: If for a filter 's invocation the associated element of var_params is "" then filter is called with clip c as its sole argument.

2]: If for a filter 's invocation the associated element of var_times is zero or less, the filter is not applied for that invocation.

3]: The first filter's argument (clip c) must not be included in var_params's elements.

Examples:

# trim-out ranges [50..100), [150..175), [200..225), [500..537) # apply a dissolve in the last trim-out # note that ops are applied successively, thus framenumbers # must be recalculated on each invocation vars = """50,25 100,25 125,25 400,37,EDOP_DISS,"10" """ clp = AviSource(...) clp2 = FilterVarChain(clp, "EditDelete", "2,1,1,1", vars)

ScaleToPCModule: filters :: utility

Definition:ScaleToPC(clip c)

Description:

Scales c to PC range ([0..255]) if it is YUV. Else returns it unchanged.

Examples:

c = AVISource(...) mask = c.ScaleToPC()

Page 183: avisynth docu

ScaleToTVModule: filters :: utility

Definition:ScaleToTV(clip c)

Description:

Scales c to CCIR range ([16..235]) if it is YUV. Else returns it unchanged.

Examples:

c = AVISource(...) mask = c.ScaleToPC() ... mclp = mask.ScaleToTV()

Page 184: avisynth docu

Installation Instructions

Downloading the right version of AVSLibAVSLib distributions will be either production versions or alpha or beta versions of the library. Alpha and beta versions will always include a notice about this fact (the terms "alpha" or "beta" inside parentheses as part of the name of the distribution). All other distributions not containing such a notice will always be production versions of the library.

In general, unless you want to participate in the testing of AVSLib or you are a developer of extensions to AVSLib, you should download the latest production or beta version (the one with the larger version number) from the AVSLib download page.

Installing AVSLibFrom version 1.1.0 AVSLib comes with a full featured installer. A source-only distribution is also provided for manual installation, in case anyone faces a problem with the installer.

Standard (recommended) installation procedureThe standard installation procedure is very simple; download and run the installer, then follow the on screen instructions.

Manual installation procedure1. Unpack the entire contents of the downloaded source-only distribution's archive to the selected

destination folder in your hard drive. Be sure to check that unpacking will recreate the archived contents folder structure.

2. Open the destination folder with Windows Explorer and locate the files loader.avsi and avslib.avsi. 3. Open the file avslib.avsi in a text editor. 4. Enter at the end of the last line (the one containing "__LIBROOT_AVSLIB = ") the full path to the

destination folder where you had unpacked the distribution in step 1. Don' t forget to surround the path with double quotes!

5. Save the modified file. 6. Copy loader.avsi and avslib.avsi to Avisynth's plugins folder (the one that is used for plugin autoloading). 7. (Optionally) create a shortcut to the AVSLib documentation on your desktop.

Using AVSLibTo use AVSLib, load into your scripts the modules that contain the desired functionality. You can use any combination of the LoadLibrary(), LoadPackage() and LoadModule() functions for this. See the packages documentation to locate the modules that contain the filters and functions you want to use.

With LoadLibrary(), which loads entire parts of the AVSLib library, you can use the following predefined constants:

• CONFIG_AVSLIB_FULL : Loads the entire AVSLib library. • CONFIG_AVSLIB_SCRIPT : Loads only scripting enhancements (the base, numeric, string and debug

packages (and any required by them modules). • CONFIG_AVSLIB_ARRAYS : Loads only the array package (and any required by them modules). • CONFIG_AVSLIB_FILTERS : Loads only the filters and clip package (and any required by them

modules).

The preferred place in your script to place the calls to the load functions is the begining, but this is not necessary. As long as you load the modules before using their functions, you can put the calls to LoadLibrary(), LoadPackage() and LoadModule() anywhere in your script.

Page 185: avisynth docu

Solving installation problemsIf the installer encounters problems during the installation, it will notify you of these. Workaround the pointed out problems and rerun the installer.

If your problem persists, check if a solution is described at the FAQs section of the documentation, or post a support request at the Help / Support AVSLib project's forum.

You may also try the manual installation procedure from the source-only distribution described above.

Uninstalling AVSLib

Standard (recommended) installation procedureRun the uninstaller and follow the on screen instructions.

Manual installation procedure• Delete the destination folder where you have had unpacked the AVSLib distribution. • Delete loader.avsi and avslib.avsi to Avisynth's plugins folder (the one that is used for plugin

autoloading).

Page 186: avisynth docu

FAQs

General questions

1. What is AVSLib?AVSLib is an extension library for the Avisynth script language. It offers a general-purpose toolkit to

Avisynth script developers for enhancing their ability to perform complex linear and non-linear video editing tasks (such as creating timelines, editing and animating clips, etc.) as well as tools to debug scripts, a rich set of functions to handle script variables, new datatypes (arrays and maybe later matrices and dictionaries) and many more.

2. What makes AVSLib different from other plugins I have found for Avisynth?

AVSLib is a script language extension library. It provides general-purpose code objects (functions, constants, custom datatypes, etc.) that extend the features offered to script developers from the host script language.

To state it in other words, most plugins concentrate on the fulfillment of a specific (usually narrow) set of tasks, while AVSLib concentrates on providing the "glue" that allows effective scripting of both Avisynth's standard tools and plugins.

3. What are the licencing terms of AVSLib?See the licence page for information.

4. Where can I download the latest version of AVSLib?Both the latest and older versions of AVSLib are available from the AVSLib project page at SourceForge.

5. Where can I find documentation for AVSLib?You can find documentation for AVSLib in the following places:

* Inside each installation package that is available for download from the AVSLib project page .

* Online, at the AVSLib home page.

6. What are the plans for the future?See the AVSLib project's roadmap.

Page 187: avisynth docu

Installation

1. How do I install AVSLib?Installation instructions are provided at a separate page of the documentation.

2. How do I install multiple versions of AVSLib?You just install them in different folders and use the proper importing mechanism of each version in your

scripts.

Note that 1.0.x and 1.1.x importing mechanisms are completely different.

For example:

Suppose you want to install versions 1.0.0 and 1.1.0 under the C:\Program Files\AVSLib\ main folder. You may choose the following destinations for each of the above distributions:

* C:\Program Files\AVSLib\version_1-0-0

* C:\Program Files\AVSLib\version_1-1-0

Now in order to use each version in you scripts (assuming full features are wanted), you will add the following line into your script:

Version 1.0.0:

Import("C:\Program Files\AVSLib\version_1-0-0\headers\avslib-h.avsi")

Version 1.1.0:

LoadLibrary("avslib", CONFIG_AVSLIB_FULL)

3. I want a partial install of AVSLib, how can it be accomplished?There is no need for a partial install. From version 1.1.0 and later AVSLib allows selective loading into

your scripts of only the desired features, through the use of the loader module.

See the LoadModule(), LoadPackage() and LoadLibrary() documentation for details. Also the "Using the loader module to build Avisynth script libraries" tutorial.

4. How do I know what version of AVSLib I have installed in my system?Enter the following lines of code to a script:

LoadModule("avslib", "base", "version")

AVSLibVersion()

Note that this will only work for version 1.1.0 and later.

5. How do I uninstall AVSLib?Depending of your type of install, either run the provided uninstaller or simply delete all associated files.

See the "Uninstalling AVSlib" section of the installation instructions page for details.

Page 188: avisynth docu

Usage

1. Are there any limitations in AVSLib?In principle not; the code of AVSlib itself has been designed to be as generic and robust as possible.

However, since AVSLib uses the machinery provided by Avisynth in order to provide its services, it does get limited in various aspects by the resources made available to scripts by the host application (ie Avisynth).

In addition, video editing is a resource instensive operation and thus there are resource limitations imposed by the hosting hardware and operating system.

The consequence is that - depending also on the Avisynth version that you use - there are practical limitations, a list of which has been compiled to a dedicated AVSLib specifications page. Please take the time to read it carefully before starting developing scripts with AVSlib.

2. Will these limitations be removed in a future version of AVSLib?The answer to this question depends mainly on factors external to the project and thus it cannot be

answered directly by the AVSLib project.

The AVSlib development team has the intention to try devising smarter ways for utilising the given resources available to Avisynth scripts but this is at this time lower in priority compared to the horizontal expansion of AVSLib features (ie features increase).

3. Are there any recommendations regarding the use of AVSLib features?Yes. See the Reserved Actions section at the AVSLib structure page and all tutorials included at the

documentation.

You may also examine the example scripts included at the documentation to see real cases of script development using AVSLib.

4. I try to run a script containing calls to AVSLib functions and I get the "I don't know what xxx means" error from Avisynth. What's going wrong?

Either you have mispelled an AVSLib function name or you didn't supply the correct module or package or library configuration constant to LoadModule(), LoadPackage() or LoadLibrary() or you didn't install properly the AVSLib distribution.

Check the above cases in the order specified, until you find the cause and repair the error.

See the installation and use instructions page for details.

5. I get unexpected errors pointing to array operator functions (ArrayOpValue / ArrayOpFunc / ArrayOpArray / ArrayOpArrayFunc). Didn't you tested them for errors?

Yes, we did; many times. Most probably the errors are not located in operator functions but inside the user-code that you have ordered them to execute.

See the last section of the container operators tutorial for best-coding guidelines and ways to debug your script.

Page 189: avisynth docu

6. My animation gets out of the clip area. What's going wrong?Animation filters use a different coordinate system than Overlay does. (x,y) values passed to them are

interpreted as specifying the position of the center of the clip and not its top-left corner. Add Round(ovl.Width/2) to all x's and Round(ovl.Height/2) to all y's to solve the problem.

You may also see the tutorial "Understanding animation filters" for getting a better insight on animation filters.

7. VirtualDub either crashes or displays a "sctip open failed!" messagebox when I try to run a script containing AVSLib commands. What's going wrong?

Most probably your code has hit onto a resource limit (memory is the first to look, especially if it took a long time before the error appeared). Break your script to a number of succesive scripts (ie construct a script chain) to lower the memory requirements of each step.

Other possible causes include:

➢ A logical error inside your script (such as producing a NaN, or specifying zero dimensions for a clip, etc.) that fires an illegal condition either inside AVSLib's or inside Avisynth's code.

➢ Your code has hit onto either an AVSLib's or an Avisynth's internal error (bug).

Try to isolate the error using the facilities of the debug package (the Break() and BreakIf() functions are especially useful for this) and decide which case of the above is more plausible. Afterwards either recode your script or ask for support from the corresponding project.

8. I made a script using arrays but I always get a "__left_str: string has > 1024 chars" message when I try to run it. What's going wrong?

You are using Avisynth version 2.5.5 or lower and you are trying to construct an array with overall size that exceeds the allowable array lenght (ie string lenght) limits. See the AVSLib specifications for details.

To workaround this either upgrade your Avisynth dll to a version greater than 2.5.5 or recode your script to use smaller arrays.

9. I try to use the EditJoin filter with a custom join function but I get an "invalid arguments to function..." error? What's going wrong?

Both the join function and the operation argument (extra_info and op, respectively) must be specified with positional notation:

EditJoin(c1, c2, ..., op=EDOP_USER, exta_info="my_func")

Page 190: avisynth docu

Support

1. I want to submit a bug report. What should I do?Bug reports should be submitted using the AVSLib project's bug tracker system.

2. I want a feature not included in AVSLib. How can I request it?Feature requests should be made using the AVSLib project's features request system.

3. Where can I find support about using AVSLib?The first place to look for support is the documentation (you are viewing it already).

The next place is the Help / Support AVSLib project's forum.

Please, review carefully the documentation before posting any question to the forums. Most of the time the answer will be there. Also note that questions that are clearly answered by the documentation (such as "...what does the xxx argument of yyy function does?...", "...what is the purpose of function xxx?...", etc.) will have little chance of being answered at all.

For submitting bug-reports and feature requests use the corresponding trackers (see FAQs no #1 and #2 above).

Direct e-mails for support to AVSlib developers will be ignored. This communication channel is reserved for other purposes.

4. I have a question about AVSLib. Where do I seek for an answer?For any question, you can seek for an answer to one of the following places:

1. Inside this documentation (an online version can always be found at AVSLib's home page).

2. At the most appropriate of the AVSLib project's forums. If the already posted content cannot answer your question, you may post a new message there.

5. Where can I contact the developers of AVSLib?Either post a message at the most appropriate of the AVSLib project's forums or use this contact form.

Page 191: avisynth docu

Contribution

1. I want to participate on AVSLib development. How can I do this?Register with the SourceForge website and then make a request to join the AVSLib project as a developer.

2. I want to contribute texts or script examples to AVSLib documentation. How can I do this?

Post the related texts / source code at the Contribution AVSLib project's forum. The texts / source code must be accompanied by a licence compatible with those used by the AVSLib project. See the licence page for details.

Page 192: avisynth docu

Structure of the AVSLib library

Library StructureThe library is structured around modules. Each module contains related filters, functions and (possibly) global variables and constants.

Modules with common characteristics are further organised into packages. A package is thus a set of modules with related scope of operation.

A package may in turn be further divided to (an unlimited depth of) sub-packages. The later typically happens when the number of modules is getting big and their puprose can be grouped to broader categories.

Library SpecificationsFeature Specification

Maximum array lenght Maximum allowed string length. This is 2^32-1 for Avisynth versions >= 2.5.6 and only 1024 for Avisynth version 2.5.5 and earlier (achieved with a hack developed by AVSLib).

Maximum number of array elements

Variable, depending on the length of the string representation of each element and the delimiter in effect. For Avisynth versions >= 2.5.6 is practically unlimited (>> 1 million); for Avisynth version 2.5.5 and earlier is rather small (around 50 - 150, depending on the types stored inside the array).

Maximum number of auto-clip globals Maximum allowed int (MAX_INT) plus one (currently 2^32)

Supported operations on array elements

All, except some very specific string-related quirks with specific values. In detail: because containers' handler functions try to evaluate elements (calling Eval() on them) when they are accessed, certain operations with strings cannot be performed. For example: adding "not" to all elements of a string array with an array operator does not work as intended. "Not" (remember Avisynth is case-insensitive) is an AVSLib function ie a global identifier. See the containers and operators tutorials for details).

Maximum nesting depth / arguments' values on itterative function calls

Limited only by available stack space and range of the result's datatype allowed by Avisynth.

Maximum number of calls to filters/functions inside scripts.

Limited only from available memory space allowed by Avisynth or/and the operating system (maximum process memory size).

Supported Avisynth versions

Any (no reports up to now for non-functioning features in a specific version). The parts of AVSLib that base their functionality on external plugins may be limited by plugin-specific limitations (most notably, they will not work on 2.0.x versions).

In typical library's usage, especially for Avisynth version 2.5.6 and later, it is unlikely that any "hard" limit will be reached. If a limit is reached it is likely to be a resource limit imposed by Avisynth or the operating system.

If this is the case, rearrange the script in groups of smaller scripts (ie divide and conquer). Keep in mind that many parts of the library (especially array-related) are "dense", meaning that even a single line in the script (depending of course on line's contents) if expanded to equivalent Avisynth statements without the use of AVSLib may well reach several pages in length.

Page 193: avisynth docu

Naming conventionsAVSLib uses naming conventions in order to divide the large number of functions it provides in separate logical namespaces, to convey structure information and to aid library's users to reduce their learning curve and avoid common mistakes.

Note that many of these are just proposals of coding-style conventions; Avisynth script language does not support separate namespaces, does not distinguishes case, nor it flags name conflicts (instead it resolves them automatically).

However, it is precisely this lack of protection of identifiers' names which makes necessary a high level of discipline on behalf of the script writer, in order to avoid masking essential library functionality and the errors that this masking will inevitably produce.

The naming conventions used throught AVSLib are the following:

• Constants are typed in uppercase. Name components are separated by a single underscore ("_"). • Private functions, variables and constants begin with a double undescore ("__") and are typed in

lowercase. Name components are separated by a single underscore ("_"). • Public functions and variables are typed with each name component capitalised. • Function arguments are typed in lowercase. Name components are separated by a single underscore ("_"). • Functions and variables related to container types operations have the name of the container type as a

prefix. • Functions and variables related to common groups of operations typically begin with a prefix derived by

the name of the group (which is usually also the containing module's name). Such is for example the case for the filters of the edit module.

• All other functions and variables do not have a prefix.

Reserved namesAll names begining with the "private" designator (the double underscore at the begining of the name) are considered reserved. Any future version of AVSLib may freely modify them, delete them, change their semantics, etc. The list of entities that this rule applies includes:

• Globals (constants and variables). • Functions • Function arguments.

Public library constants are also considered reserved in the sense that their value (and associated type) should remain unaltered by user scripts.

Reserved actionsThese include in general all actions that involve messing around with the library's reserved namespace. In particular, the following rules should be observed, unless you are a library developer or your main objective is to research curious new bug species:

• Do not directly access private names and never modify their values; if they need to be accessed, a public function will be provided by the library.

• Never assign a new value to names that are flaged as constants. • Never pass a reserved argument (one starting with "__") to a library function. • Do not define variables in the reserved namespace (ie with "__") in your scripts; they may override

library's private functions and/or globals.

Page 194: avisynth docu

Examples

1. Stack clips in a matrixThis script demonstrates the use of arrays for storing clips that will later be processed as a group and also the use of the Stack() filter, a handy way to quickly create 2D tables of clips.

First the script:

# AVSLib :: sample script# Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under the # terms of the GNU General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) any later # version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

# load required modules

LoadModule("avslib", "array", "core")LoadModule("avslib", "filters", "stack")

# load six clips

vids = ArrayCreate( \ AVISource("file001.avi"), \ AVISource("file002.avi"), \ AVISource("file003.avi"), \ AVISource("file004.avi"), \ AVISource("file005.avi"), \ AVISource("file006.avi") \ )

# stack them in a 2x3 table

return Stack(vids, 2, 3)

The script loads a bunch of clips directly into an array and then passes them to the Stack filter to arrange them in a 2 rows x 3 columns matrix.

Note that there is no restriction that the product (rows x columns) passed to Stack filter must be equal to the array's length. If it is less, the remaining clips will be discarded; if more, blank clips will be used as padding to fill the entire matrix.

Page 195: avisynth docu

This is a rather crude method to load sequentially numbered clips; a possible refinement could be like the following script excerpt:

LoadModule("avslib", "array", "operators")

names = "file001.avi,file002.avi,file003.avi,file004.avi,file005.avi,file006.avi"vids = names.ArrayOpFunc("AVISource")

or, with just one more line of code, but allowing easier application to other numbers of clips:

LoadModule("avslib", "array", "operators")

Function MakeFName(int idx) { return "file" + String(idx, "%03.0f") + ".avi" }

idxs = ArrayRange(1, 6)vids = idxs.ArrayOpFunc("MakeFName").ArrayOpFunc("AVISource")

Both refinements however cannot be considered general enough for covering all possible cases. A logical consequence would be to try and device a generic source function that would deliver an array of clips, given a path and start / stop indices, like for example the ImageSource standard Avisynth filter does.

The next script does exactly that:

# AVSLib :: sample script# Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

# load required modules

LoadModule("avslib", "base", "core")LoadModule("avslib", "array", "core")LoadModule("avslib", "array", "operators")LoadModule("avslib", "array", "slices")LoadModule("avslib", "filters", "stack")

# Function to load sequentially numbered (.avi) clips

Function ClipSource(string path, int start, int end, int "pad"){ Assert(start >= 0, "ClipSource: 'start' must be >= 0") Assert(end >= 0, "ClipSource: 'end' must be >= 0") pad = Max2(0, Default(pad, 0)) # values <= 0 result in no padding fmt = "%0" + String(pad) + ".0f" fname = path + String(start, fmt) + ".avi"

Page 196: avisynth docu

return start <= end \ ? ArrayJoin( ArrayCreate(AVISource(fname)), \ ClipSource(path, start + 1, end, pad) ) \ : ""}

vids = ClipSource("file", 1, 6, 3)

# calculate appropriate rows and columns (as the StackToFit filter does)

vlen = vids.ArrayLenrows = Round(Sqrt(vlen))cols = Ceil(Sqrt(vlen))

# reduce size to avoid making the final clip too wide / tall

vids = vids.ArrayOpFunc("ReduceBy2")

# stack them in a rows x cols table

return Stack(vids, rows, cols)

The script loads a couple of additional modules needed by the implementation and then defines ClipSource, the newly-created generic function for loading arbitrary (.avi only) sources into an array.

ClipSource uses ArrayCreate in order to create a single element array for each recursive invocation and ArrayJoin for joining the arrays together. That way there is no need to care about the housekeeping of array elements' delimiters; ArrayJoin takes care of these.

Since ClipSource is a generic function that can return an arbitrary length array, the way to calculate rows and columns for the matrix should be made generic also. The solution chosen is to use the same equations that are used by the StackToFit filter; the situation is similar.

Afterwards, the clips are made smaller in order to fit easily in a computer screen (the assumption is that they have normal video dimensions) by a single call to ArrayOpFunc containing the proper standard Avisynth filter (here ReduceBy2) and finally they are stacked in the 2D matrix.

Page 197: avisynth docu

Apply a swap transitionThis script demonstrates basic use of AVSLib's filters. The example script applies a vertical in-to-out swap transition between a still photo and a clip. In order to fit things together other filters (resizing, editing and utility) are also used.

First the script:

# AVSLib :: sample script# Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "filters", "edit")LoadModule("avslib", "filters", "resize")LoadModule("avslib", "filters", "utility")LoadModule("avslib", "filters", "animate")

# load a clip and a photo; convert photo to match clp

clpname = "story.avi"phoname = "photo.jpg"

clp = AVISource(clpname)ovlap = Round(clp.Framerate / 5)

pho = ImageSource(phoname, start=0, end=2*ovlap-1)pho = pho.AssumeFPS(clp.Framerate)pho = pho.ResizeToTarget(clp) # this, coded as is, will do a bilinear resizepho = pho.ConvertToTarget(clp)pho = pho.AudioDub(clp)

# create a vertical from-center-to-outside swap transition# for this we only need to animate size

ph1 = pho.EditTrim(0, ovlap).Amplify(0)ph2 = pho.EditTrim(ovlap)

black = ph2.BlankClip(color=color_black)white = ph2.BlankClip(color=color_white)

tmask = LineAnim(black, white, w_start=2, w_end=clp.Width).ScaleToPC()

Page 198: avisynth docu

# add ovlap frames of the stil photo length at the begining

return EditJoin(ph1, \ Overlay(ph2, clp.EditTrim(0, ovlap), mask=tmask), \ clp.EditTrim(ovlap), \ op=EDOP_ALGN)

The script loads an image and converts it to a clip with the same properties as the base story clip. Then it animates a white over a black mask to create the swap effect and finally combines the parts with EditJoin.

Page 199: avisynth docu

3. Create a simple movie intro clipThis script demonstrates the use of the FilterVarChain filter, which allows to easily chain arbitrary invocations of a filter with varying arguments. The example creates a simple movie intro clip containing a group of subtitles that appear in consecutive frames (thus the filter that is chained is SubTitle). The intro clip is then joined with the main clip.

First the script:

# AVSLib :: sample script# Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "filters", "utility")

# load a clip (640x480)clp = AVISource("script.avi")

# create a CR/LF delimited array of Subtitle parameters (ie a multiline string)# text, x, y, first_frame, last_frame, font, size, text_color, halo_color, align#sub_ttl = \""" "Smiths Productions", 320, 100, 8, 240,"verdana", 28, color_antiquewhite, color_gray30, 2"prowdly presents", 320, 140, 32, 240, "verdana", 24, color_antiquewhite, color_gray30, 2"A John Smith Film", 320, 200, 90, 240, "verdana", 28, color_lavenderblush, color_gray30, 2"The Family Grows", 320, 280, 150, 240, "verdana", 42, color_lightsalmon, color_gray30, 2"Episode III", 320, 330, 174, 240, "verdana", 36, color_antiquewhite, color_gray30, 2"Junior walks!", 320, 400, 198, 240, "verdana", 38, color_lavenderblush, color_gray30, 2"""

sub_tms = "1,1,1,1,1,1"

ttbase = clp.BlankClip(length=240, color=color_gray10)titles = ttbase.FilterVarChain("SubTitle", sub_tms, sub_ttl)

return Dissolve(titles.Blur(0.5), ttbase.Trim(0, 20), 10) + clp

In order to call the FilterVarChain filter, two arrays must be constructed:

1. The first (sub_ttl in the example) contains the argument lists of each different filter invocation, exactly as they would be written in an Avisynth script, each on a single line. It is thus a multiline string, a choice that was made to ease both its readability and its creation.

2. The second (sub_tms in the example) contains the number of times that the filter will be called with the arguments' settings of each line of the 1st array. Thus, in the example above each subtitle line is called exactly once.

For more simple cases, where a single group of settings need to be applied many times, the use of FilterChain filter is recommended.

Page 200: avisynth docu

4. Make a palette clip with all Avisynth named colorsThis script demonstrates the array facilities of AVSLib (Stack is also implemented with arrays). The example creates a color palette (ie a 2D matrix with colored rectangles) from all Avisynth's named colors

The result of running the script is presented below.

Figure 1: Clip produced by example script

Now the script:

# AVSLib :: sample script# Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "array", "core")LoadModule("avslib", "array", "operators")LoadModule("avslib", "array", "slices")LoadModule("avslib", "filters", "stack")

# make an array with all named Avisynth colors (colors_rgb.avsi); white, gray, black first

colors1 = ArrayCreate( \ color_white, color_gray10, color_gray20, color_gray30, color_gray40, \

Page 201: avisynth docu

color_gray50, color_gray60, color_gray70, color_gray80, color_gray90, \ color_black, color_aliceblue, color_antiquewhite, color_aqua, \ color_aquamarine, color_azure, color_beige, color_bisque, \ color_blanchedalmond, color_blue, color_blueviolet, color_brown, \ color_burlywood, color_cadetblue, color_chartreuse, color_chocolate, \ color_coral, color_cornflowerblue, color_cornsilk, color_crimson, \ color_cyan, color_darkblue, color_darkcyan, color_darkgoldenrod, \ color_darkgray, color_darkgreen, color_darkkhaki, color_darkmagenta, \ color_darkoliveGreen, color_darkorange, color_darkorchid, color_darkred, \ color_darksalmon, color_darkseaGreen, color_darkslateBlue, \ color_darkslateGray, color_darkturquoise, color_darkviolet, \ color_deeppink, color_deepskyblue)

colors2 = ArrayCreate( \ color_dimgray, color_dodgerblue, color_firebrick, color_floralwhite, \ color_forestgreen, color_fuchsia, color_gainsboro, color_ghostwhite, color_gold, \ color_goldenrod, color_gray, color_green, color_greenyellow, color_honeydew, \ color_hotpink, color_indianred, color_indigo, color_ivory, color_khaki, \ color_lavender, color_lavenderblush, color_lawngreen, color_lemonchiffon, \ color_lightblue, color_lightcoral, color_lightcyan, color_lightgoldenrodyellow, \ color_lightgreen, color_lightgrey, color_lightpink, color_lightsalmon, \ color_lightseagreen, color_lightskyblue, color_lightslategray, \ color_lightsteelblue, color_lightyellow, color_lime, color_limegreen, color_linen, \ color_magenta, color_maroon, color_mediumaquamarine, color_mediumblue, \ color_mediumorchid, color_mediumpurple, color_mediumseagreen, \ color_mediumslatenlue, color_mediumspringgreen, color_mediumturquoise, \ color_mediumvioletred)

colors3 = ArrayCreate( \ color_midnightblue, color_mintcream, color_mistyrose, color_moccasin, \ color_navajowhite, color_navy, color_oldlace, color_olive, color_olivedrab, \ color_orange, color_orangered, color_orchid, color_palegoldenrod, \ color_palegoldenrod, color_palegreen, color_paleturquoise, color_palevioletred, \ color_papayawhip, color_peachpuff, color_peru, color_pink, color_plum, \ color_powderblue, color_purple, color_red, color_rosybrown, color_royalblue, \ color_saddlebrown, color_salmon, color_sandybrown, color_seagreen, \ color_seashell, color_sienna, color_silver, color_skyblue, \ color_slateblue, color_slategray, color_snow, color_springgreen, \ color_steelblue, color_tan, color_teal, color_thistle, color_tomato, \ color_turquoise, color_violet, color_wheat, color_whitesmoke, \ color_yellow, color_yellowgreen)

colors = ArrayJoin(colors1, colors2, colors3)

# Create a custom function that returns a clip with the color passed in

Page 202: avisynth docu

Function PaletteCell(int palette_color) { global color_num = color_num + 1 return BlankClip(color=palette_color, width=60, height=40, length=1 \ ).SubTitle(String(color_num), size=12, text_color=color_black, halo_color=color_gray50)}

# use colors and custom function to make an array with palette cells clips

global color_num = 0palette = colors.ArrayOpFunc("PaletteCell")

# Since we have 150 colors we will stack them in a 12x13 = 154 cell grid# Last 4 cells will be black (empty).# This will result in a 780x480 clip taking into account the w,h values in custom function

return Stack(palette, 12, 13)

The script creates an array with all named Avisynth colors (using a combination of the ArrayCreate and ArrayJoin functions to overcome the 60 arguments limit of Avisynth) and then applies a user-defined function in each color which returns a clip colored with that color.Finally it calls Stack to stack the colored clips in a 2D matrix.

Page 203: avisynth docu

5. Load a text file with arbitrary clipsThis script demonstrates a way to use the ability offered by AVSLib to change the default array delimiter in order to create a script that can load and edit non-predefined clips.

The later allows to treat the script as an Avisynth "program" which, in cooperation with a command line driven encoder (such as Avs2Avi, ffmpeg or VirtualDub plus a Sylia script) can fully automate the related NLE process, since it will be reduced to a single shell command invocation.

First the script. In this example a call to StackToFit() filter has been used with mode RTF_CROP as an editing example; more complex tasks are easy to introduce.

# AVSLib :: sample script # Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

# load required modulesLoadModule("avslib", "base", "constants")LoadModule("avslib", "base", "conversion")LoadPackage("avslib", "array")LoadModule("avslib", "filters", "stack")

# load a text file containing dir /b output # surrounded by triple quotes at the start and end of filedir = Import("files.txt")

# after that dir is an array of filenames! # but be careful if you hand-type arrays...ArrayDelimiterSet(CRLF)

# cleanup dir from invalid files (CInt is used to convert true/false to 1/0)okflag = dir.ArrayOpFunc("Exist").ArrayOpFunc("CInt")dir = dir.ArrayReduce(okflag)

# read in clipsclp = dir.ArrayOpFunc("DirectShowSource")

# stack them - preserving aspect ratio by cropping - into a 960x640 framereturn StackToFit(clp, 960, 640, RTF_CROP)

As it is apparent from the code, the key aspects of the "trick" presented is

1. to insert triple quotes at the start and end lines of the input file so that Import() will consider the contents to be an Avisynth string,

2. to change the array delimiter to a CR/LF pair so that each line of the file be treated as an array element.

Because this setup produces an empty initial array element, but also as a safety check since input is unpredictable because it is not hard-coded into the script anymore, the standard Avisynth function Exist is applied to all script

Page 204: avisynth docu

elements and those where it returns false are removed from the array by ArrayReduce.

Furthermore, since ArrayReduce needs a zero / non-zero "flag" array in order to decide which elements will keep, the conversion function CInt is applied to the array that resulted from the application of Exist (see the OOP-style chain at the line assigning to okflag variable) to produce a 0 / 1 value for each false / true value.

The creation of the "files.txt" in the above example can easily be automated with a custom shell script. A working example (say named "avidir.cmd") is provided below:

@echo offecho """for %%f in (%1) do @echo %%~ffecho """

The shell script takes one (needed) argument, a wildcard specification which can include path information in case the files are not at the current directory. The script outputs absolute filenames, so that the calling avisynth script can be located anywhere in the filesystem.

The final step to automate the process is to make another custom shell script (say "makeavi.cmd") that will update the contents of "files.txt" and (optionally, depending on your needs) invoke the encoder. For example:

@echo offavidir %1 > files.txtavs2avi script.avs -l %2

The top level shell script takes the same one (needed) argument, a wildcard specification, as the previous plus an additional 2nd argument (a filename with the codec settings). It is assumed that the encoder executable is placed at a folder included in the PATH environment variable.

Thus you can invoke a single shell command in order to import, NLE process and encode a set of clips, such as:

makeavi [wildcard] [codecsettings]

If another encoder is used , the top level script must be modified appropriately to account for the different command line options needed by the encoder.

Page 205: avisynth docu

6. Create an enhanced movie intro clipThis script extends the third example, demonstrating the animation feautures of AVSLib. The script creates a movie intro clip containing a group of subtitles that appear and go in consecutive frames with fade-in and fade-out effects. In addition, subtitles are smoothed to allow a more pleasing view.

First the script:

# AVSLib :: sample script # Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "array", "core")LoadModule("avslib", "filters", "animate")LoadModule("avslib", "filters", "utility")

# load a clip (640x480)clp = AVISource("script.avi").ConvertToYV12()

# create a CR/LF delimited array of Subtitle parameters (ie a multiline string)# text, x, y, first_frame, last_frame, font, size, text_color, halo_color, alignsub_ttl = """ \ "Smiths Productions", 320, 100, 8, 240, "verdana", 28,color_antiquewhite, color_gray30, 2 "prowdly presents", 320, 140, 32, 240, "verdana", 24, color_antiquewhite, \ color_gray30, 2 "A John Smith Film", 320, 200, 90, 240, "verdana", 28,color_lavenderblush, \ color_gray30, 2 "The Family Grows", 320, 280, 150, 240, "verdana", 42, color_lightsalmon, \ color_gray30, 2 "Episode III", 320, 330, 174, 240, "verdana", 36, color_antiquewhite, color_gray30, 2 "Junior walks!", 320, 400, 198, 240, "verdana", 38, color_lavenderblush, color_gray30, 2"""

sub_tms = "1,1,1,1,1,1"

Function FadeSubTitle(clip c, string text, int x, int y, int fs, int fe, \ string font, int size, int tcolor, int hcolor, int align){ stmask = c.BlankClip().SubTitle( \ text, x, y, fs, fe, font, size, color_white, color_gray90, align) stmask = stmask.Blur(1.0).ScaleToPC() ovl = c.SubTitle(text, x, y, fs, fe, font, size, tcolor, hcolor, align) frames = ArrayCreate(fs,fs +Round((fe - fs)/5),fe - Round((fe - fs)/5), fe) opac = "0.1,1,1,0.1" return PolygonAnim(c, ovl, frames, op_array=opac, mask=stmask)}

Page 206: avisynth docu

ttbase = clp.BlankClip(length=241, color=color_gray10)titles = ttbase.FilterVarChain("FadeSubTitle", sub_tms, sub_ttl)

return Dissolve(titles, ttbase.Trim(0, 20), 10) + clp

The new features introduced are contained inside the FadeSubTitle custom filter.

The filter creates a mask of the subtitle's text (with gray halo_color) that it is blured in order to make the fonts edges fade nicely into the surrounding video. The appearance and disappearance of the subtitle are also faded (in and out) with the use of the PolygonAnim filter.

As a consequence, the final result is much better than that of the third example.

Page 207: avisynth docu

7. Stack clip frames in a matrixThe purpose of this example script is to create a library routine that stacks a given range of frames of a clip in a (single clip) matrix. Such an operation offers a way to quick preview a clip, in order for example to search for scene changes, cut points, etc.

Since we make a library routine we want for it to be generic, ie to support matrices of any dimension and clip framecounts of any size. How do we proceed to design and implementation then?

At first, one may think to simply Trim signle-frame clips and create an array of the appropriate size to pass afterwards to the Stack filter. Using recursion this process could be repeated for all the requested frame range.

However this is highly inefficient. To see this let f be the total number of frames to stack and s the frames to stack in a single output frame. Then the above approach has a startup cost of ceil(f/s) recursive calls to our new function and setups a filter chain with f Trim's plus ceil(f/s) calls to the Stack filter, which by the way is expensive (approximately s calls to StackHorizontal / StackVertical per call plus a possible overhead for blank clips creation plus a startup overhead for operation on arrays). That is f + ceil(f/s)*s ~ 2*f filters.

Fortunately, there is a faster way: the SelectEvery standard Avisynth filter. Thus, instead of trimming and making arrays every s frames, we make one array of s SelectEvery filters plus s Trim's (because an internal frame range may be requested) plus a single call to Stack. That is s + s + 1*s ~ 3*s filters. Since typically s << f, we get a speed increase of orders of magnitude.

A final culprit to deal with is that if the number of frames, f, is not a multiple of s then the last output frame will contain duplicated frames because some of the s SelectEvery filters will return a shorter by one frame clip, the last frame of which will show 2 times. To make those frames black (our choice) we must perform some additional filter operations, which however since we are dealing with one output frame there will be upper-bounded by s. That is our final filter chain is in the range of [3*s..4*s] filters.

After the above considerations, the implementation of the script is rather straightforward:

# AVSLib :: sample script # Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "array", "core")LoadModule("avslib", "array", "operators")LoadModule("avslib", "filters", "stack")Function __select_frames(int ofs, clip c, int total) { return SelectEvery(c, total, ofs)}Function __trim_frames(clip c, int n, int frames, int modulo) { return n < modulo \ ? (frames < c.Framecount ? c.Trim(0, -(frames+1)) : c) \ : c.Trim(0, -frames) + c.BlankClip(length=1) }Function StackFrames(clip c, int fstart, int fcount, int rows, int cols){ Assert(fstart >= 0, "StackFrames: 'fstart' must be zero or greater") Assert(fcount > 0, "StackFrames: 'fcount' must be positive") Assert(rows > 0 && cols > 0, "StackFrames: 'rows', 'cols' must be positive")

Page 208: avisynth docu

nlen = rows * cols offsets = ArrayRange(fstart, fstart + nlen - 1) counts = ArrayRange(0, nlen - 1) old = ArrayDelimiterReset() extra_args = ArrayCreate(c, nlen) div = fcount / nlen mod = fcount % nlen trim_args = ArrayCreate(div, mod) old = ArrayDelimiterSet(old) clips = offsets.ArrayOpFunc("__select_frames", extra_args) clips = ArrayOpArrayFunc(clips, counts, "__trim_frames", trim_args) return Stack(clips, rows, cols)}

# test

clp = BlankClip(length=166, width=632, height=472, color=$000040)clp = clp.ShowFrameNumber(scroll=true, size=48).AddBorders(4, 4, 4, 4, $ffffff)clp = clp.Spline16Resize(Round(clp.Width / 4), Round(clp.Height / 4))return StackFrames(clp, 0, clp.Framecount, 4, 4)

Page 209: avisynth docu

8. Load, convert and join arbitrary clipsThis script extends the basic ideas of the fifth example, that is to load arbitrary clips and arguments supplied in external text files through proper changing of the default AVSLib's array delimiter and process them.

The example script applies moderately complex filtering (resizing, colorspace and fps conversion) based on the arguments' values and then joins the clips serially in a single timeline.

Shell scripts to automate the creation of the text files as well as the rendering of the .avs script are also provided. The later allow to treat the script as an Avisynth "program" which, in cooperation with a command line driven encoder (such as Avs2Avi, ffmpeg or VirtualDub plus a Sylia script) can fully automate complex NLE processes, reducing them to single shell command invocations.

First the script:

# AVSLib :: sample script # Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

# load required modulesLoadModule("avslib", "base", "constants")LoadModule("avslib", "base", "conversion")LoadPackage("avslib", "array")LoadPackage("avslib", "clip")LoadModule("avslib", "numeric", "rounding")

# load a text file containing dir /b output # surrounded by triple quotes at the start and end of filedir = Import("files.txt")

# load two text files containing integers # (target width and height for the clips in dir)tw = Import("width.txt")th = Import("height.txt")

Assert(tw.IsInt && th.IsInt, "Input Error: width or/and height files contain invalid data") # after that dir is an array of filenames!# but be careful if you hand-type arrays...ArrayDelimiterSet(CRLF)

# cleanup dir from invalid files (CInt is used to convert true/false to 1/0)okflag = dir.ArrayOpFunc("Exist").ArrayOpFunc("CInt")dir = dir.ArrayReduce(okflag)Assert(dir.ArrayLen > 0, \ "Input Error: files.txt does not contain any valid filename")

Page 210: avisynth docu

# read in clipsclp = dir.ArrayOpFunc("DirectShowSource")

# force clip parameters (dimensions, framerate, colorspace) to be the same# assume all clips are progressive

b_same_fps = (clp.ArrayOpFunc("Framerate").ArrayDistinct().ArrayLen() == 1)pixel_type = clp.JointPixelType()fps = clp.JointFPS()

# to assure that target width, height match any clip's colospace # restrictions we allow for the more restrictive type (yv12)tw = RoundBs(tw, 4)th = RoundBs(th, 4)

# now convert clips (resize, convertto..., changefps)clp = clp.ArrayOpFunc("Spline36Resize", String(tw) + "," + String(th))clp = clp.ArrayOpFunc("ConvertTo" + pixel_type)clp = b_same_fps \ ? clp \ : clp.ArrayOpFunc("ConvertFPS", String(fps))

# join clips together one after the other, applying Dissolve(c1, c2, 6) # in each joinreturn clp.ArraySum(sum_func="Dissolve", sum_args="6")

In the example above a way to auto-convert all supplied clips to compatible characteristics for splicing is presented.

The core task of clip properties scanning is made by two functions of the clip package: JointPixelType and JointFPS. The first returns the dominant colorspace of a clip array, while the second the dominant framerate (so that the fewest conversions result from converting all array's clips to these values).

Based on these values (and also on the user-supplied arguments for the target size) the homogenisation of the (possibly heterogenuous) clips passed in as arguments is made compactly in just a few lines of code with the use of array operators (see also the related tutorial). The same is true for the creation of the final combined timeline.

As in the fifth example, the creation of the .txt files can easily be automated with a custom shell script. A working example for the clips (say named "avidir.cmd") is provided below:

@echo offecho """for %%f in (%1) do @echo %%~ffecho """

The shell script takes one (needed) argument, a wildcard specification which can include path information in case the files are not at the current directory. The script outputs absolute filenames, so that the calling avisynth script can be located anywhere in the filesystem.

The final step to automate the process is to make another custom shell script (say "makeavi.cmd") that will update the contents of the text files and (optionally, depending on your needs) invoke the encoder. For example:

@echo offavidir %1 > files.txt

Page 211: avisynth docu

echo %2 > width.txtecho %3 > height.txtavs2avi script.avs -l %4

The top level shell script takes four arguments, a wildcard specification, two integer values for the width and heigh and an additional 4th argument (a filename with the codec settings). It is assumed that the encoder executable is placed at a folder included in the PATH environment variable.

Thus you can invoke a single shell command in order to import, NLE process and encode a set of clips, such as:

makeavi [wildcard] [width] [height] [codecsettings]

If another encoder is used , the top level script must be modified appropriately to account for the different command line options needed by the encoder.

Page 212: avisynth docu

9. Make an animated draw of a curve with random orbitsThis script demonstrates the use of arrays for concurrent drawing of multiple clips (brush strokes) on a base clip, thus allowing for interesting effects.

The script draws an animated curve with a family of pens, each with a different color and brush (shape). The pens deviate randomly from the curve's main (x,y) coordinates within a given radius - like the "orbits" setting found in most modern painting programs - while the curve's main (x,y) coordinates advance constantly on each frame.

The result of running the script up to its last frame is presented below.

Figure 1: Last frame of clip produced by example script (version 1)

Now the script. For reasons of efficiency it uses global canvas-clips for achieving constant draw time per frame. As a consequence, works by design only on a linear pass from frame 0 to the last. That is if one adds filters at the end that request random frames back and forth it will not give the intended results.

# AVSLib :: sample script # Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "base", "core")LoadModule("avslib", "array", "core")LoadModule("avslib", "array", "operators")LoadModule("avslib", "numeric", "rounding")LoadModule("avslib", "filters", "utility")Function ImgSource(string file, clip template, int "target_w", \ int "target_h", int "frames", bool "pc_range"){ frames = Default(frames, template.Framecount) target_w = Default(target_w, template.Width) target_h = Default(target_h, template.Height) pc_range = Default(pc_range, false) ret = ImageSource(file, start=0, \ end=frames-1).AssumeFPS(template.Framerate) ret = ret.ConvertToTarget(template).BilinearResize(target_w, target_h)

Page 213: avisynth docu

return pc_range ? ret.ScaleToPC() : ret}

Function MakeSolidPen(clip brush, int pen_color) { return brush.BlankClip(color=pen_color)}

# create a clip (640x480, 5 sec)global clp = BlankClip(length=120, color=color_darkslateBlue, \ fps=24, width=640, height=480, pixel_type="YV12")

global pen_canvas = clp.BlankClip(color=color_black, length=1) # pens draw hereglobal brs_canvas = pen_canvas.ScaleToPC() # brushes draw here

# create solid color brushesglobal brushes = ArrayCreate( \ ImgSource("brush1.jpg", clp, 24, 24, pc_range=true), \ ImgSource("brush2.jpg", clp, 24, 24, pc_range=true), \ ImgSource("brush3.jpg", clp, 24, 24, pc_range=true) \ )colors = "color_gold, color_beige, color_crimson"

global pens = ArrayOpArrayFunc(brushes, colors, "MakeSolidPen")

# define the curves (they assume a 640x480 canvas)Function NormDist(float x, float m, float s) { return (1.0/(Sqrt(2*Pi)*s))*Exp(-Pow(x-m,2)/(2*Pow(s,2)))}

Function SinPulse(float x, float xc, float peak, float spread) { return peak*NormDist(x, xc, spread)*Sin((x-xc)/(2*Pi)) }

Function Curve(float x) { return 240 - 120 * Sin(0.65*x*Pi/320) + SinPulse(x, 520, 14000, 120) }

# Draw on x,y; x belongs to [x_start, x_end)# assumes brush, bmask have same dimensionsFunction DrawItems(clip pen, clip brush, int x_start, int y_start) { dx = Round(brush.Width / 2.0) dy = Round(brush.Height / 2.0) xr = x_start + \ Round(Rand(StrokeRadius*2) - StrokeRadius) # shuffle x,y based on radius yr = y_start + Round(Rand(StrokeRadius*2) - StrokeRadius)

Page 214: avisynth docu

global pen_canvas = Overlay(pen_canvas, \ pen, x=xr-dx, y=yr-dy, mask=brush, opacity=StrokeOpacity) global brs_canvas = Overlay(brs_canvas, brush, x=xr-dx, \ y=yr-dy, mask=brush, opacity=StrokeOpacity, \ pc_range=true) return 1}Function DrawCurve(clip c, string curve, int x_start, int x_end, int step){ dummy2 = (x_start < x_end && x_start > xlast) ? Eval(""" y_start = Round(Apply(curve, x_start)) dummy = ArrayOpArrayFunc(pens, brushes, "DrawItems", \ String(x_start) + "," + String(y_start)) global xlast = x_start """) : (x_start <= xlast ? Eval(""" x_start = IntBs(xlast, step) + step """) : NOP) return x_start < x_end \ ? DrawCurve(c, curve, x_start + step, x_end, step) \ : Overlay(c, pen_canvas, mask=brs_canvas, opacity=1.0, ignore_conditional=true) }

# begin drawglobal xlast = 0 global xs = 0global xe = 0xd = Int(clp.Width / clp.Framecount) global xdelta = clp.Framecount * xd < clp.Width ? xd + 1 : xdglobal StrokeRadius = 20global StrokeOpacity = 1.0

ScriptClip(clp, """global xe = Min2(xe + xdelta, last.Width)DrawCurve(last, "Curve", xs, xe, 4)""")ConditionalReader("radius.txt", "StrokeRadius")ConditionalReader("opac.txt", "StrokeOpacity")

Page 215: avisynth docu

LoadModule("avslib", "base", "core")LoadModule("avslib", "array", "core")LoadModule("avslib", "array", "operators")LoadModule("avslib", "numeric", "rounding")LoadModule("avslib", "string", "sprintf")LoadModule("avslib", "filters", "utility")

Function ImgSource(string file, clip template, int "target_w", \ int "target_h", int "frames", bool "pc_range"){ frames = Default(frames, template.Framecount) target_w = Default(target_w, template.Width) target_h = Default(target_h, template.Height) pc_range = Default(pc_range, false) ret = ImageSource(file, start=0, \ end=frames-1).AssumeFPS(template.Framerate) ret = ret.ConvertToTarget(template).BilinearResize(target_w, target_h) return pc_range ? ret.ScaleToPC() : ret}

Function MakeSolidPen(clip brush, int pen_color) { return brush.BlankClip(color=pen_color)}

# create a clip (640x480, 5 sec)

global clp = BlankClip(length=120, color=color_darkslateBlue, \ fps=24, width=640, height=480, pixel_type="YV12")

global pen_canvas = clp.BlankClip(color=color_black, length=1) # pens draw hereglobal brs_canvas = pen_canvas.ScaleToPC() # brushes draw here

# create solid color brushes

global brushes = ArrayCreate( \ ImgSource("brush1.jpg", clp, 24, 24, pc_range=true), \ ImgSource("brush2.jpg", clp, 24, 24, pc_range=true), \ ImgSource("brush3.jpg", clp, 24, 24, pc_range=true) \ )colors = "color_gold, color_beige, color_crimson"

global pens = ArrayOpArrayFunc(brushes, colors, "MakeSolidPen")

# define the curves (they assume a 640x480 canvas)

Page 216: avisynth docu

Function NormDist(float x, float m, float s) { return (1.0/(Sqrt(2*Pi)*s))*Exp(-Pow(x-m,2)/(2*Pow(s,2)))}

Function SinPulse(float x, float xc, float peak, float spread) { return peak*NormDist(x, xc, spread)*Sin((x-xc)/(2*Pi)) }

Function Curve(float x) { return 240 - 120 * Sin(0.65*x*Pi/320) + SinPulse(x, 520, 14000, 120)}

Up to this point the script loads required modules and declares the curve-generating functions and a utility function - ImgSource - that loads an image and converts it to a clip with the same characteristics as a template clip. In addition it creates the arrays with pens and brushes that will be used for drawing.

Because here different brush shapes and pen colors are drawn, the script uses two global canvas-like clips to hold brush strokes of the previous frames. One for the actual color (pen) strokes and one for the opacity mask (brush) strokes.

The actual drawing part of the script code follows:

# Draw on x,y; x belongs to [x_start, x_end)# assumes brush, bmask have same dimensionsFunction DrawItems(clip pen, clip brush, int x_start, int y_start) { dx = Round(brush.Width / 2.0) dy = Round(brush.Height / 2.0) # shuffle x,y based on radius xr = x_start + Round(Rand(StrokeRadius*2) - StrokeRadius) yr = y_start + Round(Rand(StrokeRadius*2) - StrokeRadius) global pen_canvas = Overlay(pen_canvas, pen, x=xr-dx, \ y=yr-dy, mask=brush, opacity=StrokeOpacity) global brs_canvas = Overlay(brs_canvas, brush, x=xr-dx, \ y=yr-dy, mask=brush, opacity=StrokeOpacity, \ pc_range=true) return 1 # return value doesn't really matters}

Function DrawCurve(clip c, string curve, int x_start, int x_end, int step){ dummy2 = (x_start < x_end && x_start > xlast) ? Eval(""" y_start = Round(Apply(curve, x_start)) dummy = ArrayOpArrayFunc(pens, brushes, "DrawItems", \ String(x_start) + "," + String(y_start)) global xlast = x_start """) : (x_start <= xlast ? Eval(""" x_start = IntBs(xlast, step) + step """) : NOP)

Page 217: avisynth docu

return x_start < x_end \ ? DrawCurve(c, curve, x_start + step, x_end, step) \ : Overlay(c, pen_canvas, mask=brs_canvas, opacity=1.0, \ ignore_conditional=true) }

The heart of the drawing procedure is DrawItems, which is called by ArrayOpArrayFunc for every defined pen-brush pair. The caller simply ensures that drawing occures only after the last x-point processed by the previous frames and, at the end of the recursion, overlays the pens' canvas on top of the base clip, using the brushes' canvas as a mask.

The if...elseif..else block inside DrawCurve (implemented with Eval and triply quoted strings) is used to quickly advance x_start in one step and avoid the cost of unneeded recursive function calls. IntBs(xlast, step) ensures that x_start will remain a multiple of step.

# begin drawglobal xlast = 0 global xs = 0global xe = 0xd = Int(clp.Width / clp.Framecount) global xdelta = clp.Framecount * xd < clp.Width ? xd + 1 : xdglobal StrokeRadius = 20global StrokeOpacity = 1.0

ScriptClip(clp, """global xe = Min2(xe + xdelta, last.Width)DrawCurve(last, "Curve", xs, xe, 4)""")ConditionalReader("radius.txt", "StrokeRadius")ConditionalReader("opac.txt", "StrokeOpacity")

The rest of the code is simply the setup of global variables needed for proper execution and the actual calls to ScriptClip and ConditionalReader.

The later is to allow the radius and opacity of the pen strokes to be controlled by external files; this gives greater flexibility for determining the final shape of the pen strokes. The links following give the specific files used in this example: i.radius.txt and ii.opac.txt.

The assignment to xe global is used to advance the pen strokes towards the right of the clip on each frame. It could be done in a separate FrameEvaluate call, but also in a separate line of the script passed to SriptClip (with triple quotes) as well. Here the later is selected for no special reason.

Page 218: avisynth docu

As is the case always, there is space for improvement in the script; the next example script, version 2 introduces improvements regarding the loading of brushes and pens by creating more generic and easy to adapt code.

# AVSLib :: sample script # Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "base", "core")LoadModule("avslib", "array", "core")LoadModule("avslib", "array", "operators")LoadModule("avslib", "numeric", "rounding")LoadModule("avslib", "filters", "utility")

Function ImgSource(string file, clip template, int "target_w", \ int "target_h", int "frames", bool "pc_range"){ frames = Default(frames, template.Framecount) target_w = Default(target_w, template.Width) target_h = Default(target_h, template.Height) pc_range = Default(pc_range, false) ret = ImageSource(file, start=0, \ end=frames-1).AssumeFPS(template.Framerate) ret = ret.ConvertToTarget(template).BilinearResize(target_w, target_h) return pc_range ? ret.ScaleToPC() : ret}

Function MakeSolidPen(clip brush, int pen_color) { return brush.BlankClip(color=pen_color)}

# create a clip (640x480, 5 sec)

global clp = BlankClip(length=120, color=color_darkslateBlue, \ fps=24, width=640, height=480, pixel_type="YV12")

global pen_canvas = clp.BlankClip(color=color_black, length=1) # pens draw hereglobal brs_canvas = pen_canvas.ScaleToPC() # brushes draw here

# create solid color brushesFunction LoadBrush(int idx, clip tpl, int w, int h) { fname = "brush" + String(idx) + ".jpg" return ImgSource(fname, tpl, w, h, pc_range=true)}

Page 219: avisynth docu

global brushes = ArrayRange(1, 6).ArrayOpFunc("LoadBrush", "clp, 24, 24")

colors = "color_gold, color_beige, color_crimson, color_forestgreen, color_lightskyblue, color_firebrick"global pens = ArrayOpArrayFunc(brushes, colors, "MakeSolidPen")

# define the curves (they assume a 640x480 canvas)Function NormDist(float x, float m, float s) { return (1.0/(Sqrt(2*Pi)*s))*Exp(-Pow(x-m,2)/(2*Pow(s,2)))}Function SinPulse(float x, float xc, float peak, float spread) { return peak*NormDist(x, xc, spread)*Sin((x-xc)/(2*Pi)) }Function Curve(float x) { return 240 - 120 * Sin(0.65*x*Pi/320) + \ SinPulse(x, 520, 14000, 120) }

# Draw on x,y; x belongs to [x_start, x_end)# assumes brush, bmask have same dimensionsFunction DrawItems(clip pen, clip brush, int x_start, int y_start) { dx = Round(brush.Width / 2.0) dy = Round(brush.Height / 2.0) # shuffle x,y based on radius xr = x_start + Round(Rand(StrokeRadius*2) - StrokeRadius) yr = y_start + Round(Rand(StrokeRadius*2) - StrokeRadius) global pen_canvas = Overlay(pen_canvas, pen, x=xr-dx, y=yr-dy, \ mask=brush, opacity=StrokeOpacity) global brs_canvas = Overlay(brs_canvas, brush, x=xr-dx, y=yr-dy, \ mask=brush, opacity=StrokeOpacity, \ pc_range=true) return 1}

Function DrawCurve(clip c, string curve, int x_start, int x_end, int step){ dummy2 = (x_start < x_end && x_start > xlast) ? Eval(""" y_start = Round(Apply(curve, x_start)) dummy = ArrayOpArrayFunc(pens, brushes, "DrawItems", \ String(x_start) + "," + String(y_start)) global xlast = x_start """) : (x_start <= xlast ? Eval(""" x_start = IntBs(xlast, step) + step """) : NOP) return x_start < x_end \ ? DrawCurve(c, curve, x_start + step, x_end, step) \ : Overlay(c, pen_canvas, mask=brs_canvas, \ opacity=1.0, ignore_conditional=true) }

Page 220: avisynth docu

# begin drawglobal xlast = 0 global xs = 0global xe = 0xd = Int(clp.Width / clp.Framecount) global xdelta = clp.Framecount * xd < clp.Width ? xd + 1 : xdglobal StrokeRadius = 20global StrokeOpacity = 1.0

ScriptClip(clp, """global xe = Min2(xe + xdelta, last.Width)DrawCurve(last, "Curve", xs, xe, 4)""")ConditionalReader("radius.txt", "StrokeRadius")ConditionalReader("opac.txt", "StrokeOpacity")

he result of running the modified script up to its last frame is presented below.

Figure 2: Last frame of clip produced by example script (version 2)

The differences with the first version are briefly outlined below.

# create solid color brushes

Function LoadBrush(int idx, clip tpl, int w, int h) { fname = "brush" + String(idx) + ".jpg" return ImgSource(fname, tpl, w, h, pc_range=true)}

global brushes = ArrayRange(1, 6).ArrayOpFunc("LoadBrush", "clp, 24, 24")

colors = "color_gold, color_beige, color_crimson, color_forestgreen, " + \ "color_lightskyblue, color_firebrick"

Brushes are loaded by a custom function that calculates the filename based on an index. This allows to load a sequence of brushes with a simple ArrayRange call followed by ArrayOpFunc generated calls to the custom function in the same script line, thanks to OOP notation.

Page 221: avisynth docu

Here since clp is a global we simply pass its name to the LoadBrush's arguments inside ArrayOpFunc call; else (if clp was not a global) we would have to use either ArrayCreate(clp) or StrPrint("%g", clp) to create a global and get its name as a string.

The colors array is updated also, to accommodate for the three new brushes used: brush4.jpg, brush5.jpg and brush6.jpg.

Page 222: avisynth docu

10. Loop through filter settingsThis script demonstrates the use of the array facilities of AVSLib in order to produce comprehensive previews of the result of varying combinations of a filter's settings to a source clip.

In addition, the script demonstrates the debug logging facilities of AVSLib.

The example script applies a set of different filtering parameters combinations to a single (reference) frame of a clip and then joins the filtered frames into a single clip. The coding is such that one can easily modify the loop parameters, for example to make a second fine-grained pass of the most promissing subset of parameters combinations.

First the script:

# AVSLib :: sample script # Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "array", "core")LoadModule("avslib", "array", "operators")LoadModule("avslib", "array", "slices")LoadModule("avslib", "array", "functions")

# use a log file to quickly verify the correctness of looping through indices

LoadModule("avslib", "debug", "logging")

SetDebugFile("__log__.txt")SetDebugMode(DBG_LEVEL_1) # use DBG_NODEBUG to de-activate logging

# load a reference frame clip

global ref = AVISource("reference.avi").Trim(150, -1)

# in this example the filter to loop through is Levels

# 4*3*4*3*3 = 432 framesglobal l1 = "0,40,80,120" # input_lowglobal l2 = "0.75,1.0,1.5" # gammaglobal l3 = "255,210,165,120" # input_highglobal l4 = "0,80,160" # output_lowglobal l5 = "255,190,120" # output_high

total_loops = 5

Page 223: avisynth docu

global loop_counts = "4,3,4,3,3"

Function LoopDiv(int idx, string loop_cnt) { subrange = loop_cnt.ArrayGetRange(idx) return subrange.ArrayLen > 0 ? subrange.ArrayProduct() : 1}

total_steps = loop_counts.ArrayProduct()global loop_ids = ArrayRange(1, total_loops)global loop_divs = ArrayOpFunc(loop_ids, "LoopDiv", "loop_counts")

Function GetLoopIndex(int lid, int frame) { lcnt = loop_counts.ArrayGet(lid - 1) ldiv = loop_divs.ArrayGet(lid - 1) return (frame / ldiv) % lcnt}

Function GetLoopValue(int loop_id, int index) { return Eval("l" + String(loop_id) + ".ArrayGet(" + String(index) + ")")}

Function ApplyFilter(int frame){ indices = ArrayOpFunc(loop_ids, "GetLoopIndex", String(frame)) values = ArrayOpArrayFunc(loop_ids, indices, "GetLoopValue")

DebugLog(DBG_LEVEL_1, (frame == 0 ? "Processing frames:\n" : "") + \ "\tframe = %i\tindices = %s\tvalues = %s", frame, indices, values)

# In this example all filter's arguments are contained in 'values' array, so# constructing the command line is particularly easy; if named arguments are# wanted, use StrPrint() or ArrayGetString() ret = Eval("ref.Levels(" + values + ")") return ret.SubTitle(values)}DebugLog(DBG_LEVEL_1, "Starting filter looping\n\tloop_ids = \ %s\n\tloop_divs = %s", loop_ids, loop_divs)return ScriptClip(ref.Loop(total_steps), "ApplyFilter(current_frame)")

In order to speed-up the script's execution (previews must be fast) the script does not go through the creation of a combined array of all possible parameters combinations and then a series of trims.

Instead, the combinations are calculated on-the-fly for each frame inside a custom function, which is fed to ScriptClip. The above design uses small array sizes and a much smaller filter chain, thus offering increased performance.

A call to DebugLog inside the conditional environment function (ApplyFilter) prints out a nice log of all the loops' values to assist the script developer in confirming the correct operation of the script. The calls to SetDebugFile and SetDebugMode indicate where (the log's filename) and what will be logged (DebugLog will not print anything if its first argument is less than the one passed to SetDebugMode).

Page 224: avisynth docu

11. Loop through filter settings - revisitedThis script demonstrates the use of the array facilities of AVSLib in order to produce comprehensive previews of the result of varying combinations of a filter's settings to a source clip.

The script builds upon the previous example, extending it to demonstrate how it is possible to preview more complex filters, possibly with named arguments and / or temporal characteristics.

In addition, as in the previous example the script demonstrates the debug logging facilities of AVSLib.

The example script applies a set of different filtering parameters combinations to a single (reference) subrange of a clip and then joins the filtered clips into a single clip. The coding is such that one can easily modify the loop parameters, for example to make a second fine-grained pass of the most promissing subset of parameters combinations.

In addition the script stacks horizontally side-by-side the filtered and original clip to allow for easy review of the filter's effect. For large clips this means that you will need a wide screen display or to modify the script such that only an area of interest is selected (for example using Crop).

Now the script:

# AVSLib :: sample script # Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "array", "core")LoadModule("avslib", "array", "operators")LoadModule("avslib", "array", "slices")LoadModule("avslib", "array", "functions")

# use a log file to quickly verify the correctness of looping through indicesLoadModule("avslib", "debug", "logging")

SetDebugFile("__log__.txt")SetDebugMode(DBG_LEVEL_1) # use DBG_NODEBUG to de-activate logging

# load filter-specific modules (assumes they are at the same folder as the script)

LoadPlugin("MaskTools.dll")LoadPlugin("RemoveGrain.dll")LoadPlugin("Repair.dll")Import("SeeSaw.avs")

# load a reference clip

global ref = AVISource("reference.avi").Trim(98, -8).Spline36Resize(480, 360)global ref_frames = ref.Framecount

Page 225: avisynth docu

# in this example the filter to loop through is SeeSaw# 3*3*3*3*3*3*3 = 2187 blocks * 8 frames = 17496 framesglobal l1 = "2,4,6" # NRlimitglobal l2 = "3,5,7" # NRlimit2global l3 = "1.3,1.5,1.7" # Sstrglobal l4 = "20,24,28" # SdampHiglobal l5 = "42,49,56" # biasglobal l6 = "42,49,56" # sootheTglobal l7 = "0,2,4" # sootheS

total_loops = 7global loop_counts = "3,3,3,3,3,3,3"

Function LoopDiv(int idx, string loop_cnt) { subrange = loop_cnt.ArrayGetRange(idx) return subrange.ArrayLen > 0 ? subrange.ArrayProduct() : 1}

total_steps = loop_counts.ArrayProduct()global loop_ids = ArrayRange(1, total_loops)global loop_divs = ArrayOpFunc(loop_ids, "LoopDiv", "loop_counts")

Function GetLoopIndex(int lid, int frame) { lcnt = loop_counts.ArrayGet(lid - 1) ldiv = loop_divs.ArrayGet(lid - 1) return ((frame / ref_frames) / ldiv) % lcnt # int divisions; remainder is trunced}

Function GetLoopValue(int loop_id, int index) { return Eval("l" + String(loop_id) + ".ArrayGet(" + String(index) + ")")}

Function ApplyFilter(int frame){ indices = ArrayOpFunc(loop_ids, "GetLoopIndex", String(frame)) values = ArrayOpArrayFunc(loop_ids, indices, "GetLoopValue")

DebugLog(DBG_LEVEL_1, (frame == 0 ? "Processing frames:\n" : "") + \ "\tframe = %i\tblock = %i\tindices = %s\tvalues = %s", frame, \ (frame / ref_frames), indices, values)

Page 226: avisynth docu

# In this example filter's arguments are named, so constructing the command line # is a bit more tricky cmdline = "SeeSaw(ref, NRlimit=" + values.ArrayGetString(0) + \ ", NRLimit2=" + values.ArrayGetString(1) + \ ", Sstr=" + values.ArrayGetString(2) + \ ", sdampHi=" + values.ArrayGetString(3) + \ ", bias=" + values.ArrayGetString(4) + \ ", sootheT=" + values.ArrayGetString(5) + \ ", sootheS=" + values.ArrayGetString(6) + \ ")" # run the filter; stack with the original for immediate comparison ret = Eval(cmdline) # we tream after evaluating the filter, in order for the correct frame #to be returned return StackHorizontal( \ ret.Trim(frame % ref_frames, -1).SubTitle(cmdline, size=12, \ text_color=color_white, halo_color=color_gray20), \ ref.Trim(frame % ref_frames, -1).SubTitle("Original", size=12, \ text_color=color_white, halo_color=color_gray20))}

DebugLog(DBG_LEVEL_1, "Starting filter looping\n\tloop_ids = %s\n\tloop_divs = \ %s", loop_ids, loop_divs)

# in order for stackhorizontal to work, must stack here alsoclp = ref.Loop(total_steps)return ScriptClip(StackHorizontal(clp, clp), "ApplyFilter(current_frame)")

As it is apparent from the code, the overall structure of the previous example script is retained. However, in order to achieve the new functionality a number of changes are made, notably the following:

• The filter-invocation command is constructed with ArrayGetString() due to the need to assign to named arguments.

ArrayGetString is handy for that purposes because it directly returns the proper string representation of the array element (except of quoting of string values; in that case one must use StrQuote() afterwards).

• The frame number is divided with reference clip's total frames in GetLoopIndex in order to access the correct index settings for each frame.

• ret and ref clips are trimmed (frame mod ref.Framecount) on each frame in order to achieve the "recycling" of the reference clip in the whole frame sequence.

The above skeleton can be adopted for more elaborate tasks also, with minor changes. For example, one can crop the reference clip before passing it to the conditional environment in order to focus on a specific area of the clip. Or, if a number of filtering operations is desired in one pass, one can write a custom function that will accept an array of values and will call the appropriate filters in sequence.

Page 227: avisynth docu

12. Load, convert and join with transition effect arbitrary clipsThis script extends the basic ideas of the fifth and eighth examples. It applies a moderately complex filtering sequence (resizing and colorspace and fps conversion) based on the arguments' values and also joins the clips serially in a single timeline applying a relatively complex transition effect.

Shell scripts to automate the creation of the text files as well as the rendering of the .avs script are also provided. The later allow to treat the script as an Avisynth "program" which, in cooperation with a command line driven encoder (such as Avs2Avi, ffmpeg or VirtualDub plus a Sylia script) can fully automate complex NLE processes, reducing them to single shell command invocations.

First the script. The transition code is contained first, followed by the same clips' importing and filtering section that was presented at the eighth example. The last lines of the script are different though, to allow the more complex joining process that this example demonstrates.

# AVSLib :: sample script # Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

# load required modulesLoadModule("avslib", "base", "constants")LoadModule("avslib", "base", "conversion")LoadPackage("avslib", "array")LoadPackage("avslib", "clip")LoadModule("avslib", "numeric", "rounding")LoadModule("avslib", "string", "search")LoadModule("avslib", "filters", "edit")LoadModule("avslib", "filters", "stack")

# transition codeFunction Crop4x4(int i, clip c) { cw = Round(c.Width / 4) ch = Round(c.Height / 4) row = Int(i / 4) # [0..3] col = i % 4 # [0..3] return c.Crop(col * cw, row * ch, cw, ch, true)}# Using a single underscore is a good convention for private user globals;# they do not clash with AVSLib namespaceglobal _crop_clip = BlankClip(length=0)Function ClipDivide4x4(clip base) { loop = ArrayRange(0, 15, step=1) global _crop_clip = base return ArrayOpFunc(loop, "Crop4x4", "_crop_clip")}

Page 228: avisynth docu

# assume each subclip is 15 frames long; appear is a flags arrayglobal _fade_count = 0

# either blanks clip c or leaves it unchanged, depending on value of flagFunction _ovl_clip5(clip c, val aflag) { return aflag > 0 ? c : c.BlankClip() }Function FadeSubClip(clip subclip, string appear) { ap = ArraySplit(appear, _fade_count, chunksize=5) # increase counter so that next call process next subclip global _fade_count = _fade_count + 1 # split subclip to 5 pieces ac = ArrayCreate( \ subclip.EditTrim(0, 3), \ subclip.EditTrim(3, 6), \ subclip.EditTrim(6, 9), \ subclip.EditTrim(9, 12), \ subclip.EditTrim(12, 15) \ ) # blank subclip in all parts where ap has zeros and recombine pieces video = ArrayOpArrayFunc(ac, ap, "_ovl_clip5").ArraySum() # keep audio from original clip to maintain precision return AudioDub(video, subclip)}

# Creates a vanishing / appearing checkboard transition effect.# Since we will use the function with EditJoin we know that there always be # two clip arguments.Function Transition(clip c1, clip c2) { start = c1.EditTrim(0, -8) # all but last 8 ef1 = c1.EditTrim(-8) # last 8 ef2 = c2.EditTrim(0, 7) # first 7 end = c2.EditTrim(7) # all but first 7

# divide effect clips to a matrix of 4x4 subclips, each with 15 # frames & merge (+) cr = ArrayOpArray(ef1.ClipDivide4x4(), ef2.ClipDivide4x4(), "+")

# create subclip appearence flag arrays, one for each 3 frames # (5 steps total) in each step make 4 subclips to dissapear for # ef1 and 4 to apear for ef2 b1 = "1,1,0,1, 0,1,1,1, 1,0,1,1, 1,1,1,0" b2 = "1,1,0,1, 0,0,1,0, 1,0,0,1, 0,1,1,0" b3 = "0,0,0,1, 1,0,0,0, 0,0,0,1, 0,0,1,0" b4 = "0,0,1,1, 1,0,1,0, 0,1,0,1, 1,0,1,0" b5 = "1,0,1,1, 1,1,1,0, 0,1,0,1, 1,1,1,1"

Page 229: avisynth docu

# multiplex flag arrays in order to create continuous blocks of flags # (ie the columns of the table above) for each subclip appear = ArrayPlex(b1, b2, b3, b4, b5) global _fade_count = 0 crf = ArrayOpFunc(cr, "FadeSubClip", StrQuote(appear)) trans = Stack(crf, 4, 4) return start + trans + end}# load a text file containing dir /b output # surrounded by triple quotes at the start and end of filedir = Import("files.txt")

# load two text files containing integers # (target width and height for the clips in dir)tw = Import("width.txt")th = Import("height.txt")

Assert(tw.IsInt && th.IsInt, \ "Input Error: width or/and height files contain invalid data")# after that dir is an array of filenames!# but be careful if you hand-type arrays... (see the transition code block)ArrayDelimiterSet(CRLF)

# cleanup dir from invalid files (CInt is used to convert true/false to 1/0)okflag = dir.ArrayOpFunc("Exist").ArrayOpFunc("CInt")dir = dir.ArrayReduce(okflag)

Assert(dir.ArrayLen > 0, \ "Input Error: files.txt does not contain any valid filename")# read in clipsclp = dir.ArrayOpFunc("DirectShowSource")

# force clip parameters (dimensions, framerate, colorspace) to be the same# assume all clips are progressiveb_same_fps = (clp.ArrayOpFunc("Framerate").ArrayDistinct().ArrayLen() == 1)pixel_type = clp.JointPixelType()fps = clp.JointFPS()

# to assure that target width, height match any clip's colospace # restrictions we allow for the more restrictive type (yv12)tw = RoundBs(tw, 4)th = RoundBs(th, 4)# now convert clips (resize, convertto..., changefps)clp = clp.ArrayOpFunc("Spline36Resize", String(tw) + "," + String(th))clp = clp.ArrayOpFunc("ConvertTo" + pixel_type)clp = b_same_fps \ ? clp \

Page 230: avisynth docu

: clp.ArrayOpFunc("ConvertFPS", String(fps))# restore now default array delimiter, in order for transition code to work# restore also delimiters inside clp (a simple strreplace op.)old = ArrayDelimiterReset()clp = StrReplace(clp, old, ",")

# join clips together one after the other, applying EditJoin with # custom user function (our transition) in each join# we cannot pass a quoted string to sum_args (even with three double quotes), # so we assign the string to a global and pass in the global's name unquotedglobal _tr_func = "Transition"return clp.ArraySum(sum_func="EditJoin", sum_args="op=EDOP_USER, \ extra_info=_tr_func")

In the example above the script first loads and auto-convert all supplied clips to compatible characteristics for splicing. See examples five and eight for details.

Afterwards, the now homogenised clips are integrated together with EditJoin in just a single line of code, thanks to the array operators facilities of AVSLib (see the related tutorial for a more in-depth presentation).

The transition filter is passed in as a global, because quoted arguments do not work well inside ArraySum. Although this is a hack it does not hurt to do so, since globals will always be evaluated correctly even when this limitation will eventually be arised at the future.

As in the fifth and eighth examples, the creation of the .txt files can easily be automated with a custom shell script. A working example regarding the clips (say named "avidir.cmd") is provided below:

@echo offecho """for %%f in (%1) do @echo %%~ffecho """

The shell script takes one (needed) argument, a wildcard specification which can include path information in case the files are not at the current directory. The script outputs absolute filenames, so that the calling avisynth script can be located anywhere in the filesystem.

The final step to automate the process is to make another custom shell script (say "makeavi.cmd") that will update the contents of the text files and (optionally, depending on your needs) invoke the encoder. For example:

@echo offavidir %1 > files.txtecho %2 > width.txtecho %3 > height.txtavs2avi script.avs -l %4

The top level shell script takes four arguments, a wildcard specification, two integer values for the width and heigh and an additional 4th argument (a filename with the codec settings). It is assumed that the encoder executable is placed at a folder included in the PATH environment variable.

Thus you can invoke a single shell command in order to import, NLE process and encode a set of clips, such as:

makeavi [wildcard] [width] [height] [codecsettings]

If another encoder is used , the top level script must be modified appropriately to account for the different command line options needed by the encoder.

Page 231: avisynth docu

13. Multi-color mask creation and manipulationThis example script creates combined colormasks of multiple colors and manipulates them in various ways. To demonstrate the applicability of color mask selection to moving objects, an animated source is constructed using the animation filters supplied by AVSLib.

First the script. In this example, colors are provided as R,G,B triplets in decimal, as it is common to show up in image editing applications. Typically in real video editing this will be the most convenient way to specify color values, since the values will have been read inside an image editing application from a group of sample frames of the video.

# AVSLib :: sample script # Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadPackage("avslib", "array")LoadModule("avslib", "clip", "core")LoadModule("avslib", "filters", "stack")LoadModule("avslib", "filters", "animate")LoadModule("avslib", "filters", "utility")LoadPlugin("mt_masktools.dll")

# ------ create a source ---------clp = BlankClip(pixel_type="YUY2", length=401)clp = Overlay(clp, clp.BlankClip(color=color_red, width=100, height=100), \ x=100, y=100)clp = Overlay(clp, clp.BlankClip(color=color_green, width=100, height=100), \ x=200, y=200)clp = Overlay(clp, clp.BlankClip(color=color_blue, width=100, height=100), \ x=300, y=100)clp = Overlay(clp, clp.BlankClip(color=color_magenta, width=100, height=100), \ x=300, y=300)f = ArrayRange(0,400,50)x = "0,120,240,120,0,120,240,120,0"y = "0,80,0,-100,0,80,0,-100,0"x = x.ArrayOpValue(Round(clp.Width / 2), "+")y = y.ArrayOpValue(Round(clp.Height / 2), "+")

clp = clp.BlankClip().PolygonAnim(clp, f, x, y)clp = clp.ConvertToRGB32.ResetMask()

# ------ apply color masks ---------Function _to_RGB(string colors) { old = ArrayDelimiterReset ret = MakeRGBColor(colors.ArrayGet(0), colors.ArrayGet(1), \ colors.ArrayGet(2))

Page 232: avisynth docu

old = ArrayDelimiterSet(old) return ret}Function _make_mask(int color, clip c) { return c.ColorKeyMask(color, 20).ShowAlpha().Invert()}mask_colors = "255,0,0|0,128,0|0,0,255|255,0,255"

old = ArrayDelimiterSet("|")colors = mask_colors.ArrayOpFunc("_to_RGB")cmasks = colors.ArrayOpFunc("_make_mask", ArrayCreate(clp))

# quoted strings inside sum_args do not work; workaround with a globalglobal mode = "or"msk = cmasks.ArraySum("ConvertToYV12", sum_func="mt_logic", sum_args="mode")msk_if = msk.FilterChain("mt_inflate", 6, "u=2, v=2" \ ).FilterChain("Blur", 100, "1.25" \ ).FilterChain("mt_deflate", 6, "u=2, v=2")rst = Overlay(clp, clp.BlankClip(color=color_gold), mask=msk, opacity=0.4)

StackToFit( \ ArrayCreate(clp, msk.ConvertToRGB32, msk_if.ConvertToRGB32, rst), \ 4*240, 3*240)

Now look at the code

LoadPackage("avslib", "array")LoadModule("avslib", "clip", "core")LoadModule("avslib", "filters", "stack")LoadModule("avslib", "filters", "animate")LoadModule("avslib", "filters", "utility")LoadPlugin("mt_masktools.dll")# ------ create a source ---------clp = BlankClip(pixel_type="YUY2", length=401)clp = Overlay(clp, clp.BlankClip(color=color_red, width=100, height=100), \ x=100, y=100)clp = Overlay(clp, clp.BlankClip(color=color_green, width=100, height=100), \ x=200, y=200)clp = Overlay(clp, clp.BlankClip(color=color_blue, width=100, height=100), \ x=300, y=100)clp = Overlay(clp, clp.BlankClip(color=color_magenta, width=100, height=100), \ x=300, y=300)f = ArrayRange(0,400,50)x = "0,120,240,120,0,120,240,120,0"y = "0,80,0,-100,0,80,0,-100,0"x = x.ArrayOpValue(Round(clp.Width / 2), "+")y = y.ArrayOpValue(Round(clp.Height / 2), "+")clp = clp.BlankClip().PolygonAnim(clp, f, x, y)clp = clp.ConvertToRGB32.ResetMask()

Page 233: avisynth docu

Up to this point the script loads needed modules and plugins and constructs its animated source. This consists of a blank clip on top of which four colored rectangles are overlayed. The clip then is moved in a polygonal line such that the area occupied by the rectangles seems to collide and jump back from the borders of the clip like a particle in a box.

f, x, and y correspond to frame number, x position and y position of the moving clip. The call to ArrayOpValue is made to translate the x and y coordinates from the top-left corner of the clip to its center, as needed by the PolygonAnim filter.

# ------ apply color masks ---------Function _to_RGB(string colors) { old = ArrayDelimiterReset() ret = MakeRGBColor(colors.ArrayGet(0), colors.ArrayGet(1), \ colors.ArrayGet(2)) old = ArrayDelimiterSet(old) return ret}Function _make_mask(int color, clip c) { return c.ColorKeyMask(color, 20).ShowAlpha().Invert()}mask_colors = "255,0,0|0,128,0|0,0,255|255,0,255"

old = ArrayDelimiterSet("|")colors = mask_colors.ArrayOpFunc("_to_RGB")cmasks = colors.ArrayOpFunc("_make_mask", ArrayCreate(clp))# quoted strings inside sum_args do not work; workaround with a globalglobal mode = "or"msk = cmasks.ArraySum("ConvertToYV12", sum_func="mt_logic", sum_args="mode")msk_if = msk.FilterChain("mt_inflate", 6, "u=2, v=2" \ ).FilterChain("Blur", 100, "1.25" \ ).FilterChain("mt_deflate", 6, "u=2, v=2")rst = Overlay(clp, clp.BlankClip(color=color_gold), mask=msk, opacity=0.4)

StackToFit( \ ArrayCreate(clp, msk.ConvertToRGB32, msk_if.ConvertToRGB32, rst), \ 4*240, 3*240)

To create the colors from the decimal R,G,B triplets a custom function is used that expects an array of RGB color triplets with the default (comma) array delimiter; the function then calls the MakeRGBColor to do the actual work. Current array delimiter is stored and restored before leaving the function, a practise that must be followed by any function that expects an array with a specific delimiter.

The colors array is then passed to _make_mask custom function to create the array of separate color masks. Because we want to act on what is inside the mask (ie we want to operate on masked colors and not to protect them) the Invert standard Avisynth filter is used inside _make_mask.

The separate mask clips are then summed up with mt_logic using "or" mode, with a call to ArraySum. Because mt_logic accepts only YV12 input, ConvertToYV12 is used as the elm_func argument of ArraySum to make the conversion.

The combined mask is then proccessed, with a series of calls to mt_inflate, Blur and mt_deflate filters, conveniently grouped in just a few lines through the use of the FilterChain filter. This is just to demonstrate the possibilities offered by AVSLib for irregular color key masks manipulations; here since our masked shape is highly regular the initial mask is better suited for subsequent operations.

Page 234: avisynth docu

Finally a simple color transformation of the source clip (color shift) is performed using the created mask. The original and modified clips along with the masks are stacked together in a specified frame size with the help of the StackToFit filter

Page 235: avisynth docu

14. Create an expanding rotating circle of rotating starsThis series of examples script demonstrates the (large) improvement in capacity and speed of the animation filters supplied by AVSLib in version 1.1.0, compared to previous versions.

The first example script performs the same animation as the sixth animation example of version's 1.0.0 documentation - that is twelve rectangles that move spirally from the center to the border of the screen while in parallel they enlarge and overlayed in each animation interval with a different overlay mode setting; the final visual result being a rotating circle of rectangles that grows in radius while the rectangles grow in size - but in a single script instead of a six-scripts chain.

The improvement in capacity is more than 6 to 1, since now the overal process size to run the script is now well below 1 GB, while the process size for running the previous version's scripts was a bit lower than 2 GB for each script in the chain.

The second example script makes the same animation but with clips showing a rotating star, thus producing an expanding rotating circle of rotating stars.

# AVSLib :: sample script # Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadPackage("avslib", "base")LoadPackage("avslib", "array")LoadModule("avslib", "filters", "animate")

# Animates expanding rectangles on multiple curves, with varying overlay modesglobal _thetas = ArrayRange(0, 2*Pi(), npoints=21)global _aparam = 40# r,theta correspond to Archimedes spiral (a*theta, theta)global _rs = _thetas.ArrayOpValue(_aparam, "*")

Function xpolar(float r, float theta) { return Float(r)*Cos(theta) }Function ypolar(float r, float theta) { return Float(r)*Sin(theta) }

global xy_path = ArrayPlex( \ ArrayOpArrayFunc(_rs, _thetas, "xpolar").ArrayOpFunc("Round"), \ ArrayOpArrayFunc(_rs, _thetas, "ypolar").ArrayOpFunc("Round") \ )global wh_dims = ArrayRange(12, 92, 4)global o_modes = \ "blend,add,blend,subtract,blend,chroma,blend,blend,luma,blend,blend," + \ "lighten,blend,blend,softlight,blend,blend,hardlight,blend,blend" # one less than xy_path

Page 236: avisynth docu

Function xrot(int x, int y, float angle) { return Round(x*Cos(angle) - y*Sin(angle)) }Function yrot(int x, int y, float angle) { return Round(x*Sin(angle) + y*Cos(angle)) }# rotates a plexed (x,y) path by angle radiansFunction rotate_path(string path, float angle) { path_x = path.ArrayDeplex(0, 2) path_y = path.ArrayDeplex(1, 2) new_x = ArrayOpArrayFunc(path_x, path_y, "xrot", String(angle)) new_y = ArrayOpArrayFunc(path_x, path_y, "yrot", String(angle)) return ArrayPlex(new_x, new_y)}

# the base effect functionFunction rect_effect(clip base, string path, int rect_color) { rect = BlankClip(base, color=rect_color) frames = ArrayRange(0, base.Framecount - 1, npoints=21).ArrayOpFunc("Round") # relocate path to center of base clip xp = path.ArrayDeplex(0,2).ArrayOpValue(Round(base.Width / 2), "+") yp = path.ArrayDeplex(1,2).ArrayOpValue(Round(base.Height / 2), "+") # not specifying a mask == full white mask return PolygonAnim(base, rect, frames, xp, yp, 1.0, wh_dims, \ wh_dims, mode=o_modes)}# the angle step to rotate base (x,y) path ( 2pi/{number of curves} ) the # last being 12global theta = Pi()/6 # 30 degrees

# since color constants are globals creating an array with their names will# return their valueglobal in_colors = "color_gold,color_ivory,color_mediumorchid,color_beige,color_aquamarine,” +\"color_blue,color_darkorange,color_white,color_darkred," + \"color_crimson,color_olivedrab,color_chocolate"Function MakeEffect006(clip base) { c = base c = c.rect_effect(xy_path, in_colors.ArrayGet( 0)) c = c.rect_effect(xy_path.rotate_path( theta), in_colors.ArrayGet( 1)) c = c.rect_effect(xy_path.rotate_path( 2*theta), in_colors.ArrayGet( 2)) c = c.rect_effect(xy_path.rotate_path( 3*theta), in_colors.ArrayGet( 3)) c = c.rect_effect(xy_path.rotate_path( 4*theta), in_colors.ArrayGet( 4)) c = c.rect_effect(xy_path.rotate_path( 5*theta), in_colors.ArrayGet( 5)) c = c.rect_effect(xy_path.rotate_path( 6*theta), in_colors.ArrayGet( 6)) c = c.rect_effect(xy_path.rotate_path( 7*theta), in_colors.ArrayGet( 7)) c = c.rect_effect(xy_path.rotate_path( 8*theta), in_colors.ArrayGet( 8))

Page 237: avisynth docu

c = c.rect_effect(xy_path.rotate_path( 9*theta), in_colors.ArrayGet( 9)) c = c.rect_effect(xy_path.rotate_path(10*theta), in_colors.ArrayGet(10)) c = c.rect_effect(xy_path.rotate_path(11*theta), in_colors.ArrayGet(11)) return c}

# create a 8sec animation in PAL formatbase = BlankClip(color=$020060, length=200, fps=FRATE_PAL, width=WSIZE_PAL, height=HSIZE_PAL).ConvertToYV12()return MakeEffect006(base)

Lets now look closer at the first script:

LoadPackage("avslib", "base")LoadPackage("avslib", "array")LoadModule("avslib", "filters", "animate")

global _thetas = ArrayRange(0, 2*Pi(), npoints=21)global _aparam = 40# r,theta correspond to Archimedes spiral (a*theta, theta)global _rs = _thetas.ArrayOpValue(_aparam, "*")

Function xpolar(float r, float theta) { return Float(r)*Cos(theta) }Function ypolar(float r, float theta) { return Float(r)*Sin(theta) }

global xy_path = ArrayPlex( \ ArrayOpArrayFunc(_rs, _thetas, "xpolar").ArrayOpFunc("Round"), \ ArrayOpArrayFunc(_rs, _thetas, "ypolar").ArrayOpFunc("Round") \ )global wh_dims = ArrayRange(12, 92, 4)global o_modes = \ "blend,add,blend,subtract,blend,chroma,blend,blend," + \ "luma,blend,blend,lighten,blend,blend,softlight,blend," + \ "blend,hardlight,blend,blend" # one less than xy_path

Function xrot(int x, int y, float angle) { return Round(x*Cos(angle) - y*Sin(angle)) }Function yrot(int x, int y, float angle) { return Round(x*Sin(angle) + y*Cos(angle)) }

# rotates a plexed (x,y) path by angle radiansFunction rotate_path(string path, float angle) { path_x = path.ArrayDeplex(0, 2) path_y = path.ArrayDeplex(1, 2) new_x = ArrayOpArrayFunc(path_x, path_y, "xrot", String(angle)) new_y = ArrayOpArrayFunc(path_x, path_y, "yrot", String(angle)) return ArrayPlex(new_x, new_y)}

Up to this point the script loads needed modules and plugins and constructs the spiral path for the movement of

Page 238: avisynth docu

the rectangles. Since the path is defined in polar coordinates, a couple of polar functions are defined to calculate the x,y cartesian coordinates of the path points.

The x and y arrays of coordinates are then multiplexed, by calling ArrayPlex, in a (x,y) array (the equivalent of a 2D matrix) in order to have one variable to hold all the path info.

Two additional arrays, wh_dims to hold the rectangle size at each path point, and o_modes, to hold the overlay mode in each path segment between two path points are defined.

Then a function to rotate a (x,y) path by a given angle, rotate_path, is defined. Inside it the path is de-multiplexed in separate x and y arrays by calling ArrayDeplex; then an appropriate coordinates-rotation function is applied to them and they are again multiplexed and returned as the new, rotated, path.

# the base effect functionFunction rect_effect(clip base, string path, int rect_color) { rect = BlankClip(base, color=rect_color) frames = ArrayRange(0, base.Framecount - 1, npoints=21).ArrayOpFunc("Round") # relocate path to center of base clip xp = path.ArrayDeplex(0,2).ArrayOpValue(Round(base.Width / 2), "+") yp = path.ArrayDeplex(1,2).ArrayOpValue(Round(base.Height / 2), "+") # not specifying a mask == full white mask return PolygonAnim(base, rect, frames, xp, yp, 1.0, \ wh_dims, wh_dims, mode=o_modes)}

# the angle step to rotate base (x,y) path ( 2pi/{number of curves} ) the last being 12global theta = Pi()/6 # 30 degrees

# since color constants are globals creating an array with their names # will return their valueglobal in_colors = "color_gold,color_ivory,color_mediumorchid,color_beige," + \ "color_aquamarine,color_blue,color_darkorange,color_white,color_darkred," + \ "color_crimson,color_olivedrab,color_chocolate"Function MakeEffect006(clip base) { c = base c = c.rect_effect(xy_path, in_colors.ArrayGet( 0)) c = c.rect_effect(xy_path.rotate_path( theta), in_colors.ArrayGet( 1)) c = c.rect_effect(xy_path.rotate_path( 2*theta), in_colors.ArrayGet( 2)) c = c.rect_effect(xy_path.rotate_path( 3*theta), in_colors.ArrayGet( 3)) c = c.rect_effect(xy_path.rotate_path( 4*theta), in_colors.ArrayGet( 4)) c = c.rect_effect(xy_path.rotate_path( 5*theta), in_colors.ArrayGet( 5)) c = c.rect_effect(xy_path.rotate_path( 6*theta), in_colors.ArrayGet( 6)) c = c.rect_effect(xy_path.rotate_path( 7*theta), in_colors.ArrayGet( 7)) c = c.rect_effect(xy_path.rotate_path( 8*theta), in_colors.ArrayGet( 8)) c = c.rect_effect(xy_path.rotate_path( 9*theta), in_colors.ArrayGet( 9)) c = c.rect_effect(xy_path.rotate_path(10*theta), in_colors.ArrayGet(10)) c = c.rect_effect(xy_path.rotate_path(11*theta), in_colors.ArrayGet(11)) return c}

Page 239: avisynth docu

The base effect function, rect_effect, demultiplexes the supplied path, translates, using ArrayOpValue, all coordinates so that they correspond to the center of the overlay clip and passes the arrays to PolygonAnim filter to draw the animation accross the supplied path. Frame numbers are calculated dynamically, based on base clip's length, with the aid of ArrayRange function.

A small note here: the excersized reader may have already noticed that if separate x and y arrays where used instead of a combined (x,y) array we would avoid the costs of uneeded multiplexing and demultiplexing operations with only the small added complexity of passing one more parameter; however this is a demonstration script, thus we can afford to be a bit more un-optimized in order to show in addition the way to construct a combined (x,y) path for the case someone needs it at the future!

The rest is the definition of rotation angle, of rectangles' colors and of the overall effect function, which simply calls the base effect function for all elements of the colors array with increasing rotation angle.

# create a 8sec animation in PAL formatbase = BlankClip(color=$020060, length=200, fps=FRATE_PAL, width=WSIZE_PAL, \ height=HSIZE_PAL).ConvertToYV12()return MakeEffect006(base)

Finally, a base source is created and the overall animation effect function is called.

The second script example adds a level of complexity and visual appealence to the basic idea, simply because it can now afford to do so due to the increased capacity of AVSLib version 1.1.0 animation filters: instead of animating rectangles, it animates clips showing a rotating star. The overal effect is now an expanding rotating circle of rotating stars.

The second script is as below:

# AVSLib :: sample script # Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadPackage("avslib", "base")LoadPackage("avslib", "array")LoadModule("avslib", "filters", "resize")LoadModule("avslib", "filters", "animate")LoadModule("avslib", "filters", "utility")

# Animates expanding rectangles on multiple curves, with varying overlay modes

global _thetas = ArrayRange(0, 2*Pi(), npoints=21)global _aparam = 40# r,theta correspond to Archimedes spiral (a*theta, theta)global _rs = _thetas.ArrayOpValue(_aparam, "*")

Function xpolar(float r, float theta) { return Float(r)*Cos(theta) }Function ypolar(float r, float theta) { return Float(r)*Sin(theta) }

global xy_path = ArrayPlex( \

Page 240: avisynth docu

ArrayOpArrayFunc(_rs, _thetas, "xpolar").ArrayOpFunc("Round"), \ ArrayOpArrayFunc(_rs, _thetas, "ypolar").ArrayOpFunc("Round") \ )global wh_dims = ArrayRange(12, 92, 4)global o_modes = \ "blend,add,blend,subtract,blend,chroma,blend,blend,luma,blend,blend," + \ "lighten,blend,blend,softlight,blend,blend,hardlight,blend,blend" # one less than xy_path

Function xrot(int x, int y, float angle) { return Round(x*Cos(angle) - y*Sin(angle)) }Function yrot(int x, int y, float angle) { return Round(x*Sin(angle) + y*Cos(angle)) }

# rotates a plexed (x,y) path by angle radiansFunction rotate_path(string path, float angle) { path_x = path.ArrayDeplex(0, 2) path_y = path.ArrayDeplex(1, 2) new_x = ArrayOpArrayFunc(path_x, path_y, "xrot", String(angle)) new_y = ArrayOpArrayFunc(path_x, path_y, "yrot", String(angle)) return ArrayPlex(new_x, new_y)}

# the base effect functionFunction rect_effect(clip base, clip effmask, string path, int rect_color) { rect = BlankClip(base, color=rect_color) frames = ArrayRange(0, base.Framecount - 1, npoints=21).ArrayOpFunc("Round") # relocate path to center of base clip xp = path.ArrayDeplex(0,2).ArrayOpValue(Round(base.Width / 2), "+") yp = path.ArrayDeplex(1,2).ArrayOpValue(Round(base.Height / 2), "+") return PolygonAnim(base, rect, frames, xp, yp, 1.0, wh_dims, wh_dims, mode=o_modes, mask=effmask)}

# the angle step to rotate base (x,y) path ( 2pi/{number of curves} ) the last # being 12global theta = Pi()/6 # 30 degrees

# since color constants are globals creating an array with their names will # return their valueglobal in_colors = "color_gold,color_ivory,color_mediumorchid,color_beige,color_aquamarine, + \"color_blue,color_darkorange,color_white,color_darkred," + \"color_crimson,color_olivedrab,color_chocolate"Function MakeEffect006(clip base, clip effmask) { c = base c = c.rect_effect(effmask, xy_path, in_colors.ArrayGet( 0)) c = c.rect_effect(effmask, xy_path.rotate_path( theta), in_colors.ArrayGet( 1)) c = c.rect_effect(effmask, xy_path.rotate_path( 2*theta), in_colors.ArrayGet( 2))

Page 241: avisynth docu

c = c.rect_effect(effmask, xy_path.rotate_path( 3*theta), in_colors.ArrayGet( 3)) c = c.rect_effect(effmask, xy_path.rotate_path( 4*theta), in_colors.ArrayGet( 4)) c = c.rect_effect(effmask, xy_path.rotate_path( 5*theta), in_colors.ArrayGet( 5)) c = c.rect_effect(effmask, xy_path.rotate_path( 6*theta), in_colors.ArrayGet( 6)) c = c.rect_effect(effmask, xy_path.rotate_path( 7*theta), in_colors.ArrayGet( 7)) c = c.rect_effect(effmask, xy_path.rotate_path( 8*theta), in_colors.ArrayGet( 8)) c = c.rect_effect(effmask, xy_path.rotate_path( 9*theta), in_colors.ArrayGet( 9)) c = c.rect_effect(effmask, xy_path.rotate_path(10*theta), in_colors.ArrayGet(10)) c = c.rect_effect(effmask, xy_path.rotate_path(11*theta), in_colors.ArrayGet(11)) return c}

# create a 8sec animation in PAL formatbase = BlankClip(color=$020060, length=200, fps=FRATE_PAL, width=WSIZE_PAL, height=HSIZE_PAL)base = base.ConvertToYV12()effmask = ImageSource("star%06d.jpg", 0, 48, 25.0).Reverse().Loop(10).Trim(0,199)effmask = effmask.ResizeToTarget(base).ConvertToTarget(base).ScaleToPC()return MakeEffect006(base, effmask)

The base effect function now accepts one more argument, a clip mask, which is passed to the PolygonAnim filter. The same is true for the overall effect function, since it must pass the mask to the base effect function.

In addition, two more modules are loaded, to provide the filters (ResizeToTarget and ConvertToTarget) that convert the mask's source image sequence into a clip with the same characteristics as the base clip.

The top-level section of the script loads the image sequence and (with the filters above) converts it to a mask clip compatible with the base clip. ScaleToPC ensures that the mask is in full [0..255] range.

The result of running the script is presented below.

Page 242: avisynth docu

15. Per frame filtering, a position + size + color animationThis series of example scripts demonstrates the capabilities offered by the filters of the new in AVSLib version 1.1.0 filters :: frames module. The filter used in the examples is FrameFilterReader.

The first example script moves a rotating star accross a complex closed x,y curve, while in parallel its dimensions (width and height) oscillate giving the impression of the star tilting accross the horizontal and vertical axes. At the same time the star's color varies constantly due to variation of its RGB components.

The first script:

# AVSLib :: sample script # Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "base", "constants")LoadPackage("avslib", "array")LoadModule("avslib", "clip", "core")LoadModule("avslib", "filters", "frames")LoadModule("avslib", "filters", "resize")LoadModule("avslib", "filters", "utility")

# afford a start/end blank to make code nicer to look# it will be cleaned by the stuff belowvarfiles = """r.txtg.txtb.txtw.txth.txtx.txty.txt""" old = ArrayDelimiterSet(CRLF)okflag = varfiles.ArrayOpFunc("Exist").ArrayOpFunc("CInt")varfiles = varfiles.ArrayReduce(okflag)old = ArrayDelimiterSet(old)

FilterScript = """star_mask=%grect_color = MakeRGBColor(${read1}, ${read2}, ${read3})ovl = BlankClip(last, width=last.SafeWidth(${read4}), \ height=last.SafeHeight(${read5}), color=rect_color)

Page 243: avisynth docu

star_mask = star_mask.Resize(ovl.Width, ovl.Height).ScaleToPC()Overlay(last, ovl, ${read6} - Round(ovl.Width / 2), \ ${read7} - Round(ovl.Height / 2), mask=star_mask)"""

clp = BlankClip(color=$102005, pixel_type="yv12", length=300)

effmask = ImageSource("star%06d.jpg", 0, 48, 25.0).Reverse().Loop(10).Trim(0,299)effmask = effmask.ResizeToTarget(clp).ConvertToTarget(clp).ScaleToPC()

SetDefaultResizer("bicubic")FrameFilterReader(clp, FilterScript, varfiles, effmask)

Lets now look closer at the first script:

LoadModule("avslib", "base", "constants")LoadPackage("avslib", "array")LoadModule("avslib", "clip", "core")LoadModule("avslib", "filters", "frames")LoadModule("avslib", "filters", "resize")LoadModule("avslib", "filters", "utility")

# afford a start/end blank to make code nicer to look# it will be cleaned by the stuff belowvarfiles = """r.txtg.txtb.txtw.txth.txtx.txty.txt""" old = ArrayDelimiterSet(CRLF)okflag = varfiles.ArrayOpFunc("Exist").ArrayOpFunc("CInt")varfiles = varfiles.ArrayReduce(okflag)old = ArrayDelimiterSet(old)

After loading the necessary modules, a CR/LF delimited array of seven text files is declared. They will be read by FrameFilterReader and set the values of seven unique to each filter call global variables that will automatically be created by FrameFilterReader. The format of the files is that of the ConditionalReader standard Avisynth filter.

The lines immediately after clean-up the array from non-existent entries; their purpose here is to allow line breaks to occur inside the filenames' array (useful for visually grouping files and formatting).

FilterScript = """star_mask=%grect_color = MakeRGBColor(${read1}, ${read2}, ${read3})ovl = BlankClip(last, width=last.SafeWidth(${read4}), \ height=last.SafeHeight(${read5}), color=rect_color)

Page 244: avisynth docu

star_mask = star_mask.Resize(ovl.Width, ovl.Height).ScaleToPC()Overlay(last, ovl, ${read6} - Round(ovl.Width / 2), \ ${read7} - Round(ovl.Height / 2), mask=star_mask)"""

clp = BlankClip(color=$102005, pixel_type="yv12", length=300)

effmask = ImageSource("star%06d.jpg", 0, 48, 25.0).Reverse().Loop(10).Trim(0,299)effmask = effmask.ResizeToTarget(clp).ConvertToTarget(clp).ScaleToPC()

Next, the prototype script that will be executed in every frame is assigned to the FilterScript string variable, the base clip of the animation (clp) is created and the rotating star image sequence is loaded and converted to a clip (effmask) with the same colospace and dimensions as the base clip.

The prototype script assings a mask (to be supplied as argument) to the star_mask local variable and an rgb color to rect_color. The later is created by the first three global variables that will be read by FrameFilterReader from the r.txt, g.txt and b.txt text files, respectively. To combine the three integer values (in the range [0..255] the function MakeRGBColor is used.

Then a rect_color-colored clip with dimensions set by the global variables that are read from the w.txt and h.txt text files is created. SafeWidth and SafeHeight ensure that the dimensions will be compatible with base clip's colorspace, thus preventing an error message showing when the script will be passed internally by FrameFilterReader to ScriptClip.

Afterwards, star_mask is resized to the same dimensions as ovl using the Resize filter. The later was selected because it does not hard-code a specific resizer selection inside the script (see below) thus making the script more reusable; for example appropriate for deriving a function that is based on it.

Finally, the colored clip is overlayed on top of the base clip using star_mask as the overlay mask, with its center in in x,y coordinates read by FrameFilterReader from files x.txt and y.txt.

SetDefaultResizer("bicubic")FrameFilterReader(clp, FilterScript, varfiles, effmask)

The rest of the script selects a specific resizer to be used by the Resize filter (with SetDefaultResizer) and calls FrameFilterReader to do the per frame animation.

The second script is:

# AVSLib :: sample script # Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "base", "constants")LoadPackage("avslib", "array")LoadPackage("avslib", "string")LoadModule("avslib", "clip", "core")LoadModule("avslib", "filters", "frames")LoadModule("avslib", "filters", "resize")LoadModule("avslib", "filters", "utility")

Page 245: avisynth docu

# afford a start/end blank to make code nicer to look# it will be cleaned by the stuff belowvarfiles = """r.txtg.txtb.txtw.txth.txtx.txty.txt""" old = ArrayDelimiterSet(CRLF)okflag = varfiles.ArrayOpFunc("Exist").ArrayOpFunc("CInt")varfiles = varfiles.ArrayReduce(okflag)old = ArrayDelimiterSet(old)

FilterScript = """star_mask=%gx_ofs = %iy_ofs = %irect_color = %b ? color_white : MakeRGBColor(${read1}, ${read2}, ${read3})ovl = BlankClip(last, width=last.SafeWidth(${read4}), \ height=last.SafeHeight(${read5}), color=rect_color)star_mask = star_mask.Resize(ovl.Width, ovl.Height).ScaleToPC()Overlay(last, ovl, x_ofs + ${read6} - Round(ovl.Width / 2), \ y_ofs + ${read7} - Round(ovl.Height / 2), mask=star_mask)"""

clp = BlankClip(color=$102005, pixel_type="yv12", length=300)

effmask = ImageSource("star%06d.jpg", 0, 48, 25.0).Reverse().Loop(10).Trim(0,299)effmask = effmask.ResizeToTarget(clp).ConvertToTarget(clp).ScaleToPC()

SetDefaultResizer("bicubic")

Function MakeEffect(int xofs, int yofs, clip base, \ string script, string files, clip effmask, bool is_mask){ return FrameFilterReader(base.BlankClip(), script, files, effmask, xofs, \ yofs, is_mask)}

xofs = "0,60,-60,0,0,43,43,-43,-43"yofs = "0,0,0,60,-60,43,-43,43,-43"

Page 246: avisynth docu

clips = ArrayOpArrayFunc(xofs, yofs, "MakeEffect", \ StrPrint("%g, %q, %q, %g, %b", clp, FilterScript, varfiles, effmask, false))masks = ArrayOpArrayFunc(xofs, yofs, "MakeEffect", \ StrPrint("%g, %q, %q, %g, %b", clp, FilterScript, varfiles, effmask, true))

global ret = clp

Function OverlayEffect(clip clp, clip clpmask){ global ret = Overlay(ret, clp, mask=clpmask.ScaleToPC()) return true}

dummy = ArrayOpArrayFunc(clips, masks, "OverlayEffect")return ret

The second script example demonstrates the ability to call the filters of the frames module multiple times in our scripts, without the need to manage globals; they are all taken care by them.

The example executes the same animation in a group of clips, with constant x,y offsets from the central coordinates defined inside the x.txt and y.txt files. Thus instead of a single moving rotating star the script now moves a circle of rotating stars.

The differences with the previous script are presented:

...LoadPackage("avslib", "string")...FilterScript = """star_mask=%gx_ofs = %iy_ofs = %irect_color = %b ? color_white : MakeRGBColor(${read1}, ${read2}, ${read3})ovl = BlankClip(last, width=last.SafeWidth(${read4}), \ height=last.SafeHeight(${read5}), color=rect_color)star_mask = star_mask.Resize(ovl.Width, ovl.Height).ScaleToPC()Overlay(last, ovl, x_ofs + ${read6} - Round(ovl.Width / 2), \ y_ofs + ${read7} - Round(ovl.Height / 2), mask=star_mask)""" ...

The per frame script now contains two more lines to get the x, y offset arguments, a conditional statement to return a white clip if an (argument) boolean flag is set, in order for the clip to be used as mask and a change in Overlay arguments in oder for the x, y offsets to have effect.

...Function MakeEffect(int xofs, int yofs, clip base, \ string script, string files, clip effmask, bool is_mask){ return FrameFilterReader(base.BlankClip(), script, files, effmask, xofs, yofs,

Page 247: avisynth docu

is_mask)}xofs = "0,60,-60,0,0,43,43,-43,-43"yofs = "0,0,0,60,-60,43,-43,43,-43"clips = ArrayOpArrayFunc(xofs, yofs, "MakeEffect", \ StrPrint("%g, %q, %q, %g, %b", clp, FilterScript, varfiles, effmask, false))masks = ArrayOpArrayFunc(xofs, yofs, "MakeEffect", \ StrPrint("%g, %q, %q, %g, %b", clp, FilterScript, varfiles, effmask, true))

global ret = clp

Function OverlayEffect(clip clp, clip clpmask){ global ret = Overlay(ret, clp, mask=clpmask.ScaleToPC()) return true}

dummy = ArrayOpArrayFunc(clips, masks, "OverlayEffect")return ret

The body of the script now contains a function to create the moving star effect (MakeEffect) and two arrays to hold the x, y offsets for each rotating star clip.

The clips are created by operating, with ArrayOpArrayFunc, MakeEffect on both x, y offset arrays. StrPrint is used to construct the argument lists of the additional arguments to pass to MakeEffect by the array operator.

The overall effect is created using a global clip as accumulator, to accept all the overlays performed, and a second function (OverlayEffect) to perform each overlay. The function is applied to all elements of the clip and mask arrays again with a call to ArrayOpArrayFunc. After that the global overaly accumulator is return as the script's return value.

Page 248: avisynth docu

16. Per frame filtering, exporting specific frame(s)This series of example scripts demonstrates the capabilities offered by the filters of the new in AVSLib version 1.1.0 filters :: frames module. In particular, they serve as an example of how one can easily create new custom filters from them.

All example scripts export specific frames as images (using internally the ImageWriter standard Avisynth filter), but in a different flavor. All have the frame export facilities wrapped inside a custom function, so that they can easily be reused in your scripts . The first script is:

# AVSLib :: sample script # Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "array", "properties")LoadModule("avslib", "filters", "frames")Function ExportFrames(clip clp, string frames, string "path", string "type", \ bool "info"){ # frames export runtime script; needs array::properties module FF_EXPORT = """ expframes = %q file = %q type = LCase(%q) info = %b # Overlay is used to avoid colorspace conversion if type != ebmp expframes.ArrayContains(current_frame) ? ( \ type == "ebmp" ? \ ImageWriter(last, file, current_frame, current_frame + 1, type, info) \ : \ Overlay(last, ImageWriter(last.ConvertToRGB24, file, current_frame, \ current_frame + 1, type, info), opacity=0, ignore_conditional=true) \ ) : last """ path = Default(path, "frame") type = Default(type, "ebmp") info = Default(info, false) return FrameFilter(clp, FF_EXPORT, frames, path, type, info)}expframes = "5,23,35,55,99" # export these frames onlyclp = AVISource("story.avi").ConvertToYUY2ExportFrames(clp, expframes, "selected", "jpg")Compare(last, clp) # verify that clp is passed through ExportFrames untouched

Page 249: avisynth docu

Lets now look closer at the first script. This defines a new filter, ExportFrames, that exports any frame(s) whose framenumber(s) is(are) contained in an array passed as argument.

LoadModule("avslib", "array", "properties")LoadModule("avslib", "filters", "frames")

Function ExportFrames(clip clp, string frames, string "path", string "type", \ bool "info"){ # frames export runtime script; needs array::properties module FF_EXPORT = """ expframes = %q file = %q type = LCase(%q) info = %b # Overlay is used to avoid colorspace conversion if type != ebmp expframes.ArrayContains(current_frame) ? ( \ type == "ebmp" ? \ ImageWriter(last, file, current_frame, current_frame + 1, type, info) \ : \ Overlay(last, ImageWriter(last.ConvertToRGB24, file, current_frame, \ current_frame + 1, type, info), opacity=0, ignore_conditional=true) \ ) : last """ path = Default(path, "frame") type = Default(type, "ebmp") info = Default(info, false) return FrameFilter(clp, FF_EXPORT, frames, path, type, info)}

The larger part of the filter is the runtime script that does the frame exporting. The script arguments are first assigned to local variables. This makes the script easier to read and saves the need to supply the same argument many times if it is used in more than one location in the script.

Then a simple test with the runtime variable current_frame is performed: if it is in the array with frame numbers passed in (the expframes local variable) then the frame is exported; else not. Using the AVSLib-supplied ArrayContains function makes this test a simple one-liner.

One of the design targets of the filter is to let the clip passed in to go through untouched, whatever is the export image type requested. This is of concern for types other than "ebmp", since then the ImageWriter standard Avisynth filter requires that the input is RGB24 and a colorspace conversion would then be required (because in order to export a frame the filter must be in the active filter chain, thus it must deliver the converted to RGB24 frame to its successor filter, for it to convert it back to the original colorspace).

Thus, the script forks on export image type with a conditional operator and if type != "ebmp" it combines ImageWriter with Overlay with an opacity of zero to achieve letting the source clip untouched.

The rest of the filter's code initialises the filter's optional arguments to default values (see the ImageWriter's documentation for details) and calls FrameFilter to do the actual processing.

expframes = "5,23,35,55,99" # export these frames onlyclp = AVISource("story.avi").ConvertToYUY2ExportFrames(clp, expframes, "selected", "jpg")Compare(last, clp) # verify that clp is passed through ExportFrames untouched

Page 250: avisynth docu

The main body of the script tests the filter's implementation with a real source clip (substitute your own to verify) and a random selection of frames (expframes variable). The source clip, which in our test case was YV12, is converted to a colorspace supported by Compare which is used to verify that the input and the return value of the ExportFrames filter are identical.

Second script is:

# AVSLib :: sample script # Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "array", "properties")LoadModule("avslib", "filters", "frames")

Function ExportFramesEvery(clip clp, int step_size, string offsets, \ string "path", string "type", bool "info"){ Assert(step_size > 0, "ExportFramesEvery: 'step_size' must be positive") # frames export runtime script; needs array::properties module FF_EXPORT_EVERY = """ step = %i offsets = %q file = %q type = LCase(%q) info = %b # Overlay is used to avoid colorspace conversion if type != ebmp offsets.ArrayContains(current_frame % step) ? ( \ type == "ebmp" ? \ ImageWriter(last, file, current_frame, current_frame + 1, type, info) \ : \ Overlay(last, ImageWriter(last.ConvertToRGB24, file, current_frame, \ current_frame + 1, type, info), opacity=0, ignore_conditional=true) \ ) : last """ path = Default(path, "frame") type = Default(type, "ebmp") info = Default(info, false) return FrameFilter(clp, FF_EXPORT_EVERY, step_size, offsets, path, type, info)}clp = AVISource("story.avi").ConvertToYUY2ExportFramesEvery(clp, 12, "0,3,5,11", "sel_every_", "png")Compare(last, clp) # verify that clp is passed through ExportFramesEvery untouched

Page 251: avisynth docu

The second script defines a new filter, ExportFramesEvery, that works in a similar way with the SelectEvery standard Avisynth filter but instead delivering a new clip with the selected frames it exports them as images and returns the input clip untouched.

Another difference with SelectEvery is that here offsets are contained in an AVSLib array; however if the default array delimiter is used when the filter is called, the array is simply the argument list that would be passed to SelectEvery after the "step_size" argument enclosed in double quotation marks.

The decision to use an array was to make easier supplying the rest arguments (from ImageWriter) that the filter supports. As a by-product this also raises the 60 arguments-limit of Avisynth; you can pass as many numbers inside the array as wished.

LoadModule("avslib", "array", "properties")LoadModule("avslib", "filters", "frames")Function ExportFramesEvery(clip clp, int step_size, string offsets, string "path", \ string "type", bool "info"){ Assert(step_size > 0, "ExportFramesEvery: 'step_size' must be positive") # frames export runtime script; needs array::properties module FF_EXPORT_EVERY = """ step = %i offsets = %q file = %q type = LCase(%q) info = %b # Overlay is used to avoid colorspace conversion if type != ebmp offsets.ArrayContains(current_frame % step) ? ( \ type == "ebmp" ? \ ImageWriter(last, file, current_frame, current_frame + 1, type, info) \ : \ Overlay(last, ImageWriter(last.ConvertToRGB24, file, current_frame, \ current_frame + 1, type, info), opacity=0, ignore_conditional=true) \ ) : last """ path = Default(path, "frame") type = Default(type, "ebmp") info = Default(info, false) return FrameFilter(clp, FF_EXPORT_EVERY, step_size, offsets, path, type, info)}

The differences with the previous filter are suprisingly little:

1. An additional argument of the runtime script (step_size) is assigned to a local variable (step); the argument list of the call to FrameFilter is changed accordingly.

2. The containment test (now on the offsets array) is done to the modulo of division of current_frame runtime variable with step (again with ArrayContains).

Here also the design target of the filter is to let the clip passed in to go through untouched, whatever is the export image type requested. Thus, the script forks on export image type with a conditional operator just like the previous example.

clp = AVISource("story.avi").ConvertToYUY2ExportFramesEvery(clp, 12, "0,3,5,11", "sel_every_", "png")Compare(last, clp) # verify that clp is passed through ExportFramesEvery untouched

The main body of the script tests the filter's implementation with a real source clip (substitute your own to verify) and a random selection of frames, coded directly inside the filter call. The source clip, which in our test case was

Page 252: avisynth docu

YV12, is converted to a colorspace supported by Compare, which is used to verify that the input and the return value of the ExportFramesEvery filter are identical.

The third script is# AVSLib :: sample script # Copyright (c) 2007 George Zarkadas ([email protected])# This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software# Foundation; either version 2 of the License, or (at your option) any later# version. This program is distributed in the hope that it will be useful, but# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more# details. You should have received a copy of the GNU General Public License along# with this program; if not, write to the "Free Software Foundation, Inc., 59# Temple Place, Suite 330, Boston, MA 02111-1307 USA"

LoadModule("avslib", "filters", "frames")

Function ExportFramesReader(clip clp, string framesfile, string "path", \ string "type", bool "info"){ # frames export runtime script FF_EXPORT_READER = """ file = %q type = LCase(%q) info = %b # Overlay is used to avoid colorspace conversion if type != ebmp ${read1} != 0 ? ( \ type == "ebmp" ? \ ImageWriter(last, file, current_frame, current_frame + 1, type, info) \ : \ Overlay(last, ImageWriter(last.ConvertToRGB24, file, current_frame, \ current_frame + 1, type, info), opacity=0, ignore_conditional=true) \ ) : last """ path = Default(path, "frame") type = Default(type, "ebmp") info = Default(info, false) return FrameFilterReader(clp, FF_EXPORT_READER, framesfile, path, type, info)}clp = AVISource("story.avi").ConvertToYUY2ExportFramesReader(clp, "frames.txt", "reader", "jpeg")Compare(last, clp) # verify that clp is passed through ExportFramesReader untouched

The third script defines a new filter, ExportFramesReader, that gets the framenumbers to export from a text file such as those read by the ConditionalReader standard Avisynth filter. The text file, a sample of which is provided must contain int values different from zero for every frame that is to be exported.

Page 253: avisynth docu

The text file, a sample of which is provided here, must contain int values different from zero for every frame that is to be exported.

type intdefault 05 112 123 199 1100 1101 1155 1212 1222 1345 1512 1513 1514 1515 1

LoadModule("avslib", "filters", "frames")Function ExportFramesReader(clip clp, string framesfile, string "path", \ string "type", bool "info"){ # frames export runtime script FF_EXPORT_READER = """ file = %q type = LCase(%q) info = %b # Overlay is used to avoid colorspace conversion if type != ebmp ${read1} != 0 ? ( \ type == "ebmp" ? \ ImageWriter(last, file, current_frame, current_frame + 1, type, info) \ : \ Overlay(last, ImageWriter(last.ConvertToRGB24, file, current_frame, \ current_frame + 1, type, info), opacity=0, ignore_conditional=true) \ ) : last """ path = Default(path, "frame") type = Default(type, "ebmp") info = Default(info, false) return FrameFilterReader(clp, FF_EXPORT_READER, framesfile, path, type, info)}

Again, the differences with the previous filters are very little, essentially the test condition. Here there is no need for containment test; the special ${read1} variable (it will be substituted by FrameFilterReader by the actual variable that is set on each frame by the contents of the text file) is directly compared to zero and if not equal the frame is exported.

Here also the design target of the filter is to let the clip passed in to go through untouched, whatever is the export

Page 254: avisynth docu

image type requested. Thus, the script forks on export image type with a conditional operator just like the previous examples.

clp = AVISource("story.avi").ConvertToYUY2ExportFramesReader(clp, "frames.txt", "reader", "jpeg")Compare(last, clp) # verify that clp is passed through ExportFramesReader untouched

The main body of the script tests the filter's implementation with a real source clip (substitute your own to verify) and a random selection of frames, coded inside the text file. The source clip, which in our test case was YV12, is converted to a colorspace supported by Compare, which is used to verify that the input and the return value of the ExportFramesReader filter are identical.

Page 255: avisynth docu

Tutorials

Understanding containersContainer types are implemented as specially delimited strings. Elements are accessed (retrieved,set) with the use of functions, where an integer index argument specifies the desired element to operate with. This is the only way to implement them with the capabilities offered by the Avisynth script language while retaining relative simplicity and atomicity of container types' variables.

Implementation selectionsThe valid index range was selected to be from zero to number-of-elements minus one, both because it is the more usual case and because it makes coding easier. Furthermore, it was decided to allow negative indices, in the style used by the Python programming language.

Thus, the access functions add number-of-elements to negative indices and then check if resulting index is in the interval [0..number-of-elements); if yes the element is accessed, else an 'index error' occures. This makes easier to access container elements backwards from the end (for example, to access the last element, use an index of -1).

The index is checked during each element or subrange access for containment in the interval [0..number-of-elements); this assures that an out of bound index (a common programming error) will be reported to the user.

In order to implement clip containers a scheme was deviced for copying clips passed to containers in "reserved" global variables and storing these global variables' names into the container.

Rather than having a special type of clip container it was chosen to create a unified implementation of container types which can handle every possible type. For this purpose special handler functions were created to transparently set/retrieve variables of the appropriate type to/from the string representation of them in the container. The actions of the handler depend on the type of operation:

Operation Handler's actions

Retrieve an element

Evaluate the element as an expression (by passing it to the Eval() standard Avisynth function). If the element evaluates, return the result of the evaluation. Else, return the element itself (ie the string stored in element).

Assign to an elementIf the new value is of the clip type, copy it to a newly created "reserved" global variable1 and assign the name of the global variable to the element. Else, assing the result of applying String() to new value.

1 The variable is created by combining a prefix with the string representation of an integer counter which is incremented every time a call to the creation function is made.

The element delimiter was chosen to be variable and not hard-coded, in order to allow the maximum of flexibility to users. A reasonable default (the comma character) was selected and special globals hold the variables associated with the delimiters. These were made "private" and accessible by special functions in order to aid error-free manipulation of them.

For the same reason the element handler functions were also chosen to be variable and accessible by special functions. However, since this feature is considered to be developer-level, no additional documentation but the source code will be provided.

Page 256: avisynth docu

Impact of selections on functionalityA first consequence of the above setup is that containers can be created by assigning appropriate string expressions to variables, such as in the examples below.

# assume library's defaults for delimiters applyar1 = "1.2, 3.4, 4.5, 6.7" # whitespace is ignored (allowed)ar2 = "true, false, true"ar3 = "This, is, a, nice, day." # whitespace in strings is NOT ignored# clip arrays can also be directly coded, if elements are globalsglobal clip1 = AVISource(...)global clip2 = AVISource(...)global clip3 = AVISource(...)global clip4 = AVISource(...)ar4 = "clip1,clip2,clip3,clip4"

A second one is that accessing containers' elements is slower than directly accessing variables because:

• Any variable retrieved or stored to a container needs to be transformed from string to the desired type (and vice versa) which results in calling a handler function.

• In order to access an element, a scan of the string for delimiters has to be performed; this is particularly costly when accessing the last elements of an array or recursing backwards over it, from end to start.

However, keep in mind that the extra time needed when parsing a script to produce frames is compensated more than enough from the time gained during the development of the script by the flexibility, ease and speed of coding that containers offer.

Taking into account that this extra time will be in the majority of cases a small fraction of the time needed to process the video streams, most of the time using containers will be the best choice of implementation.

Another consequence is that container variables can contain apart from the usual case of one type of elements, the following:

• Elements of different types, in any order and proportion desired. • Global variables' names or even arbitrary expressions, as long as they contain only globals (variables

and/or functions) and constant values, since Eval() will be called from the handler functions and not from user code).

In fact one can even store entire scripts in a container (if working only with globals) by embedding blocks of code in double quotes and assigning them to the container elements [1].

The following examples illustrate the above.

inclip = AVISource(...)ovclip = AVISource(...)global rect = BlankClip(width=320, height=240, color=$ffffff)mixar = "0, 0, true, rect, 0.8" # mixed arrays can be used as structures# for reducing arguments, specifying presets, etc.clipvar = some_user_filter(inclip, ovclip, mixar)...

branch = ...# construct an array of size 3 with code blocks# note the unescaped with backslash linescodar = \

Page 257: avisynth docu

"global c = BlankClip(color=$ff00cc) global d = c.Levels(0,1.0,255,0,128)" \ + "#" + \ "global c = BlankClip(color=$00ff00) global d = c.ConvertToYUY2().Tweak(hue=135)" \ + "#" + \ "global c = ColorBars() global d = c.Levels(0,1.4,255,100,200).ConvertToYUY2().Tweak(hue=150)"# because code blocks contain commas, # was used as delimiter# that's why we have to tell AVSLib to use our delimiterArrayDelimiterSet("#")temp = codar.ArrayGet(branch > 2 ? 0 : (branch < 0 ? 1 : 2) )ArrayDelimiterReset()# and restore to defaults when finished (see below)new_clip = some_user_filter(d)...

Be aware though that this functionality is rarely needed; wrapping code to functions or using the container's operator functions provided by AVSLib is a more scallable and easier to understand alternative.

Of course, this added flexibility also means that one must be careful with the types stored in the container, since most of the time uniformity is the desired feature (after all, the major purpose for working with containers is to perform a series of operations to a group of similar objects).

In particular the following note has to be made:

When creating containers with strings one must be aware that due to the evaluation of each string in a retrieve action, there is the possibility of retrieving a global's value instead of the string if the contents of the string are the same with the name of the global.

In addition, the facility provided by Avisynth to allow calling a function without parentheses means that all function names, both standard and user-defined, obey the same rule. This may lead to strange errors since a function called without parentheses tries first to operate on the implicit variable last.

For example:global animals = 34species = ArrayCreate("fishes", "birds", "animals", "serpents", "humans")t = species.ArrayGet(2) # t is 34 (an integer) and not "animals"!!# 'not ' will produce a strange error in ArrayOpValue if the bool package# is loaded due to the existence of the 'Not' function in the package# (lang is case insensitive!) and the fact that functions can be called without parentheses# (which results in "last" implicit variable supplied as argument).a9 = "is ,is ,has ,was "a14 = ArrayOpValue(a9, "not ", "+") # an error pointing that Avisynth forgotten a previously declared# local variable appears

Page 258: avisynth docu

In addition, one must be careful if he/she decides to play with the container's delimiters. Since these are global variables, the effect of setting them to a different value is immediate. The following example demonstrates this issue:

coords = "100, 10, 200, 25, 300, 40, 400, 80"# change delimiter to # to allow a string-array with commas inside.ArrayDelimiterSet("#")subtitles = "Hey friend, how are you?#Fine, thanks!#Nice weather today."# This won't work; the entire coords array will be returned.x0 = coords.ArrayGet(0)# This won't work either; script execution will halt with an 'index error'.y0 = coords.ArrayGet(1)sub1 = subtitles.ArrayGet(0)sub2 = subtitles.ArrayGet(1)...

The correct way to code in such situations is to organise access to non-standard arrays in blocks and wrap each block with calls to the pair of ArrayDelimiterSet() and ArrayDelimiterReset() functions, as demonstrated by the following example:

coords = "100, 10, 200, 25, 300, 40, 400, 80"# change delimiter to # to allow a string-array with commas inside.subtitles = "Hey friend, how are you?#Fine, thanks!#Nice weather today."x0 = coords.ArrayGet(0)y0 = coords.ArrayGet(1)# wrap blocks of operations on non-standard arrays;# do not access normal arrays inside these blocks.ArrayDelimiterSet("#")sub1 = subtitles.ArrayGet(0)sub2 = subtitles.ArrayGet(1)ArrayDelimiterReset()...

What containers can do for youWell, actually nearly everything, since they are a general purpose programming facility. That's why they are a standard element of nearly every programming and scripting language.

A few possibilities specific to Avisynth usage are outlined at the list below. Keep in mind though that this is a very small set; the only limit is imagination.

• Organisation of clips in timelines (ie arrays of clips) and batch application of filters and any type of processing. For example, in order to combine a collection of titled-at-the-start episodes into a continuous movie one can use:

• a timeline and an array of titles, • an animation function inside a custom user function (taking a clip and a string argument) to

create a title-clip with a transition effect and return the combination of the effect and the original clip,

• the ArrayOpArrayFunc() function on the timeline and titles arrays with the user function mentioned above,

• the ArraySum() function to join all timeline clips in the final video stream. • Overlaying of timelines, for example by passing user-function wrappers of Overlay() to

ArrayOpArrayFunc(). • Animation on arbitrary curves, with varying opacity and size. See the animate module's source code for

Page 259: avisynth docu

an example of this use. • Rotation of clips accross the vertical or horizontal axes, if animated resizing is organised with an

appropriate sequence, an auxiliary video used as a back and FlipVertical() / FlipHorizontal() is applied on one copy of the clip.

• Operations on clip groups such as stacking in rows, columns or matrices, application of masks, etc. • Creation of preset collections of clips, masks, curves, etc. as global variables / constants for using with

Import() in scripts.

See the examples at the container operators tutorial and the source code of the test scripts included in the distribution of AVSLib to get an inshight of real use cases of container types.

Hints for effective useThe following list provides some guidelines for effective use of containers.

• Carefully review the corresponding parts of the library specifications section to avoid exceeding the allowed limits for containers size (in case you use Avisynth 2.5.5 or earlier).

• Try to use negative indices When accessing elements near the end of the container; they result in easier to read code.

• Avoid direct manipulation of containers; try to use only the associated AVSLib functions for interacting with their elements.

• Try to use the associated container operators whenever you want to process a container's elements. This also applies for subranges, since containers are accompanied with a rich set of functions to operate on subranges.

• When creating a recursive function that parses a container type try to code it such that it parses the container forward, from start to end.

• Cache wherever possible the container's number of elements into an integer variable (since determining it requires parsing the entire string each time it is requested).

• Try to use OOP notation; while it is of course a matter of style, it does makes chaining container related functions more easier to write (no need to worry if parentheses are coupled) and also promotes the notion of a container class with properties and methods, which overally enhances code readability.

[1]: Make sure that the code blocks do not generate errors because these will be masked by the try..catch block of the container's retrieve handler and it will appear that the scheme does not work, while it actually does. A hint to debugging: If an error appears inside a code block, only the globals assigned before the error occured will have the correct values. That way you can trace, by examining all associated globals, where the error occured.

Page 260: avisynth docu

Container operators

IntroductionHaving a container without a means to conveniently operate on all of its elements is quite disappointing; why then to have it in the first place? That's why all programming and scripting languages that support containers provide a means to effectively operate on them.

In most of these languages the means is special looping language constructs (such as the for, while, do..loop, etc.). In AVSLib, since the underlying script language does not support natively containers at all, it is a set of special AVSLib functions, collectively called container operators.

Container operators give the ability to operate on all elements of a container in a single step. In addition, coupled with the subrange selection functions that AVSLib provides for each container type, they give the ability to operate on subranges of a container in a single step.

Currently AVSLib supports only one container type, the array.

Array operatorsThere are five fundamental array operator functions, from which a whole family of array operator functions can be derived. They are presented below:

• ArrayOpValue, • ArrayOpFunc, • ArrayOpArray, • ArrayOpArrayFunc, • ArraySum,

The first four of the above functions operate on the individual elements of the array (or arrays) passed as arguments and produce a new array. The fifth operates both on the individual elements of the array and the array as a whole producing a single value[1], which is the analog of the integral of the array. Let's have a closer look on them.

ArrayOpValueThe operator function performs the requested operation between a scalar (a single value) and every array element. In effect the operator performs the [vector] <op> scalar or scalar <op> [vector] action.

The operation, which is provided as a string, can be anyone that Avisynth script language supports for the types of scalar and element (for example "+", "-", "*", "/", "%", "&&", etc.).

The operator function performs the operation with element as the first operand (ie the expression evaluated is [element] <op> scalar). If this is not the desired order, the optional argument array_first can be set to false to reverse the order of the operands (ie to evaluate the expression scalar <op> [element]).

Examples

a1 = ArrayCreate(4, 2, 6, 3, 5, 1, 7) # lets add 3 to all a1 elements a2 = ArrayOpValue(a1, 3, "+") # a2 == "7,5,9,6,8,4,10" # lets divide all a1 elements by 3 a3 = ArrayOpValue(a1, 3, "/") # a3 == "1,0,2,1,1,0,2" # lets divide 3 by each element of a1 (we need the "false", in order this to work) a4 = ArrayOpValue(a1, 3, "/", false) # a4 == "0,1,0,1,0,3,0" # what happened? well all operands are ints and so int division was performed

Page 261: avisynth docu

# now lets force float division by making 3 -> 3.0 a5 = ArrayOpValue(a1, 3.0, "/") # a5 == "1.3333,0.6667,2.0,1.0,1.6667,0.3333,2.3333" a6 = ArrayOpValue(a1, 3.0, "/", false) # a6 == "0.75,1.5,0.5,1.0,0.6,3.0,0.4286" ______________________________________________________________________________________# lets create an array of clips and add start_logo and end_logo at their # beggining and end respectively (single clips are also scalar values) c1 = AVIsource(...) ... c10 = AVIsource(...) start_logo = AVIsource(...) end_logo = AVIsource(...) ac1 = ArrayCreate(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10) # since we are interested in the final result we reassign ac1 to reuse identifiers; # we also use OOP notation, for its better readability ac1 = ac1.ArrayOpValue(start_logo, "+", false) ac1 = ac1.ArrayOpValue(end_logo, "+") # we are done; note the false in the first call, to put start_logo as the left operand

ArrayOpFuncThe operator function applies a user-defined function to every array element. In effect the operator performs the f([vector]) action.

The function must accept element as its first argument. Additional arguments can be defined as an argument string (a string-representation of the additional arguments passed to the function separated by commas).

Examples

# lets calculate the y's of a curve on the interval [40, 200] # the curve is y = 2.345x-1 + 3.12x - 4.002x1.5 Function my_curve(float x) { coef = "5.347,-2.11,1.002" pows = "-1,1,1.2" return PowSeriesAA(x, coef, pows) } cvx = ArrayCreate(40,80,120,160,200,240,280,320,360,400) cvy = cvx.ArrayOpFunc("my_curve") # now pass the cvx, cvy to an animation filter such as PolygonAnim() ... ______________________________________________________________________________________# a custom filter that resizes a clip to NTSC dimensions, adjusts hue, # brightness and contrast and softens a little between frames Function my_filter(clip c) { ret = c.ConvertToYUY2() ret = ret.BilinearResize(720,480) ret = ret.Tweak(hue=15, bright=2.5, cont=1.2, coring=false) ret = ret.TemporalSoften(4,4,8,15,2) return ret

Page 262: avisynth docu

} # lets create an array of clips and then apply my_filter() to them c1 = AVIsource(...) ... c10 = AVIsource(...) ac1 = ArrayCreate(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10) # lets convert all clips' framerate its easier to do in one step # after array creation; that's operators are made for ac1 = ac1.ArrayOpFunc("AssumeFPS", "25") # now apply your custom filter ac1 = ac1.ArrayOpFunc("my_filter")

ArrayOpArrayThe operator function performs the requested operation between every element pair of the two arrays supplied as arguments. In effect the operator performs the [vector1] <op> [vector2] action.

The operation, which is provided as a string, can be anyone that Avisynth script language supports for the types of element pairs (for example "+", "-", "*", "/", "%", "&&", etc.).

The order of operands in the expression evaluated ([element] <op> [element]) is decided by the ordering of the arrays in the argument list; the elements of the first array are always the left operand of the expression.

Examples

# titles and movies are arrays of 20 clips each (say a collection of family clips # produced during your vacations and the intros for each one, respectively) titles = ArrayCreate(tvac1, ..., tvac20) movies = ArrayCreate(mvac1, ..., mvac20) # convert to common format (if all clips have the same, skip this step) titles = titles.ArrayOpFunc("ConvertToYUY2") movies = movies.ArrayOpFunc("ConvertToYUY2") # now lets combine the intros with the respective family clips stories = ArrayOpArray(titles, movies, "+") ... ______________________________________________________________________________________# (x0,y0) and (x0,y4) define two curves on our clip coordinates x0 = "100,180,260,340,420,500,580" y0 = "0,100,350,480,350,250,0" y4 = "50,200,450,580,450,350,50" # lets generate 3 more curves (x0,y1), (x0,y2), (x0,y3) evenly distributed between # (x0,y0) and (x0,y4), in order to to feed them all later to an animation function # such as PolygonAnim() # 1st step: calculate the span between curves (y4[i] - y0[i]) ysp = ArrayOpArray(y4, y0, "-") # 2nd step: divide span by 4 and round to integer ysp = ysp.ArrayOpValue(4.0, "/").ArrayOpFunc("Round")

Page 263: avisynth docu

# 3rd step: get curve n+1 by adding final ysp to curve n y1 = ArrayOpArray(y0, ysp, "+") y2 = ArrayOpArray(y1, ysp, "+") y3 = ArrayOpArray(y2, ysp, "+")

ArrayOpArrayFuncThe operator function applies a user-defined function to every element pair of the two arrays supplied as arguments. In effect the operator performs the f([vector1],[vector2]) action.

The function must accept element[vector1], element[vector2] as its two first argument. Additional arguments can be defined as an argument string (a string-representation of the additional arguments passed to the function separated by commas).

Examples

Function my_subtitle(clip c, string s) { return c.SubTitle(s, size=24, text_color=$ffffff) } c1 = AVIsource(...) ... c4 = AVIsource(...) # ac1 is a clip array; at1 is a string array containing subtitles ac1 = ArrayCreate(c1, c2, c3, c4) at1 = "subtitle 1,subtitle 2,subtitle 3,subtitle 4" # create an array with subtitled clips sc = ArrayOpArrayFunc(ac1, at1, "my_subtitle") ... ______________________________________________________________________________________# return a simple overlay of the clips passed as arguments Function my_overlay(clip base, clip ovl, string "omode") { omode = Default(omode, "blend") opac = omode == "blend" ? 0.5 : 1.0 return Overlay(base, ovl, mode=omode, opacity=opac) } # ac1 and ac2 are two clip arrays with 4 elements each ac1 = ArrayCreate(c1, c2, c3, c4) ac2 = ArrayCreate(d1, d2, d3, d4) # lets overlay them ov1 = ArrayOpArrayFunc(ac1, ac2, "my_overlay") # this will use 'blend' as mode # string arguments to user-supplied functions must be quoted ov2 = ArrayOpArrayFunc(ac1, ac2, "my_overlay", StrQuote("add")) # lets overlay the results one more time to see what happens fin = ArrayOpArrayFunc(ov1, ov2, "my_overlay", StrQuote("luma")) ...

Page 264: avisynth docu

ArraySumThe operator function applies an optional elm_func user-defined function to every array element (if none is supplied it defaults to element itself). It then sums the return values of elm_func with an optional sum_func user-defined function (if none is supplied it defaults to simple addition: "+"). In effect the operator performs the sum_func(elm_func([vector])) action which is the equivalent of integrating over the array elements.

Usually, the precise order of application of sum_func will not be of importance. However, if the outcome of sum_func is not symmetrical to its main operands (ie the first two required arguments which correspond to array elements), it may be. Therefore, the following paragraph presents the internals of the summing process.

The summing of values is always performed in the backward direction, from array end (element with index array.ArrayLen()) to start (element with index 0).

Thus, the full expansion of the sum operation has the form (values inside brackets denote array elements with the designated index, ie [0] means array[0]):

sum_func(elm_func([0], elm_args), sum_func(elm_func([1], elm_args), sum_func(elm_func([2], elm_args), sum_func( ... sum_func(elm_func([ArrayLen-2], elm_args), elm_func([ArrayLen-1], elm_args), sum_args) ... , sum_args), sum_args), sum_args), sum_args)

Therefore, the first argument of sum_func is always the result of the application of elm_func on an array element, while the second is the result of the succesive application of sum_func on all elm_func results for array elements with index > element's index. For the last two array elements sum_func is applied directly to the outcomes of elm_func on them.

Since the order of operation of sum_func is fixed inside the operator function's code, if for any reason a different order is required, the only way to accomplish this is to use the array manipulation functions (such as ArrayInvert()) for setting the desired order of array element's before passing it to ArraySum.

Examples

# lets use the array 'ac1' produced by the second example of ArrayOpValue # 'ac1' contains 10 clips with a front and back-cover logo # now lets concatenate all stories to a single clip my_clip = ac1.ArraySum() ______________________________________________________________________________________# lets use the array 'stories' produced by the first example of ArrayOpArray # 'stories' contains 20 clips with a front-cover title # now lets concatenate all stories to a single clip, using Dissolve # (with overlap=5) to create a smoother transition my_movie = stories.ArraySum(sum_func="Dissolve", sum_args="5") ______________________________________________________________________________________# lets calculate an integral and print the results # the function defining the curve # y = 2.345x-1 + 3.12x - 4.002x1.5 Function my_f(float x) { coef = "2.345,3.12,-4.002" pows = "-1,1,1.5" return PowSeriesAA(x, coef, pows) }

# the function calculating the area using trapezoid rule Function t_area(float y1, float y2, float dx) {

Page 265: avisynth docu

Assert(dx > 0, "dx must be greater than zero") return (y1 + y2) * dx / 2 }

# divide [0.5..1] to subintervals with width 0.05 ax = ArrayRange(0.5, 1, step=0.05) # now calculate the integral of a function f(x) ie the area between y=0 and y=f(x) # use as f(x) 'my_f' # to calculate the integral use the trapezoid rule (in sum_func) area = ax.ArraySum(elm_func="my_f", sum_func="t_area", sum_args="0.05") return Print("The xs are:", ax, "The ys are:", \ ax.ArrayOpFunc("my_f"), "The area is:", area)

Usage (what to do and what not to do)In order to be able to operate on every container regardless of its elements' type(s) without imposing significant overhead, operator functions do not check the validity of the parameters passed to them (except some trivial checks, such as equality of the number of elements of arrays when >1 array are passed as arguments). This has the consequence that common errors made by the user during the coding of the script, for example

• constructing an array with erroneous values or format (this more easily happens when you hard-code an array as a string) and then passing it to the operator,

• mispelling a function name, • forgetting to quote strings (with the StrQuote() function) contained inside the extra argument strings that

a user-supplied function may require, • forgetting to place commas between the individual arguments composing an extra argument string, • putting excess commas at the start or end of an extra argument string, • selecting an operation not supported by the array's elements type (such as "||" for numeric types), • logic errors inside user-supplied functions that return invalid results,

etc. may result in an error message box by Avisynth pointing inside the code body of the operator function.

There are also many ways (at least for earlier versions of Avisynth) for a call to an operator to crash Avisynth and the video rendering application, due to the limitations imposed to AVSLib by the host application (Avisynth). Two classes of possible ways are the following:

• (Avisynth versions 2.5.5 and earlier) If the user instructs the operator function to return a value with a much larger string representation than the original element (for example an entire array) for each element of the array parsed and the array is significant in size, a container exceeding the maximum allowed string limit may be created and a fatal buffer overflow condition will eventually arise.

• If a complex iterrative function for processing container elements is passed to the operator along with a large container, the Avisynth stack space may well be exausted.

Thus, the following list of best usage procedures should be followed in order to maximize the benefits from operators and containers altogether.

• Carefully review the library specifications section of the documentation, in order to avoid passing arrays of inappropriate size to operator functions.

• Before supplying a user function to an operator, test it passing single values as arguments. It is easier to debug a single function call and you also avoid tampering with the source code of AVSLib.

• Confirm that the arrays passed to the operator have elements with the correct type and value. The debugging helpers Break and BreakIf are especially useful for this purpose. Simply, break before invoking the operator function to inspect variables and assure everything looks normal.

• Confirm the validity of all arguments passed to the operator. In particular, ensure that argument strings are properly constructed.

• Avoid putting break points inside the AVSLib source code; you risk accidentally modifying it. They are

Page 266: avisynth docu

rarely needed also. For example: • If you want to break inside the ArrayOpValue or ArrayOpArray operator functions, you can use a

custom function to perform the desired operation and then place the breakpoint inside this function and use ArrayOpFunc or ArrayOpArrayFunc, respectively to achieve the same operation.

• If you want to break inside the ArrayOpFunc or ArrayOpArrayFunc operator functions, simply place the breakpoint inside the user function that you supply.

• If you want to break inside ArraySum, provide custom copies of the Self and Sum2 functions (you can copy the definitions from the base :: core module or provide them by your self; they simply return x and x1 + x2) for the elm_func and sum_func arguments of ArraySum, respectively. Then place the breakpoint inside those functions. If you already supplying a custom function for any of the above arguments, simply place the breakpoint inside the custom function.

• If you ever need to put a breakpoint inside the AVSLib source code, then make a copy of the original module(s) file(s) and after debugging replace the modified files with the original copies.

[1]: This is the usual case. It is though possible, with proper coding of the elm_func and sum_func arguments of ArraySum function (user-supplied functions) to return an array as a result.

Page 267: avisynth docu

Understanding editing filters

IntroductionEditing filters provide a standardized interface for common editing operations with clips, such as trimming, replacing parts of a clip with another, inserting and deleting parts and sequentially joining clips.

Currently there are six editing filters, three of which operate on single clips, two on pairs of clips and one on groups of clips (see the corresponding filter documentation for usage examples):

• EditDelete : Deletes a part of the clip. • EditInsert : Inserts a part of a clip inside another. • EditJoin : Joins a group of clips sequentially (one after the other). • EditReplace : Replaces a part of a clip with a part of another clip • EditTrim : Returns a portion of a clip, like the Trim standard Avisynth function but with a different set of

parameters. • EditTrimRange : Returns portions of a clip, typically disjoint, with the same or varying length. The ranges

are joined together in one clip, using EditJoin.

The main advantage of using the editing filters (except of course the standardization and the error checking performed by them, which are already good reasons to adopt their use) is the ability to specify post-processing operations on the parts that compose the final result of editing. We will examine this subject in detail at a following section.

The editing modelAll editing filters treat clips as being an array of frames. To promote this notion of an array, frame numbers behave like array incides. More specifically:

• Valid frame numbers are in the range [0..clip.Framecount) • When selecting subranges, starting frame number is included in the subrange while ending frame number

is not included. • Negative frame numbers are supported also, meaning offset from the end of clip (the length of clip ie

clip.Framecount is added to a negative frame number inside the editing functions)[1].

Internally all editing filters use calls to the Trim() standard Avisynth filter to select the requested subranges of frames and then, as a final step, they assemble the selected subranges and form the final result of the editing operation.

Depending of the filter called and the values of the parameters, the number of subranges created for each clip or clip pair may vary from one to three. Because this is of interest to user-supplied functions the following table presents the possible different cases. For EditTrimRange the discussion for EditJoin applies.

Page 268: avisynth docu

Function Place of operation Parts Comments

EditReplace / EditInsert

At the middle of the clip (frame > 0 and not all frames up to the end are replaced)

31st and 3rd parts belong to clip #1, 2nd part belongs to clip #2 at the function's argument list

At the start of the clip (frame = 0 and not all frames up to the end are replaced)

21st part belongs to clip #2, 2nd part belongs to clip #1 at the function's argument list

At the end of the clip (frame > 0 and all frames up to the end are replaced)

21st part belongs to clip #1, 2nd part belongs to clip #2 at the function's argument list

EditDelete

At the middle of the clip (frame > 0 and not all frames up to the end are deleted)

2Both parts belong to the clip. The start of the original clip belongs to the 1st part

At the start or end of the clip 1

EditJoin At the end of the clip (this is the only option) 2

The 1st part is the entire left clip, the 2nd is the entire right clip1

1 EditJoin may take up to 50 clip arguments but it joins them incrementally and thus in each join only two clips are participating. The left clip is the combined join of all clips that have been joined so far (ie at the first step it is the clip #1 at the function's argument clip (the right operand is clip #2), at the second step it is the result of the combination of clip #1 and clip #2 (the right operand is now clip #3) and so on..

The following figures demonstrate the above.

Figure 1: Clip parts resulting from EditReplace and EditInsert filters' action

Page 269: avisynth docu

Figure 2: Clip parts resulting from EditDelete and EditJoin filters' action

Avisynth provides a number of ways to assemble clips together, namely UnallignedSplice, AllignedSplice and Dissolve. Instead of having separate versions of each editing filter for each one of these ways, an optional parameter "op" is declared at the argument list of the filters, the value of which controls the way that final result's subranges will be assembled together. One more option added by AVSLib is to process the clips by an arbitrary user-supplied function.

We will examine in more detail this final step of the editing operation at the following section

Assembling the parts of the final resultThe editing filters provide four ways to perform the assembly of the parts consisting the final result, controlled by the value of the op[2] optional parameter:

• By using the UnallignedSplice standard Avisynth filter ie the "+" operator. This is the default operation when op is ommited.

• By using the AllignedSplice standard Avisynth filter ie the "++" operator. • By using the Dissolve standard Avisynth filter. • By using a custom, user supplied function.

For the last two options a second optional parameter, extra_info, is provided in order to supply the necessary information to the editing function for performing the operation (the overlap in the case of Dissolve and the name of the user function to call in the last case). In both cases the information must be supplied as a string.

Which selection will be used is application-dependent and we will not analyse this issue in depth. UnallignedSplice appears to be the most common type of assembling operation and thus it was chosen as the default, implicit case. Dissolve may be more appropriate when replacing a scene with a similar one from a second source or when cutting scenes out. See the corresponding filter's documentation for usage examples.

The fourth option (user supplied functions) will be presented in detail since it is a new concept and provides a rich set of options (transitions, conditional inclusion, amendment of front-cover clips and logos, special effects, etc.) not found in the other three.

Page 270: avisynth docu

User-supplied functionsUser supplied functions provide a generic and versatile mechanism for post-editing clips. We use the term "post-editing" since the call to the user function is the last step of the editing operation; the final result will be whatever function(part1, part2, ...) returns.

As a matter of fact, the user function is free to return anything, even a non-clip value (for example an integer). The only exceptions are EditTrim, where the whole conversation does not apply anyway, and EditJoin when more than two clips are supplied to it (the user function still can return anything, but it must be a clip).

Of course returning something completely irrelevant to the original clips passed to the editing filter or a non-clip value is bad, since it breaks the semantics associated with the names of the filters and in general it results in hard to understand code. Nevertheless, it may be of use in certain situations (for example when you want to insert a clip only if it meets certain requirements that are associated with the final parts of the editing and not the original clips, or when an error condition needs to be flagged). Thus, it is left up to the end-user of the library.

Most of the time however, the user function will return something that has direct relation with the supplied clips. There are many possibilities as pointed out earlier but first let us look at how this user function must be defined.

User supplied functions can expect to be provided with a minimum of one and a maximum of three clips (see the figures above for a visual presentation). The actual number depends on the type of operation and the frame number(s) where the operation was requested. The same is true regarding the initial clip from which the part originates.

Thus, user functions must in general have a parameter list with one required and two optional clips in the first three argument slots. Additional optional arguments do not harm, but they will never be supplied by the caller (ie the editing filter). It is however possible to use a function with less clip slots in the argument list if you know beforehand the number of parts that the editing filter will produce, since the check on arguments' number is done by Avisynth at runtime.

What the user function does with its parameters (ie the processing of the clip parts) is up to the user, so we will not go any further. A limited, indicative list of possible applications is presented below:

• Apply a transition effect between the parts. • Insert a joining clip to provide continuity of the story (such as a "two minutes later..." logo). • Insert a front-cover clip in front of every clip (most useful when joining clips with EditJoin, say to

construct a movie with a series of episodes. • Replace a part that does not meet some specifications (for example it is too short) with another or remove

it completely from the final output. • Insert another clip between the parts, for example a commercial, a diagram (if you are constructing

educational videos), etc. • Overlay another clip on top of the final result (say a parallel story inside a window, etc.). • Apply different sets of filters to each part and the overall result.

At the next section a generic example of a user-supplied function is presented to help clarify the above conversation.

A generic example of a user-supplied functionThe following code snippet presents a generic example of a user-supplied function that can be used will all editing filters and all possible values of their arguments.

Function user_function_template(clip c1, clip "c2", clip "c3") { # get number of clips supplied and a reasonable default for all arguments nparts = 1 + (Defined(c2) ? 1 : 0) + (Defined(c3) ? 1 : 0) c2 = Default(c2, Null(c1)) c3 = Default(c3, Null(c1)) # now perform whatever custom processing the user function is designed for ...}

The first line stores the number of parts supplied to the user function, while the next ones assure that all arguments

Page 271: avisynth docu

are initialised to clip-type variables. If an argument is not supplied, the Null() function assigns a zero-length clip to it.

The next lines should perform the intended operations on the clip parts, possibly using the information stored at the nparts local variable; if you not need it you may remove the corresponding line. A final clip should be returned at the end.

It should be noted that there is no generic way for the user function to figure out in which of the original clips a specific part belongs in all cases. While this is an issue only for the cases of EditReplace and EditInsert filters when only two parts are supplied (see the table at the section "The editing model" above), it is nevertheless considered a limitation and will be removed in one of the next versions of AVSLib. For the time being, this knowledge should be derived by the kind of operations that the user performs to the edited clips.

You need not however always use the template above in your scripts, since you know what your script does. This generic template is actually needed only if you are constructing general-case functions to make a post-editing library. Most of the time it will be enough to construct simpler variants of the above template such as

• Function user_function_3c(clip c1, clip c2, clip c3) { ... } • Function user_function_2c(clip c1, clip c2) { ... } • Function user_function_1c(clip c1) { ... }

Of course you must then assure that the correct variant is used in every case, but this is not difficult. [1]: See the section Implementation selections at the backgrounder "Understanding containers" for more details. [2]: The allowed values for the op parameter are coded into a global set of constants ("EDOP_...") by the filters :: edit module.

Page 272: avisynth docu

Understanding animation filters

IntroductionAnimation filters use a combination of the Overlay and ScriptClip standard Avisynth filters in order to achieve animation of position (x and y coordinates) and opacity of the overlayed clip (the clip to be animated) on top of the base clip. Furthermore, they use the Resize filter in order to achieve animation of size (width and height) of the overlayed clip.

From AVSLib version 1.1.0, animation filters are rewritten internally (use of C++ plugins instead Avisynth scripts and also change of algorithm, so that ScriptClip instead of Animate is used at the core) in order to improve memory usage and execution speed. The new version of animation filters is now capable of executing complex animations in a single script; see the 14th example script for more information.

There is a version for animating between two end points (frame numbers) of a clip, LineAnim(), as well as a version for animating between an arbitrary number of consecutive points (frames) of a clip, PolygonAnim(). At each frame number (x,y) position, opacity and size (width,height) can be set independently. The change of them between animation end-points is linear.

For the PolygonAnim() there is also the ability to specify different parameters regarding the way that the animated clip is overlayed in each animation segment (such as overlay mode, mask clip, whether the mask is a greyscale one, etc.).

Thus in principle animation filters can achieve the simulation of any 3D movement of a clip with reference to the base clip's viewport in which at least one axis remains parallel to one axis of the viewport (that is rotations are excluded except for the case of rotation along the x or y axes, where it can be simulated with a series of resize-shift-resize steps and an auxiliary "back" clip) without the need to resort to external plugins.

Animation coordinate systemAnimation filters use a coordinate system in which (x,y) coordinates are displaced by half the width and height of the overlayed clip (ie if w,h are the later, xa = x - w/2, ya = y - h/2). The axes retain the direction of the standard clip coordinate system (x increases to the right and y to the bottom of the clip).

The selection may seem a bit uncommon at first site, but it was made for a good reason: to allow easy calculation of the placement of a clip which is animated both in position and size.

Indeed it is a lot easier to define a movement for a clip that constantly changes size in terms of its center; else a detailed knowledge of its size in each frame is needed to modify the coordinates defining its upper left corner. Since the size animation functions produce a clip in which the size animated, overlayed clip is assured to be always centered, it suffices to subtract half the width and height in order to achieve the desired transformation.

To account for this displacement of coordinates inside the animation filters the user must add the same amounts (w/2 for x and h/2 for y) to every end point passed to them.

For example, if the final size animated clip has (w,h) dimensions equal to (400,200) and we want to position animate it across a polygon defined by the points

(0,0), (150,50), (300,250), (300,350), (150,370), (-400,300),

with respect to its top-left corner, we must add 200 to each x and 100 to each y value in order to get the polygon points with respect to its center. The points will then be

(200,100), (350,150), (400,350), (400,450), (350,470), (-200,400).

The significance of masksAll animation filters use masks in order to animate any type of clip on top of any type of clip and allow consequtive stacking of an arbitrary number of animated clips on a base clip without interference with previous animations. If no mask is provided, the functions create an all-white mask with the dimensions of the animated clip.

The masks are animated in parallel with the animated clip. Thus, at each frame the clip affects only the area on top

Page 273: avisynth docu

of which is positioned and all the modes (and other arguments) supported by the Overlay standard Avisynth filter can be applied without nasty side effects to other areas of the base clip. This mechanism also makes possible to stack animations on the base clip without cross-interference.

Since the masks are clips and there are argument slots in the animation filters for the user to supply them explicitly, it is possible to provide masks that they transform during the clip's duration.

This makes possible to animate the shape of the clip also (for example to gradually turn it from rectangular to elliptical, or to a star-like or an irregular shape, or simulate rotation by creating a rotated white area inside a full-black mask, etc.). The possibilities are endless.

The only thing that one has to pay attention, if YUV clips are used as masks, is that all masks passed in must be in the full (PC) range (this is a requirement of Overlay, which is propagated by the animation filters, since they use Overlay internally).

Usage tips and examplesFirst of all, except for the simpler cases, create a scenario. Define what effects you want to achieve and the sequence of events necessary to implement them. Next, identify the components needed for implementing them (filters, AVSLib functions and data structures, etc.). Then follow the guidelines presented below:

• Organise the animation to small blocks (preferably functions) that can easier be conceived, implemented, tested and debugged. You can then later chain the blocks to produce the overall animation.

• Proceed step-by-step, verifying the correct operation of each block before going to the next; it is easier to spot the correct location of errors this way.

• When constructing animation paths always take into account the different coordinate system used by the animation filters and compensate for that. You may find it easier to work on the usual top-left coordinate system and then convert values. If you select this way, you will find ArrayOpValue() extremely useful.

• The standard way to animate multiple clips on top of a base clip is to order the first animation on top of the base clip and then order each subsequent animation on top of the previous result.

For this to work correctly it is essential that masks, if used, are in the full PC range.

Also it is advisable to convert the base clip to a YUV colorspace before applying the animations in order to avoid excess conversions back and forth between RGB and YUV that are made by the Overlay standard Avisynth function; else final result's chroma quality will be affected.

Examples of animation filters' uses are provided by some of the example scripts included with AVSLib documentation.

Page 274: avisynth docu

Using the loader module to build Avisynth script libraries

IntroductionThe loader module, new to AVSLib version 1.1.0 provides a set of functions and globals that together form a unified loading mechanism of Avisynth "modules" (.avsi scripts).

In particular, the loader module allows for loading modules in a minimal fashion, ie only those modules that are required from the script. This can be accomplished if each individual module loads in a pull-requirements fashion, that is it self-loads any required modules.

That way and with proper partition of library code to modules it is possible to build Avisynth libraries of any complexity while not inducing performance penalties to scripts needing only a small subset of the library's functionality.

For anything that is not been covered by this tutorial, see the loader module functions' documentation as well as the AVSLib's source code for details and working examples.

Module internalsEach module in order to register with the loader module must declare its name and position in the library's hierarchy. This is accomplished by the use of the DefineModule "macro", typically as the first line in the module's script file (it is called a macro because it is designed to be called without been assigned to a variable - it returns last).

What the DefineModule "macro" does is to create a unique global variable and assign true to it. Three string arguments must be supplied to it:

• The name of the library that the module belongs to. • The name of the package / subpackage that the module belongs to. • The name of the module itself.

The same arguments must be supplied to LoadModule, in order for the module to be actually loaded (imported) at the main script.

What LoadModule does is to check whether the global variable associated with the module is defined. If it is defined then it is assumed that the module is already loaded and no operation is executed; else a proper Import statement is executed to load the module.

The convention followed by the loader routines to determine the path of the module's script file is briefly presented below:

• The library name determines the root folder where the library's components are installed.

The library must install in Avisynth's plugins folder a file that declares a string constant with name __LIBROOT_{library name} and value the path to the library's root folder.

That file should also declare any configuration constants recognised by the library (see the LoadLibrary documentation for details).

• The package / subpackage name is a relative path (from library's root folder) to the folder where the package's modules are located.

Multiple levels of hierarchy are allowed through the use of the "/" (slash) character. Each part of the path following a "/" is considered a subfolder of the folder determined by the part of the path preceeding the "/".

• The module name is the name of the module's script file without the extension (which is assumed to always be ".avsi").

In addition, each module must explicitly (if a pull-requirements loading fashion is selected as is the case with AVSLib) load any modules that is depended to. This is typically executed at the next lines of the module's script after the call to DefineModule.

In order not to mess with user scripts the load calls should assign their return value to a dummy variable (so that

Page 275: avisynth docu

they not override the last special variable).

Because loading a bunch of modules to satisfy dependencies tends to produce an ugly block of consecutive assignments, it is recommended to group them inside triply doublequoted multiline strings which are passed to Eval standard Avisynth function, as in the following example:

DefineModule("avslib", "string", "sprintf")global __load__ = Eval(""" LoadModule("avslib", "base", "core") LoadModule("avslib", "numeric", "core") """)global __load__ = IsPackageLoaded("avslib", "string") ? NOP : Eval(""" LoadModule("avslib", "string", "core") LoadModule("avslib", "string", "search") """)global __load__ = IsPackageLoaded("avslib", "array") ? NOP : Eval(""" LoadModule("avslib", "array", "core") LoadModule("avslib", "array", "slices") LoadModule("avslib", "array", "operators") LoadModule("avslib", "array", "transforms") """)

The IsPackageLoaded and IsModuleLoaded test functions are used to determine if a package or module is already loaded to leave the corresponding block with a NOP if the later is true instead of executing a block of function calls.

Package internalsPackages are declared and loaded with similar to modules mechanisms. Since however they are a collection of modules, there are some specific requirements that must be fulfiled.

Each package is declared in a special .avsi file (__init.avsi) contained at the same folder as the modules (and / or subpackages) that belong to the package.

In order to register with the loader module the package must declare its name and position in the library's hierarchy. This is accomplished by the use of the DefinePackage "macro", typically at the first line in the package's special script file (it is called a macro because it is designed to be called without been assigned to a variable - it returns last).

The only other thing that the package's script file has to do is to load all modules of the package (remember, dependencies fulfilment has been assigned to modules).

In order not to mess with user scripts the load calls should assign their return value to a dummy variable (so that they not override the last special variable).

Because loading a bunch of modules tends to produce an ugly block of consecutive assignments, it is recommended to group them inside triply doublequoted multiline strings which are passed to Eval standard Avisynth function, as in the following example:

DefinePackage("avslib", "numeric")global __load__ = Eval(""" LoadModule("avslib", "numeric", "core") LoadModule("avslib", "numeric", "rounding") LoadModule("avslib", "numeric", "powseries") LoadModule("avslib", "numeric", "functions") LoadModule("avslib", "numeric", "statistics") LoadModule("avslib", "numeric", "curves2d") """)

Library internalsIn order for a library to cooperate with the loader, it must follow the general structure anticipated by the loader's routines (see the two sections above). In addition it must provide two script (.avsi) files:

• An .avsi file (__init.avsi) contained at the root folder of the library that loads the various configurations

Page 276: avisynth docu

of the library based on the value of the __LIBCONFIG global variable.

This is the file that will be called by LoadLibrary; the later will assign to __LIBCONFIG the value passed as the second argument to LoadLibrary.

• A special .avsi file that must be installed in Avisynth's plugins folder that declares a string constant with name __LIBROOT_{library name} and value the path to the library's root folder.

That file should also declare any configuration constants recognised by the library. Those are the values that are passed as the second argument to LoadLibrary.

An example of a library's __init.avsi is presented below (taken from AVSLib version 1.1.0):

global __load__ = \ __LIBCONFIG == CONFIG_AVSLIB_FULL ? Eval(""" LoadPackage("avslib", "base") LoadPackage("avslib", "numeric") LoadPackage("avslib", "bool") LoadPackage("avslib", "string") LoadPackage("avslib", "array") LoadPackage("avslib", "clip") LoadPackage("avslib", "debug") LoadPackage("avslib", "filters") """) : ( \ __LIBCONFIG == CONFIG_AVSLIB_SCRIPT ? Eval(""" LoadPackage("avslib", "base") LoadPackage("avslib", "numeric") LoadPackage("avslib", "string") LoadPackage("avslib", "debug") """) : ( \ __LIBCONFIG == CONFIG_AVSLIB_ARRAYS ? Eval(""" LoadPackage("avslib", "array") """) : ( \ __LIBCONFIG == CONFIG_AVSLIB_FILTERS ? Eval(""" LoadPackage("avslib", "clip") LoadPackage("avslib", "filters") """) \ : Assert(false, \ "AVSLib: 'config' argument out of accepted range") )))

The last line of the if..elseif..else construct presented above throws an error if the user pass in an invalid configuration argument. Another approach that one might wanted to follow is to silently load the entire library if an out-of-range configuration value is passed in.

An example of a library's declaration file that is copied to Avisynth plugins folder is presented below (taken again from AVSLib version 1.1.0):

# LoadLibrary configuration constants# zero should always be reserved for full loadingglobal CONFIG_AVSLIB_FULL = 0global CONFIG_AVSLIB_SCRIPT = 1global CONFIG_AVSLIB_ARRAYS = 2global CONFIG_AVSLIB_FILTERS = 3

# this will be filled by the setup program upon installationglobal __LIBROOT_AVSLIB = "path_to_the_library_root_folder"

The names of the global constants are arbitrary; nevertheless a sound convention such as the one presented above (in particular the use of library's name inside the constants' names) is useful to avoid name clashes with other libraries.

Page 277: avisynth docu

Library organisationThe organisation of the library is up to the developer; the only restrictions (a sum up of the previous sections) imposed by the loader are the following:

• There must be at least one package (a good name for small libraries is "base" or "core"). • The name of the folder containing a package must be the same with the visible to user name of the

package. The same is true for modules also. • All visible to the user modules of the package (ie those that LoadModule can be called to load them)

must be inside the containing package's folder (utility files that are loaded by the module such as other script files or plugins need not).

• All visible to the user packages of the library (ie those that LoadPackage can be called to load them) must be inside the containing library's folder (utility files - see above - need not).

• Plugins cannot be loaded directly; a thin wrapper module is required (this is intentional, since one of the purposes was to present to the user a single interface for loading anything).

• All script files visible to the user (ie packages, modules and special __init.avsi files) must have the extension .avsi.