Log in

View Full Version : Reversible YV12->YUY2->YV12


vampiredom
28th October 2008, 17:57
Hi all --

I know it's probably old-hat to most, but I am a big fan of the GrapeSmoother plugin: It's very fast, minimally destructive and seems to be ideal for already "mostly clean" material, like HDV or AVCHD footage.

Unfortunately, it only works in YUY2. I think I've found a way to convert YV12->YUY2->YV12 without the goofy sort of resampling that takes place with the conventional method, which seems to be especially troublesome for interlaced sources:

function GrapeSmootherYV12(clip c, int "strength") {
strength=Default(Strength, 0)
c

wasYV12 = isYV12(c)

SeparateFields()
y = ConvertToYUY2()
uv = PointResize(width, height*2)
u = uv.UtoY().ConvertToYUY2()
v = uv.VtoY().ConvertToYUY2()

(wasYV12) ? YToUV(u,v,y).Weave().ConvertToYUY2(interlaced=true) : c
(strength > 0) ? GrapeSmoother(strength) : last
(wasYV12) ? ConvertToYV12(interlaced=true) : last

}

Is there a better or faster way to do this? It is a bit slower than simply ConvertToYUY2().GrapeSmoother().ConvertToYV12() ... but the chroma integrity seems much better when done my way.

Or perhaps I'm totally wrong about my enitre approach? Advice would be appreciated :)

stickboy
28th October 2008, 20:04
You might want to look at this thread http://forum.doom9.org/showthread.php?t=105313

Although I don't know if it's actually any better.

vampiredom
28th October 2008, 20:38
Thanks for the reply... we are essentially talking about the same kind of thing. I tried the code in your post here:

http://forum.doom9.org/showthread.php?p=764655#post764655

It's a bit slower than mine (averaging around around 12fps vs. 15fps on an HDV source via DGIndex): There are more colorplane-switcheroos and colorspace conversions. I also imagine theat Interleave(a,a).Weave() [x2] is probably slower than PointResize [x1], but I'm not certain.

I also like that my method only requires ConvertToYV12(interlaced=true) to "restore" it to YV12.

vampiredom
29th October 2008, 04:49
I think I found a better approach to this, using something more like stickboy's suggestion. When input is YV12, the function converts to YUY2. When input is YUY2 it converts back to YV12.

function TogglePlanar(clip c) {
c
wasYV12 = isYV12()

y = ConvertToYUY2()
u = UtoY()
u = Interleave(u,u).AssumeFieldBased().Weave().ConvertToYUY2()
v = VtoY()
v = Interleave(v,v).AssumeFieldBased().Weave().ConvertToYUY2()

(wasYV12) ? YToUV(u,v,y) : c.ConvertToYV12()
(GetParity(c)) ? AssumeTFF() : AssumeBFF()
}

So, in my case of GrapeSmoother (though it could be any YUY2-only filter)...

# usage example:

(isYV12) ? TogglePlanar().GrapeSmoother(30).TogglePlanar()
\ : GrapeSmoother(30)


I was surprised to see that Interleave(v,v).AssumeFieldBased().Weave() was a tiny bit faster than PointResize() ?? Thanks!