GRunT

From Avisynth wiki
Jump to: navigation, search
Abstract
Author Gavino
Version v1.0.1
Download GRunT101.zip
Category Support filters
License GPLv2
Discussion Doom9 Thread


Contents

Description

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.

Features

  • 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.

function bracket_luma(clip c, float th1, float th2) {
    Assert(0 <= th1 && th1 < th2 && th2 <= 255, "Invalid thresholds!")
    ScriptClip(c, """
       avl = AverageLuma()
       avl <= th1 ? last.BlankClip() : avl >= th2 ? last.BlankClip(color=color_white) : last
    """, args="th1,th2", local=true)
}

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).


Run-time Filters

GRunT provides extended versions of the following run-time filters:

ScriptClip

ScriptClip(clip clip, string filter [, bool showx, bool after_frame, string args, bool local])
GScriptClip(clip clip, string filter [, bool show, bool after_frame, string args, bool local])

cf. AviSynth internal function ScriptClip
FrameEvaluate

FrameEvaluate(clip clip, string filter, [, bool showx, bool after_frame, string args, bool local])
GFrameEvaluate(clip clip, string filter [, bool show, bool after_frame, string args, bool local])

cf. AviSynth internal function FrameEvaluate
ConditionalFilter

ConditionalFilter(clip testclip, clip source1, clip source2, string expression1, string operator, string expression2
     [, bool showx, string args, bool local])

GConditionalFilter(clip testclip, clip source1, clip source2, string expression1, string operator, string expression2
     [, bool show, string args, bool local])

ConditionalFilter(clip testclip, clip source1, clip source2, string expression
     [, bool showx, string args, bool local])

GConditionalFilter(clip testclip, clip source1, clip source2, string expression
     [, bool show, string args, bool local])

cf. AviSynth internal function ConditionalFilter
WriteFile

WriteFile(clip clip, string filename, string expression1 [, string expression2 [, ...]]
     [, bool append, bool flush, string args, bool local])

GWriteFile(clip clip, string filename, string expression1 [, string expression2 [, ...]]
     [, bool append, bool flush, string args, bool local])

cf. AviSynth internal function WriteFile
WriteFileIf

WriteFileIf(clip clip, string filename, string expression1 [, string expression2 [, ...]]
     [, bool append, bool flush, string args, bool local])

GWriteFileIf(clip clip, string filename, string expression1 [, string expression2 [, ...]]
     [, bool append, bool flush, string args, bool local])

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.
  • Elements of the args string can also take the form name=expression; the expression is evaluated in the current context and sets the value of the named variable.
Example:
args="x, y=n+1, c=c.Trim(2, 0)"
will set values for the variables x, y and c. Here y need not even exist in the current environment (although x, n and c must exist).
  • The simple form (without =expression) is just a shorthand for the more general form, with the variable name itself being used as the expression. So, for example,
args="x, y, z"
is equivalent to
args="x=x, y=y, z=z"
passing the values of the compile-time variables x, y and z (from outside the run-time script) into the variables of the same name inside the script.
  • Spaces may be freely used (or not) inside the args string, just as in Avisynth function calls.
  • 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.


Run-time Functions

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:

function InterpLuma2(clip c) {
    lm_k = AverageLuma(c)
    lm_km1 = AverageLuma(c, -1)
    lm_kp1 = AverageLuma(c, 1)
    dvg = (lm_km1 - 2 * lm_k + lm_kp1) / 2
    return lm_k + Sign(dvg) * Sqrt(Abs(dvg))
}

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:

function AverageRed(clip c) {
    return RGBDifference(ShowRed(c), BlankClip(c))
}

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:

ScriptClip("MyFunc()")

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.

Average
AverageLuma (clip [, int offset])
AverageChromaU (clip [, int offset])
AverageChromaV (clip [, int offset])
Difference
RGBDifference (clip1, clip2 [, int offset])
LumaDifference (clip1, clip2 [, int offset])
ChromaUDifference (clip1, clip2 [, int offset])
ChromaVDifference (clip1, clip2 [, int offset])
Difference from previous
RGBDifferenceFromPrevious (clip [, int offset])
YDifferenceFromPrevious (clip [, int offset])
UDifferenceFromPrevious (clip [, int offset])
VDifferenceFromPrevious (clip [, int offset])
Difference to next
RGBDifferenceToNext (clip [, int offset])
YDifferenceToNext (clip [, int offset])
UDifferenceToNext (clip [, int offset])
VDifferenceToNext (clip [, int offset])
Color plane median, min, max, range
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.


ConditionalFilter

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()).

For example,

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.


Configuration

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.


Changelog

  • 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)


Archived Downloads

Version Download Mirror
v1.0.1 GRunT101.zip


Document v1.0.1 (Gavino, 27th September 2008)


Back to External Filters

Personal tools