View Full Version : 'Cheat' gives runtime error message
anton_foy
6th November 2022, 04:06
I have a script that works the way I want except that an error message pops in after frame 0.
Is there a way for this 'cheat' to avoid getting this error message? Since it is a runtime error it burns the message into the image making it unusable.
EDIT: disable showing error messages for runtime environment.
Script:
Current_frame=0
Luma=averageluma()
Lo=fft3dfilter(sigma=6)
Hi=fft3dfilter(sigma=2)
Conditionalfilter(last,Lo,Hi,"luma","lessthan","17600")
EDIT2: here Gavino mention this 'cheat'
https://forum.doom9.org/showthread.php?p=1496483#post1496483
But this is how I set it up as his example shows, yet the error shows up (something like "conditionalfilter doesnt know what luma means") yet it deos the job as I want it. I will post the exact error message when I come home.
I would think this cheat is faster than real runtime since it does not have to evalute for every frame?
StainlessS
6th November 2022, 18:32
You dont say what the error message is, but it dont matter, you are using the cheat wrong.
That 'cheat' is only of use if eg using inside a for loop to access frames outside of runtime script (current_frame=i, where i = loop counter, to access frame i),
or if accessing frame 0, and only frame 0, then current_frame=0.
Can also use that cheat to access eg current_frame - x, inside of runtime (ie relative to the current current frame, eg current_frame=current_frame-1 access previous frame)
sss="""
n = current_frame
current_frame=n - 1
pY = AverageLuma() # AverageLuma of frame prior to REAL current_frame
current_frame=n + 1
nY = AverageLuma() # AverageLuma of frame after to REAL current_frame
current_frame = n # restore current_frame
# ... # plus more code
"""
BLUE Added
The cheat is only for use to access a frame other than the real current_frame, but in AVS+, there is an offset arg to do that anyway.
Just use standard runtime methods.
EDIT: looks like additional prob with the 'luma" thiing, I test out and come back.
anton_foy
6th November 2022, 19:07
You dont say what the error message is, but it dont matter, you are using the cheat wrong.
That 'cheat' is only of use if eg using inside a for loop to access frames outside of runtime script (current_frame=i, where i = loop counter, to access frame i),
or if accessing frame 0, and only frame 0, then current_frame=0.
Can also use that cheat to access eg current_frame - x, inside of runtime (ie relative to the current current frame, eg current_frame=current_frame-1 access previous frame)
sss="""
n = current_frame
current_frame=n - 1
pY = AverageLuma() # AverageLuma of frame prior to REAL current_frame
current_frame=n + 1
nY = AverageLuma() # AverageLuma of frame after to REAL current_frame
"""
The cheat is only for use to access a frame other than the real current_frame, but in AVS+, there is an offset arg to do that anyway.
Just use standard runtime methods.
EDIT: looks like additional prob with the 'luma" thiing, I test out and come back.
Thanks, I suspected something like that, pity. Would be wonderful to be able to use only a specified frame for conditionalfilter to decide A or B so that it does not have to do it every single frame. Besides the error msg burnt into the image from frame 1 and forward it is working as wanted. Like "selected_frame" instead of "current_frame" in this case would be awesome.
StainlessS
6th November 2022, 19:21
Two scripts to play with
K=BlankClip(Pixel_Type="YV12",color=$000000)
W=K.BlankClip(color=$FFFFFF)
M=K.BlankClip(color=$808080)
R=K.BlankClip(color=$FF0000)
B=K.BlankClip(color=$0000FF)
Last = Interleave(K,W,M)
current_frame = 0 # Cheat
Luma = AverageLuma() # The color of frame 0(ie from K clip) , [and value of luma will NEVER change]
Conditionalfilter(last,R,B,"luma","lessthan","128") # luma ALWAYS 0, so luma ALWAYS less than 128, and so always returns RED frame.
Return last
K=BlankClip(Pixel_Type="YV12",color=$000000)
W=K.BlankClip(color=$FFFFFF)
M=K.BlankClip(color=$808080)
R=K.BlankClip(color=$FF0000)
B=K.BlankClip(color=$0000FF)
Last = Interleave(K,W,M)
Conditionalfilter(last,R,B,"Averageluma","lessthan","128")
Return last
EDIT: and I think you want something like this
K=BlankClip(Pixel_Type="YV12",color=$000000)
W=K.BlankClip(color=$FFFFFF)
M=K.BlankClip(color=$808080)
R=K.BlankClip(color=$FF0000)
B=K.BlankClip(color=$0000FF)
Last = Interleave(M,K,W) # I CHANGED ORDER, so frame 0 is grey (Otherwise output would never change if frame 0 white or black)
current_frame = 0 # Cheat
Luma = AverageLuma() # The color of frame 0(ie from M clip) , [and value of luma will NEVER change]
Scriptclip("return (AverageLuma() < Luma) ? R : B ") # scriptclip is more flexible, and fewer surprises.
Return last
anton_foy
7th November 2022, 00:22
Two scripts to play with
K=BlankClip(Pixel_Type="YV12",color=$000000)
W=K.BlankClip(color=$FFFFFF)
M=K.BlankClip(color=$808080)
R=K.BlankClip(color=$FF0000)
B=K.BlankClip(color=$0000FF)
Last = Interleave(K,W,M)
current_frame = 0 # Cheat
Luma = AverageLuma() # The color of frame 0(ie from K clip) , [and value of luma will NEVER change]
Conditionalfilter(last,R,B,"luma","lessthan","128") # luma ALWAYS 0, so luma ALWAYS less than 128, and so always returns RED frame.
Return last
K=BlankClip(Pixel_Type="YV12",color=$000000)
W=K.BlankClip(color=$FFFFFF)
M=K.BlankClip(color=$808080)
R=K.BlankClip(color=$FF0000)
B=K.BlankClip(color=$0000FF)
Last = Interleave(K,W,M)
Conditionalfilter(last,R,B,"Averageluma","lessthan","128")
Return last
EDIT: and I think you want something like this
K=BlankClip(Pixel_Type="YV12",color=$000000)
W=K.BlankClip(color=$FFFFFF)
M=K.BlankClip(color=$808080)
R=K.BlankClip(color=$FF0000)
B=K.BlankClip(color=$0000FF)
Last = Interleave(M,K,W) # I CHANGED ORDER, so frame 0 is grey (Otherwise output would never change if frame 0 white or black)
current_frame = 0 # Cheat
Luma = AverageLuma() # The color of frame 0(ie from M clip) , [and value of luma will NEVER change]
Scriptclip("return (AverageLuma() < Luma) ? R : B ") # scriptclip is more flexible, and fewer surprises.
Return last
Thanks StainlessS although I do not know how this would fit my needs.
I think I just don't understand your script examples :)
All I want is:
Lo=fft3dfilter(sigma=6) #stronger filtering for lower luma
Hi=fft3dfilter(sigma=2) #lighter filtering for brighter luma
Conditionalfilter(last,Lo,Hi,"averageluma","lessthan","17600")
But since the 'cheat' (current_frame=0) is faster I thought I could get around the error message.
StainlessS
7th November 2022, 04:37
You are trying to compare against AverageLuma of frame 0, for all frames, I'm guessin that is not as intended. (with your cheat)
Maybe this as required.
K=BlankClip(Pixel_Type="YV12",color=$000000)
W=K.BlankClip(color=$FFFFFF)
M=K.BlankClip(color=$808080)
Last = Interleave(M,K,W) # Your Source
# Remove the BlankClip stuff [is just so as to see if it works with blankclip source]
Lo=Last.BlankClip(color=$0000FF).fft3dfilter(sigma=6) # Your fft3dfilter(sigma=6)
Hi=Last.BlankClip(color=$FF0000).fft3dfilter(sigma=2) # Your fft3dfilter(sigma=2)
THRESH = 128
Return Conditionalfilter(last,Lo,Hi,"Averageluma","lessthan","THRESH")
# OR
#Return Conditionalfilter(last,Lo,Hi,"Averageluma","lessthan",String(THRESH)) # Probably slightly faster [no access to THRESH variable in name table inside conditionalfilter (is a numeric string instead)]
# OR
#Return Scriptclip("return (AverageLuma() < THRESH) ? LO : HI ") # All evaluated in single string instead of Conditionalfilter's multiple string args.
# OR
#Return Scriptclip("return (AverageLuma() < " + String(THRESH) + " ) ? LO : HI ") # All evaluated in single string instead of Conditionalfilter's multiple string args.
# The String(THRESH) and joining with the rest of the string is done OUTSIDE of Scriptclip, before call to scriptclip, not withing ScriptClip.
# Might be slightly faster than previous one, no access to name table for THRESH variable inside scriptclip,
# value of THRESH when turned into a numeric, is processed directly via the script parser instead of fetching from variable THRESH.
# OR Inside function
#Return TestFunc(Last,lo,hi,thresh)
###############
Function TestFunc(clip c, clip lo, clip hi, Float Thresh) {
Return c.GScriptclip("return (AverageLuma() < THRESH) ? LO : HI ",args="LO,HI,THRESH") # Req Grunt for GStriptClip(args="...")
# OR
# Return c.GScriptclip("return (AverageLuma() < " + String(THRESH) + ") ? LO : HI ",args="LO,HI") # Req Grunt for GStriptClip(args="...") # Embed THRESH as float number, similar to a previous example
}
# Dont know if my imagination, but the Scriptclip/GScriptclip versions seem to flash faster, maybe test in AvsMeter or something.
EDIT:
Return Conditionalfilter(last,Lo,Hi,"Averageluma","lessthan","THRESH")
In Blue above is applied to Last inside of ConditionalFilter, ie equivalent to
Return Conditionalfilter(last,Lo,Hi,"Last.Averageluma()","lessthan","THRESH")
Because of Implicit Last.
If you used your original
Conditionalfilter(last,Lo,Hi,"luma","lessthan","17600")
it is equivalent to
Conditionalfilter(last,Lo,Hi,"Last.luma()","lessthan","17600")
which probably dont make much sense as your luma is a float variable (ie the AverageLuma of frame 0).
However, I think that script parser will first try
Conditionalfilter(last,Lo,Hi,"luma","lessthan","17600")
And only if it fails (ie would produce error) will it retry with implicit Last,
Conditionalfilter(last,Lo,Hi,"Last().luma","lessthan","17600")
which should definitely fail.
###
So, taking your script and converting a little bit, and using 8 bit thresh of 128 instead of your 17600, is sorta similar to
K=BlankClip(Pixel_Type="YV12",color=$000000)
W=K.BlankClip(color=$FFFFFF)
M=K.BlankClip(color=$808080)
Last = Interleave(M,K,W) # Your Source
# Remove the BlankClip stuff [is just so as to see if it works with blankclip source]
Lo=Last.BlankClip(color=$0000FF).fft3dfilter(sigma=6) # Your fft3dfilter(sigma=6)
Hi=Last.BlankClip(color=$FF0000).fft3dfilter(sigma=2) # Your fft3dfilter(sigma=2)
Current_frame=0
Luma=averageluma() # Average luma of frame 0(ie clip M[0]), as a float {RGB $808080 is TV levels mid value Y, 126.0}
#RT_DebugF("Luma=%f",luma)
Return Conditionalfilter(last,Lo,Hi,"luma","lessthan","128") # As luma of frame 0 {clip M[0]} is 126.0, so will always return LO, in this case BLUE frame}
will behave exactly like this
# SAME RESULT AS PREV SCRIPT, ALWAYS BLUE, ie LO clip.
K=BlankClip(Pixel_Type="YV12",color=$000000)
W=K.BlankClip(color=$FFFFFF)
M=K.BlankClip(color=$808080)
Last = Interleave(M,K,W) # Your Source
# Remove the BlankClip stuff [is just so as to see if it works with blankclip source]
Lo=Last.BlankClip(color=$0000FF).fft3dfilter(sigma=6) # Your fft3dfilter(sigma=6)
Hi=Last.BlankClip(color=$FF0000).fft3dfilter(sigma=2) # Your fft3dfilter(sigma=2)
Current_frame=0
Luma=averageluma() # Average luma of frame 0(ie clip M[0]), as a float {RGB $808080 is TV levels mid value Y, 126.0}
#RT_DebugF("Luma=%f",luma)
Return (luma < 128) ? LO : HI # The only difference to previous script, but exact same result
The Cheat,
current_frame = N
luma = AverageLuma()
is only a cheat to access frame N outside of runtime environment, only does a single AverageLuma on frame N, and frame N only, does nothing else.
It is not used because it is faster (which it may or may not be).
It can be used like this though
AviSource("...")
for(n=0,Framecount-1) {
current_frame = n # Cheat so as to use runtime function on frame n, outside of runtime environment
Y = AverageLuma() # This would NOT normally be possible, would normally throw error.
RT_DebugF("%d] %f", n, Y) # do something useful
}
Return MessageClip("Done")
Or can use cheat inside of scriptclip (runtime environment) too
AviSource("...")
SSS = """
n = current_frame
Y = AverageLuma
current_frame = n-1
Prv = AverageLuma
current_frame = n+1
Nxt = AverageLuma
current_frame = n # restore current_frame
# ... Other code
RT_Subtitle("%d] PrevY=%f : Y=%f : NextY=%f", n, Prv, Y, Nxt)
Return Last
"""
Return Scriptclip(SSS)
Although, Avisynth std v2.61 and AVS+ both have Offset args for AverageLuma and some other runtime funcs. ie AverageLuma(clip c,Int "Offset"=0)
which makes the scriptclip cheat unnecessary. { Prv=Last.AverageLuma(-1) : Nxt=Last.AverageLuma(1) }
http://avisynth.nl/index.php/Internal_functions#Runtime_functions
Above two snippets Untested.
anton_foy
7th November 2022, 14:56
Wow this I gotta try when I get home! Many thanks. Yes I noticed that conditionalfilter in its normal usage was slower than my cheat so I hoped to avoid the runtime thingy with current_frame=0. But as it will not accept this it burns in the annoying error message yet besides that it works as I intended. Hope in the future averageluma and its peers can be used outside runtime as an option to fetch stats from given frame only once when the script is loaded.
StainlessS
7th November 2022, 16:07
RT_Stats (8 bit only at present) has for average luma,
RT_AverageLuma(clip c, int n, int delta, ... , int x, int y, int w, int h) # (from memory)
where n is optional frame number so works inside/outside runtime environment, and delta is same as AVS+ offset (relative to frame n if supplied).
Oh WOW, here RT_Stats on Wiki, never seen it before, great works guys :)
http://avisynth.nl/index.php/RT_Stats
Masked Luma Y Functions
Compile time/runtime functions, Planar, YUY2, RGB24 & RGB32. (RGB internally converted to YUV-Y).
The compiletime/runtime clip functions share some common characteristics:-
The 'n' arg is an optional frame number and defaults to 'current_frame' if not specified.
The x,y,w,h, coords specify the source rectangle under scrutiny and are specified as for Crop(), the default 0,0,0,0 is full frame.
If 'interlaced' is true, then every other line is ommited from the scan, so if eg y=1, then scanlines 1,3,5,7 etc are scanned,
if eg y=4 then scanlines 4,6,8,10 etc are scanned. The 'h' coord specifies the full height scan ie same whether interlaced is true
or false, although it will not matter if the 'h' coord is specified as eg odd or even, internally the height 'h' is reduced by 1
when interlaced=true and 'h' is even.
Matrix: Conversion matrix for conversion of RGB to YUV-Y Luma. 0=REC601 : 1=REC709 : 2 = PC601 : 3 = PC709,
Default = (Width > 1100 OR Height>600) then 3(PC709) else 2(PC601). YUV not used
The optional mask clip, governs which pixels are processed by the functions. Where a luma pixel in selected area of the the mask clip is
in range "MaskMin" to "MaskMax" inclusive, then those pixels will be processed. The Mask must also be Planar but not
necessarily the same colorspace as clip c, also must be same dimensions and have at least the same number of frames as clip c.
Calling without mask clip OR with MaskMin=0,MaskMax=255 will effectively ignore the mask and scan full x,y,w,h area.
RT_AverageLuma(clip c,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,
int "Matrix"=(Width>1100||Height>600?3:2),clip "mask"=NOT_USED,int "MaskMin"=128,"MaskMax"=255)
Return int -1, if no valid pixels in Mask clip.
Returns FLOAT value average luma (0.0 -> 255.0) in frame(n+delta) for area x,y,w,h.
EDIT: Also, the FINAL script in post #6, would perhaps be better rewritten to access prev frame, then current, then next,
less likely to cause probs when using frame in-accurate source filter, always best to try access frames in ascending order if possible.
anton_foy
7th November 2022, 16:15
RT_Stats (8 bit only at present) has for average luma,
RT_AverageLuma(clip c, int n, int delta, ... , int x, int y, int w, int h) # (from memory)
where n is optional frame number so works inside/outside runtime environment, and delta is same as AVS+ offset (relative to frame n if supplied).
Oh WOW, here RT_Stats on Wiki, never seen it before, great works guys :)
http://avisynth.nl/index.php/RT_Stats
But yes thats what im talking about! Awesome! Now you have the HBD challenge :D
EDIT: The wiki doesn't mention it is 8-bit only though.
EDIT2: Ok it says further down.
anton_foy
8th November 2022, 22:59
StainlessS thanks again!
This works like a charm (avoiding error) although the same speed as if I do a normal conditionalfilter routine:
current_frame=0
luma=averageluma()
LO=fft3dfilter(sigma=6)
HI=fft3dfilter(sigma=2)
(luma < 17600) ? LO : HI
I will try the rest of your scripts in a moment.
EDIT:
This gives me error Conditionalfilter: First expression did not return an integer, bool or float! :
SSS = """
n = current_frame
Y = AverageLuma
current_frame = n-1
Prv = AverageLuma
current_frame = n+1
Nxt = AverageLuma
current_frame = n # restore current_frame
# ... Other code
Return Last
"""
#Scriptclip(SSS)
lo=fft3dfilter(sigma=6)
hi=fft3dfilter(sigma=2)
conditionalfilter(last, lo, hi, string(sss), "lessthan", "17600")
I probably messed it up doing not what you intended.
EDIT2:
This loads really fast but throws another error:
Conditionalfilter: Second expression did not return a string, as in first string expression
SSS = """
n = current_frame
Y = AverageLuma
current_frame = n-1
Prv = AverageLuma
current_frame = n+1
Nxt = AverageLuma
current_frame = n # restore current_frame
# ... Other code
Return Last
"""
#Scriptclip(SSS)
lo=fft3dfilter(sigma=6)
hi=fft3dfilter(sigma=2)
conditionalfilter(last, lo, hi, "sss", "lessthan", "17600")
EDIT3:
This is the fastest so far but only slightly (noticed also that averageluma inside conditionalfilter gives a higher value so upped thres to 23600):
THRES=23600
lo=fft3dfilter(sigma=6)
hi=fft3dfilter(sigma=2)
conditionalfilter(last, lo, hi, "averageluma", "lessthan", string(THRES))
StainlessS
9th November 2022, 14:47
I probably messed it up doing not what you intended.
Yep, the SSS script was intended for Scriptclip not, ConditionalFilter which requires something more like "AverageLuma".
EDIT: At End of SSS, "Return Y" instead of "Return Last" would work (ConditionalFilter wants a returned value, not a clip)
EDIT2:
This loads really fast but throws another error:
Same thing.
EDIT: Same as above EDIT.
Perhaps for debugging your last script,
K=BlankClip(Pixel_Type="YV12",color=$000000)
W=K.BlankClip(color=$FFFFFF)
M=K.BlankClip(color=$808080)
Interleave(K,W,M)
Convertbits(16) # Your Source. Judging by your THRES, this may be appropriate
SSS ="""
Y=AverageLuma
RT_DebugF("%d] %.3f",current_frame,Y,Name="anton_foy: ") # Output to DebugView : https://learn.microsoft.com/en-us/sysinternals/downloads/debugview
Return Y # equivalent to your "AverageLuma"
"""
THRES=23600
lo=fft3dfilter(sigma=6)
hi=fft3dfilter(sigma=2)
conditionalfilter(last, lo, hi, SSS, "lessthan", string(THRES))
But SSS ="""Return AverageLuma()""" OR """AverageLuma""" quicker after debug. (Assign of AverageLuma to Y variable, and then get return value from Y, both take time)
VoodooFX
9th November 2022, 16:47
For a last InpaintDelogo version I was doing benchmarks with conditionals:
ConditionalFilter & ConditionalSelect gave me same speed, ScriptClip was ~20% slower.
And I noticed that a light weight scripting inside ScriptClip slows it down, so better to do it outside and feed variables with "args" parameter.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.