Log in

View Full Version : yv12lutxy?


joshbm
9th September 2004, 23:27
I've been reading some threads and as a newb it is my understanding that this is similar OR can be similar to the function "overlay"?

Is that correct? I'm probably totally wrong, but if I'm right could anyone tell me how exactly to use it as an "overlay" function, 50% opacity over 2 clips:

overlay(v1,v3,opacity=0.5,mode="blend")

The reason it sparked my interest is because of people explaining the increase in speed.

Regards,
- joshbm

Vectrangle
10th September 2004, 00:40
yv12lut and yv12lutxy are part of the filter set masktools, and they basically perform arithmetic on each pixel of a frame. yv12lut works on one frame at a time, whereas yv12lutxy takes two inputs so that you can combine 2 clips together in all sorts of interesting ways.

You could use it to perform overlay, but that wouldn't be all that useful, the usefulness of it is when you are doing something complicated that could take 5-10 lines normally (or be impossible), which can be achieved with a single line of yv12lutxy.

Here's what the masktools readme has to say:
RGBLUT / YV12LUT / YV12LUTxy

YV12LUT (clip, string "yexpr", string "uexpr", string "vexpr")
RGBLUT (clip, string "Rexpr", string "Gexpr", string "Bexpr", string "AMPFile")
YV12LUTxy (clipx, clipy, string "yexpr", string "uexpr", string "vexpr")

These filters apply a function to each pixel of the picture. In order to allow a fast computation, every possible value of the function are precomputed and stored in a Look-Up Table ( hence the name ). That makes the filters fairly fast. RGBLUT works exactly the same way as YV12LUT, except that it has an additional argument AMPFile. It allows you to load a photoshop color profile.

In order to be able to apply almost every possible function, this one is given by a string which represents an expression in reverse polish notation. The principle of this notation is to write firstly the operands / parameters of an operator / function, and then the operator / function itself. Hence, "3 + 7" becomes "3 7 +", and "sin(3)" becomes "3 sin". Going further in the explanations, "3 * 7 + 5" becomes "3 7 * 5 +", and "(3 + 7) * 5" : "3 7 + 5 *". Now, you understand the main asset of this notation : no need of parenthesis.

Computations are lead on real numbers. Positive numbers also represent a true statement, whereas negative numbers represent a false statement. In the string, the symbol "x" is tha value of the pixel before the use of the function. For YV12LUTxy you also have the symbol "y", which represents the value of the collocated pixel in the second clip. The symbols must be separated by a single space.

Some operators and functions are implemented :

* +, -, /, *, ^, % are the operators plus, minus, divide, multiply, power and modulo.
* &, |, °, !& are the logical operators and, or, xor, and not. If the result is true, they return 1.0, else -1.0.
* <, <=, >, >=, =, != are the relationnal operators less than, less or equal to, more than, more or equal to, equal to, not equal to. If the result is true, they return 1.0, else -1.0.
* cos, sin, tan, acos, asin, atan, exp, log, abs are the functions cosine, sine, tangent, arccosine, arcsine, arctangent, exponential, napierian logarithm, absolute value.
* ? allows to do a condition test. It's a ternary operator, the first operand being the condition, the second the value if the condition is true, the third if false.

Some examples :

* Binarization of the picture with a threshold at 128 : "x 128 < 0 255 ?". It is translated as : "(x < 128) ? 0 : 255".
* Levels(il, gamma, ih, ol, oh) ( have a look at the filter Levels ) : "x il - ih il - / 1 gamma / ^ oh ol - *". It is translated as "(((x - il) / (ih - il)) ^ (1 / gamma)) * (oh - ol)".

Defaults are : Yexpr = Uexpr = Vexpr = "x" ( hence, the filter does nothing ).

joshbm
10th September 2004, 00:54
Thanks for the info!

Vectrangle
10th September 2004, 01:34
Actually when I was reading back my own post after I posted (a habit of mine that has saved me many times) I read through the readme excerpt that I posted and realized that because YV12LUTxy uses a look up table it could potentially be faster than overlay.

I ran a quick test and it does appear to be a little faster! My test was pretty crude though, it'd be nice to see someone find out how much faster it actually is.

Anyway here's the 50% overlay function, as requested:

yv12lutxy(v1,v3,yexpr="x y + 2 /",uexpr="x y + 2 /",vexpr="x y + 2 /")

If you want to learn how to write 'yv12lut speak', do a google search for reverse polish notation. It doesn't take long to learn :)

joshbm
10th September 2004, 01:56
How about a function?

function Yv12overlay(clip a,clip b,float "opacity")
{
recip=1./opacity
return yv12lutxy(a,b,yexpr="x y + "+String(recip)+" /",uexpr="x y + "+String(recip)+" /",vexpr="x y + "+String(recip)+" /")
}

Would that do the job?

Yv12overlay(v2,v4,opacity=0.5)

Regards
- joshbm

Vectrangle
10th September 2004, 02:05
nope not quite ^^

the string "x y + 2 /" I used translates to (x + y) / 2, so merely changing the 2 wont help.

what you want to do is x*opacity + y*(1 - opacity) (or is it the other way around? just switch x and y if it is) which would translate to "x opacity * y 1 opacity - * +", which you would need to write as "x "+string(opacity)+" * y 1 "+string(opacity)+" - * +"

joshbm
10th September 2004, 02:30
Ohhh.... lol :-P... So...

