PDA

View Full Version : weave3 puzzle script challenge!


jmac698
9th January 2011, 14:59
Hi,
I'm stuck on a certain operation. I need to weave 3 clips spatially, a b c as pixels abc.
Likewise weave(a,b) does a|b vertically.

Update: I solved it. That's a good puzzle, I'll leave it out there as a challenge. Here's a start:

a=blankclip(color=$ff0000)
b=blankclip(color=$ff00)
c=blankclip(color=$ff)
weaveh(a,b,c)

function weaveh(clip a, clip b, clip c) {#horizontally weave 3 clips
#???
}

I can pretty much guarantee it involves weave, as that's the only way to spatially mix pixels. If it involves weave, it probably uses assumetff and assumefieldbased somewhere. And if you weave something, you have to have something to weave so it probably uses interleave. And since we have to use weave, and that's vertical, there's probably a turnright. If there's a turnright, there has to be a turnleft at the end. And since we can only weave in multiples of 2, we need some clever way to get odd sizes. Sizz-ess.
Props to first to solve!

Didée
9th January 2011, 15:09
Here: http://forum.doom9.org/showthread.php?t=153737

jmac698
9th January 2011, 16:09
wow. credits to pbristow for solving it and didee for noticing!

function weaveh(clip a, clip b, clip c) {#horizontally weave 3 clips
a=a.turnright
b=b.turnright
c=c.turnright
interleave(a,b,a,c)#0 1 2 3->01 23->0213->213 or abc
assumefieldbased
assumetff
weave
assumefieldbased
assumetff
weave
pointresize(width,height*3/4)#deletes every 4th line offset 0
turnleft
}

(I thought that was impossible at first)

Gavino
9th January 2011, 17:07
interleave(a,b,a,c)
Not that this works only for RGB (although the weave3h operation only makes sense visually for RGB anyway).
For YUV formats, it needs to be interleave(a,c,b,a) because of the different way PointResize works between RGB/YUV.

(Actually, it can be (a,c,b,x) where x is either a, b or c, since the 4th one is not used in the final result)

jmac698
9th January 2011, 18:21
I used it as is in my v210 reader. See other thread. The result is yv12. I didn't notice any combing in my picture, so I'll have to double check this. And yes it makes perfect sense visually :) In the packed pixel format I'm decoding I get pixels in groups of 3 (or 6 with color).
So I'll need a 6clip version someday.

Gavino
9th January 2011, 18:52
Try this test:
clip1 = BlankClip(pixel_type="YV12", color_yuv=$108080)
clip2 = BlankClip(pixel_type="YV12", color_yuv=$808080)
clip3 = BlankClip(pixel_type="YV12", color_yuv=$EB8080)
weaveh(clip1, clip2, clip3)
You will see that what you actually get (with your code) is repetitions of (clip1, clip1, clip2).

jmac698
10th January 2011, 02:53
Indeed. Here's a nice way to test it; if the screen looks dark grey everything is fine. So that brings up a point; since this is the only way to do it in script and it's implementation specific; how to stop my script from breaking? Can you try it on 2.6 if you have it handy? And does it have to be different in each case? Well, we're stuck with it now because at least one other person used it. I think the best way is to add a SelectLineEvery from which Weave could be derived. There's also consequences for color. There's an assumption that correspondiing lines in fields in yv12 have same chroma; what does weave do, average them anyhow?

w=32
h=128
clip1 = BlankClip(width=w,height=h,pixel_type="YUY2", color_yuv=$4164d4)#red
clip2 = BlankClip(width=w,height=h,pixel_type="YUY2", color_yuv=$70483a)#grn
clip3 = BlankClip(width=w,height=h,pixel_type="YUY2", color_yuv=$23d472)#blu
clip4 = BlankClip(width=w,height=h,pixel_type="YUY2", color_yuv=$9a388b)#yel
Global colorspace="rgb"#change this line to show the bug
weave3h(clip1.c, clip2.c, clip3.c, clip4.c)
function c(clip v) {lcase(colorspace)=="rgb"?v.converttorgb:v}
#Results: dark grey everything ok, yellowish means first line of 4 is not being deleted

