GRunT
(GRunT) |
(add external links section) |
||
(12 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 bug in the run-time system | + | <!-- NOT SURE IF CURRENT INFO |
− | * Lightweight plugin extending the standard run-time environment | + | * 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 | ||
* 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> | ||
− | == [[ | + | </div> |
+ | == Requirements == | ||
+ | * [x86] [[AviSynth+]] or [https://sourceforge.net/projects/avisynth2/ AviSynth 2.6.0] | ||
+ | * [x64] [[AviSynth+]] | ||
+ | * Supported color formats: All | ||
+ | <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> | ||
+ | |||
+ | {{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. |
− | + | <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). | ||
+ | |||
+ | :*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. | ||
+ | |||
+ | 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> | ||
+ | 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" > |
− | - fix for Avisynth 2.5.7 (have to use alternative names for filters, eg GScriptClip) | + | *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.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): | + | *v1.0.0 (Gavino, 9th July 2008): |
− | - add 'args' and 'local' to filters | + | :- add 'args' and 'local' to filters |
− | - run-time functions with offset from current_frame | + | :- run-time functions with offset from current_frame |
− | - new variant of ConditionalFilter (single boolean expr) | + | :- new variant of ConditionalFilter (single boolean expr) |
− | v0.1 (Gavino, 18th June 2008): | + | *v0.1 (Gavino, 18th June 2008): |
− | - fix Avisynth bug in setting of current_frame | + | :- fix Avisynth bug in setting of current_frame |
− | - make current_frame global (allows run-time functions to be cslled inside user functions)</ | + | :- 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 100: | 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 |
Contents |
[edit] 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.
[edit] 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).
[edit] Requirements
- [x86] AviSynth+ or AviSynth 2.6.0
- [x64] AviSynth+
- Supported color formats: All
[edit] 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).
[edit] Run-time Filters
GRunT provides extended versions of the following run-time filters:
[edit] 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
[edit] 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
[edit] 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
[edit] 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
[edit] 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.
[edit] 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.
[edit] Average
AverageLuma (clip [, int offset])
AverageChromaU (clip [, int offset])
AverageChromaV (clip [, int offset])
[edit] Difference
RGBDifference (clip1, clip2 [, int offset])
LumaDifference (clip1, clip2 [, int offset])
ChromaUDifference (clip1, clip2 [, int offset])
ChromaVDifference (clip1, clip2 [, int offset])
[edit] Difference from previous
RGBDifferenceFromPrevious (clip [, int offset])
YDifferenceFromPrevious (clip [, int offset])
UDifferenceFromPrevious (clip [, int offset])
VDifferenceFromPrevious (clip [, int offset])
[edit] Difference to next
RGBDifferenceToNext (clip [, int offset])
YDifferenceToNext (clip [, int offset])
UDifferenceToNext (clip [, int offset])
VDifferenceToNext (clip [, int offset])
[edit] 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.
[edit] 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.
[edit] 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.
[edit] 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)
[edit] Archived Downloads
Version | Download | Mirror |
---|---|---|
v1.0.1 | GRunT101.zip | GRunT101.zip |
[edit] External Links
- GitHub - Source code repository.
Back to External Filters ←