Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
18th June 2009, 11:18 | #1 | Link |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,435
|
GScript - language extensions for Avisynth
This is something I started as a 'proof of concept' for my own amusement.
As I think some people will find it useful, I am making it generally available. GScript is a plugin that extends the Avisynth scripting language to provide additional control-flow constructs: multi-line conditionals (if-then-else blocks), 'while' loops and 'for' loops. Rather than trying to simulate these constructs with functions, GScript effectively extends the language syntax, making it easy to use the new constructs in a natural way and in arbitrary combinations. Here are the constructs in detail: 'if' statement Code:
if ( condition ) { statements } else { statements } The statements can be any Avisynth statements, including the GScript extensions themselves, and so the new constructs can be nested. The else part may be omitted (equivalent to else {}). GScript also provides the 'else if' construct (optionally repeated to create a chain of conditionals). Thus Code:
if ( condition ) { statements } else if ( condition ) { statements } else if (...) { ... } ... else { statements } Code:
while ( condition ) { statements } Example: Code:
while (Height() < h) { StackVertical(last, c) } Code:
for ( variable = init , limit , step ) { statements } First the variable is set to the value of init. The statements are repeated until the exit condition is met, ie variable exceeds limit (if step > 0), or is less then limit (if step < 0). After each iteration, variable is incremented by step. If the initial value satisfies the exit condition, the number of iterations will be zero. Example: Code:
for (i=1, nBlurs) { Blur(0.5) } Once the plugin is loaded (either via LoadPlugin or by installing GScript.dll in your plugins folder), there are two ways to use the extended language features. Firstly, a script (or part of a script) containing extensions can be passed as a text string to the GScript function (similar to the way functions like ScriptClip or MT are used). For example, Code:
GScript(""" if (i > 10) { x = 1 y = 2 z = 3 } else { x = 4 y = 5 z = 6 } """) The advantage of this is that you don't have to put quotes around the script, or worry about possible problems if the embedded script itself contains both triple and single quotes. Thus, you can write entire scripts directly in the extended language and just pass to Avisynth a single GImport command to read it. Code:
GImport("MyGScript.avs") Update: Version 1.1 (GScript_11.zip) released 6th Dec 2009 Last edited by Gavino; 15th February 2010 at 13:58. Reason: Remove v1.0 dll from attachments |
18th June 2009, 11:51 | #2 | Link |
Registered User
Join Date: May 2006
Posts: 957
|
Good god man! This is brilliant.
__________________
x264 log explained || x264 deblocking how-to preset -> tune -> user set options -> fast first pass -> profile -> level Doom10 - Of course it's better, it's one more. |
18th June 2009, 14:11 | #4 | Link | |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,391
|
Quote:
For *such* a simple task, Avisynth's standard language (conditional operation through bool ? this : that) is fully sufficient ... Code:
src = last dest_modulo = 2 # or 4, 6, 8, 1337, ... src_modulo = src.width()%dest_modulo padding = dest_modulo - src_modulo src_modulo==0 ? src : src.addborders(0,0,padding,0)
__________________
- We´re at the beginning of the end of mankind´s childhood - My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!) |
|
18th June 2009, 14:20 | #5 | Link | |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,435
|
Quote:
EDIT: as Didée has just shown! Where the extended 'if' becomes really useful is when you need to write more than one statement in one of the conditional 'branches'. Without GScript, you are limited to the rather messy techniques described here, which can't be easily nested. See also here. Last edited by Gavino; 18th June 2009 at 14:22. Reason: Didée's answer |
|
18th June 2009, 15:58 | #7 | Link |
Registered User
Join Date: Mar 2005
Posts: 366
|
Very nice indeed! This way of coding in a more readable syntax(plus the extra functions) is more that welcome. One could hope that this would eventually be implemented in Avisynth so the quotes around the script would not be needed at all.
__________________
DVD slideshow GUI(Freeware). |
18th June 2009, 18:00 | #8 | Link |
Kid for Today
Join Date: Aug 2004
Posts: 3,493
|
hehe ok thanks fellas, as we say in France "caviar doesn't taste better w/ a big spoon"...ideally I'd love to an automatic script that'd make everything mod2 in ffdshow by simply adding horizontal black bars *only* if required, I'll look into Didée's script
|
18th June 2009, 20:39 | #9 | Link |
Resize Abuser
Join Date: Apr 2005
Location: Seattle, WA
Posts: 623
|
Gavino, thanks for doing this! It makes script development a lot simpler now
__________________
Mine: KenBurnsEffect/ZoomBox CutFrames Helped: DissolveAGG ColorBalance LQ Animation Fixer |
19th June 2009, 17:16 | #11 | Link | |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,435
|
Quote:
To implement the plugin, I used a modified version of the Avisynth parser code. The changes are relatively self-contained and all clearly marked in my source code. It would take little more than a cut-and-paste job to put those changes into the 'real' parser. |
|
25th June 2009, 23:50 | #12 | Link |
Registered User
Join Date: Mar 2005
Posts: 366
|
(I know that it ain't xmas - but imagine what you could do with those functions combined with two new functions(just idears): one to paint a pixel(x,y,color) and one to read the color of a pixel(x,y) then the more complicated imagemanipulation filters could be prototyped in avisynth.)
Anyway thanks again for the Gscript plugin.
__________________
DVD slideshow GUI(Freeware). |
18th September 2009, 21:25 | #13 | Link |
Registered User
Join Date: Mar 2005
Posts: 366
|
A bunch of gradients done with gscript.
Uncomment the various Gradient lines to check them out: Code:
loadplugin("GScript.dll") function Gradient(int gwidth, int gheight, int ared, int agreen, int ablue, int bred, int bgreen, int bblue, int cred, int cgreen, int cblue) { blankclip(1,gwidth,1) GScript(""" for (i=1, gheight,1){ r=int(spline(i,0,ared,int(gheight/2),bred,gheight,cred,true)/float(gheight)*255) g=int(spline(i,0,agreen,int(gheight/2),bgreen,gheight,cgreen,true)/float(gheight)*255) b=int(spline(i,0,ablue,int(gheight/2),bblue,gheight,cblue,true)/float(gheight)*255) c=blankclip(1,720,1,color=r*65536 + g*256 + b) StackVertical(last, c) } """) crop(0,1,0,0) } function GradientNoSpline(int gwidth, int gheight, int ared, int agreen, int ablue, int bred, int bgreen, int bblue, int cred, int cgreen, int cblue) { blankclip(1,gwidth,1) GScript(""" for (i=1, gheight,1){ r=int(spline(i,0,ared,int(gheight/2),bred,gheight,cred,false)/float(gheight)*255) g=int(spline(i,0,agreen,int(gheight/2),bgreen,gheight,cgreen,false)/float(gheight)*255) b=int(spline(i,0,ablue,int(gheight/2),bblue,gheight,cblue,false)/float(gheight)*255) c=blankclip(1,720,1,color=r*65536 + g*256 + b) StackVertical(last, c) } """) crop(0,1,0,0) } #Gradient(720, 576,86,107,103,184,164,126,140,36,29)#Vintage America #Gradient(720, 576,59,61,40,113,117,76,255,113,68)#Dawn #Gradient(720, 576,160, 88, 50, 209,169, 75, 249,209,140)#fruity #Gradient(720, 576,225,230,250,171,200,226,24,49,82)#Blue #Gradient(720, 576,236,224,158,145,134,90,191,62,47) #Gradient(720, 576, 62,102,51,220,240,242,150,35,9)#GreenBlueRed #Gradient(720, 576,62,153,96,159,235,74,237,255,116)#Greenish #Gradient(720, 576,117,0,0,215,215,215,0,100,200)#BleuBancRouge #Gradient(720, 576,178,255,0,194,194,194,255,96,10)#GreenBlueRed #Gradient(720, 576,118,192,245,223,236,245,245,105,198)#Baby #Gradient(720, 576,118,192,245,255,170,85,255,0,0)#Sunset #Gradient(720, 576, 17,0,28,94,0,30,17,9,28)#RedPurple #Gradient(720, 576, 6,171,170,5,91,161,0,28,54)#Deep Ocean #Gradient(720, 576,217,204,143,109,140,42,37,64,25)#Grassy Fields #Gradient(720, 576,103,57,15,217,139,43,42,23,12)#Brown #Gradient(720, 576,178,150,82,255,94,53,166,222,161)#OrangeGreen #Gradient(720, 576,249,209,147,75,83,106,193,90,55)#Blue Evening GradientNoSpline(720, 576,121,121,59,216,186,72,51,7,6)#Red jungle
__________________
DVD slideshow GUI(Freeware). Last edited by tin3tin; 18th September 2009 at 21:31. |
19th September 2009, 09:47 | #14 | Link |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,435
|
Thanks, tin3tin. A good example of how GScript makes this sort of thing easier to write.
Of course, it can also be done in standard Avisynth by using recursive procedures, but most people would find it more natural to write an iterative construction like this directly as a loop. Note that the GScript call need not be confined to the 'non-standard' parts of the script. For example, each function (or even both together) could be put inside GScript. This way, the GScript parser is invoked only once, rather than on each call to the function. For example, Code:
GScript(""" function Gradient( ... ) { ... } function GradientNoSpline( ... ) { ... } """) |
19th September 2009, 09:56 | #15 | Link |
Registered User
Join Date: Mar 2005
Posts: 366
|
Will that make it faster? As it is this gradient function is properly too slow(thanks to stackvertical?) to be really useful.
__________________
DVD slideshow GUI(Freeware). |
19th September 2009, 10:48 | #16 | Link |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,435
|
In principle, moving the GScript to outside the function declaration will speed up compilation of the function calls (and hence script loading), but the difference is unlikely to be noticeable. It doesn't affect the 'run-time' - GScript acts purely at 'compile-time'.
I'm not sure if the slowness here comes from the StackVertical or the Spline function - I will look into it and see if it can be made faster in some way. In your code Code:
r=int(spline(i,0,ared,int(gheight/2),bred,gheight,cred,true)/float(gheight)*255) ... etc ... I get better results with just r=int(spline(...)) |
20th September 2009, 09:30 | #17 | Link | |
Registered User
Join Date: Mar 2005
Posts: 366
|
Quote:
__________________
DVD slideshow GUI(Freeware). |
|
20th September 2009, 17:04 | #18 | Link |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,435
|
tin3tin - Looking at this more closely, I think the overhead is due to the repeated use of StackVertical. For an image height of 576, you have 576 instances of StackVertical, each copying an average of 288 lines, so that's over 150000 lines being copied!
A faster way would be to directly use a resizer as the interpolator instead of the Spline function. Try these alternative versions which should produce similar results to yours (I believe identical in the non-spline case). Code:
function Gradient2(int gwidth, int gheight, int ared, int agreen, int ablue, \ int bred, int bgreen, int bblue, int cred, int cgreen, int cblue) { c1 = BlankClip(1, gwidth, 3, color=ared*65536 + agreen*256 + ablue) c2 = BlankClip(1, gwidth, 1, color=bred*65536 + bgreen*256 + bblue) c3 = BlankClip(1, gwidth, 3, color=cred*65536 + cgreen*256 + cblue) StackVertical(c1, c2, c3) Spline16Resize(gwidth, gheight, 0, 2.5, 0, -2.5) } function GradientNoSpline2(int gwidth, int gheight, int ared, int agreen, int ablue, \ int bred, int bgreen, int bblue, int cred, int cgreen, int cblue) { c1 = BlankClip(1, gwidth, 2, color=ared*65536 + agreen*256 + ablue) c2 = BlankClip(1, gwidth, 1, color=bred*65536 + bgreen*256 + bblue) c3 = BlankClip(1, gwidth, 2, color=cred*65536 + cgreen*256 + cblue) StackVertical(c1, c2, c3) BilinearResize(gwidth, gheight, 0, 1.5, 0, -1.5) } (BTW there was another bug in your original code, where 720 was used in place of gwidth in the BlankClips.) |
21st September 2009, 08:29 | #19 | Link |
Registered User
Join Date: Mar 2005
Posts: 366
|
Wow, that's clever - and fast!
Before it was impossible(too slow) to make a gradient lib like this(using 3 out of 5 colors from Kuler): Code:
Gradient(720, 576,86,107,103,184,164,126,140,36,29).Subtitle("Vintage America", align=2,text_color=$FFFFFF)#Vintage America last+Gradient(720, 576,59,61,40,113,117,76,255,113,68).Subtitle("Dawn", align=2,text_color=$FFFFFF)#Dawn last+Gradient(720, 576,160, 88, 50, 209,169, 75, 249,209,140).Subtitle("Red Yellow Pink", align=2,text_color=$FFFFFF)#Red Yellow Pink last+Gradient(720, 576,225,230,250,171,200,226,24,49,82).Subtitle("Blue", align=2,text_color=$FFFFFF)#Blue last+Gradient(720, 576,236,224,158,145,134,90,191,62,47).Subtitle("White Green Red", align=2,text_color=$FFFFFF)#White Green Red last+Gradient(720, 576, 62,102,51,220,240,242,150,35,9).Subtitle("Green White Red", align=2,text_color=$FFFFFF)#GreenWhiteRed last+Gradient(720, 576,62,153,96,159,235,74,237,255,116).Subtitle("Greenish", align=2,text_color=$FFFFFF)#Greenish last+Gradient(720, 576,117,0,0,215,215,215,0,100,200).Subtitle("Bleu Banc Rouge", align=2,text_color=$FFFFFF)#BleuBancRouge last+Gradient(720, 576,178,255,0,194,194,194,255,96,10).Subtitle("Green Blue Red", align=2,text_color=$FFFFFF)#GreenBlueRed last+Gradient(720, 576,118,192,245,223,236,245,245,105,198).Subtitle("Baby", align=2,text_color=$FFFFFF)#Baby last+Gradient(720, 576,118,192,245,255,170,85,255,0,0).Subtitle("Sunset", align=2,text_color=$FFFFFF)#Sunset last+Gradient(720, 576, 17,0,28,94,0,30,17,9,28).Subtitle("Red Purple", align=2,text_color=$FFFFFF)#RedPurple last+Gradient(720, 576, 6,171,170,5,91,161,0,28,54).Subtitle("Deep Ocean", align=2,text_color=$FFFFFF)#Deep Ocean last+Gradient(720, 576,217,204,143,109,140,42,37,64,25).Subtitle("Grassy Fields", align=2,text_color=$FFFFFF)#Grassy Fields last+Gradient(720, 576,103,57,15,217,139,43,42,23,12).Subtitle("Brown", align=2,text_color=$FFFFFF)#Brown last+Gradient(720, 576,178,150,82,255,94,53,166,222,161).Subtitle("Orange Green", align=2,text_color=$FFFFFF)#OrangeGreen last+Gradient(720, 576,249,209,147,75,83,106,193,90,55).Subtitle("Blue Evening", align=2,text_color=$FFFFFF)#Blue Evening last+GradientNoSpline(720, 576,121,121,59,216,186,72,51,7,6).Subtitle("Red jungle", align=2,text_color=$FFFFFF)#Red jungle
__________________
DVD slideshow GUI(Freeware). Last edited by tin3tin; 21st September 2009 at 09:04. |
21st September 2009, 14:13 | #20 | Link | |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,435
|
Quote:
Perhaps starting out with yuv values as the arguments instead of rgb? Note that BlankClip has a color_yuv parameter, so I think you can just do something similar to the rgb version, using pixel_type="YUY2", and convert to YV12 after the resize. |
|
Tags |
for-loop, if-then-else, while-loop |
Thread Tools | Search this Thread |
Display Modes | |
|
|