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

Reply
 
Thread Tools Search this Thread Display Modes
Old 12th October 2016, 06:30   #1  |  Link
blaze077
Registered User
 
Join Date: Jan 2016
Posts: 79
Question about Scope of Variables

Can a run-time filter change the value defined for a variable in the top-level script?

The following code does not change the value of x from 5 to 6.
Code:
BlankClip(length=240, width=640, height=480, pixel_type="RGB32", fps=24, fps_denominator=1, audio_rate=44100, channels=1, sample_type="16bit", color=$000000)
x = 5
FrameEvaluate("x = 6", show=false, after_frame=false)
Subtitle(String(x))
And can a run-time function pass a global variable?

The following code does not define a value for x.
Code:
BlankClip(length=240, width=640, height=480, pixel_type="RGB32", fps=24, fps_denominator=1, audio_rate=44100, channels=1, sample_type="16bit", color=$000000)
FrameEvaluate("global x = current_frame")
Subtitle(String(x))
Thank you.
blaze077 is offline   Reply With Quote
Old 12th October 2016, 08:41   #2  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by blaze077 View Post
Can a run-time filter change the value defined for a variable in the top-level script?
Yes, but the change naturally occurs at run-time.

In your examples, the argument to Subtitle is evaluated at compile-time, before the run-time filter does the assignment.
See The script execution model/Sequence of events.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 12th October 2016, 19:20   #3  |  Link
blaze077
Registered User
 
Join Date: Jan 2016
Posts: 79
That makes sense. Thank you.
blaze077 is offline   Reply With Quote
Old 13th October 2016, 02:07   #4  |  Link
blaze077
Registered User
 
Join Date: Jan 2016
Posts: 79
Sorry if this is asking the same thing as before but if the run-time filter is evaluated after the other filters, then in this script:

Code:
BlankClip()
x = "black"
ScriptClip("""x="white" Subtitle(x)""")
Subtitle(x)
Why does the final output have "black" on top of "white" instead of the opposite?
blaze077 is offline   Reply With Quote
Old 13th October 2016, 09:25   #5  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,431
Quote:
Originally Posted by blaze077 View Post
if the run-time filter is evaluated after the other filters, then in this script:
...
Why does the final output have "black" on top of "white" instead of the opposite?
The run-time script [x="white" Subtitle(x)] is evaluated after the main script, and this evaluation happens each time ScriptClip() is asked to produce a frame. However, this does not change the order of the filter chain itself, which is:
BlankClip() -> ScriptClip() -> Subtitle()

So after ScriptClip() has produced a frame with a white subtitle, the frame is passed on to the final Subtitle() and has a black title superimposed. (Black because the argument to that Subtitle() is evaluated only once, at compile-time)
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 13th October 2016, 21:11   #6  |  Link
blaze077
Registered User
 
Join Date: Jan 2016
Posts: 79
Got it. Thank you.
blaze077 is offline   Reply With Quote
Old 2nd March 2017, 04:25   #7  |  Link
blaze077
Registered User
 
Join Date: Jan 2016
Posts: 79
I, again, have a question. Is there any way to use values from AverageLuma(), YDifferenceFromPrevious() etc. outside ScriptClip(), FrameEvaluate() etc.? Let's say I want to perform a simple lut expression using AverageLuma. Is it possible to do this outside ScriptClip()?
Code:
 avgluma = *some function that returns the value from AverageLuma()*
mt_lut("x " + String(avgluma) +" *")
blaze077 is offline   Reply With Quote
Old 2nd March 2017, 04:46   #8  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
The problem is, you do not have a current frame to test, only exists in runtime filter.
You can do something like (fake current_frame)

current_frame=42
x=c.AverageLuma

where c has already been established as a clip.
v2.6 also has some arg (cant remember name, off-hand) that allows test of frame relative to currrent_frame,
in RT_stats, I use term Delta for the same thing. In RT, can supply frame to 'n' arg, which is same as setting current_frame fake variable.
[EDIT: Delta equiv name in 2.6 is Offset I think] [EDIT: Also can use in Grunt methinks]

Your example, would only work outside of runtime environment, if setting current_frame at every frame, otherwise, how would it know what frame
you require testing.

