View Full Version : Dynamic (indexed) filtering
Hotte
17th November 2014, 21:20
Hi,
is there something in avisynth to alter filtering due to an index or indexed frame ?
Say I tied to clips together into one single AVI with an NLE. Clip A has little noise, clip B is very noisy.
I would like to tell avisynth to apply weak noise reduction to clip A but strong parameters to clip B. I could add an index frame or something at the beginning of each clip to tell avisynth which filtering it should apply. After the filtering avysynth would remove the index frames.
Any ideas how to do this ?
Thanks.
TheFluff
17th November 2014, 21:22
write a program that generates an avisynth script full of trim commands, or use one already written (YATTA would be one example but it's really dated now)
or use vapoursynth which has this sort of thing kinda natively
StainlessS
17th November 2014, 22:20
Perhaps this might help,
Avisource("D:\avs\test.avi")
ORG=Last
V1 = FFT3DFilter(Plane=0,Sigma=1.6) # Light luma
V2 = FFT3DFilter(Plane=0,Sigma=2.0) # Med luma
V3 = FFT3DFilter(Plane=0,Sigma=4.0) # High luma
V4 = FFT3DFilter(Plane=3,Sigma=1.6) # Light Chroma
V5 = FFT3DFilter(Plane=3,Sigma=2.0) # Med Chroma
V6 = FFT3DFilter(Plane=3,Sigma=4.0) # High Chroma
V7 = FFT3DFilter(Plane=4,Sigma=1.6) # Light Luma+Chroma
V8 = FFT3DFilter(Plane=4,Sigma=2.0) # Med Luma+Chroma
V9 = FFT3DFilter(Plane=4,Sigma=4.0) # High Luma+Chroma
V10= FlipHorizontal() # Flip-H
V11= FlipVertical() # Flip-V
V12= Invert() # Invert
NickNames =""" # Psuedonyms for clips
L0 = 1 # Light Luma
L1 = 2 # Med Luma
L2 = 3 # High Luma
C0 = 4 # Light Chroma
C1 = 5 # Med Chroma
C2 = 6 # High Chroma
LC0 = 7 # Light Luma + Chroma
LC1 = 8 # Med Luma + Chroma
LC2 = 9 # High Luma + Chroma
FH = 10 # Flip-H
FV = 11 # Flip-V
INV = 12 # Invert
"""
SCMD=""" # Clip editing commands in string, can also use commands in file
C0 0,99 # Light Chroma frames @ 0 -> 99
L0 100,-200 # Light Luma frames @ 100, 200 frames ie frames 100->299
INV 300,399 # Invert 300->399
L0 400,499 # Light Luma frames 400->499
FH 500,599 # Flip-H 500->599
LC2 600,699 # High Luma + Chroma
C1 800 # Med Chroma, Single frame
1 900,999 # Light Luma, We used the clip number instead of a NickName
FV 1000,1099 # Flip-V
LC1 2000,0 # Med Luma + Chroma, 2000 -> lastframe
"""
SHOW=True
ClipClop(ORG,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,scmd=SCMD,nickname=NickNames,show=SHOW)
ClipClop() here: http://forum.doom9.org/showthread.php?t=162266&highlight=clipclop
Replaces ranges in source clip with same range from alternate clips.
You can if you wish use clip number eg 1 to mean clip1 ie L0 (which will repesent V1).
Any ranges not replaced will remain as original clip.
Audio not affected.
Can replace as many ranges or single frames as you like (maximim that I've tried was about 40,000, parsed before first frame
served in about 1 second).
Max 255 replacement clips.
Hotte
17th November 2014, 22:42
Thanks stainless. I would not have been able to understand ClipClop() from the thread without this example, but your code makes it instantly clear.
The only issue is, that I would prefer not to determine the filter changes by given frame numbers but by key frames that are being inserted right before the clip area, where a new filter should be applied. I could easily do that in the NLE. I wished avisynth would then "react" to a certain keyframe or any other frame based information dynamically.
I do not know if the processing model of avisynth is capable of doing this - Just say no, if this approach is not possible.
StainlessS
17th November 2014, 22:46
I dont know of anything that can do as you wish in Avisynth, sorry.
poisondeathray
17th November 2014, 22:58
Was that just an oversimplified example ? Just two clips ? Appended together ?
Because there are obviously easier ways to that
Can you be more descriptive in what a typical use would be ? How many clips, variations, types of edits ?
Another way would be to use AVFS (avisynth virtual file system) and replace the clips with filtered avfs versions in the NLE once you've done your edits.
Or were you more interested in the mechanics and the approach as a theoretical experiment ?
StainlessS
17th November 2014, 23:09
And what do you mean by "keyframe or any other frame based information" or indexed frame ? and how would they denote filtering required ?
I dont use NLE's (well I did have a play a few times many years ago).
poisondeathray
17th November 2014, 23:12
@Hotte - If you're not familiar with AVFS, it's just an emulation method of making a "fake" AVI that allows you to use .avs scripts into NLE's and other programs. To the other program, it just "looks" like an uncompressed AVI . Nothing is rendered, you just mount the .avs. (You would have a different .avs for each version of filters, e.g heavy vs. light, etc...) . In most NLE's it's very easy to replace all instances of all videos with 2 clicks if you've organize the clips into a single folder. The problem you might have is memory issues if you deal with a lot of clips, or heavy filters
So another method you might use is use a "control layer" in the NLE to indicate to avisynth what filter to use with conditionalfilter() with one of the runtime functions like AverageChromaU . Since avisynth does this on a per frame basis, you use a solid color the same as your clip length as an overlay. The colors indicate what filters to apply over what sections. All you need to do is render out the overlay. So "red" might indicate filter this section with filter stack "A", "blue" might indicate filter this section with filter stack "B" , or something like AverageLuma() for white and dark. This isn't the same as what you asked for (inserting a single frame per section), but it works, as I've done this before
Hotte
17th November 2014, 23:32
poisondeathray: I would like to apply avisynth filters to a completed NLE-Project. The final video consists of numerous different clips and was exported as avi. Final step is to apply some subtle sharpening and degraining with tools only available with avisynth. In the NLE process I would like to predetermine which clip will have more or less sharpening or degraining when being post-processed by avisynth.
I think I could do that with StainlessS' approach. But then I would have to write a script or at least a textfile with all the frame-positions and filters to be applied. It seems much more practical to me if - in the NLE - I could insert a certain keyframe that would tell avisynth: Hey, the follwing frames need sharpen=3.0, and one clip later another keyframe (or information of whatever kind) which tells avisynth to apply sharpen=1.0 now, because this clip is already pretty sharp and so on.
I read that "conditional filtering" allows adaptive motion filtering so in principle it seems possible, however the available frame runtime functions seem difficult to be "misused" as keyframes (and - honestly - I do not understand all the mechanics).
Yeah itīs not a theoretical but a practical question.
Hotte
17th November 2014, 23:37
Just to add: I am not looking for something to add to the NLE or to use with AVFS. Forget about it. I export an AVI from NLE and load it into avisynth as a final process. And because there are some "special" frames coded into it, avisynthīs filters a being steered by these special frames. They are just there to set parameters. Could be a subtitle saying "sharpen=3.0". The problem is to evaluate such a frame.
poisondeathray
17th November 2014, 23:42
I read that "conditional filtering" allows adaptive motion filtering so in principle it seems possible, however the available frame runtime functions seem difficult to be "misused" as keyframes (and - honestly - I do not understand all the mechanics).
The control layer approach just chooses frames from a filtered version based on the color of the overlay. So if your filters are adaptive or temporal, then the final version will also be . It's 100% accurate , and has nothing to do with keyframes. I'm probably not describing it very well. You render out the AVI as normal. But you also render out the colored overlay. The colors tell avisynth which frames to choose from which filtered version .
StainlessS
17th November 2014, 23:49
You perhaps could do something like bottom quarter left frame Fine Red ($FF0000), bottom Right Fine Blue ($0000FF),
top lhs, maybe eg 6 or 8 32x32 blocks of either BLACK ($000000) or WHITE ($FFFFFF) binary encoded to mean a filter clip number.
Avisynth script could scan your clip looking for RED/BLUE "I'm here" type markers and write a ClipClop command file.
You would need to write the script for the V1, V2 etc clips as given in clipclop example but would not need NickName,
can directly use the binary coded clip number (clip 0 is reserved for original clip and so binary 0 would mean do not touch).
After that, run it though clipclop, no problem.
OR a control layer as PDR suggests, YOU have to have some way to encode command data, what can you suggest.
EDIT:
Could be a subtitle saying "sharpen=3.0",
Nah, OCR and then some kind AI to try to figure out what you want and then to write a good script, no chance.
YOU would have to decide what each numbered filter would do, and write the script as in the V1,V2 examples given in clipclop.
If you had only a simple filter in mind with only a couple of variables eg FFT3DFilter(Plane=4,Sigma=VAR_1,Sharpen=VAR_2)
then if you can find a way to encode to two variables into a control clip then those could be used to vary the VAR_1 VAR_2 variables,
either continuously (every frame) or if you can also encode some kind of "I'm HERE" marker, then effective from that frame onwards.
Hotte
18th November 2014, 00:19
Stainless:
OK, I understand the principle. Could you tell me how avisynth scans a clip e.g. for $FF0000 color blocks ? Just a few codelines perhaps ? Sorry, I am pretty new to avisynth and you guys are all so enormously experienced (Its my fault to grabbing for the stars with so limited knowledge....).
poisondeathray:
I understand! In NLE I would overlay my cut video with different solid colors over time (the control layer) where I would like a certain filter stack to be applied. Each color represents a certain filter stack. I would render out the original (avi1) plus the control layer as avi2 and feed both avi's into a conditionalfilter(). Sounds good!
Could you please, please help me with some code statements (say with simple blur(1.0) / blur(1.58) due to a different colorcode from avi2)
Thanks!
poisondeathray
18th November 2014, 01:27
poisondeathray:
I understand! In NLE I would overlay my cut video with different solid colors over time (the control layer) where I would like a certain filter stack to be applied. Each color represents a certain filter stack. I would render out the original (avi1) plus the control layer as avi2 and feed both avi's into a conditionalfilter(). Sounds good!
Could you please, please help me with some code statements (say with simple blur(1.0) / blur(1.58) due to a different colorcode from avi2)
Thanks!
Yes! that's it. When you edit it in the NLE, it helps to change the opacity of the control layer to 50% or something to "see" what is going on when you do the actual editing. Change it back when you export
The problem with what you initially wanted, is a single control frame doesn't indicate to avisynth anything about how many frames to affect (mark in, but no mark out point) . It also introduces other problems such as having to deleting it.
Sure, the 2 case example is straight forward. "Blur" , might not be easy to distinguish, so in this example, I choose levels to make a A) dark FilterA B) blown out FilterB. I chose the control layer to be black for FilterA, and red for FilterB. You can easily change the filters or control layer variables, or use different expressions like greater than, less than etc.....
For this example, the original clip is colorbars ("orig" in the script), frames 0-299 . Pretend this is the AVI that you exported
My control layer goes from 0-150 black, 151-299 red in this example . Pretend this is the overlay layer that you exported . Control layer doesn't have to be the same dimensions as main video. It can be 16x16 for example. That will export very fast from NLE
It's easy to debug with "show=true" to see what values are being returned . Comment it out of course when you use it for final encode. You can choose different runtime functions to measure (I used AverageChromaU in this example, for Red)
http://avisynth.nl/index.php/ConditionalFilter#Runtime_Functions
You can use conditionalselect() for more cases as well, or combine conditional filter calls
http://avisynth.nl/index.php/ConditionalFilter
colorbars(width=640,height=480, pixel_type="yv12").showframenumber().trim(0,299)
orig=last
orig
levels(0,0.1,255,0,255,false)
subtitle("FilterA")
FilterA=last
orig
levels(0,3,255,0,255,false)
subtitle("FilterB")
FilterB=last
red=blankclip(orig, color=color_red)
black=blankclip(orig)
controllayer=black.trim(0,150)+red.trim(151,299)
ConditionalFilter(controllayer, filtera, filterb, AverageChromaU()", ">", "120", show=true)
StainlessS
18th November 2014, 01:42
SEE edit above
It would probably be easiest to have a separate control clip rather than a Fine Red/Blue I'm Here type clip (easier for you mostly, not really a problem this end).
You could have continuously varying VARS (as mentioned above) or FILTER_FROM_HERE type frames. For FILTER_FROM_HERE mode, non switch on
frames could be BLACK, and ignored (use previously set filter vars). (Or maybe just use the bottom half of frame to flag FILTER_FROM_HERE leaving top
half of frame to encode data).
If not ignored, then would need to extract some kind of data from eg Binary BLOCK coding in particular positions, OR
eg area 0,0,8,8 (x,y,w,h) might hold info as Average Luma data range 16->235 representing eg 0.0 to 1.0 for a particular variable for eg Sharpen.
eg area 8,0,8,8 (x,y,w,h) might hold info as Average Luma data range 16->235 representing eg 5.0 to 8.0, for some other function.
eg area 16,0,8,8, etc.
OR maybe if only eg 3 variables in total, simply encode 1 in each of the RGB channels, 0,0,0 being ignored and 1->255 being scaled to whatever
was required for particular output variable.
RT_Stats has a number of runtime functions to scan a frames, down to individual pixels for luma or RGB and can easily extract binary block coded
data or encoded as eg luma or RGB channel level. It really only requires that you can successfully encode something, we can extract it (but not subtitles, hehe).
I guess you could even encode ASCII text into Luma or RGB channels and RT_Stats could pick it out of that channel and convert it from a number eg
65 to ASCII 'A'.
It really all depends on what you can persuade your NLE to let you encode on your control clip key frames.
You could even if you like have eg BLACK frame = IGNORED, ORANGE (giving us exactly what you consider to be orange) meaning eg Degrain = 1.1, Sharpen 1.2.
RED = Degrain = 1.2, Sharpen 1.1
etc.
You need to figure out what you can encode, then we'll set about extracting that.
poisondeathray
18th November 2014, 01:53
Here is an example of a 3 state situation, using ConditionalSelect() . It's the same above, but the control layer is black , grey, and white , and goes from 0-100,101-200,201-300 in this simple example
I chose black = filterA , grey= original, white= filterB
colorbars(width=640,height=480, pixel_type="yv12").showframenumber().trim(0,299)
orig=last
orig
levels(0,0.1,255,0,255,false)
subtitle("FilterA")
FilterA=last
orig
levels(0,3,255,0,255,false)
subtitle("FilterB")
FilterB=last
black=blankclip(orig) #16
grey=blankclip(orig, color=$A9A9A9) #161
white=blankclip(orig, color=$FFFFFF) #235
controllayer=black.trim(0,100)+grey.trim(101,199)+white.trim(200,299)
ConditionalSelect(controllayer, "luma_av = AverageLuma()"+chr(13)+"luma_av < 170 ? (luma_av < 17 ? 2 : 1) : 0", FilterB, orig, FilterA, show=true)
How did I know to use those specific numbers <17 and <170? I used them in ConditionalFilter and used show=true. The values are 16 for black, 161 for the shade of grey I used (color=$A9A9A9), and 235 for white
StainlessS
18th November 2014, 02:11
PDR, can I suggest this as easier, especially when a few more Filters are added
colorbars(width=640,height=480, pixel_type="yv12").showframenumber().trim(0,299)
orig=last
orig
levels(0,0.1,255,0,255,false)
subtitle("FilterA")
FilterA=last
orig
levels(0,3,255,0,255,false)
subtitle("FilterB")
FilterB=last
black=blankclip(orig) #16
grey=blankclip(orig, color=$A9A9A9) #161
white=blankclip(orig, color=$FFFFFF) #235
controllayer=black.trim(0,100)+grey.trim(101,199)+white.trim(200,299)
Cond_S = """
luma_av = AverageLuma()
Result = luma_av < 170 ? (luma_av < 17 ? 2 : 1) : 0
Return Result
"""
ConditionalSelect(controllayer,Cond_S, FilterB, orig, FilterA, show=true)
Only extracted the string expression to Cond_S and added the Result var
EDIT: From RT_Stats
RT_RgbChanAve(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 "chan"=0,int "mask"=NOT_USED, int "MaskMin"=128,"MaskMax"=255)
Return int -1, if no valid pixels in Mask clip.
Returns FLOAT average channel value (0.0 -> 255.0) in frame(n+delta) for area x,y,w,h, and selected Chan channel (0=R,1=G,2=B, RGB32 3=ALPHA).
Can just use eg
Red = RT_RgbChanAve(0) # Red = RT_RgbChanAve(0,w=1,h=1) for single pixel sample at 0,0
Grn = RT_RgbChanAve(1)
Blu = RT_RgbChanAve(2)
if you want to use RGB color, can also perhaps use the RGB colors from avisynth Colors_Rgb_avsi, here a small sample
global color_aliceblue = $F0F8FF
global color_antiquewhite = $FAEBD7
global color_aqua = $00FFFF
global color_aquamarine = $7FFFD4
global color_azure = $F0FFFF
global color_beige = $F5F5DC
global color_bisque = $FFE4C4
EDIT: If using the avsi, then this function might be easier
RT_RGB32AsInt(clip,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0)
Compile/Runtime clip function.
Given an RGB32 clip that had a pixel value created from an Int, gets that pixel and returns as the
original Int. By creating single pixel clips and stacking them horizontally/vertically,
you can use a frame as a two dimensional array of Int, perhaps use the frame number for a third dimension.
Returns colors as RGB Int, will get from pixel(0,0) by default but be much quicker than scanning entire frame.
poisondeathray
18th November 2014, 02:18
Nice StainlessS, I'll keep it in mind. I've only used the 2 filter case before with my NLE, because I prefer to do it these sorts of things with remapframes() method in avisynth.
Hotte
18th November 2014, 03:25
Thank you guys - so much input! It will take me some time to go through your suggestions and come back with questions.
Short first question concerning performance: Are Filter A and B both calculated for the whole video or only for those parts of the video where they are finally applied to ? I use quite performance hungry filters. Selecting out of 3 or 4 variants might slow down heavily if everything is being calcualted for the whole clip ?
StainlessS
18th November 2014, 03:49
Only for those parts of the video where they are finally applied to.
Any filters not used at all (as in the ClipClop example) will only have the overhead of calling any filter constructors, ie before the first frame is served.
Hotte
18th November 2014, 07:28
Any filters not used at all (as in the ClipClop example) will only have the overhead of calling any filter constructors
allright, how about the ConditionalSelect(controllayer,Cond_S, FilterB, orig, FilterA, show=true) ?
StainlessS
18th November 2014, 13:25
ConditionalSelect() is a filter and requires calling of constructor (once at startup), the Cond_S script is executed for each frame, not really
that much of an overhead to scan a single frame using eg AverageLuma, however complete frame is scanned. If you used
RT_AverageLuma(x=0,y=0,w=1,h=1) or RT_RgbChanAve(x=0,y=0,w=1,h=1) to sample a single pixel @0x0 then would of course be faster.
ConditionalSelect() or ScriptClip() etc scripts are slow if they contain filters with high startup costs (at each frame), but
AverageLuma/RT_AverageLuma are functions not filters (they do not return a frame) and so have no start up constructor overhead.
I would not worry too much about speed here, but it depends upon what way you choose to encode command data.
A single specific RGB color could be used to mean many filter settings, but as I said you would need to
set up the V1 type filters (as in clipclop example), would also be faster than trying to programmatically make adjustments at each frame
(together with filter constructor overheads at each frame).
EDITED:
StainlessS
18th November 2014, 14:19
As PDR suggested somewhere, control clip could be eg 32x32 (or whatever) in size and so very fast to process.
Instead of ConditionalSelect() could just scan the clip and write a ClipClop command file.
Eg you could equate RGB $FF00FF to mean FFT3DFilter(Plane=0,Sigma=3.5,sharpen=0.5).
At this end, when writing ClipClop command file, we could convert RGB $FF00FF to be eg clip number 1, or even NickName "FFT_0_35_05",
if clip 1 chosen then need to make filter chain for clip 1 equivalent to FFT3DFilter(Plane=0,Sigma=3.5,sharpen=0.5), if
NickName "FFT_0_35_05", chosen, then can delay decision about which clip number it is, can create control clip, scan control clip
in Avisynth to make ClipClop command file using chosen nickname strings (rather than fixed clip index), and then after you have
created all your filters chains, decide which filter chain will be applied to a clip number, and then define the NickNames to suit the
chosen clip index.
What I'm getting at is, you equate eg RGB $FF00FF to be "FFT_0_35_05", and later decide how you are gonna achieve that.
EDIT: I'll do a small example of what I mean a little later today.
Hotte
18th November 2014, 21:42
StainlessS, though I am getting to the limit of my understanding, I am happily waiting for codelines with a simple example to try out. Sound an interesting approach!
StainlessS
19th November 2014, 01:54
Almost there but I've got a squash resistant bug somewhere.
Way faster than I thought it might be.
Hopefully the example (well its pretty much the whole thing really) will clarify a few things.
StainlessS
19th November 2014, 18:24
Here is a script that just makes a test Control clip identical functionality to SCMD in first example given in post #3.
# MakeControlClipAVI.avs, Make Dummy control clip for testing, Save to Control.AVI
ORG=Avisource("D:\avs\test.avi").ConvertToRGB32().PointResize(32,32).KillAudio # Take Blankclip attributes from this
BLACK = $000000
BLUE = $0000FF
GREEN = $00FF00
CYAN = $00FFFF
RED = $FF0000
MAGENTA = $FF00FF
YELLOW = $FFFF00
WHITE = $FFFFFF
ORANGE = $FFA500
DARKGRAY = $A9A9A9
SILVER = $C0C0C0
PLUM = $DDA0DD
POWDERBLUE = $B0E0E6
V0 = ORG.BlankClip(Color=BLACK)
V1 = ORG.BlankClip(Color=BLUE)
V2 = ORG.BlankClip(Color=GREEN)
V3 = ORG.BlankClip(Color=CYAN)
V4 = ORG.BlankClip(Color=RED)
V5 = ORG.BlankClip(Color=MAGENTA)
V6 = ORG.BlankClip(Color=YELLOW)
V7 = ORG.BlankClip(Color=WHITE)
V8 = ORG.BlankClip(Color=ORANGE)
V9 = ORG.BlankClip(Color=DARKGRAY)
V10 = ORG.BlankClip(Color=SILVER)
V11 = ORG.BlankClip(Color=PLUM)
V12 = ORG.BlankClip(Color=POWDERBLUE)
NickNames =""" # Psuedonyms for clip index
SOURCE = 0 # Original Clip BLACK
L0 = 1 # Light Luma BLUE
L1 = 2 # Med Luma GREEN
L2 = 3 # High Luma CYAN
C0 = 4 # Light Chroma RED
C1 = 5 # Med Chroma MAGENTA
C2 = 6 # High Chroma YELLOW
LC0 = 7 # Light Luma + Chroma WHITE
LC1 = 8 # Med Luma + Chroma ORANGE
LC2 = 9 # High Luma + Chroma DARKGRAY
FH = 10 # Flip-H SILVER
FV = 11 # Flip-V PLUM
INV = 12 # Invert POWDERBLUE
"""
SCMD=""" # Clip editing commands in string, can also use commands in file
C0 0,99 # Light Chroma frames @ 0 -> 99 RED
L0 100,-200 # Light Luma frames @ 100, 200 frames ie frames 100->299 BLUE
INV 300,399 # Invert 300->399 POWDERBLUE
L0 400,499 # Light Luma frames 400->499 BLUE
FH 500,599 # Flip-H 500->599 SILVER
LC2 600,699 # High Luma + Chroma DARKGRAY
C1 800 # Med Chroma, Single frame MAGENTA
1 900,999 # Light Luma, We used the clip number instead of a NickName BLUE
FV 1000,1099 # Flip-V PLUM
LC1 2000,0 # Med Luma + Chroma, 2000 -> lastframe ORANGE
"""
SHOW=FALSE
ClipClop(V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,scmd=SCMD,nickname=NickNames,show=SHOW)
Script to extract RGB color from Control Clip and convert to ClipClop Command file.
# MakeClopCmd.avs, Convert commands embedded in Control.AVI RGB COLOUR, to ClipClop Command file.
Avisource("Control.AVI").ConvertToRGB32 # Just incase RGB24
CMD = "Command.Txt" # ClipClop Command file (Output of this script)
###
### HERE, YOU DECIDE THE NICKNAMES TO USE FOR WHICH COLOR CONTROL, BUT NOT WHICH CLIP INDEX THEY REFER TO
###
MAP = """ # RGB Hex Color Code, NickName, Color As Comment ('$000000 = SOURCE # BLACK' means original clip)
$000000 = SOURCE # BLACK
$0000FF = L0 # BLUE
$00FF00 = L1 # GREEN
$00FFFF = L2 # CYAN
$FF0000 = C0 # RED
$FF00FF = C1 # MAGENTA
$FFFF00 = C2 # YELLOW
$FFFFFF = LC0 # WHITE
$FFA500 = LC1 # ORANGE
$A9A9A9 = LC2 # DARKGRAY
$C0C0C0 = FH # SILVER
$DDA0DD = FV # PLUM
$B0E0E6 = INV # POWDERBLUE
"""
###
### Create Color_Code -> NickName DBase
###
RT_FileDelete(CMD) # Delete existing Command file
DB = "~"+RT_LocalTimeString+".DB" # Temp DBase filename
RT_DBaseAlloc(DB,0,"iss") # Create zero record DB (Int,String,String)
MakeColorNickDBase(DB,MAP) # Fill DB with Color->NickName data (sorted by HexColor)
###
### Scan Control.AVI and create ClipClop Command file
###
GSCript("""
RECORDS = RT_DBaseRecords(DB)
HEXFIELD = 0 # Int field
NICKFIELD = 1 # String field
COMMFIELD = 2 # String field
FC = FrameCount
CurrCol = -1
CurrNick = ""
CurrComm = ""
SFrm = 0
For(n=0,FC) {
Dat = (n==FC) ? -1 : RT_BitAND(RT_RGB32AsInt(n=n,x=0,y=0),$FFFFFF) # Sample single pixel RGB32 Color as Int (clr Alpha)
if(n == FC || Dat != CurrCol) {
Frames = n - SFrm
if(Frames > 0) { # If not Frame 0
if(Frames == 1) { # Write NickName and Frame Number
RT_DebugF("%-16s %6d # $%06X %s",CurrNick,SFrm,CurrCol,CurrComm)
RT_WriteFile(CMD,"%-16s %6d # $%06X %s",CurrNick,SFrm,CurrCol,CurrComm,Append=True)
} Else { # Write NickName and Range
RT_DebugF("%-16s %6d,%-6d # $%06X %s",CurrNick,SFrm,n-1,CurrCol,CurrComm)
RT_WriteFile(CMD,"%-16s %6d,%-6d # $%06X %s",CurrNick,SFrm,n-1,CurrCol,CurrComm,Append=True)
}
}
if(n < FC) { # Else, ALL DONE .. writing LAST range only
CurrCol = Dat
SRec = DB_FindVar(DB,HEXFIELD,CurrCol)
Assert(SRec != -1,RT_String("Cannot Find RGB Hex Color($%06X) in DBase @ Frame %d",CurrCol,n))
CurrNick = RT_DBaseGetField(DB,SRec,NICKFIELD) # Get Associated NickName
CurrComm = RT_DBaseGetField(DB,SRec,COMMFIELD) # Get Associated Comment
SFrm = n # REM new start frame
}
}
}
RT_FileDelete(DB) # Clean up
return MessageClip(RT_String("All Done, Created %s",CMD))
###
###
###
Function DB_FindVar(String DB,Int Field,Var) {
# DB_FindVar Returns record number containing Var in Field field, using Binary Search
# Var type can be Int, Float or String(Case Insig).
# DBase MUST be sorted ascending by Field.
# Field is the DB field that contains Var to find.
# Return record number or -1 = NOT FOUND.
result = -1 # Init NOT FOUND
low = 0
high = RT_DBaseRecords(DB) - 1
while(low <= high) {
mid = (low + high) / 2
if(RT_DBaseGetField(DB,mid,Field) < Var) {
low = mid + 1
} Else If (RT_DBaseGetField(DB,mid,Field) > Var) {
high = mid - 1
} Else {
low = high + 1 # Force exit
Result = mid
}
}
return result
}
""")
Function MakeColorNickDBase(String DB,String MAP) {
/*
Parse MAP string and create Sort Ascending (by Hex Color) DBase for efficiently Scanning Control.AVI
*/
GSCript("""
MAP=RT_StrReplaceDeep(RT_StrReplace(MAP,Chr(9)," ")," "," ") # TAB and SPACE compact (multi to single SPACE)
M=RT_TxtSort(MAP,Mode=0) # Sort Ascending, case insig (by Hex Color Code)
NLINES = RT_TxtQueryLines(M) # Lines of text in M
For(i=0,NLINES-1) {
STR = RT_TxtGetLine(M,i)
S = STR
While(RT_Ord(S)==32) { S=MidStr(S,2) } # Eat White
if(MidStr(S,1,1)=="$") {
S = MidStr(S,2) # Swalla the Dolla
c = UCase(MidStr(S,1,1))
IsHexDig = ((c>="0" && c<="9") || (c>="A" && c<="F"))
Assert(IsHexDig,RT_String("String(%d) Hex Color Code Missing @'%s'\n'%s'",i,S,STR))
HexColor = RT_NumberValue(S,16)
While(StrLen(S)>=1 && IsHexDig) { # Swalla Hex
S = MidStr(S,2)
c = UCase(MidStr(S,1,1))
IsHexDig = ((c>="0" && c<="9") || (c>="A" && c<="F"))
}
While(RT_Ord(S)==32) { S=MidStr(S,2) } # Eat White
if(MidStr(S,1,1)=="=") {
S = MidStr(S,2) # Swalla optional '='
While(RT_Ord(S)==32) {S=MidStr(S,2)} # Eat White
}
c = UCasE(MidStr(S,1,1))
Assert((c>="A" && c<="Z") || c=="_",RT_String("String(%d) NickName Missing @'%s'\n'%s'",i,S,STR))
NickLen=1
SLen = StrLen(S)
For(j=2,Slen) {
c = UCase(MidStr(S,j,1))
if((c>="0" && c<="9") || (c>="A" && c<="Z") || c=="_") {
NickLen = NickLen + 1
} else {
j = SLen # Break
}
}
NickName = MidStr(S,1,NickLen)
S = MidStr(S,NickLen+1)
While(RT_Ord(S)==32) {S=MidStr(S,2)} # Eat White
Comment = ""
if(MidStr(S,1,1)=="#") {
S = MidStr(S,2) # Swalla Hash
While(RT_Ord(S)==32) {S=MidStr(S,2)} # Eat White
if(StrLen(S)>0) { # End Trim White
S=RevStr(S)
While(RT_Ord(S)==32) {S=MidStr(S,2)} # Eat White
S=RevStr(S)
Comment=S
S=""
}
}
RT_DebugF("%3d ] $%06X : %-10s : %s",i,HexColor,NickName,Comment) # Output to DebugView
RT_DBaseAppend(DB,HexColor,NickName,Comment) # Append record to DBase
}
While(RT_Ord(S)==32) { S=MidStr(S,2) } # Eat White
if(RT_Ord(S) == RT_Ord("#")) { S="" } # Swallow, Only Comment Remaining
Assert(S=="",RT_String("String(%d) Non Parse @'%s'\n'%s'",i,S,STR))
}
""")
Return RT_DBaseRecords(DB) # Return Something
}
Final ClipClop script using Command.txt file created by above previous script
Avisource("D:\avs\test.avi")
CMD="Command.Txt"
V0 = Last # SOURCE
V1 = FFT3DFilter(Plane=0,Sigma=1.6) # Light luma
V2 = FFT3DFilter(Plane=0,Sigma=2.0) # Med luma
V3 = FFT3DFilter(Plane=0,Sigma=4.0) # High luma
V4 = FFT3DFilter(Plane=3,Sigma=1.6) # Light Chroma
V5 = FFT3DFilter(Plane=3,Sigma=2.0) # Med Chroma
V6 = FFT3DFilter(Plane=3,Sigma=4.0) # High Chroma
V7 = FFT3DFilter(Plane=4,Sigma=1.6) # Light Luma+Chroma
V8 = FFT3DFilter(Plane=4,Sigma=2.0) # Med Luma+Chroma
V9 = FFT3DFilter(Plane=4,Sigma=4.0) # High Luma+Chroma
V10= FlipHorizontal() # Flip-H
V11= FlipVertical() # Flip-V
V12= Invert() # Invert
###
### HERE, You Assign NickNames to Clip Index. (You could if you wanted use color names, eg ORANGE as NickNames).
### RGB ColorCodes entered in Comments just as reminder
### NickNames MUST match those used in previous script
NickNames =""" # Psuedonyms for clip index
SOURCE = 0 # Original Clip BLACK
L0 = 1 # Light Luma BLUE
L1 = 2 # Med Luma GREEN
L2 = 3 # High Luma CYAN
C0 = 4 # Light Chroma RED
C1 = 5 # Med Chroma MAGENTA
C2 = 6 # High Chroma YELLOW
LC0 = 7 # Light Luma + Chroma WHITE
LC1 = 8 # Med Luma + Chroma ORANGE
LC2 = 9 # High Luma + Chroma DARKGRAY
FH = 10 # Flip-H SILVER
FV = 11 # Flip-V PLUM
INV = 12 # Invert POWDERBLUE
"""
SHOW=True
ClipClop(V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,cmd=CMD,nickname=NickNames,show=SHOW)
ClipClop Command.txt file extacted from test Control.AVI
C0 0,99 # $FF0000 RED
L0 100,299 # $0000FF BLUE
INV 300,399 # $B0E0E6 POWDERBLUE
L0 400,499 # $0000FF BLUE
FH 500,599 # $C0C0C0 SILVER
LC2 600,699 # $A9A9A9 DARKGRAY
SOURCE 700,799 # $000000 BLACK
C1 800 # $FF00FF MAGENTA
SOURCE 801,899 # $000000 BLACK
L0 900,999 # $0000FF BLUE
FV 1000,1099 # $DDA0DD PLUM
SOURCE 1100,1999 # $000000 BLACK
LC1 2000,13860 # $FFA500 ORANGE
Here original SCMD in post#3 example
SCMD=""" # Clip editing commands in string, can also use commands in file
C0 0,99 # Light Chroma frames @ 0 -> 99
L0 100,-200 # Light Luma frames @ 100, 200 frames ie frames 100->299
INV 300,399 # Invert 300->399
L0 400,499 # Light Luma frames 400->499
FH 500,599 # Flip-H 500->599
LC2 600,699 # High Luma + Chroma
C1 800 # Med Chroma, Single frame
1 900,999 # Light Luma, We used the clip number instead of a NickName
FV 1000,1099 # Flip-V
LC1 2000,0 # Med Luma + Chroma, 2000 -> lastframe
"""
EDITED:
StainlessS
20th November 2014, 14:05
If you want to use colors as the nicknames (some may find it easier), then below script will enable use of all color names
(minus the initial 'color_') mentioned in Avisynth standard Colors_rgb.avsi as RGB control colors in your control.avi clip:
EDIT: Avisynth+ is broken as far as RT_PluginDir() is concerned, you could change to explicit path if required.
# MakeClopCmdUsingColorsRgbAvsi.avs
Avisource("Control.AVI").ConvertToRGB32 # Just incase RGB24
CMD = "Command.Txt" # ClipClop Command file (Output of this script)
USED = "Commands_Used.Txt"
COLORS_AVSI=RT_PluginDir()+"\colors_rgb.avsi"
Assert(Exist(COLORS_AVSI),RT_String("%s\nDoes NOT exist in Plugins Dir",COLORS_AVSI))
CMAP=RT_ReadTxtFromFile(COLORS_AVSI)
RT_FileDelete(CMD) # Delete existing Command file
RT_FileDelete(USED)
DB = "~"+RT_LocalTimeString+".DB" # Temp DBase filename
RT_DBaseAlloc(DB,0,"issb") # Create zero record DB (Int,String,String,bool)
T_START=RT_TimerHP()
MakeColorAvsiNickDBase(DB,CMAP) # Fill DB with Color->NickName data (sorted by HexColor)
###
### Scan Control.AVI and create ClipClop Command file using names from Colors_RGB.Avsi
###
GSCript("""
RECORDS = RT_DBaseRecords(DB)
HEXFIELD = 0 # Int field
NICKFIELD = 1 # String field
COMMFIELD = 2 # String field
USEDFIELD = 3 # Bool field
FC = FrameCount
CurrCol = -1
CurrNick = ""
CurrComm = ""
SFrm = 0
For(n=0,FC) {
Dat = (n==FC) ? -1 : RT_BitAND(RT_RGB32AsInt(n=n,x=0,y=0),$FFFFFF) # Sample single pixel RGB32 Color as Int (clr Alpha)
if(n == FC || Dat != CurrCol) {
Frames = n - SFrm
if(Frames > 0) { # If not Frame 0
if(Frames == 1) { # Write NickName and Frame Number
RT_DebugF("%-16s %6d # $%06X %s",CurrNick,SFrm,CurrCol,CurrComm)
RT_WriteFile(CMD,"%-16s %6d # $%06X %s",CurrNick,SFrm,CurrCol,CurrComm,Append=True)
} Else { # Write NickName and Range
RT_DebugF("%-16s %6d,%-6d # $%06X %s",CurrNick,SFrm,n-1,CurrCol,CurrComm)
RT_WriteFile(CMD,"%-16s %6d,%-6d # $%06X %s",CurrNick,SFrm,n-1,CurrCol,CurrComm,Append=True)
}
}
if(n < FC) { # Else, ALL DONE .. writing LAST range only
CurrCol = Dat
SRec = DB_FindVar(DB,HEXFIELD,CurrCol)
Assert(SRec != -1,RT_String("Cannot Find RGB Hex Color($%06X) in DBase @ Frame %d",CurrCol,n))
CurrNick = RT_DBaseGetField(DB,SRec,NICKFIELD) # Get Associated NickName
CurrComm = RT_DBaseGetField(DB,SRec,COMMFIELD) # Get Associated Comment
SFrm = n # REM new start frame
RT_DBaseSetField(DB,SRec,USEDFIELD,True) # Used
}
}
}
TIM=RT_TimerHP-T_START
RT_WriteFile(USED,"# Total Time Taken = %.3f secs for %d Frames\n#\n",TIM,FC)
for(n=0,RECORDS-1) {
if(RT_DBaseGetField(DB,n,USEDFIELD)) {
S=RT_String("%-20s # $%06X %s",RT_DBaseGetField(DB,n,NICKFIELD),RT_DBaseGetField(DB,n,HEXFIELD),RT_DBaseGetField(DB,n,COMMFIELD))
RT_WriteFile(USED,"%s",S,Append=True)
}
}
RT_FileDelete(DB) # Clean up
return MessageClip(RT_String("All Done, Created '%s' AND '%s'",CMD,USED))
###
###
###
Function DB_FindVar(String DB,Int Field,Var) {
# DB_FindVar Returns record number containing Var in Field field, using Binary Search
# Var type can be Int, Float or String(Case Insig).
# DBase MUST be sorted ascending by Field.
# Field is the DB field that contains Var to find.
# Return record number or -1 = NOT FOUND.
result = -1 # Init NOT FOUND
low = 0
high = RT_DBaseRecords(DB) - 1
while(low <= high) {
mid = (low + high) / 2
if(RT_DBaseGetField(DB,mid,Field) < Var) {
low = mid + 1
} Else If (RT_DBaseGetField(DB,mid,Field) > Var) {
high = mid - 1
} Else {
low = high + 1 # Force exit
Result = mid
}
}
return result
}
""")
Function MakeColorAvsiNickDBase(String DB,String CMAP) {
GSCript("""
Fnd_S=RT_String("GLOBAL\nCOLOR_\n=\n")
Rep_S=RT_String("\n\n\n")
CMAP=RT_StrReplaceMulti(CMAP,Fnd_S,Rep_S,sig=False) # Delete some stuff
CMAP=RT_StrReplaceDeep(RT_StrReplace(CMAP,Chr(9)," ")," "," ") # TAB and SPACE compact (multi to single SPACE)
NLINES = RT_TxtQueryLines(CMAP) # Lines of text in CMAP
M=""
For(i=0,NLINES-1) {
S = RT_TxtGetLine(CMAP,i)
While(RT_Ord(S)==32) { S=MidStr(S,2) } # Eat White
if(StrLen(S)>0 && MidStr(S,1,1)!="#") {
Dollar=RT_FindStr(S,"$")
Assert(Dollar>0, RT_string("Dollar Not Found @ Line%d\n%s",i,S))
H=MidStr(S,Dollar+1)
H=RevStr(H)
While(RT_Ord(H)==32) { H=MidStr(H,2) } # Eat White
H=RevStr(H)
NN=MidStr(S,1,Dollar-1)
While(RT_Ord(NN)==32) { NN=MidStr(NN,2) } # Eat White
NN=RevStr(NN)
While(RT_Ord(NN)==32) { NN=MidStr(NN,2) } # Eat White
NN=RevStr(NN)
S=RT_String("%s%s",H,NN)
M=RT_TxtAddStr(M,S)
}
}
M=RT_TxtSort(UCase(M),Mode=0) # Sort Ascending (by Hex Color Code)
NLINES = RT_TxtQueryLines(M) # Lines of text in M
For(i=0,NLINES-1) {
S = RT_TxtGetLine(M,i)
H=MidStr(S,1,6)
NICK=MidStr(S,7)
HexCol=RT_NumberValue(H,16)
Comment = NICK
RT_DebugF("%3d ] $%06X %-20s # %s",i,HexCol,NICK,Comment) # Output to DebugView
RT_DBaseAppend(DB,HexCol,NICK,Comment,False) # Append record to DBase
}
Return RT_DBaseRecords(DB) # Return Something
""")
}
Ouput from previously posted test Control.avi
RED 0,99 # $FF0000 RED
BLUE 100,299 # $0000FF BLUE
POWDERBLUE 300,399 # $B0E0E6 POWDERBLUE
BLUE 400,499 # $0000FF BLUE
SILVER 500,599 # $C0C0C0 SILVER
DARKGRAY 600,699 # $A9A9A9 DARKGRAY
BLACK 700,799 # $000000 BLACK
MAGENTA 800 # $FF00FF MAGENTA
BLACK 801,899 # $000000 BLACK
BLUE 900,999 # $0000FF BLUE
PLUM 1000,1099 # $DDA0DD PLUM
BLACK 1100,1999 # $000000 BLACK
ORANGE 2000,13860 # $FFA500 ORANGE
And additional output to 2nd file, Commands_Used.txt
# Total Time Taken = 17.406 secs for 13861 Frames
#
BLACK # $000000 BLACK
BLUE # $0000FF BLUE
DARKGRAY # $A9A9A9 DARKGRAY
POWDERBLUE # $B0E0E6 POWDERBLUE
SILVER # $C0C0C0 SILVER
PLUM # $DDA0DD PLUM
RED # $FF0000 RED
MAGENTA # $FF00FF MAGENTA
ORANGE # $FFA500 ORANGE
EDITED: Added time taken to Commands_Used.txt
Hotte
21st November 2014, 23:00
Stainless, you really put a lot of work into this!
Forgive a beginner...it is not easy to understand all this.
So what I did: I copied clipclop26.dll into my avisynth plugins folder. Then I copied the first code box of #26.
First question: What is "D:\avs\test.avi" ?
I put one of my avi-clips in place here and ended up with "avisynth access violation" reading my file. Of course i did something wrong. Which file has to be loaded here ?
Thanks.
StainlessS
22nd November 2014, 00:36
Did the error msg give a line number ?
What was size of clip, HD ?
Edit, mobile at moment.
You did nothing wrong, I seem to have a problem somewhere.
The avi you mention was just any old clip, for testing.
The access violation is a little worrying.
I'll get back soon.
Hotte
22nd November 2014, 09:46
The error is precisely:
Avisynth open failure
Avisynth: access violation at 0x00000000 in c:\...VirtualDub.exe
attempting to read from 0x00000000
(D:\...\myscript.avs, line 64)
line64 is the ClipClop(V0,... line, which is the last line in myscript.avs.
My avisynth Version is 2.60 built 2012-05-16
My load command is ORG=Avisource("D:\Video\_Pool\bk.avi").ConvertToRGB32()....
bk.avi is a 4-sek Edius canopus hq 1920x1080 avi source clip at 50fps and is 156Mbytes large.
I have not quite understood what the first step does. I suppose it creates an index clip of the same length as my input clip with a number of colored frames that are being used to filter the main clip differently in the next steps. Is that right ?
StainlessS
22nd November 2014, 17:10
In an earlier post, PoisonDeathRay suggests use of a 'Control.Avi' clip instead of your 'marker frames' embedded in source clip, idea.
A range of frames of a specific colour would be used to apply a particular filter chain to that range, and you would not need to
get rid of your embedded marker frames afterwards.
Post #26 just creates a test control.avi clip where ranges of frames are set to specific 'Command Colors', with meaning exactly the same as
post #3 script. I dont have your NLE nor your clips but still need something to test with, this is it.
The only requirement of the input to the ControlAvi creator script is that it has more than 2000 frames as one of the commands is applied
from frame 2000, to the end of clip (ie 2000,0).
There was some time ago a problem reported by Jenyok, however all I could get out of him was something like "It does not work",
which does not assist much. IIRC the problem seemed to be with 64bit and memory greater than 4GB, I'm on XP32 4GB and can find
no problem that affects me.
I'll do a debug version of Clipclop for you, and include a copy of DebugView, can you please run DebugView to capture messages and PM me back the
results, its probably gonna be the only way I can find the problem.
I think PDR suggested that he already uses something similar to the Control.avi thing, go back a re-read what he said, I dont use NLE's and
so dont know what is or is not available. (EDIT: IIRC PDR said he only uses 2 color control clip to select from choice of two filter chains
and used ReplaceFramesSimple instead of clipclop [RFS only deals with 2 clips]).
EDIT:
I suppose it creates an index clip of the same length as my input clip with a number of colored frames that are being used to filter the main clip differently in the next steps. Is that right ?
Yep, thats pretty much it, but every frame is significant, ie entire range of frames should be set at specific color, BLACK is source.
EDIT: By the way, did you actually try post #3 script, if so presumably that worked OK ?
StainlessS
22nd November 2014, 18:14
I forgot, there is already some Debug functionality in ClipClop, but only in the constructor (when parsing NickNames, Commands),
add DV=5 to ClipClop line. And download this DebugView and run before script.
http://technet.microsoft.com/en-gb/sysinternals/bb896647.aspx
It should at least let me know if it occurs in constructor or during GetFrame().
With crashing script, can you also try adding "PURGE=False" to clipclop line. (any difference ?)
Hotte
23rd November 2014, 19:39
Thanks, StainlessS.
First I replaced the input video, because it had less than 2.000 frames. Just to be clear: I am using an ordinary clip taken with my camera as input. Still itīs a canopus avi 50fps 1920x1080 that runs fine with mediaplayer or whatever.
I added PURGE=False and also DV=5 to the clipclop-line and I tried the code in #3 also.
I downloaded debug an started it.
Then I started the script with same result.
In any constellation Debug always throws the same single line:
[3456] SSETools 0.1
Is that of any help ?
StainlessS
23rd November 2014, 19:50
"[3456] SSETools 0.1", I think that is just a message saying the SSETools 0.1 have been installed (LoadPlugin),
Any program can write to debug output at any time.
My debug stuff usually incudes a colon ( : ) eg "ClipClop: ", you can set filter in debugview on only show debug
output including colon.
I'm gonna re-install my system now (crashing lately due to hacking several USB drivers for android devices, screwed the registry).
I'm not really sure what is happening, the bug reveals itself in VirtualDub so frame has already had metrics text rendered on frames
without access violation, not really a clue what the cause of bug is.
Hotte
23rd November 2014, 20:31
I am happy to try out something else if you like. No stress.
Just to be sure I added the code that causes the error here.
# MakeControlClipAVI.avs, Make Dummy control clip for testing, Save to Control.AVI
ORG=Avisource("D:\Video\_Pool\HD Nikon D5300\N3_00390.avi").ConvertToRGB32().PointResize(32,32).KillAudio # Take Blankclip attributes from this
BLACK = $000000
BLUE = $0000FF
GREEN = $00FF00
CYAN = $00FFFF
RED = $FF0000
MAGENTA = $FF00FF
YELLOW = $FFFF00
WHITE = $FFFFFF
ORANGE = $FFA500
DARKGRAY = $A9A9A9
SILVER = $C0C0C0
PLUM = $DDA0DD
POWDERBLUE = $B0E0E6
V0 = ORG.BlankClip(Color=BLACK)
V1 = ORG.BlankClip(Color=BLUE)
V2 = ORG.BlankClip(Color=GREEN)
V3 = ORG.BlankClip(Color=CYAN)
V4 = ORG.BlankClip(Color=RED)
V5 = ORG.BlankClip(Color=MAGENTA)
V6 = ORG.BlankClip(Color=YELLOW)
V7 = ORG.BlankClip(Color=WHITE)
V8 = ORG.BlankClip(Color=ORANGE)
V9 = ORG.BlankClip(Color=DARKGRAY)
V10 = ORG.BlankClip(Color=SILVER)
V11 = ORG.BlankClip(Color=PLUM)
V12 = ORG.BlankClip(Color=POWDERBLUE)
NickNames =""" # Psuedonyms for clip index
SOURCE = 0 # Original Clip BLACK
L0 = 1 # Light Luma BLUE
L1 = 2 # Med Luma GREEN
L2 = 3 # High Luma CYAN
C0 = 4 # Light Chroma RED
C1 = 5 # Med Chroma MAGENTA
C2 = 6 # High Chroma YELLOW
LC0 = 7 # Light Luma + Chroma WHITE
LC1 = 8 # Med Luma + Chroma ORANGE
LC2 = 9 # High Luma + Chroma DARKGRAY
FH = 10 # Flip-H SILVER
FV = 11 # Flip-V PLUM
INV = 12 # Invert POWDERBLUE
"""
SCMD=""" # Clip editing commands in string, can also use commands in file
C0 0,99 # Light Chroma frames @ 0 -> 99 RED
L0 100,-200 # Light Luma frames @ 100, 200 frames ie frames 100->299 BLUE
INV 300,399 # Invert 300->399 POWDERBLUE
L0 400,499 # Light Luma frames 400->499 BLUE
FH 500,599 # Flip-H 500->599 SILVER
LC2 600,699 # High Luma + Chroma DARKGRAY
C1 800 # Med Chroma, Single frame MAGENTA
1 900,999 # Light Luma, We used the clip number instead of a NickName BLUE
FV 1000,1099 # Flip-V PLUM
LC1 2000,0 # Med Luma + Chroma, 2000 -> lastframe ORANGE
"""
SHOW=FALSE
ClipClop(V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,scmd=SCMD,nickname=NickNames,show=SHOW,DV=5,PURGE=False)
StainlessS
20th December 2014, 14:35
I'm back, sorry, I sort of got waylaid.
Try This
# MakeControlClipAVI.avs, Make Dummy control clip for testing, Save to Control.AVI
# Requires clip at least 2001 frames
Avisource("D:\avs\test.avi")
#Avisource("D:\Video\_Pool\HD Nikon D5300\N3_00390.avi")
Trim(0,2000) # 2001 frames
ConvertToRGB32().KillAudio
# .PointResize(32,32) # We want to see Metrics in debug test
ORG=Last # Take Blankclip attributes from this
BLACK = $000000
BLUE = $0000FF
GREEN = $00FF00
CYAN = $00FFFF
RED = $FF0000
MAGENTA = $FF00FF
YELLOW = $FFFF00
WHITE = $FFFFFF
ORANGE = $FFA500
DARKGRAY = $A9A9A9
SILVER = $C0C0C0
PLUM = $DDA0DD
POWDERBLUE = $B0E0E6
V0 = ORG.BlankClip(Color=BLACK)
V1 = ORG.BlankClip(Color=BLUE)
V2 = ORG.BlankClip(Color=GREEN)
V3 = ORG.BlankClip(Color=CYAN)
V4 = ORG.BlankClip(Color=RED)
V5 = ORG.BlankClip(Color=MAGENTA)
V6 = ORG.BlankClip(Color=YELLOW)
V7 = ORG.BlankClip(Color=WHITE)
V8 = ORG.BlankClip(Color=ORANGE)
V9 = ORG.BlankClip(Color=DARKGRAY)
V10 = ORG.BlankClip(Color=SILVER)
V11 = ORG.BlankClip(Color=PLUM)
V12 = ORG.BlankClip(Color=POWDERBLUE)
NickNames =""" # Psuedonyms for clip index
SOURCE = 0 # Original Clip BLACK
L0 = 1 # Light Luma BLUE
L1 = 2 # Med Luma GREEN
L2 = 3 # High Luma CYAN
C0 = 4 # Light Chroma RED
C1 = 5 # Med Chroma MAGENTA
C2 = 6 # High Chroma YELLOW
LC0 = 7 # Light Luma + Chroma WHITE
LC1 = 8 # Med Luma + Chroma ORANGE
LC2 = 9 # High Luma + Chroma DARKGRAY
FH = 10 # Flip-H SILVER
FV = 11 # Flip-V PLUM
INV = 12 # Invert POWDERBLUE
"""
SCMD=""" # Clip editing commands in string, can also use commands in file
C0 0,99 # Light Chroma frames @ 0 -> 99 RED
L0 100,-200 # Light Luma frames @ 100, 200 frames ie frames 100->299 BLUE
INV 300,399 # Invert 300->399 POWDERBLUE
L0 400,499 # Light Luma frames 400->499 BLUE
FH 500,599 # Flip-H 500->599 SILVER
LC2 600,699 # High Luma + Chroma DARKGRAY
C1 800 # Med Chroma, Single frame MAGENTA
1 900,999 # Light Luma, We used the clip number instead of a NickName BLUE
FV 1000,1099 # Flip-V PLUM
LC1 2000,0 # Med Luma + Chroma, 2000 -> lastframe ORANGE
"""
SHOW =TRUE
PURGE=TRUE
DV =4
ClipClop(V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,scmd=SCMD,nickname=NickNames,show=SHOW,DV=DV,PURGE=PURGE)
Also included here with debug version LINK REMOVED, See post #40.
Just change to name of clip with at least 2001 frames.
Next post has sample of output
StainlessS
20th December 2014, 14:37
Post #2 of 2.
Sample Debug output
00000001 0.00000000 ClipClop: AvisynthPluginInt Calling Addfunction
00000002 0.00004232 ClipClop: AvisynthPluginInt Returns to Avisynth
00000003 0.13216157 SSETools 0.1
00000004 0.26308435 ClipClop: AvisynthPluginInt Calling Addfunction
00000005 0.26310748 ClipClop: AvisynthPluginInt Returns to Avisynth
00000006 0.26315022 ClipClop: Create_ClipClop ENTRY
00000007 0.26317528 ClipClop: Create_ClipClop Getting dv from args[6].AsInt(0)
00000008 0.26319981 ClipClop: Create_ClipClop Check Invalid dv
00000009 0.26322374 ClipClop: Create_ClipClop Printing (c)
00000010 0.26324499 ClipClop:
00000011 0.26326647 ClipClop: v1.22 - 20 Dec 2014 - (c) StainlessS.
00000012 0.26328796 ClipClop:
00000013 0.26330933 ClipClop: DEBUG, Avisynth Creating Filter. Calling ClipClop Constructor
00000014 0.26333857 ClipClop: DEBUG, Constructor IN <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
00000015 0.26336256 ClipClop: DEBUG, ENTRY Rx Clips = 12
00000016 0.26338610 ClipClop: DEBUG, Command File = NO ('')
00000017 0.26340926 ClipClop: DEBUG, Command String = YES
00000018 0.26343262 ClipClop: DEBUG, NoErr = NO
00000019 0.26345587 ClipClop: DEBUG, DV = 4
00000020 0.26347896 ClipClop: DEBUG, Show = YES
00000021 0.26350209 ClipClop: DEBUG, Ver = NO
00000022 0.26352519 ClipClop: DEBUG, Nickname = YES
00000023 0.26354855 ClipClop: DEBUG, Purge = YES
00000024 0.26357061 ClipClop: DEBUG,
00000025 0.26359525 ClipClop: DEBUG, About to Allocate Arrays
00000026 0.26363355 ClipClop: DEBUG, About to Initalize Arrays & Check ColorSpace & Rez
00000027 0.26368421 ClipClop: INFO, Source clip R0 = 2001 frames
00000028 0.26371622 ClipClop: DEBUG, Initalize & Check Done, About to Parse
00000029 0.26373932 ClipClop: DEBUG, About to Parse Nicknames
00000030 0.26376501 ClipClop: DEBUG, NICKNAME Line 1:1 *COMMENT ONLY* # Psuedonyms for clip index
00000031 0.26379389 ClipClop: INFO, NICKNAME Line 2:1 SOURCE=R0 : $SOURCE = 0 # Original Clip BLACK
00000032 0.26382202 ClipClop: INFO, NICKNAME Line 3:1 L0=R1 : $L0 = 1 # Light Luma BLUE
00000033 0.26384926 ClipClop: INFO, NICKNAME Line 4:1 L1=R2 : $L1 = 2 # Med Luma GREEN
00000034 0.26387659 ClipClop: INFO, NICKNAME Line 5:1 L2=R3 : $L2 = 3 # High Luma CYAN
00000035 0.26390368 ClipClop: INFO, NICKNAME Line 6:1 C0=R4 : $C0 = 4 # Light Chroma RED
00000036 0.26393101 ClipClop: INFO, NICKNAME Line 7:1 C1=R5 : $C1 = 5 # Med Chroma MAGENTA
00000037 0.26395851 ClipClop: INFO, NICKNAME Line 8:1 C2=R6 : $C2 = 6 # High Chroma YELLOW
00000038 0.26398584 ClipClop: INFO, NICKNAME Line 9:1 LC0=R7 : $LC0 = 7 # Light Luma + Chroma WHITE
00000039 0.26401323 ClipClop: INFO, NICKNAME Line 10:1 LC1=R8 : $LC1 = 8 # Med Luma + Chroma ORANGE
00000040 0.26404062 ClipClop: INFO, NICKNAME Line 11:1 LC2=R9 : $LC2 = 9 # High Luma + Chroma DARKGRAY
00000041 0.26406819 ClipClop: INFO, NICKNAME Line 12:1 FH=R10 : $FH = 10 # Flip-H SILVER
00000042 0.26409569 ClipClop: INFO, NICKNAME Line 13:1 FV=R11 : $FV = 11 # Flip-V PLUM
00000043 0.26412323 ClipClop: INFO, NICKNAME Line 14:1 INV=R12 : $INV = 12 # Invert POWDERBLUE
00000044 0.26414704 ClipClop: DEBUG, About to Parse Command String
00000045 0.26417291 ClipClop: DEBUG, SCMD Line 1:1 *COMMENT ONLY* # Clip editing commands in string, can also use commands in file
00000046 0.26420280 ClipClop: INFO, SCMD Line 2:1 C0{4}[0,99] $C0 0,99 # Light Chroma frames @ 0 -> 99 RED
00000047 0.26423320 ClipClop: INFO, SCMD Line 3:1 L0{1}[100,299] $L0 100,-200 # Light Luma frames @ 100, 200 frames ie frames 100->299 BLUE
00000048 0.26426348 ClipClop: INFO, SCMD Line 4:1 INV{12}[300,399] $INV 300,399 # Invert 300->399 POWDERBLUE
00000049 0.26429293 ClipClop: INFO, SCMD Line 5:1 L0{1}[400,499] $L0 400,499 # Light Luma frames 400->499 BLUE
00000050 0.26432267 ClipClop: INFO, SCMD Line 6:1 FH{10}[500,599] $FH 500,599 # Flip-H 500->599 SILVER
00000051 0.26435244 ClipClop: INFO, SCMD Line 7:1 LC2{9}[600,699] $LC2 600,699 # High Luma + Chroma DARKGRAY
00000052 0.26438093 ClipClop: INFO, SCMD Line 8:1 C1{5}[800,800] $C1 800 # Med Chroma, Single frame MAGENTA
00000053 0.26441076 ClipClop: INFO, SCMD Line 9:1 L0{1}[900,999] $1 900,999 # Light Luma, We used the clip number instead of a NickName BLUE
00000054 0.26444116 ClipClop: INFO, SCMD Line 10:1 FV{11}[1000,1099] $FV 1000,1099 # Flip-V PLUM
00000055 0.26447037 ClipClop: INFO, SCMD Line 11:1 LC1{8}[2000,2000] $LC1 2000,0 # Med Luma + Chroma, 2000 -> lastframe ORANGE
00000056 0.26449230 ClipClop: INFO,
00000057 0.26451555 ClipClop: INFO, ---------- Purge Check ---------
00000058 0.26453742 ClipClop: INFO,
00000059 0.26456189 ClipClop: INFO, L1 (R2) Not used in Output Clip ... Purging
00000060 0.26458618 ClipClop: INFO, L2 (R3) Not used in Output Clip ... Purging
00000061 0.26461053 ClipClop: INFO, C2 (R6) Not used in Output Clip ... Purging
00000062 0.26463470 ClipClop: INFO, LC0 (R7) Not used in Output Clip ... Purging
00000063 0.26465780 ClipClop: INFO, Clips Purged = 4
00000064 0.26467955 ClipClop: INFO,
00000065 0.26470277 ClipClop: DEBUG, Constructor About to End
00000066 0.26472574 ClipClop: DEBUG, Constructor 0 Errors
00000067 0.26474980 ClipClop: DEBUG, Constructor OUT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
00000068 0.26477149 ClipClop: DEBUG, Returning ClipClop Filter to Avisynth
00000069 0.26479468 ClipClop: Create_ClipClop EXIT
00000070 0.51500839 ClipClop:
00000071 0.51502734 ClipClop: GetFrame on Frame 0
00000072 0.51505649 ClipClop: GetFrame on Frame 0 Calling rClips[4]->GetFrame(0)
00000073 0.51508272 ClipClop: GetFrame on Frame 0 Check Non NULL, rClips[4] = $0162EAA0
00000074 0.52703381 ClipClop: GetFrame Calling DrawShow to print metrics
00000075 0.52759683 ClipClop: DrawShow Making Writable and rendering metrics
00000076 0.52893412 ClipClop: DrawShow_0 Writing Metrics='0 ] ClipClop:'
00000077 0.52899581 ClipClop: DrawShow_1 Writing Metrics='Using Clip C0{R4}[0]'
00000078 0.52907097 ClipClop: GetFrame Returned from DrawShow
00000079 0.52911550 ClipClop: GetFrame Returning frame 0 to Client
00000080 0.56394333 ClipClop:
00000081 0.56398171 ClipClop: GetFrame on Frame 1
00000082 0.56402183 ClipClop: GetFrame on Frame 1 Calling rClips[4]->GetFrame(1)
00000083 0.56406194 ClipClop: GetFrame on Frame 1 Check Non NULL, rClips[4] = $0162EAA0
00000084 0.56411493 ClipClop: GetFrame Calling DrawShow to print metrics
00000085 0.56414109 ClipClop: DrawShow Making Writable and rendering metrics
00000086 0.56491482 ClipClop: DrawShow_0 Writing Metrics='1 ] ClipClop:'
00000087 0.56497115 ClipClop: DrawShow_1 Writing Metrics='Using Clip C0{R4}[1]'
00000088 0.56503612 ClipClop: GetFrame Returned from DrawShow
00000089 0.56506181 ClipClop: GetFrame Returning frame 1 to Client
00000090 0.60306340 ClipClop:
00000091 0.60308617 ClipClop: GetFrame on Frame 2
00000092 0.60311323 ClipClop: GetFrame on Frame 2 Calling rClips[4]->GetFrame(2)
00000093 0.60314047 ClipClop: GetFrame on Frame 2 Check Non NULL, rClips[4] = $0162EAA0
00000094 0.60316902 ClipClop: GetFrame Calling DrawShow to print metrics
00000095 0.60319525 ClipClop: DrawShow Making Writable and rendering metrics
00000096 0.60393482 ClipClop: DrawShow_0 Writing Metrics='2 ] ClipClop:'
00000097 0.60399139 ClipClop: DrawShow_1 Writing Metrics='Using Clip C0{R4}[2]'
00000098 0.60405618 ClipClop: GetFrame Returned from DrawShow
00000099 0.60408169 ClipClop: GetFrame Returning frame 2 to Client
00000100 0.64785111 ClipClop:
...
00000340 1.59617686 ClipClop:
00000341 1.59637558 ClipClop: GetFrame on Frame 27
00000342 1.59639561 ClipClop: GetFrame on Frame 27 Calling rClips[4]->GetFrame(27)
00000343 1.59642994 ClipClop: GetFrame on Frame 27 Check Non NULL, rClips[4] = $0162EAA0
00000344 1.59658682 ClipClop: GetFrame Calling DrawShow to print metrics
00000345 1.59667611 ClipClop: DrawShow Making Writable and rendering metrics
00000346 1.59767580 ClipClop: DrawShow_0 Writing Metrics='27 ] ClipClop:'
00000347 1.59768903 ClipClop: DrawShow_1 Writing Metrics='Using Clip C0{R4}[27]'
00000348 1.59776580 ClipClop: GetFrame Returned from DrawShow
00000349 1.59779859 ClipClop: GetFrame Returning frame 27 to Client
00000350 1.60504556 ClipClop: DEBUG, Destructor IN <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
00000351 1.60506737 ClipClop: DEBUG, Destructor delete[] Pseudonyms
00000352 1.60514390 ClipClop: DEBUG, Destructor delete[] rFramesHi
00000353 1.60515594 ClipClop: DEBUG, Destructor delete[] rClips
00000354 1.60519373 ClipClop: DEBUG, Destructor delete[] modedat
00000355 1.60523093 ClipClop: DEBUG, Destructor OUT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Hotte
21st December 2014, 16:32
Hi Stainless,
welcome back and thanks a lot for your efforts.
I downloaded Cliclop-Debug dll and started the code above replacing test-avi with my file that you were being so nice to leave as comment in the code.
Error-Message was the same:
Avisynth open failure:
Avisynth: access violation at 0x00000000 in C:\Diverses\VirtualDub\VirtualDub.exe,
attempting to read from 0x00000000
(D:\Temp\clipclop.avs, line 76)
Debug output has only 6 lines:
[2904] ClipClop: AvisynthPluginInt Calling Addfunction
[2904] ClipClop: AvisynthPluginInt Returns to Avisynth
[2904] SSETools 0.1
[2904] ClipClop: AvisynthPluginInt Calling Addfunction
[2904] ClipClop: AvisynthPluginInt Returns to Avisynth
[2904] ClipClop: Create_ClipClop ENTRY
I hope that helps.
Hotte
StainlessS
21st December 2014, 17:02
Well that is weird, everything looks OK to me, perhaps I cannot see the wood for the trees.
Here is source, perhaps someone can spot a problem that I cannot.
// This is the function that created the filter, when the filter has been called.
// This can be used for simple parameter checking, so it is possible to create different filters,
// based on the arguments recieved.
AVSValue __cdecl Create_ClipClop(AVSValue args, void* user_data, IScriptEnvironment* env) {
DPRINTF(("Create_ClipClop ENTRY")) // LAST Message Printed
DPRINTF(("Create_ClipClop Getting dv from args[6].AsInt(0)")) // Added Line
int dv = args[6].AsInt(0); // dv
DPRINTF(("Create_ClipClop Check Invalid dv")) // Added Line
if(dv<0 || dv>4) { // Default to Debug if invalid
DPRINTF(("Create_ClipClop Correcting dv")) // Added Line
dv=4;
}
if(dv) { // Below SHOULD be printed as dv == 4, ie crash before here
DPRINTF(("Create_ClipClop Printing (c)")) // Added Line
OutputDebugString("ClipClop:\n"); // Line separator in DebugView
OutputDebugString(VERS " - (c) StainlessS.\n"); // Version
OutputDebugString("ClipClop:\n"); // Line separator in DebugView
}
if(dv>3) {
OutputDebugString("ClipClop: DEBUG, Avisynth Creating Filter. Calling ClipClop Constructor\n");
}
// Call the constructor with the arguments provied.
AVSValue ret = new ClipClop(
args[0].AsClip(), // clip compulsory arg
args[1], // Rx array, at least one
args[2].AsString(""), // Cmd file
args[3].AsString(""), // SCmd String
args[4].AsBool(false), // Show
args[5].AsBool(false), // Ver
dv, // dv
args[7].AsBool(false), // NoErr
args[8].AsString(""), // Nickname
args[9].AsBool(true), // Purge
env);
if(dv>3)
OutputDebugString("ClipClop: DEBUG, Returning ClipClop Filter to Avisynth\n");
DPRINTF(("Create_ClipClop EXIT"))
return ret;
}
// The following function is the function that actually registers the filter in AviSynth
// It is called automatically, when the plugin is loaded to see which functions this filter contains.
#ifdef AVISYNTH_PLUGIN_25
extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {
#else
/* New 2.6 requirement!!! */
// Declare and initialise server pointers static storage.
const AVS_Linkage *AVS_linkage = 0;
/* New 2.6 requirement!!! */
// DLL entry point called from LoadPlugin() to setup a user plugin.
extern "C" __declspec(dllexport) const char* __stdcall
AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {
/* New 2.6 requirment!!! */
// Save the server pointers.
AVS_linkage = vectors;
#endif
DPRINTF(("AvisynthPluginInt Calling Addfunction"))
env->AddFunction("ClipClop", "cc+[Cmd]s[SCmd]s[Show]b[Ver]b[dv]i[NoErr]b[Nickname]s[Purge]b", Create_ClipClop, 0);
// The AddFunction has the following paramters:
// AddFunction(Filtername , Arguments, Function to call,0);
// Arguments is a string that defines the types and optional nicknames of the arguments for you filter.
// c - Video Clip
// i - Integer number
// f - Float number
// s - String
// b - boolean
// . - Any type (dot)
// Array Specifiers
// i* - Integer Array, zero or more
// i+ - Integer Array, one or more
// .* - Any type Array, zero or more
// .+ - Any type Array, one or more
// Etc
DPRINTF(("AvisynthPluginInt Returns to Avisynth"))
return "`ClipClop' ClipClop plugin";
// A freeform name of the plugin.
}
StainlessS
21st December 2014, 17:54
ClipClop Debug updated here with 2.6 + 2.58 dll's and source added.
http://www.mediafire.com/download/spi25vgbhmsuauc/ClipClop_Debug.zip
EDIT: Added a couple more messages to debug output, re-uploaded.
Debug output in post #37 updated.
StainlessS
21st December 2014, 22:44
OK, I think I may have twigged what the problem is,
The error is precisely:
Avisynth open failure
Avisynth: access violation at 0x00000000 in c:\...VirtualDub.exe
attempting to read from 0x00000000
(D:\...\myscript.avs, line 64)
line64 is the ClipClop(V0,... line, which is the last line in myscript.avs.
My avisynth Version is 2.60 built 2012-05-16
My load command is ORG=Avisource("D:\Video\_Pool\bk.avi").ConvertToRGB32()....
bk.avi is a 4-sek Edius canopus hq 1920x1080 avi source clip at 50fps and is 156Mbytes large.
I have not quite understood what the first step does. I suppose it creates an index clip of the same length as my input clip with a number of colored frames that are being used to filter the main clip differently in the next steps. Is that right ?
We use this in source
/* New 2.6 requirement!!! */
// Declare and initialise server pointers static storage.
const AVS_Linkage *AVS_linkage = 0;
/* New 2.6 requirement!!! */
// DLL entry point called from LoadPlugin() to setup a user plugin.
extern "C" __declspec(dllexport) const char* __stdcall
AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {
/* New 2.6 requirment!!! */
// Save the server pointers.
AVS_linkage = vectors;
Which is implemented for Avisynth v2.6 Alpha 4 (you are using Alpha 3),
Update to v2.6 Alpha 5, and I hope the problem will disappear. (Or alternatively use the v2.58 dll).
(Although, how it gets as far as it does without crashing sooner, I dont know.)
EDIT: This post seems to confirm conclusion: http://forum.doom9.org/showthread.php?p=1657879#post1657879
EDIT: Although according to Sourceforge, there were releases in March 2011 and next was Jan 2013, so perhaps you are using
an MT version.
EDIT: Yep, GOT IT. Installed MT version from same date as yours and I get a crash, update as suggested to latest MT should fix it.
Here: http://forum.doom9.org/showthread.php?t=148782
EDIT: Yep, the new MT v2.6 works fine. You may need the latest version of 7zip to extract Avisynth.dll as WinRar may have problems with the new 7zip format used.
Hotte
23rd December 2014, 01:26
YEAH!
I was able to produce this control clip with changing colours over time now. But I had to add ConvertToYV12 at the very end, otherwise Canopus HQ would have produced a plain blank avi out of virtual dub (it does not seem to like RGB). I hope this is of no disadvantage of any kind in the next steps !?
Sorry to report that it took me quite some time to find out, that I need your RT_stats-plugin to proceed with step 2 (it does not seem to be mentioned as a prerequisite in the doc...).
Another great addition as far as I am able to judge....
So next trap door now. I am sure, this is a much easier one for you:
Avisynth open failure:
Script error: there is no function named "GSCript"
(D:\Temp\Create Commandfile.avs, line 166)
(D:\Temp\Create Commandfile.avs, line 32)
Itīs there ?!
# MakeClopCmd.avs, Convert commands embedded in Control.AVI RGB COLOUR, to ClipClop Command file.
Avisource("D:\Temp\Control.avi").ConvertToRGB32 # Just incase RGB24
CMD = "Command.Txt" # ClipClop Command file (Output of this script)
###
### HERE, YOU DECIDE THE NICKNAMES TO USE FOR WHICH COLOR CONTROL, BUT NOT WHICH CLIP INDEX THEY REFER TO
###
MAP = """ # RGB Hex Color Code, NickName, Color As Comment ('$000000 = SOURCE # BLACK' means original clip)
$000000 = SOURCE # BLACK
$0000FF = L0 # BLUE
$00FF00 = L1 # GREEN
$00FFFF = L2 # CYAN
$FF0000 = C0 # RED
$FF00FF = C1 # MAGENTA
$FFFF00 = C2 # YELLOW
$FFFFFF = LC0 # WHITE
$FFA500 = LC1 # ORANGE
$A9A9A9 = LC2 # DARKGRAY
$C0C0C0 = FH # SILVER
$DDA0DD = FV # PLUM
$B0E0E6 = INV # POWDERBLUE
"""
###
### Create Color_Code -> NickName DBase
###
RT_FileDelete(CMD) # Delete existing Command file
DB = "~"+RT_LocalTimeString+".DB" # Temp DBase filename
RT_DBaseAlloc(DB,0,"iss") # Create zero record DB (Int,String,String)
MakeColorNickDBase(DB,MAP) # Fill DB with Color->NickName data (sorted by HexColor)
###
### Scan Control.AVI and create ClipClop Command file
###
GSCript("""
RECORDS = RT_DBaseRecords(DB)
HEXFIELD = 0 # Int field
NICKFIELD = 1 # String field
COMMFIELD = 2 # String field
FC = FrameCount
CurrCol = -1
CurrNick = ""
CurrComm = ""
SFrm = 0
For(n=0,FC) {
Dat = (n==FC) ? -1 : RT_BitAND(RT_RGB32AsInt(n=n,x=0,y=0),$FFFFFF) # Sample single pixel RGB32 Color as Int (clr Alpha)
if(n == FC || Dat != CurrCol) {
Frames = n - SFrm
if(Frames > 0) { # If not Frame 0
if(Frames == 1) { # Write NickName and Frame Number
RT_DebugF("%-16s %6d # $%06X %s",CurrNick,SFrm,CurrCol,CurrComm)
RT_WriteFile(CMD,"%-16s %6d # $%06X %s",CurrNick,SFrm,CurrCol,CurrComm,Append=True)
} Else { # Write NickName and Range
RT_DebugF("%-16s %6d,%-6d # $%06X %s",CurrNick,SFrm,n-1,CurrCol,CurrComm)
RT_WriteFile(CMD,"%-16s %6d,%-6d # $%06X %s",CurrNick,SFrm,n-1,CurrCol,CurrComm,Append=True)
}
}
if(n < FC) { # Else, ALL DONE .. writing LAST range only
CurrCol = Dat
SRec = DB_FindVar(DB,HEXFIELD,CurrCol)
Assert(SRec != -1,RT_String("Cannot Find RGB Hex Color($%06X) in DBase @ Frame %d",CurrCol,n))
CurrNick = RT_DBaseGetField(DB,SRec,NICKFIELD) # Get Associated NickName
CurrComm = RT_DBaseGetField(DB,SRec,COMMFIELD) # Get Associated Comment
SFrm = n # REM new start frame
}
}
}
RT_FileDelete(DB) # Clean up
return MessageClip(RT_String("All Done, Created %s",CMD))
###
###
###
Function DB_FindVar(String DB,Int Field,Var) {
# DB_FindVar Returns record number containing Var in Field field, using Binary Search
# Var type can be Int, Float or String(Case Insig).
# DBase MUST be sorted ascending by Field.
# Field is the DB field that contains Var to find.
# Return record number or -1 = NOT FOUND.
result = -1 # Init NOT FOUND
low = 0
high = RT_DBaseRecords(DB) - 1
while(low <= high) {
mid = (low + high) / 2
if(RT_DBaseGetField(DB,mid,Field) < Var) {
low = mid + 1
} Else If (RT_DBaseGetField(DB,mid,Field) > Var) {
high = mid - 1
} Else {
low = high + 1 # Force exit
Result = mid
}
}
return result
}
""")
Function MakeColorNickDBase(String DB,String MAP) {
/*
Parse MAP string and create Sort Ascending (by Hex Color) DBase for efficiently Scanning Control.AVI
*/
GSCript("""
MAP=RT_StrReplaceDeep(RT_StrReplace(MAP,Chr(9)," ")," "," ") # TAB and SPACE compact (multi to single SPACE)
M=RT_TxtSort(MAP,Mode=0) # Sort Ascending, case insig (by Hex Color Code)
NLINES = RT_TxtQueryLines(M) # Lines of text in M
For(i=0,NLINES-1) {
STR = RT_TxtGetLine(M,i)
S = STR
While(RT_Ord(S)==32) { S=MidStr(S,2) } # Eat White
if(MidStr(S,1,1)=="$") {
S = MidStr(S,2) # Swalla the Dolla
c = UCase(MidStr(S,1,1))
IsHexDig = ((c>="0" && c<="9") || (c>="A" && c<="F"))
Assert(IsHexDig,RT_String("String(%d) Hex Color Code Missing @'%s'\n'%s'",i,S,STR))
HexColor = RT_NumberValue(S,16)
While(StrLen(S)>=1 && IsHexDig) { # Swalla Hex
S = MidStr(S,2)
c = UCase(MidStr(S,1,1))
IsHexDig = ((c>="0" && c<="9") || (c>="A" && c<="F"))
}
While(RT_Ord(S)==32) { S=MidStr(S,2) } # Eat White
if(MidStr(S,1,1)=="=") {
S = MidStr(S,2) # Swalla optional '='
While(RT_Ord(S)==32) {S=MidStr(S,2)} # Eat White
}
c = UCasE(MidStr(S,1,1))
Assert((c>="A" && c<="Z") || c=="_",RT_String("String(%d) NickName Missing @'%s'\n'%s'",i,S,STR))
NickLen=1
SLen = StrLen(S)
For(j=2,Slen) {
c = UCase(MidStr(S,j,1))
if((c>="0" && c<="9") || (c>="A" && c<="Z") || c=="_") {
NickLen = NickLen + 1
} else {
j = SLen # Break
}
}
NickName = MidStr(S,1,NickLen)
S = MidStr(S,NickLen+1)
While(RT_Ord(S)==32) {S=MidStr(S,2)} # Eat White
Comment = ""
if(MidStr(S,1,1)=="#") {
S = MidStr(S,2) # Swalla Hash
While(RT_Ord(S)==32) {S=MidStr(S,2)} # Eat White
if(StrLen(S)>0) { # End Trim White
S=RevStr(S)
While(RT_Ord(S)==32) {S=MidStr(S,2)} # Eat White
S=RevStr(S)
Comment=S
S=""
}
}
RT_DebugF("%3d ] $%06X : %-10s : %s",i,HexColor,NickName,Comment) # Output to DebugView
RT_DBaseAppend(DB,HexColor,NickName,Comment) # Append record to DBase
}
While(RT_Ord(S)==32) { S=MidStr(S,2) } # Eat White
if(RT_Ord(S) == RT_Ord("#")) { S="" } # Swallow, Only Comment Remaining
Assert(S=="",RT_String("String(%d) Non Parse @'%s'\n'%s'",i,S,STR))
}
""")
Return RT_DBaseRecords(DB) # Return Something
}
Thanks!
StainlessS
23rd December 2014, 05:44
Whoops, sorry bout dat. Almost everything I do requires RT_Stats, also GScript, and sometimes GRunt, both from that now elusive fellow Gavino.
(rumour has it that he has gotten religion, and gone to work in a leper colony on the dark side of the moon) :)
GSCript: http://forum.doom9.org/showthread.php?t=147846&highlight=GSCript
GRunt: http://forum.doom9.org/showthread.php?t=139337
It is suggested to always have both of these gems in your autoload plugins dir.
GScript allows use of eg if/else and for/while loops to extend the Avisynth script language
(makes some things a lot less cumbersome, and some impossible/implausible things possible).
There may be potential problem Converting to YV12 for Canopus as conversion to YV12 and back again to RGB can set inexact RGB color,
(R and/or G and/or B component off by 1). You might need to use only specific colors that convert to YV12 and back again without being
'zonked'.
Is it not possible to use eg UT_Video, very good codec and fast. Do some comparisons with Canopus and see if you like it.
EDIT: Also, the Control.avi will only be 32x32 in size so does not actually require any kind of HD codec.
EDIT: The Control.avi stuff relies on exact RGB color, anything else would both complicate and slow your workflow (significantly).
EDIT: Only the Control.avi needs to be RGB, your working clip can be any colorspace you like.
Hotte
23rd December 2014, 09:41
Thanks, that was definetly helpful.
I also downloaded UT-codec and coded the Control.avi in RGB as Utvideo RGB VCM using Fast recompress in VDub.
Now I am getting:
Avisynth open failure:
Cannot Find RGB Hex Color($DF0000) in DBase @ Frame 0
([GScript], line 29)
([GScript], line 34)
([GScript], line 35)
([GScript], line 35)
(D:\Temp\Videotest\Create Commandfile.avs, line 101)
StainlessS
23rd December 2014, 14:05
Hi Hotte, that threw me a little bit, but figured it out.
You need to use the original script from post #26 and not the debugging script which puts metrics on frame.
EDIT: To make the control.avi
Also, dump the debug version of ClipClop and use the current release, everything should then I hope run OK.
EDIT: Also, You dont need to use Fast Recompress in VD, as it is already RGB and being compressed to UT_Video RGB,
just saving you from doing an un-necessary step every time, just leave on Full Processing, dont think there will be much
if any time penalty.
Hotte
23rd December 2014, 20:27
Getting close now, but still...
I did everything you asked me, i.e. replaced clipclop26.dll and used the script of #26, and so I got the command-text file.
Now on to step 3 I run into new troubles while opening the script:
Avisynth open failure:
Avisynth: access violation at 0x000428E9 in C:\Windows\system32\fftw3.dll,
attempting to write to 0x00000040
(D:\Temp\Videotest\Create Final.avs, line 14)
Before you decide to have a look into this - remember itīs Christmas!
Avisource("D:\Video\_Pool\HD Nikon D5300\N3_00390.avi")
CMD="Command.Txt"
V0 = Last # SOURCE
V1 = FFT3DFilter(Plane=0,Sigma=1.6) # Light luma
V2 = FFT3DFilter(Plane=0,Sigma=2.0) # Med luma
V3 = FFT3DFilter(Plane=0,Sigma=4.0) # High luma
V4 = FFT3DFilter(Plane=3,Sigma=1.6) # Light Chroma
V5 = FFT3DFilter(Plane=3,Sigma=2.0) # Med Chroma
V6 = FFT3DFilter(Plane=3,Sigma=4.0) # High Chroma
V7 = FFT3DFilter(Plane=4,Sigma=1.6) # Light Luma+Chroma
V8 = FFT3DFilter(Plane=4,Sigma=2.0) # Med Luma+Chroma
V9 = FFT3DFilter(Plane=4,Sigma=4.0) # High Luma+Chroma
V10= FlipHorizontal() # Flip-H
V11= FlipVertical() # Flip-V
V12= Invert() # Invert
###
### HERE, You Assign NickNames to Clip Index. (You could if you wanted use color names, eg ORANGE as NickNames).
### RGB ColorCodes entered in Comments just as reminder
### NickNames MUST match those used in previous script
NickNames =""" # Psuedonyms for clip index
SOURCE = 0 # Original Clip BLACK
L0 = 1 # Light Luma BLUE
L1 = 2 # Med Luma GREEN
L2 = 3 # High Luma CYAN
C0 = 4 # Light Chroma RED
C1 = 5 # Med Chroma MAGENTA
C2 = 6 # High Chroma YELLOW
LC0 = 7 # Light Luma + Chroma WHITE
LC1 = 8 # Med Luma + Chroma ORANGE
LC2 = 9 # High Luma + Chroma DARKGRAY
FH = 10 # Flip-H SILVER
FV = 11 # Flip-V PLUM
INV = 12 # Invert POWDERBLUE
"""
SHOW=True
ClipClop(V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,cmd=CMD,nickname=NickNames,show=SHOW)
StainlessS
23rd December 2014, 20:52
I am sorry, forgot how much a newbie you are. ( well at post start, I had no idea of that,
Bit pissed right now.
Perhaps someone else can advise on required dll, s.
Is fft3dfilter,
Please some one sort him out.
Actually, that is just a democlip, and u could substitute anything.
Hotte, I expect you to get into av scripting, you know it makes sense.
Hotte
23rd December 2014, 21:30
Oops! Very sorry for that.
If it is just a missing dll Iīll be getting there. I thought I had FFT3DFilter installed already and the message was driving me into wrong direction. You really went a long way. Thanks a lot.
Hotte
23rd December 2014, 22:06
GOT IT RUNNING NOW!
I just replaced FFT3DFilter with the filters of my taste (I do not use FFT3DFilter anyway) and here we are: The effects change nicely over time steered by the color index clip.
This way I will be able to use color to preempt automated post-processing with avisynth in NLE already. That christmas-dream has come true.
StainlessS:thanks::thanks::thanks: for this powerful tool and excellent advice.
Hotte
24th December 2014, 13:01
Meanwhile last message from my side:
I made a couple of tests in connection with my video editor and I can tell you that it works perfectly and is most recommended. Some (like me) may have to adjust index colors to get there since NLE-export might shift colors somewhat.
Again thanks to StainlessS. clipclop is a very useful tool!
If anyone is interested in a summary of what came out of all the discussion and how you can make use of it for yourself, just leave a message. Then I will write something after christmas days.
vBulletin® v3.8.11, Copyright ©2000-2025, vBulletin Solutions Inc.