AviSynth's run-time environment is very powerful, supporting complex video processing that would be difficult or impossible to perform in a normal script. But it's not easy to use - the behaviour of run-time scripts (especially in combination) can be hard to understand, and there are usability problems concerning scope and lifetime of variables.
GRunT (Gavino's Run-Time ) is a plugin which addresses these and other problems, making the run-time system much easier to use.
- Simple, natural and robust way to pass variables into a run-time script from 'outside'
- A run-time script can be evaluated in its own independent scope
- Run-time functions can be called from a user function
- Run-time functions can be applied to any frame (relative to the current one)
- New variant of ConditionalFilter with a single boolean expression
- Lightweight plugin extending the standard run-time environment with minimal time and memory overhead
- 100% backwards compatible with existing scripts
GRunT should be useful to anyone who uses run-time filters, from those who make occasional use of ScriptClip to those who write complex functions based on run-time features (such as Restore24 or Mrestore).
A variables scope and lifetime example
A short example (please compare to the original) shows how this greatly simplifies passing function parameters into a run-time script.
This is much easier than the standard approach of dynamically building the runtime script using string concatenation, or passing the values via global variables.
Because the run-time script is evaluated in its own scope, there is now no problem in calling bracket_luma more than once in the same script (previously the variables th1 and th2 of different instances could interfere with each other).
GRunT provides extended versions of the following run-time filters:
- cf. AviSynth internal function ScriptClip
- cf. AviSynth internal function FrameEvaluate
- cf. AviSynth internal function ConditionalFilter
- cf. AviSynth internal function WriteFile
- cf. AviSynth internal function WriteFileIf
The alternative (G*) names may be used if you wish, but this is optional in AviSynth version 2.58 or later.
Each filter is 100% backwards compatible with its standard equivalent, but has two additional optional arguments:
- string args: the variables whose values are to be imported into the run-time script, written as a list of names separated by commas. The given variable names are evaluated in the current (compile-time) context, so can include function parameters or local variables. Each value becomes the initial value of the corresponding variable at each invocation of the run-time script.
- bool local: if true, the filter will evaluate its run-time script in a new variable scope, avoiding unintended sharing of variables between run-time scripts. Default is true if args is also specified, otherwise false (to preserve backwards compatibility).
- As in the AviSynth internal counterparts, show (or showx) to true will display the actual values on the screen.
The plugin also provides the following extensions to the run-time functions (such as AverageLuma):
- These functions can now be called inside a user function, when (and only when) the user function is called from a run-time script.
- Each function has a new optional int argument, which can be used to get the value from another frame, relative to the current one.For example, AverageLuma(-1) returns the value for the previous frame.
Note that to support the first feature, current_frame is now a global variable (see discussion). However, the second feature means that it is no longer necessary to change current_frame to access other frames. In fact, for most purposes, you can forget that current_frame exists as an explicit variable.
Here is an example of a weighted second order luma interpolation function:
This function can be called from any run-time script. Previously, something like this this had to be done by assigning to current_frame (or using additional filters, eg Trim(1,0)), and the code had to be written directly in the run-time script rather than in a function.
In effect, we are now able to write run-time functions of our own, derived from the standard ones. Here is another example:
Note too that, while useful in its own right, the ability to call run-time functions in a user function gives you more than just that. For the first time, it allows an entire run-time script to be put inside a function body, called for example like this:
As the function body will be evaluated in a separate scope, this is another way of eliminating the problem of unintended sharing of variables between run-time scripts. However, you may prefer to write the run-time script 'in-line' and invoke the run-time filter with local=true.
Here is the complete list of run-time functions, with their extended interface.
AverageLuma (clip [, int offset])
AverageChromaU (clip [, int offset])
AverageChromaV (clip [, int offset])
RGBDifference (clip1, clip2 [, int offset])
LumaDifference (clip1, clip2 [, int offset])
ChromaUDifference (clip1, clip2 [, int offset])
ChromaVDifference (clip1, clip2 [, int offset])
RGBDifferenceFromPrevious (clip [, int offset])
YDifferenceFromPrevious (clip [, int offset])
UDifferenceFromPrevious (clip [, int offset])
VDifferenceFromPrevious (clip [, int offset])
RGBDifferenceToNext (clip [, int offset])
YDifferenceToNext (clip [, int offset])
UDifferenceToNext (clip [, int offset])
VDifferenceToNext (clip [, int offset])
YPlaneMax (clip, float threshold [, int offset])
UPlaneMax (clip, float threshold [, int offset])
PlaneMax (clip, float threshold [, int offset])
YPlaneMin (clip, float threshold [, int offset])
UPlaneMin (clip, float threshold [, int offset])
VPlaneMin (clip, float threshold [, int offset])
YPlaneMedian (clip [, int offset])
UPlaneMedian (clip [, int offset])
VPlaneMedian (clip [, int offset])
YPlaneMinMaxDifference (clip, float threshold [, int offset])
UPlaneMinMaxDifference (clip, float threshold [, int offset])
VPlaneMinMaxDifference (clip, float threshold [, int offset])
The optional offset parameter specifies the offset (which may be negative) from the current frame; default is zero.
For added convenience, there is a new variant of ConditionalFilter which takes a single boolean expression instead of three separate parameters as at present. This is useful when the condition to be tested is a compound one or is already available in boolean form (like IsCombed()).
ConditionalFilter(c, c1, c2, \ "AverageLuma(c1) > AverageLuma() && AverageLuma(c1) > AverageLuma(c2)")
where previously you would have to say
ConditionalFilter(c, c1, c2, \ "AverageLuma(c1) > AverageLuma() && AverageLuma(c1) > AverageLuma(c2)", \ "==", "true")
Note that this form of ConditionalFilter also makes it easier use the relational operators <=, >= and !=, which are not supported as the operator in the standard ConditionalFilter.
For the extended run-time filters, for compatibility reasons the default for local is false unless args is also specified. However, it is recommended to always use local=true unless you really need to communicate values of variables from one run-time script to another (note that you can always use global variables for this).
To this end, the plugin provides GRTConfig:
- GRTConfig(bool local)
GRTConfig(local=true) sets local=true by default for all subsequent filters.
- v1.0.1 (Gavino, 27th September 2008):
- - fix for Avisynth 2.5.7 (have to use alternative names for filters, eg GScriptClip)
- v1.0.0 (Gavino, 9th July 2008):
- - add 'args' and 'local' to filters
- - run-time functions with offset from current_frame
- - new variant of ConditionalFilter (single boolean expr)
- v0.1 (Gavino, 18th June 2008):
- - fix Avisynth bug in setting of current_frame
- - make current_frame global (allows run-time functions to be cslled inside user functions)
Back to External Filters ←