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.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage
Register FAQ Calendar Today's Posts Search

Reply
 
Thread Tools Search this Thread Display Modes
Old 3rd June 2008, 22:22   #1  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Problems using AverageLuma etc in user-defined function

Why can't I use a run-time function (like AverageLuma) inside my own function, as long as my function is only called inside a run-time script (eg via ScriptClip)? Why doesn't this work:
Code:
function AL(clip c) {
  Subtitle(c, string(AverageLuma(c)))
}
...
ScriptClip("AL()")
when it's effectively equivalent to this:
Code:
ScriptClip("Subtitle(string(AverageLuma()))")
which does?

It's clear that run-time functions can only be used inside a run-time script. But here the call to function AL is inside the run-time script. I also understand the distinction between parse-time and run-time, which is usually at the root of problems with ScriptClip and friends. But here both the failing script ("AL()") and the working one ("Subtitle(...)") are at the same level.

Is it a bug, or a feature, or is my code wrong?
Gavino is offline   Reply With Quote
Old 4th June 2008, 20:06   #2  |  Link
gzarkadas
Registered User
 
gzarkadas's Avatar
 
Join Date: Sep 2005
Location: 100011110010001000001 10000011111111000001
Posts: 221
This is because runtime variables and functions are made available at the top-level runtime script code only and not in nested scopes (thus they are effectively locals and not globals). Thus although "AL()" and "Subtitle(...)" are at the same level, the AverageLuma call inside your function is not. It is in a nested local scope and not the top-level (local) script scope.

It may not be intuitive, but this is the way things work ; the runtime environment is different from the "normal" script environment.
__________________
AVSLib, a free extension library for Avisynth. Current version: 1.1.0 (beta), 14/05/2007.
[ Home page | Download page ]
gzarkadas is offline   Reply With Quote
Old 4th June 2008, 21:30   #3  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Thanks gzarkadas, I understand what you are saying.

Do you know if there is a good reason that it has to work that way, or is it "just the way it is"?

For usability, it would be advantageous to allow their use in functions called from within the run-time script. For my simple example it doesn't much matter, but for large/complex run-time scripts, it would make for more readable and maintainable code. Or would there be undesirable consequences that I am not foreseeing?

(Maybe this is now really a question for the development forum?)
Gavino is offline   Reply With Quote
Old 5th June 2008, 23:22   #4  |  Link
gzarkadas
Registered User
 
gzarkadas's Avatar
 
Join Date: Sep 2005
Location: 100011110010001000001 10000011111111000001
Posts: 221
Quote:
Originally Posted by Gavino View Post
...
Do you know if there is a good reason that it has to work that way, or is it "just the way it is"?...
Runtime filters construct a script parser on-the-fly at each call to GetFrame to parse the runtime script. Before doing so they set runtime variables -most importantly, current_frame- on the top-level local script code. The runtime functions search for the existent of current_frame variable and exit with error if not found. Since the variable is at local scope, when calling them from within a function, which has its own local scope, the search fails.

Now, about the reason, I can only speculate, since I am not an AviSynth developer , but I see the following difficulty if the choise were made to let runtime filters setting runtime variables at the global scope:
The user script is allowed to do anything inside the very one GetFrame call that has set current_frame. This includes calling other runtime filters with different frame number(s).

The later would set current_frame to their own value(s) and since in our scenario that assigment would be global, they would override current_frame.

If then the script at the initial GetFrame call tried to call another runtime function, the later would operate at a different framenumber than the intended (even a non-existent one). The same is true if just the current_frame variable was used in some way (say to Trim a clip).

That, would certainly resulted in a havoc, sooner or later.
Using local scopes avoids this interaction; and now that I can step back and see my speculation in its entirety, I must admit that there is a good reason .
__________________
AVSLib, a free extension library for Avisynth. Current version: 1.1.0 (beta), 14/05/2007.
[ Home page | Download page ]
gzarkadas is offline   Reply With Quote
Old 6th June 2008, 00:45   #5  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Thanks for your very comprehensive reply.

I need to study your argument at greater length, but it strikes me that the restriction results from the specific way the run-time features are implemented 'under the hood', rather than something inherent in the concept.

(That's still a 'good reason' if it's really just too hard to do it any other way.)
Gavino is offline   Reply With Quote
Old 6th June 2008, 10:46   #6  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
If I understand gzarkadas correctly, he is saying:
  1. You cannot call AverageLuma (etc) inside a user function because current_frame is not visible there.
  2. This in turn is because current_frame is created as a local variable on entry to the runtime script (inside the GetFrame of ScriptClip).
  3. It needs to be local rather than global to prevent problems with cases like:
    Code:
    ScriptClip("""
       ...
       ScriptClip("...")
       ...
    """)
    in which the inner run-time script could disrupt the correct functioning of the outer one by its own use of current_frame. Therefore it needs its own independent instance of the variable.
I'm not sure that the above example can really cause a problem, because the inner run-time script is executed after the statements of the outer one (which in turn are executed after any others in the top-level (normal) script). Perhaps a more complicated example is needed to illustrate the problem.

But in any case, could this not be fixed just by ScriptClip resetting current_frame to its initial value when it exits GetFrame (just like it does with last)? current_frame could then be allowed to be global, and we could have access to it (and hence AverageLuma etc) in user functions.
Gavino is offline   Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 01:16.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.