GRunT
Raffriff42 (Talk | contribs) m (add links, use Template:FuncDef, Template:BoxWidthIndent more TODO) |
Raffriff42 (Talk | contribs) (more content imported from docfile) |
||
Line 1: | Line 1: | ||
{{FilterCat|External_filters|Plugins|Support_filters}} | {{FilterCat|External_filters|Plugins|Support_filters}} | ||
{{Filter3 | {{Filter3 | ||
− | | Gavino | + | | {{Author/Gavino}} |
| v1.0.1 | | v1.0.1 | ||
| 3=[http://forum.doom9.org/attachment.php?s=e3dfd39b17aff991b34523778ca798f5&attachmentid=8852&d=1222533692 GRunT101.zip] | | 3=[http://forum.doom9.org/attachment.php?s=e3dfd39b17aff991b34523778ca798f5&attachmentid=8852&d=1222533692 GRunT101.zip] | ||
− | | 4=Support filters | + | | 4=[[:Category:Support_filters|Support filters]] |
| 5=[http://www.gnu.org/licenses/gpl-2.0.txt GPLv2] | | 5=[http://www.gnu.org/licenses/gpl-2.0.txt GPLv2] | ||
| 6=[http://forum.doom9.org/showthread.php?t=139337 Doom9 Thread]}} | | 6=[http://forum.doom9.org/showthread.php?t=139337 Doom9 Thread]}} | ||
<br> | <br> | ||
== Description == | == Description == | ||
− | AviSynth's [[Runtime_environment|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 [[The_script_execution_model/Scope_and_lifetime_of_variables#Runtime_scripts|scope and lifetime of variables]]. | + | [[Main_Page|AviSynth]]'s [[Runtime_environment|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 [http://forum.doom9.org/showthread.php?p=338712#post338712 hard to understand], and there are usability problems concerning [[The_script_execution_model/Scope_and_lifetime_of_variables#Runtime_scripts|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. | + | '''[[GRunT]]''' (Gavino's Run-Time ) is a plugin which addresses these and other problems, making the run-time system much easier to use. |
<br> | <br> | ||
<br> | <br> | ||
Line 19: | Line 19: | ||
* Run-time functions can be called from a user function | * Run-time functions can be called from a user function | ||
* Run-time functions can be applied to any frame (relative to the current one) | * Run-time functions can be applied to any frame (relative to the current one) | ||
− | * Additional variant of [[ConditionalFilter]] with single boolean expression | + | * Additional variant of [[#ConditionalFilter]] with a single boolean expression |
* Fixes a fairly serious [http://forum.doom9.org/showthread.php?t=138755 bug] in the run-time system | * Fixes a fairly serious [http://forum.doom9.org/showthread.php?t=138755 bug] in the run-time system | ||
* Lightweight plugin extending the standard run-time environment with minimal time and memory overhead | * Lightweight plugin extending the standard run-time environment with minimal time and memory overhead | ||
* 100% backwards compatible with existing scripts | * 100% backwards compatible with existing scripts | ||
− | '''GRunT''' should be useful to anyone who uses | + | '''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]]). |
<br> | <br> | ||
<br> | <br> | ||
− | == | + | == A variables scope and lifetime example == |
+ | A short example (please compare to the [[The_script_execution_model/Scope_and_lifetime_of_variables#A_variables_scope_and_lifetime_example|original]]) shows how this greatly simplifies passing function parameters into a run-time script. | ||
+ | <div {{BoxWidthIndent|60|2}}> | ||
+ | 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) | ||
+ | } | ||
+ | </div> | ||
+ | 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|ScriptClip]]'' ===== | ||
+ | <div {{BoxWidthIndent|70|2}} > | ||
+ | {{Func2Def | ||
+ | |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''])}} | ||
+ | </div> | ||
+ | |||
+ | ===== ''[[FrameEvaluate#FrameEvaluate|FrameEvaluate]]'' ===== | ||
+ | <div {{BoxWidthIndent|70|2}} > | ||
+ | {{Func2Def | ||
+ | |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''])}} | ||
+ | </div> | ||
+ | |||
+ | ===== ''[[ConditionalFilter]]'' ===== | ||
+ | <div {{BoxWidthIndent|70|2}} > | ||
+ | {{Func2Def | ||
+ | |ConditionalFilter(clip ''testclip'', clip ''source1'', clip ''source2'', string ''expression1'', string ''operator'', string ''expression2'' | ||
+ | <br> [, bool ''showx'', string ''args'', bool ''local'']) | ||
+ | |GConditionalFilter(clip ''testclip'', clip ''source1'', clip ''source2'', string ''expression1'', string ''operator'', string ''expression2'' | ||
+ | <br> [, bool ''show'', string ''args'', bool ''local''])}} | ||
+ | <br> | ||
+ | |||
+ | {{Func2Def | ||
+ | |ConditionalFilter(clip ''testclip'', clip ''source1'', clip ''source2'', string ''expression'' | ||
+ | <br> [, bool ''showx'', string ''args'', bool ''local'']) | ||
+ | |GConditionalFilter(clip ''testclip'', clip ''source1'', clip ''source2'', string ''expression'' | ||
+ | <br> [, bool ''show'', string ''args'', bool ''local''])}} | ||
+ | </div> | ||
+ | |||
+ | ===== ''[[WriteFile]]'' ===== | ||
+ | <div {{BoxWidthIndent|70|2}} > | ||
+ | {{Func2Def | ||
+ | |WriteFile(clip ''clip'', string ''filename'', string ''expression1'' [, string ''expression2'' [, ...]] | ||
+ | <br> [, bool ''append'', bool ''flush'', string ''args'', bool ''local'']) | ||
+ | |GWriteFile(clip ''clip'', string ''filename'', string ''expression1'' [, string ''expression2'' [, ...]] | ||
+ | <br> [, bool ''append'', bool ''flush'', string ''args'', bool ''local''])}} | ||
+ | </div> | ||
+ | |||
+ | ===== ''[[WriteFileIf]]'' ===== | ||
+ | <div {{BoxWidthIndent|70|2}} > | ||
+ | {{Func2Def | ||
+ | |WriteFileIf(clip ''clip'', string ''filename'', string ''expression1'' [, string ''expression2'' [, ...]] | ||
+ | <br> [, bool ''append'', bool ''flush'', string ''args'', bool ''local'']) | ||
+ | |GWriteFileIf(clip ''clip'', string ''filename'', string ''expression1'' [, string ''expression2'' [, ...]] | ||
+ | <br> [, bool ''append'', bool ''flush'', string ''args'', bool ''local''])}} | ||
+ | </div> | ||
+ | The alternative ({{FuncDef|G*}}) names may be used if you wish, but this is optional in AviSynth version 2.58 or later. | ||
Line 57: | Line 100: | ||
:*''string'' {{FuncDef|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. | :*''string'' {{FuncDef|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. | ||
+ | {{BlueBox}} | ||
+ | *Elements of the <span style="color: purple; font-weight: bold">args</span> string can also take the form <tt>''name=expression''</tt>; the expression is evaluated in the current context and sets the value of the named variable.<br> | ||
+ | :Example: <br> | ||
+ | <pre style="width:20em;margin:0 0 0 3em;padding:0;border:none;"> | ||
+ | args="x, y=n+1, c=c.Trim(2, 0)" | ||
+ | </pre> | ||
+ | :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 the expression) is just a shorthand for the more general form, with the variable name itself being used as the expression. So, for example, | ||
+ | <pre style="width:20em;margin:0 0 0 3em;padding:0;border:none;"> | ||
+ | args="x, y, z" | ||
+ | </pre> | ||
+ | :is equivalent to | ||
+ | <pre style="width:20em;margin:0 0 0 3em;padding:0;border:none;"> | ||
+ | args="x=x, y=y, z=z" | ||
+ | </pre> | ||
+ | :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 <span style="color: purple; font-weight: bold">args</span> string, just as in Avisynth function calls. | ||
+ | {{End_BlueBox}} | ||
+ | |||
:*''bool'' {{FuncDef|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). | :*''bool'' {{FuncDef|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). | ||
+ | [[TODO]] - document {{FuncDef|show}}, {{FuncDef|showx}} | ||
− | + | ||
− | <div {{BoxWidthIndent| | + | == Run-time Functions == |
− | function | + | 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, <tt>AverageLuma(-1)</tt> returns the value for the previous frame. | |
− | + | ||
− | + | Note that to support the first feature, ''current_frame'' is now a ''global'' variable (see [http://forum.doom9.org/showthread.php?t=138392 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: | ||
+ | <div {{BoxWidthIndent|40|1}}> | ||
+ | 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)) | ||
} | } | ||
</div> | </div> | ||
− | This | + | 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: | |
+ | <div {{BoxWidthIndent|40|1}}> | ||
+ | function AverageRed(clip c) { | ||
+ | return RGBDifference(ShowRed(c), BlankClip(c)) | ||
+ | } | ||
+ | </div> | ||
+ | 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: | ||
+ | <div {{BoxWidthIndent|20|1}}> | ||
+ | ScriptClip("MyFunc()") | ||
+ | </div> | ||
+ | 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 [[Internal_functions/Runtime_functions#Runtime_functions|run-time functions]], with their extended interface. | |
− | + | ===== [[Internal_functions/Runtime_functions#Average|Average]] ===== | |
− | + | :<code>AverageLuma (clip [, int offset])</code> | |
+ | :<code>AverageChromaU (clip [, int offset])</code> | ||
+ | :<code>AverageChromaV (clip [, int offset])</code> | ||
+ | |||
+ | ===== [[Internal_functions/Runtime_functions#Difference|Difference]] ===== | ||
+ | :<code>RGBDifference (clip1, clip2 [, int offset])</code> | ||
+ | :<code>LumaDifference (clip1, clip2 [, int offset])</code> | ||
+ | :<code>ChromaUDifference (clip1, clip2 [, int offset])</code> | ||
+ | :<code>ChromaVDifference (clip1, clip2 [, int offset])</code> | ||
+ | |||
+ | ===== [[Internal_functions/Runtime_functions#Difference_from_previous|Difference from previous]] ===== | ||
+ | :<code>RGBDifferenceFromPrevious (clip [, int offset])</code> | ||
+ | :<code>YDifferenceFromPrevious (clip [, int offset])</code> | ||
+ | :<code>UDifferenceFromPrevious (clip [, int offset])</code> | ||
+ | :<code>VDifferenceFromPrevious (clip [, int offset])</code> | ||
+ | |||
+ | ===== [[Internal_functions/Runtime_functions#Difference_to_next|Difference to next]] ===== | ||
+ | :<code>RGBDifferenceToNext (clip [, int offset])</code> | ||
+ | :<code>YDifferenceToNext (clip [, int offset])</code> | ||
+ | :<code>UDifferenceToNext (clip [, int offset])</code> | ||
+ | :<code>VDifferenceToNext (clip [, int offset])</code> | ||
+ | |||
+ | ===== [[Internal_functions/Runtime_functions#Color_plane_median.2C_min.2C_max.2C_range|Color plane median, min, max, range]] ===== | ||
+ | :<code>YPlaneMax (clip, float threshold [, int offset])</code> | ||
+ | :<code>UPlaneMax (clip, float threshold [, int offset])</code> | ||
+ | :<code>PlaneMax (clip, float threshold [, int offset])</code> | ||
+ | :<code>YPlaneMin (clip, float threshold [, int offset])</code> | ||
+ | :<code>UPlaneMin (clip, float threshold [, int offset])</code> | ||
+ | :<code>VPlaneMin (clip, float threshold [, int offset])</code> | ||
+ | :<code>YPlaneMedian (clip [, int offset])</code> | ||
+ | :<code>UPlaneMedian (clip [, int offset])</code> | ||
+ | :<code>VPlaneMedian (clip [, int offset])</code> | ||
+ | :<code>YPlaneMinMaxDifference (clip, float threshold [, int offset])</code> | ||
+ | :<code>UPlaneMinMaxDifference (clip, float threshold [, int offset])</code> | ||
+ | :<code>VPlaneMinMaxDifference (clip, float threshold [, int offset])</code> | ||
+ | |||
+ | The optional {{FuncDef|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 <tt>IsCombed()</tt>). | ||
+ | |||
+ | 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)", "=", | ||
+ | |||
+ | Note that this form of ConditionalFilter also makes it easier use the relational operators <tt><=</tt>, <tt>>=</tt> and <tt>!=</tt>, which are not supported as the ''operator'' in the standard [[ConditionalFilter]]. | ||
+ | |||
+ | <!-- NOT SURE IF CURRENT INFO | ||
+ | == Bug fix == | ||
+ | The plugin fixes a fairly serious [http://forum.doom9.org/showthread.php?t=138755 bug] I discovered in the run-time system. This fix is needed if you are running a version of Avisynth prior to build 080620 of 2.58. (GRunT actually originated as a means to demonstrate this bug-fix, but I have now extended it to do a lot more.) | ||
+ | |||
+ | Since things like [[ScriptClip]] are often hidden deep inside huge functions like [[Restore24]], you may be affected by this bug without even realising it. | ||
+ | --> | ||
+ | |||
+ | == Configuration == | ||
+ | For the extended run-time filters, for compatibility reasons the default for {{FuncDef|local}} is ''false'' unless {{FuncDef|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''': | ||
+ | :{{FuncDef|GRTConfig(bool ''local'')}} | ||
+ | |||
+ | <tt>GRTConfig(local=true)</tt> sets ''local=true'' by default for all subsequent filters. | ||
+ | |||
− | |||
− | |||
− | |||
− | |||
− | |||
== Changelog == | == Changelog == | ||
− | + | *v1.0.1 (Gavino, 27th September 2008): | |
− | - fix for Avisynth 2.5.7 (have to use alternative names for filters, eg GScriptClip) | + | :- 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 == | == Archived Downloads == | ||
{| class="wikitable" border="1"; width="600px" | {| class="wikitable" border="1"; width="600px" | ||
Line 110: | Line 253: | ||
|} | |} | ||
<br> | <br> | ||
− | + | ''Document v1.0.1 ({{Author/Gavino}}, 27th September 2008)'' | |
− | + | ||
− | + | ||
----------------------------------------------- | ----------------------------------------------- | ||
'''Back to [[External_filters#Support_filters|External Filters]] ←''' | '''Back to [[External_filters#Support_filters|External Filters]] ←''' |
Revision as of 02:05, 5 January 2016
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)
- Additional variant of #ConditionalFilter with a single boolean expression
- Fixes a fairly serious bug in the run-time system
- 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])
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])
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])
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])
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])
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 the 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).
TODO - document show, showx
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)", "=",
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 ←