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 29th November 2012, 21:18   #1  |  Link
fvisagie
Registered User
 
Join Date: Aug 2008
Location: Isle of Man
Posts: 586
How and why does this function's validation get invoked?

Hi All,

I'm putting together a script where the main decision variable ends up as an integer [0..n] as below. It sounds natural to use this integer with Select() to call the corresponding filter. However, when I do this, it seems ALL items in the Select() list have their validation code invoked, not just the one you want to call. I actually discovered this with real filters, but the same happens with functions here.

Code:
# "Received" parameter
Filter  = "f0"

# Evaluate 'Filter'
filtnum = (Filter == "f0") ? 0 : \
          (Filter == "f1") ? 1 : \
          (Filter == "f2") ? 2 : 3
Assert(filtnum < 3, """'Filter' choice """" + Filter + """" is invalid""")

# Filter defaults:	        filter0      filter1      filter3
rad     = Select( filtnum,      24,          24,          12     )
str     = Select( filtnum,      10.0,        10.0,        5.0    )
thrL    = Select( filtnum,      0,           0,           2      )
thrH    = Select( filtnum,      0,           0,           40     )

# This works
(filtnum == 0) ? Version.filter0(rad, str) : \
(filtnum == 1) ? Version.filter1(rad, str) : \
(filtnum == 2) ? Version.filter2(rad, str, thrL, thrH) : \
Assert(false, "This shouldn't happen")

# This fails with "filter2: radius must be < 16", although filter2() should never be invoked
Select(filtnum, \
        Version.filter0(rad, str), \
        Version.filter1(rad, str), \
        Version.filter2(rad, str, thrL, thrH) \
)

function filter0 (clip c, int radius, float strength) {
    Assert(radius < 32, "filter0: radius must be < 32")
    return(MessageClip("0"))
}

function filter1 (clip c, int radius, float strength) {
    Assert(radius < 32, "filter1: radius must be < 32")
    return(MessageClip("1"))
}

function filter2 (clip c, int radius, float strength, int thrL, int thrH) {
    Assert(radius < 16, "filter2: radius must be < 16")
    return(MessageClip("2"))
}
Why is this?

Other than using other conditional constructs, or splitting variables so each function/filter has its own set which I would regard very messy, what other ways are there of getting around this issue?

Many thanks,
Francois
fvisagie is offline   Reply With Quote
Old 29th November 2012, 21:36   #2  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,380
The Select() function, although built-in to Avisynth, is not treated specially by the parser, so all its arguments are evaluated before it is called to make its actual choice.

On the other hand, the conditional test with '?' and ':' is a ternary operator built into the parser itself, so only evaluates the 'true' or 'false' branch as appropriate.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 29th November 2012, 21:56   #3  |  Link
IanB
Avisynth Developer
 
Join Date: Jan 2003
Location: Melbourne, Australia
Posts: 3,168
@Gavino, you're to quick

@fvisagie,

The ? : is implemented directly in the parser so only the one branch is evaluated at compile time.
Code:
...
AVSValue ExpConditional::Evaluate(IScriptEnvironment* env)
...
  return (cond.AsBool() ? Then : Else)->Evaluate(env);
...
Select is an inbuilt function, the parser evaluates all the arguments before calling the function.
Code:
...
AVSValue Select(AVSValue args, void*, IScriptEnvironment* env)
{ int i = args[0].AsInt();
...
  return args[1][i];
}
Consider this piece of script :-
Code:
Function MySelect(Int i, Clip A, Clip B, Clip C) {
  Return Select(i, A, B, C)
}

Last edited by IanB; 29th November 2012 at 21:58. Reason: Gavino to quick
IanB is offline   Reply With Quote
Old 30th November 2012, 07:50   #4  |  Link
fvisagie
Registered User
 
Join Date: Aug 2008
Location: Isle of Man
Posts: 586
@IanB,

Great suggestion, not Select()ing functions. In my case it ended up as follows which works great.

Code:
Eval(Select(shrpnum, \
        """a.gaussianblur(varY=vshy, varC=vshc, y=ysh, u=ush, v=vsh).mt_lutxy(a, "y x - " + String(strsh) + " * y +", y=ysh, u=ush, v=vsh)""", \
        """a.unsharp (varY=vshy, varC=vshc, strength=strsh, y=ysh, u=ush, v=vsh)""", \
        """a.mt_lutxy (a.repair (a.repair (a.repair (a.repair (a.repair (a.repair (a.repair (a.repair (a.medianblur (rshy, rshc, rshc), 4), 4), 4), 4), 4), 4), 4), 4), "x x y - abs " + string (strsh, "%#.2f") + " 2 ^ / 1 " + string (strsh, "%#.2f") + " / ^ " + string (strsh, "%#.2f") + " 3 ^ * x y - x y - abs " + string (strsh, "%#.2f") + " + / * +", y=ysh, u=ush, v=vsh)""", \
        """a.TUnSharp(strength=Int(strsh), thresholdL=thL, thresholdU=thU, type=type, map=map, lim=lim, radius=rshy, gui=false)""" \
     ) \
)
You've been a great help, thanks guys.
fvisagie is offline   Reply With Quote
Reply

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 00:03.


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