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

 
 
Thread Tools Search this Thread Display Modes
Prev Previous Post   Next Post Next
Old 27th October 2013, 10:55   #1  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
Runtime variables scope and lifetime

EDIT 13th November 2013: put discussion result here. The code example is a framework for a versatile and robust RTE usage.

Code:
#~ Example needs Gavino's GRunT, GScript and StainlessS' RT_Stats plugins

function RTE(clip c, string ExampleVarFromNonRTE_Parameter) {
    #######################################
    # Unique Identifier Definition
    #######################################
    Try { global RTE_InstanceNumber = RTE_InstanceNumber+1 } catch(err) { global RTE_InstanceNumber = 1 }

    # Runtime Environment Preparation & Call
    GScript(RT_StrReplace("""	#"   for use without GScript, use Eval( instead
        #######################################
        # 1) Unique Global Variables Initialization
        #######################################
        global RTE_last_frame%%% = -1
        # ... more variables as needed
        
        #######################################
        # 2) Unique Runtime Function Definition
        #######################################
        function RTE_%%%(clip c, string JustMyExampleString) {
            # ... insert complete runtime code here
            # NOTE: Avoid GScript("...") and Eval("...") inside this function, i.e. all functions which expect a script string
            Try {
                c
                Subtitle(string(current_frame - RTE_last_frame%%%))
                Subtitle(JustMyExampleString, align=4)
                global RTE_last_frame%%% = current_frame
                return last
            } catch (err) {
                assert(false, "RTE_ScriptClip %%%: "+err)
            }
        }
        
        #######################################
        # 3) Unique Runtime Call
        #######################################
        ARGS = "ExampleVarFromNonRTE_Parameter"
        c
        #ScriptClip must be a one-liner:
        GScriptClip("RTE_%%%(last, "+ARGS+")", local=true, args=ARGS)
    """, "%%%", string(RTE_InstanceNumber)))	#"
    return last
}

ExampleVarFromNonRTE = "hi there"
BlankClip()
StackHorizontal(last.RTE(ExampleVarFromNonRTE), last.RTE("it works"))

(probably this is a reopening of earlier discussions)

Many, especially powerful scripts like 'Srestore()' use the runtime environment to vary processing on frame level.

The variables they use inside the runtime environment are typically 'shared', in that they share one scope. The variables are 'static' in that their lifetime is same as script lifetime. During rendering stage, the value from the previously processed frame is still there when the function (graph node) is called again.

This approach has the advantage, that the function can build the processing on the previous processing, which is crucial for many algorithms. It has the severe disadvantage however, that multiple instances of the function mash up their variables (even worse: no matter if the same runtime function is used in several nodes of the graph, or even a different function uses a variable with the same name). It makes it impossible to use the function for more than one node in the video graph without interference, as shown in the example.

In a proper implementation and environment, both frames should show a '1' when the clip is rendered forward frame by frame, or the distance from the previous frame otherwise:
Code:
#~ Example needs Gavino's GRunt plugin!
function RTE(clip c) {
    c.GScriptClip("""	# "
    Try { last_frame = last_frame } catch(err) { last_frame = -100 }
    Subtitle(string(current_frame - last_frame))
    last_frame = current_frame
    last
    """, local=false)	#"
}
BlankClip()
StackHorizontal(last.RTE(), last.RTE())
Thanks to and since Gavino's GRunT plugin, the scope can be set to 'local=true'.

This makes the scopes of each RTE instance separate, which is highly desirable in many cases, allowing more than one instance (node) to work properly, and reliefs from problems like 'tunneling x' between different functions.
*But* as second effect, the lifetimes are then restricted to one execution of the function. For the next rendered frame, all previous information is lost. Thus, all algorithms that tie in with the previous frame can not be implemented this way - Except they use global variables, but then the other problem reappears.

For all plugins, it is not a question that it is possible to use them twice ore more in a script, and if they use static variables - no problem.
But for scripted functions, it seems impossible.

Any suggestions?

Last edited by martin53; 13th November 2013 at 08:30. Reason: better (I think) wording
martin53 is offline   Reply With Quote
 

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

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 14:16.


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