PDA

View Full Version : Lossless YV12-YUY2-YV12


actionman133
8th January 2006, 10:13
Hi,

Just finished with a filter that some people might find useful. It's a filter that allows YV12 video to be converted to YUY2 (to meet input requirements for a filter like ConvertFPS, or a program like Premiere Pro), and then back to YV12 without loss. It works by storing YV12 chroma in YUY2 and filling the remaining chroma with a BlankClip. It then converts back by cropping the BlankClip out and restoring the original chroma.Function YV12toYUY2 (clip Last) {

Y = Tweak (sat = 0, coring = false).ConvertToYUY2 ()
U = StackVertical (UtoY (), BlankClip (UtoY ())).ConvertToYUY2 ()
V = StackVertical (VtoY (), BlankClip (VtoY ())).ConvertToYUY2 ()

Return YtoUV (U, V, Y)

}

Function YUY2toYV12 (clip Last) {

Y = Tweak (sat = 0, coring = false).ConvertToYV12 ()
U = UtoY ().Crop (0, 0, Y.Width / 2, Y.Height / 2).ConvertToYV12 ()
V = VtoY ().Crop (0, 0, Y.Width / 2, Y.Height / 2).ConvertToYV12 ()

Return YtoUV (U, V, Y)

}
If you edit in Premiere Pro, you would edit as you like without using these functions. Then, when you come to your final rendering, you add this line to the end of your script and save the movie with a lossless YUY2 codec (such as HuffYUV). Then open the lossless AVI with another script and use YUY2toYV12 and you'll get the original video back losslessly. Within AVISynth you could use it like this:#YV12 source
YV12toYUY2 ()
ConvertFPS (25)
YUY2toYV12 ()

You can test losslessness for yourself with a single line... Subtract (clip, clip.YV12toYUY2 ().YUY2toYV12 ())Just putting it out there for anyone who might like it...

stickboy
8th January 2006, 23:25
Bah, just when I thought I had some grasp on the colorspace stuff.

Doesn't YV12 use 4:2:0 subsampling and YUY2 4:2:2? Isn't everything with 4:2:0 representable with 4:2:2, and if so, why is there loss going from YV12->YUY2->YV12? (I can see that there is loss with AviSynth's built-in conversion routines, but I don't understand where that loss comes from.)

stickboy
8th January 2006, 23:45
BTW, your approach will leave the frames looking very wrong, which would be bad if you ran any filters on the video between colorspace conversions.

A better approach might be something like:
function YV12toYUY2(clip last) {
y = Tweak(sat=0, coring=false).ConvertToYUY2()
uy = UtoY()
vy = VtoY()
u = Interleave(uy, uy).AssumeFieldBased().Weave().ConvertToYUY2()
v = Interleave(vy, vy).AssumeFieldBased().Weave().ConvertToYUY2()
return YtoUV(u, v, y)
}

function YUY2toYV12(clip last) {
y = Tweak(sat=0, coring=false).ConvertToYV12()
u = UtoY().AssumeFrameBased().SeparateFields().SelectEven().ConvertToYV12()
v = VtoY().AssumeFrameBased().SeparateFields().SelectEven().ConvertToYV12()
return YtoUV(u, v, y)
}which duplicates chroma samples instead of using blank ones (and is what I expected the internal ConvertToYV12() and ConvertToYUY2() to do).

Wilbert
9th January 2006, 00:02
Doesn't YV12 use 4:2:0 subsampling and YUY2 4:2:2? Isn't everything with 4:2:0 representable with 4:2:2, and if so, why is there loss going from YV12->YUY2->YV12? (I can see that there is loss with AviSynth's built-in conversion routines, but I don't understand where that loss comes from.)
Because in both cases chroma is interpolated vertically and not point-sampled (or duplicated as you call it):

http://www.avisynth.org/Sampling

stickboy
9th January 2006, 00:26
Because in both cases chroma is interpolated vertically and not point-sampled (or duplicated as you call it)Ah, okay.

Should there be an option to ConvertToYUY2() and ConvertToYV12() to allow point-sampling?

IanB
9th January 2006, 13:15
In 2.6 we are using the resizer core to resample the chroma size between different subsampling regimes. Currently it is fixed to only use the bicubic method, but there an intention to make this user selectable.

Richard Berg
9th January 2006, 21:07
There's already precedent for this sort of behavior: ConvertBackToYUY2(). We could use a similar naming scheme for the YUY2 -> YV12 routine.

actionman133
10th January 2006, 14:36
Just made me think... Can we expect a ConvertBackToYV12 () for material that's undergone YV12->RGB32 conversions in the next release?

IanB
11th January 2006, 22:44
@actionman133,

The 2.6 core has direct RGB<->YV24 (4:4:4) routines (prior versions stuffed around going via YUY2 (Also 2.6 has direct YUY2<->YV16 (4:2:2))). As mentions above, the conversion between various planar formats uses the resizer core, currently this is only bicubic but there is an intention to make it user selectable.

Almost certainly there will not be an explicit ConvertBackToYV12() verb but the functionality will be very easy to achieve.

ConvertBackToYUY2() works by only sampling chroma from the left pixel of a RGB pair which on the ConvertToRGB() pass was directly calculated, the ignored right pixel of the pair was interpolated from the chroma on either side of it. Thus on repeated conversions there is no successive blurring.

For ConvertBackToYV12() functionality, horizontally the same left only logic can be used but vertically you must always take the average of the top and bottom pixel otherwise you introduce a 0.5 pixel chroma positional shift. Thus for lossless RGB<->YV12 conversions it is the forward conversion (RGB->YV12) that must not vertically interpolate, so you really need a ConvertToRGBBack() as well.

IanB

Inc
11th January 2006, 23:01
In 2.6 we are using the resizer core to resample the chroma size between different subsampling regimes. Currently it is fixed to only use the bicubic method, but there an intention to make this user selectable.

Something like this approach ...
http://forum.doom9.org/showthread.php?p=762787#post762787

?

actionman133
11th January 2006, 23:29
Any chance we'll be seeing Y-only format for black and white and dealing with UtoY () and VtoY ()? I find it a little frustrating that my YV12 video needs height to be a multiple of 4 to get the chroma channels.

IanB
12th January 2006, 00:47
@incredible, Internally yes.

@actionman133,

Yes Y8 format is supported in version 2.6 see this thread Proposal for AviSynth 2.6 (http://forum.doom9.org/showthread.php?t=98585)