GRunT: Difference between revisions
Raffriff42 (talk | contribs) m add links, use Template:FuncDef, Template:BoxWidthIndent more TODO |
add external links section |
||
| (11 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
{{ | <div style="max-width:62em" > | ||
{{FilterCat4|External_filters|Plugins|Plugins_x64|Support_filters}} | |||
{{Filter3 | {{Filter3 | ||
| Gavino | | {{Author/Gavino}}, {{Author/pinterf}} | ||
| v1.0. | | v1.0.2 | ||
| 3=[ | | 3=[https://github.com/pinterf/GRunT/releases GRunT-v1.02.7z] | ||
| 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]}} | ||
< | </div> | ||
== 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]]. | <div style="max-width:62em" > | ||
[[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> | ||
</div> | |||
==Features== | ==Features== | ||
<div style="max-width:62em" > | |||
* Simple, natural and robust way to pass variables into a run-time script from 'outside' | * 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 | * 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 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) | ||
* | * [[#ConditionalFilter2|New 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 | <!-- NOT SURE IF CURRENT INFO | ||
* 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> | |||
</div> | |||
== Requirements == | |||
* [x86] [[AviSynth+]] or [https://sourceforge.net/projects/avisynth2/ AviSynth 2.6.0] | |||
* [x64] [[AviSynth+]] | |||
* Supported color formats: All | |||
<br> | <br> | ||
== A variables scope and lifetime example == | |||
<div style="max-width:62em" > | |||
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). | |||
</div> | |||
== Run-time Filters == | |||
<div style="max-width:62em" > | |||
'''GRunT''' provides extended versions of the following run-time filters: | |||
===== ''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> | |||
:''cf. AviSynth internal function ''[[ConditionalFilter#ScriptClip|ScriptClip]] | |||
===== ''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> | |||
:''cf. AviSynth internal function ''[[ConditionalFilter#FrameEvaluate|FrameEvaluate]] | |||
===== ''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> | <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> | |||
:''cf. AviSynth internal function ''[[ConditionalFilter#ConditionalFilter|ConditionalFilter]] | |||
===== ''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> | |||
:''cf. AviSynth internal function ''[[WriteFile]] | |||
=== | ===== ''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> | |||
:''cf. AviSynth internal function ''[[WriteFileIf]] | |||
The alternative ({{FuncDef|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: | Each filter is 100% backwards compatible with its standard equivalent, but has two additional optional arguments: | ||
:*''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. | ||
<div {{NotaBeneWidthIndent|50|4|0px solid black}} > | |||
*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 ''=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. | |||
</div> | |||
:*''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). | ||
:*As in the AviSynth internal counterparts, {{FuncArg|show}} (or {{FuncArg|showx}}) to true will display the actual values on the screen. | |||
</div> | |||
== Run-time Functions == | |||
<div style="max-width:62em" > | |||
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. | |||
<div {{BoxWidthIndent| | |||
function | 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> | |||
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> | </div> | ||
This is | 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. | |||
</div> | |||
<div id="ConditionalFilter2"> | |||
== ConditionalFilter == | |||
<div style="max-width:62em" > | |||
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)", | |||
\ "==", "true") | |||
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. | |||
--> | |||
</div> | |||
</div> | |||
== Configuration == | |||
<div style="max-width:62em" > | |||
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. | |||
</div> | |||
== Changelog == | == Changelog == | ||
< | <div style="max-width:62em" > | ||
- | *v1.0.2 (pinterf 30th April 2020): | ||
:-AviSynth 2.6 Interface | |||
:-Register as [[MT_NICE_FILTER]] for AviSynth+ | |||
*v1.0.1a (yesmanitsbearman, 17th May 2016): | |||
:- fix compilation with AviSynth+ | |||
:- 64-bit binary compiled with Microsoft Visual Studio C++ 2015. | |||
:- [https://forum.doom9.org/showthread.php?p=1767990#post1767990 Doom9 post] | |||
v1.0. | *v1.0.1 (Gavino, 27th September 2008): | ||
- | :- fix for Avisynth 2.5.7 (have to use alternative names for filters, eg GScriptClip) | ||
v0.1 (Gavino, 18th June 2008): | *v1.0.0 (Gavino, 9th July 2008): | ||
- fix Avisynth bug in setting of current_frame | :- add 'args' and 'local' to filters | ||
- make current_frame global (allows run-time functions to be cslled inside user functions)</ | :- 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) | |||
</div> | |||
<br> | <br> | ||
== Archived Downloads == | == Archived Downloads == | ||
<div style="max-width:62em" > | |||
{| class="wikitable" border="1"; width="600px" | {| class="wikitable" border="1"; width="600px" | ||
|- | |- | ||
| Line 105: | Line 289: | ||
|- | |- | ||
!v1.0.1 | !v1.0.1 | ||
|[ | |[https://forum.doom9.org/attachment.php?s=e3dfd39b17aff991b34523778ca798f5&attachmentid=8852&d=1222533692 GRunT101.zip] | ||
| | |[https://web.archive.org/web/20200523170646if_/https://files.videohelp.com/u/223002/GRunT101.zip GRunT101.zip] | ||
|- | |- | ||
|} | |} | ||
</div> | |||
<br> | <br> | ||
==External Links == | == External Links == | ||
*[https://github.com/pinterf/GRunT GitHub] - Source code repository. | |||
<br> | <br> | ||
<br> | <br> | ||
----------------------------------------------- | ----------------------------------------------- | ||
'''Back to [[External_filters#Support_filters|External Filters]] ←''' | '''Back to [[External_filters#Support_filters|External Filters]] ←''' | ||
Latest revision as of 17:07, 23 May 2020
| Abstract | |
|---|---|
| Author | Gavino, pinterf |
| Version | v1.0.2 |
| Download | GRunT-v1.02.7z |
| Category | Support filters |
| License | GPLv2 |
| Discussion | Doom9 Thread |
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).
Requirements
- [x86] AviSynth+ or AviSynth 2.6.0
- [x64] AviSynth+
- Supported color formats: All
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.
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.
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.2 (pinterf 30th April 2020):
- -AviSynth 2.6 Interface
- -Register as MT_NICE_FILTER for AviSynth+
- v1.0.1a (yesmanitsbearman, 17th May 2016):
- - fix compilation with AviSynth+
- - 64-bit binary compiled with Microsoft Visual Studio C++ 2015.
- - Doom9 post
- 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 | GRunT101.zip |
External Links
- GitHub - Source code repository.
Back to External Filters ←