eg, something like below is recommended
Code:
SSS=""" # ScriptClip etc auto set current_frame, at every frame before this SSS ScriptClip script is executed.
    avgluma=AverageLuma()                              # implicit use of current_frame
    # avgluma=RT_AverageLuma()                         # Same result, implicit use of current_frame
    # avgluma=RT_AverageLuma(n=current_frame)          # Same result, explicit use
    # avgluma=RT_AverageLuma(n=0, delta=current_frame) # Same result, this one not really recommended.
    mt_lut("x " + String(avgluma) +"...")
    retunn Last
"""

ScriptClip(SSS)

# Below would only execute once (just before frameserving starts, after ScriptClip constructor is called,
# functions and filter Constructors called pretty much in listing order), 
# and apart from the one supplying n=27, would fail.

# avgluma=AverageLuma()                    # This would FAIL, no current_frame exists
# avgluma=RT_AverageLuma()                 # Same again
# avgluma=RT_AverageLuma(n=current_frame)  # Same again
# avgluma=RT_AverageLuma(n=27)             # OK so long a Last clip exists.
AverageLuma, is a function, not a filter, it only returns a single value once, if you want it to do it at every frame, then it must be called in runtime environment were it can be called at every frame. ScripClip etc, automatically set current_frame, at every frame and so that
is why it works as you would like (In runtime environment).

Filters MUST return a clip (frame by frame) so they can live and work in the frameserving time period, anything that does not return a frame/clip is not a filter (is function) and can only be called once unless called in runtime script where current_frame is auto set.

By the way, ScriptClip etc remove the special current_frame variable when exiting ScriptClip/etc, for some reason, one of the WriteFile type funcs actually sometimes set current_frame to -1 on exit (between frames), no idea why.



Hope some of that makes sense.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 2nd March 2017 at 06:08.
StainlessS is offline   Reply With Quote
Old 2nd March 2017, 05:05   #9  |  Link
blaze077
Registered User
 
Join Date: Jan 2016
Posts: 79
Got it. Thank you.
blaze077 is offline   Reply With Quote
Old 26th March 2017, 00:14   #10  |  Link
blaze077
Registered User
 
Join Date: Jan 2016
Posts: 79
I'm having trouble with debugging this function:
Code:
function DiffFunc(clip a, clip b, val "y", val "u", val "v"){
    #Set default threshold for Y, U and V planes.
    isInt(y) ? Assert((y >= 0), "Y must be positive") : NOP()
    isInt(u) ? Assert((u >= 0), "U must be positive") : NOP()
    isInt(v) ? Assert((v >= 0), "V must be positive") : NOP()
    yPlane = (!(Defined(y)) || IsBool(y) && y) ? 2 : \
        (IsBool(y) && !y) ? -1 : \
        (isInt(y)) ? y : Assert(false, "Y must be a boolean or an int")
    uPlane = (!(Defined(u)) || IsBool(u) && u) ? 2 : \
        (IsBool(u) && !u) ? -1 : \
        (isInt(u)) ? u : Assert(false, "U must be a boolean or an int")
    vPlane = (!(Defined(v)) || IsBool(v) && v) ? 2 : \
        (IsBool(v) && !v) ? -1 : \
        (isInt(v)) ? v : Assert(false, "V must be a boolean or an int")
    Assert(!(yPlane==uPlane==vPlane==-1), "You need to select at least one plane")
    threshold = yPlane + uPlane + vPlane
    a.GScriptClip("""
    totalDiff = 0
    yPlane >= 0 ? Eval("totalDiff+=LumaDifference(a, b)") : NOP()
    uPlane >= 0 ? Eval("totalDiff+=ChromaUDifference(a, b)") : NOP()
    vPlane >= 0 ? Eval("totalDiff+=ChromaVDifference(a, b)") : NOP()
    totalDiff > threshold ? Subtitle("0") : Subtitle("1")
    """, args="a, b, yPlane, uPlane, vPlane, threshold") 
}
I'm using this script:
Code:
c = BlankClip(pixel_type="YV12")
DiffFunc(c, c)
And get the error:
Code:
Script error: syntax error
((null), line 1, column 11)
([ScriptClip], line 3)
Could someone point out what is wrong?

EDIT: I don't quite understand the "(null)" message as the values for all variables in args seem to be passed. Maybe it has something to do with the condition.

Thank you.

Last edited by blaze077; 26th March 2017 at 01:00.
blaze077 is offline   Reply With Quote
Old 26th March 2017, 00:52   #11  |  Link
TheFluff
Excessively jovial fellow
 