function weave3h(clip a, clip b, clip c, clip x) {#horizontally weave 3 clips. tested only with Avisynth 2.58.
#Relies on implementation specific behaviour, may break in other versions.
#There will be color issues in yv12 vertically, and all yuv spaces when horizontal
a=a.turnright
b=b.turnright
c=c.turnright
x=x.turnright
interleave(x,b,a,c)#0 1 2 3->01 23->0213->213 or abc in rgb; 021 or xab in yuv
#x,b,a,c for rgb; a,c,b,x for yv12
#to fix use:
#a.isrgb?interleave(x,b,a,c):interleave(a,c,b,x)
assumefieldbased
assumetff
weave
assumefieldbased
assumetff
weave
pointresize(width,height*3/4)#Deletes every 4th line offset 0 in rgb;
#deletes every 4th line offset 3 in yuv. This is the part that's colorspace/version dependant.
#turnleft#avoid color issues for this test
}

jmac698
10th January 2011, 06:31
And here's a compatible way to test it. It's very awkward. Definitely need comments from an expert here:

#Test pointresize offset by colorspace.
Global tstBlack=BlankClip(width=4,height=4,pixel_type="YV12", color_yuv=$108080)
Global tstWhite=BlankClip(width=4,height=4,pixel_type="YV12", color_yuv=$EB8080)
tstOffsetRef0=stackvertical(tstBlack,tstWhite)
tstOffsetRef0=stackvertical(tstOffsetRef0,tstOffsetRef0,tstOffsetRef0,tstOffsetRef0).pointresize(4,8)#4x8 reference clip
Global tstOffsetYV12=tstOffsetRef0.pointresize(4,4)#If odd lines, offset 0, this is black, otherwise white
Global tstOffsetRGB=tstOffsetRef0.converttorgb.pointresize(4,4)#If odd lines, offset 0, this is black, otherwise white

blankclip.ScriptClip("""
Global YV12ResizeOffset=LumaDifference(tstOffsetYV12,tstBlack)
Global RGBResizeOffset=RGBDifference(tstOffsetRGB,tstBlack.converttorgb)
blankclip
subtitle("YV12ResizeOffset="+string(YV12ResizeOffset)+" RGBResizeOffset="+string(RGBResizeOffset))
""")
#YV12ResizeOffset, RGBResizeOffset can now be used in a weave3 function,
# but only after conforming all test videos to your weave videos!


I wish there was a way to do this in run-once context. What if you could compare a single frame at run-once?

This is yet another example where I need a ConformTo() function, I mean to copy video properties from a template or another video. I use it over and over because fundamentally, there's places like this where you need it. I think it should be a language feature really, but no one believes me :)

jmac698
10th January 2011, 06:47
Btw, to properly weave in YV12 you'd have to separate out the color and bilinearrize(w,h/3).

Gavino
10th January 2011, 11:15
since this is the only way to do it in script and it's implementation specific; how to stop my script from breaking?
It's not implementation specific - at least, not version specific - but it is a consequence of an Avisynth implementation detail that RGB clips are processed 'upside-down'. This is not likely to change (I think it ultimately comes from VfW), as that would break many existing plugins, etc.
The impact is that when doing PointResize with a view to extracting specific pixels, you need to know if you are dealing with RGB or not. Once you understand how it works, it's perfectly predictable. For RGB, you generally need to use a different vertical offset (src_top) in the PointResize - a less efficient alternative is to FlipVertical before and after. A simple IsRGB() test is all it takes to distinguish the two cases.
There's also consequences for color. There's an assumption that correspondiing lines in fields in yv12 have same chroma; what does weave do, average them anyhow?
:confused:
Weave just copies rows of pixels - no blending is ever required.
pointresize(width,height*3/4)#Deletes every 4th line offset 0 in rgb;
#deletes every 4th line offset 3 in yuv. This is the part that's colorspace/version dependant.
You've got the comment the wrong way round - it's offset 0 for YUV and offset 3 for RGB.
I wish there was a way to do this in run-once context. What if you could compare a single frame at run-once?
Not sure what you mean by run-once.
If you mean outside ScriptClip, you can cheat by doing this:
current_frame = 0 # fools LumaDifference, etc, into working outside ScriptClip
YV12ResizeOffset=LumaDifference(tstOffsetYV12,tstBlack)
RGBResizeOffset=RGBDifference(tstOffsetRGB,tstBlack.converttorgb)
blankclip
subtitle("YV12ResizeOffset="+string(YV12ResizeOffset)+" RGBResizeOffset="+string(RGBResizeOffset))
(As an aside, none of the 'global's are necessary, even in your original script.)
This is yet another example where I need a ConformTo() function, I mean to copy video properties from a template or another video. I use it over and over because fundamentally, there's places like this where you need it. I think it should be a language feature really, but no one believes me :)
I have the following function in a .avsi in my plugins folder
function MatchColorSpace(clip c, clip template) {
template.isYV12() ? c.ConvertToYV12() \
: template.isYUY2() ? c.ConvertToYUY2() \
: template.isRGB32() ? c.ConvertToRGB32() \
: template.isRGB24() ? c.ConvertToRGB24() \
: NOP # 'impossible?'
}
It needs to be extended to cover the new spaces supported in v2.6. This makes it more unwieldy, so there is a case for having such a function built-in. But in your previous post you referred to conforming width and height as well, which I think is best left for the user to decide how to do in the script.