function Yv12overlay(clip a,clip b,float "opacity")
{
aExp="x "+string(opacity)+" * y 1 "+string(opacity)+" - * +"
return yv12lutxy(a,b,yexpr=aExp,uexpr=aExp,vexpr=aExp)
}

?

Regards,
- joshbm

Vectrangle
10th September 2004, 03:20
should work, test it with blankclip(color=$000000) and blankclip(color=$FFFFFF) if you don't trust it ^^

joshbm
10th September 2004, 04:05
Yup worked like a charm :D.

Thanks!
- joshbm

Manao
10th September 2004, 14:13
YV12LUTxy may be faster than overlay, but it clearly won't be any faster than MergeLuma().MergeChroma() :rolleyes:

kingmob
10th September 2004, 19:00
I cannot seem to find the function? It is not recognized when i use the latest masktools.dll...

Vectrangle
10th September 2004, 19:51
@kingmob

You're probably getting masktools from the wrong site, the newest version is actually 1.5.1 and can be found here (http://jourdan.madism.org/~manao/).

lol @ Manao :D

Ok since noone else took it upon themselves to run a test, I did.

(sorry for such a formal write-up, I have these habits ingrained into me from HS physics ^^)

Aim:
To determine if using YV12LUTxy as an overlay function is faster, and if so, by how much.

Method:
1. Play each of the following clips for 30 seconds (in vdubmod) and count how many frames are rendered in that time.
(a) control clip, with some basic filters
(b) control clip + 10 50% blend functions using overlay()
(c) control clip + 10 50% blend functions using yv12lutxy()
(d) control clip + 10 50% blend functions using mergeluma.mergechroma
2. Calculate rendering time in ms/frame for each blend function and compare

Results:
1.
(a) 163 frames
(b) 120 frames
(c) 144 frames
(d) lol... I had to ctrl-alt-del vdubmod because of this script :D
2.
Overlay() - 6.6ms / frame
YV12LUTxy() - 2.4ms / frame :)

Conclusion:
YV12LUTxy() is faster than Overlay() by a factor of 175%! (ie nearly 3 times faster) :eek:

Manao
10th September 2004, 21:55
Overlay converts the clip in YUY2, then process it, then converts it back to YV12, so no surprises.

But I checked mergeluma.mergechroma, and it's faster ( at least, with a 0.5 weight, I should have tested more thoroughly with different coefficients )

Vectrangle
11th September 2004, 02:07
hmm really? I thought you were joking when you said that, I've always found mergeluma and mergechroma fairly slow... and when I tested it before with 10 back to back merges it took about 20 seconds to render each frame o_o

maybe it was an issue with me blending a clip together with itself?


btw I used 0.5 weight for everything too. actually I probably cheated a little since I just used "x y + 2 /" as the expression for yv12lutxy, instead of "x 0.5 * y 0.5 * +" but it shouldn't have made much difference, I think

madness
11th September 2004, 05:35
Hmmmm.... this is quite intresting.
I use overlay() with the x & y offset, I just want to ask that how do I set the x & y offset using the YV12lutxy or is it possible to do it?

Vectrangle
11th September 2004, 06:37
you would have to do yv12lutxy(clip1, clip2.addborders(...).crop(...), ...) which could end up being slower than overlay. Test it and find out, if you want :)

madness
11th September 2004, 06:59
well I already got 2 clips one is original and the other one is 4 pixels cropped off so all i'm doing is slapping the 2 clip together using the overlay() and adjust the x and y offset to 4 so the picture is align correctly.

kingmob
11th September 2004, 11:45
Thanks, that did it Vectrangle :).
Oh, and by the way, is it just me or is the script only 1.2 times faster? (144/120)

Vectrangle
11th September 2004, 18:32
Nope, because with that calculation you're not taking into account the time taken by the rest of the script (I added in some extra filters, to make sure the script would always go slower than realtime so that I could get accurate results)

What you need to do is think of how many ms are taken to render each frame:
control: 184ms/frame
control + overlay x 10: 250ms/frame
control + yv12lutxy x 10: 208ms/frame

therefore:
overlay x 10 = 250 - control = 66ms/frame --> overlay = 6.6ms/frame
yv12lutxy x 10 = 208 - control = 24ms/frame --> yv12lutxy = 2.4ms/frame

and so the ratio of their speeds is 6.6/2.4 = 2.75 (ie 175% faster)

joshbm
12th September 2004, 03:30
Thanks for the really detailed speed tests against overlay ;)!

mergeluma.mergechroma? So that would be faster than even yv12lutxy? Could anyone run some tests against the current yv12lutxy solution?

Also what about Layer? Is that a fast solution?

Thanks!
- joshbm

joshbm
12th September 2004, 18:40
Anyone?

Compare the actual:

function Yv12overlay(clip a,clip b,float "opacity")
{
aExp="x "+string(opacity)+" * y 1 "+string(opacity)+" - * +"
return yv12lutxy(a,b,yexpr=aExp,uexpr=aExp,vexpr=aExp)
}

to

a.MergaLuma(b,0.5).MergeChroma(b,0.5)

to

a.Layer(b,"fast")

or to the add in Layer.

Thanks!
- joshbm

Manao
12th September 2004, 19:00
On a 720x576 source, YV12LUTxy x 10 computes 18226 frames in 1350 seconds, while MergeLuma.MergeChroma x 10 computes those same 18226 in 813 seconds. A script with the source only 280 seconds, so MergeLuma.MergeChroma is roughly 2 times faster than YV12LUTxy.

Layer is irrelevant, since it can't process YV12 data.

joshbm
12th September 2004, 23:16
Thank You!