Join Date: Jun 2004
Location: rude
Posts: 1,100
The error message was fairly clear, I thought? You only have one ScriptClip and while the (null) is a bit confusing, looking at line 3 you see an Eval() which seems pretty suspicious, and at position 11 in the string argument to that Eval() you have the equals sign of +=.

Avisynth script doesn't have C-like extended assignment operators (+=, -= etc).
TheFluff is offline   Reply With Quote
Old 26th March 2017, 01:03   #12  |  Link
blaze077
Registered User
 
Join Date: Jan 2016
Posts: 79
Got it. I did not understand what "(null)" meant as all values for the variables were passed to ScriptClip. I was confusing the null error for Eval with ScriptClip. Sorry and thank you.
blaze077 is offline   Reply With Quote
Old 26th March 2017, 01:25   #13  |  Link
TheFluff
Excessively jovial fellow
 
Join Date: Jun 2004
Location: rude
Posts: 1,100
Well, the context info should say "Eval", not "(null)". It got the string position right so it obviously knows what the context is, it's just not being reported correctly. There's probably a bug somewhere, either in GScript or in the Avisynth script parser.

Last edited by TheFluff; 26th March 2017 at 01:27.
TheFluff is offline   Reply With Quote
Old 26th March 2017, 01:48   #14  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
This is (I think) same as original logic

Code:
function DiffFunc(clip a, clip b, val "y", val "u", val "v") {
    #Set default threshold for Y, U and V planes.
    y=Default(y,true)       u=Default(u,true)       v=Default(v,true)   # identical to original script logic    
    isInt(y) ? Assert((y >= 0), "Y must be positive") : NOP()
    isInt(u) ? Assert((u >= 0), "U must be positive") : NOP()
    isInt(v) ? Assert((v >= 0), "V must be positive") : NOP()
    yPlane = (y.IsBool ) ? ((y) ? 2 : -1)  : (y.isInt) ? y : Assert(false, "Y must be a boolean or an int")
    uPlane = (u.IsBool ) ? ((u) ? 2 : -1)  : (u.isInt) ? u : Assert(false, "U must be a boolean or an int")
    vPlane = (v.IsBool ) ? ((v) ? 2 : -1)  : (v.isInt) ? v : Assert(false, "V must be a boolean or an int")
    Assert(!(yPlane==uPlane==vPlane==-1), "You need to select at least one plane")
    threshold = yPlane + uPlane + vPlane
#    RT_DebugF("yPlane=%d uPlane=%d vPlane=%d threshold=%d",yPlane,uPlane,vPlane,threshold)
    a.GScriptClip("""
        totalDiff = 0
        totalDiff = totalDiff + ((yPlane>=0) ? LumaDifference(Last, b)    : 0)
        totalDiff = totalDiff + ((uPlane>=0) ? ChromaUDifference(Last, b) : 0)
        totalDiff = totalDiff + ((vPlane>=0) ? ChromaVDifference(Last, b) : 0)
        totalDiff > threshold ? Subtitle("0") : Subtitle("1")
    """, args="b, yPlane, uPlane, vPlane, threshold",Local=true) 
}

c = BlankClip(pixel_type="YV12")
DiffFunc(c, c)
EDIT: Despite below looking a little odd, should work as intended.
Code:
    Assert(!(yPlane==uPlane==vPlane==-1), "You need to select at least one plane")
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 26th March 2017 at 02:00.
StainlessS is offline   Reply With Quote
Old 26th March 2017, 02:05   #15  |  Link
blaze077
Registered User
 
Join Date: Jan 2016
Posts: 79
TheFluff: Thanks for your help. I think it is the Avisynth script parser as using vanilla ScriptClip or FrameEvaluate gives me that error.

Code:
Assert(!(yPlane==uPlane==vPlane==-1), "You need to select at least one plane")
I was also not sure this would work but it seemed to work just fine.

Thank you, StainlessS, your code is definitely a better alternative than what I came up with.

Last edited by blaze077; 26th March 2017 at 02:09.
blaze077 is offline   Reply With Quote
Old 26th March 2017, 02:11   #16  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
That assert line explained in a few posts here:- https://forum.doom9.org/showthread.p...32#post1783132
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???
StainlessS is offline   Reply With Quote
Reply

Tags
run-time

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 08:52.


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