jmac698
10th January 2011, 14:59
That current_frame = 0 is a fantastic tip! I've wanted to do this before. And yes, I'm talking about the parse complete phase as in the manual.
I didn't really explain about my need for conforming; I thought that these ResizeOffset would need to be the same video length as the video I'm working on; what value could it be on a frame where it doesn't exist? That's what's still not clear to me - a variable is set at a certain frame number, does it just keep that value? I still need it to evaluate every frame of the whole script, because I could jump to any frame with the slider and not run any other frames.
You certainly have deep knowledge of avisynth, many things a user could never know about. Let me see if I can update the manual. I was trying to find Select the other day and it wasn't easy.
Thanks for your help as always.
ps ConformTo(template, preset="VCD", except="size,audio") I was thinking lately.. anyhow I started writing a utility for it. Another thing I use all the time is shiftclip(int offsetX, int offsetY, padding_color) where it can be one pixel and even sometimes fractional. Hmm does overlay do fractional? But there's the conforming awkwardsness again.

Gavino
10th January 2011, 16:20
That current_frame = 0 is a fantastic tip! I've wanted to do this before. And yes, I'm talking about the parse complete phase as in the manual.
Basically, this trick makes the run-time functions available at compile-time (where normally they would give an error). In case it's not clear, note that by setting current_frame to n, you get the value corresponding to frame n.
I thought that these ResizeOffset would need to be the same video length as the video I'm working on; what value could it be on a frame where it doesn't exist? That's what's still not clear to me - a variable is set at a certain frame number, does it just keep that value? I still need it to evaluate every frame of the whole script, because I could jump to any frame with the slider and not run any other frames.
I don't understand what you're getting at here. The offsets are independent of frame number and depend only on RGB or not.
I was trying to find Select the other day and it wasn't easy.
It helps to understand the structure of the manual.
Look at the main page here (http://avisynth.org/mediawiki/Main_Page#Usage). You will see that there are various sections for internal filters, external filters, etc. Select is not a filter (it operates on values of any type), so it is found under Internal functions (http://avisynth.org/mediawiki/Internal_functions).
Another thing I use all the time is shiftclip(int offsetX, int offsetY, padding_color) where it can be one pixel and even sometimes fractional. Hmm does overlay do fractional?
For shifting, you want to use the extra parameters of the resizers (src_left, src_top), which are floats, supporting subpixel shifts.

Gavino
11th January 2011, 12:06
You've got the comment the wrong way round - it's offset 0 for YUV and offset 3 for RGB.
I was wrong here - your original comment is correct, ie
pointresize(width,height*3/4)#Deletes every 4th line offset 0 in rgb;
#deletes every 4th line offset 3 in yuv. This is the part that's colorspace/version dependant.
I was getting confused between lines deleted and lines kept. :(

jmac698
11th January 2011, 12:41
ha, the invulnerable g collapses :)
So I did try your gscript, about 250,000 simple loops per sec (x=x+i) that's about 1s per frame for pixel manipulation.. will try some other operations.
Thought a mandel plotter video woudl be cool :)