Here's the second part of my tests:
Part 2
As jorel explained, the ATI YUV12 Codec incorrectly converts from YV12 to RGB. The colours look "washed": there's less contrast and they generally look duller. Here's why:
YUV data is usually clamped, the luma (Y) component to [16,235], and the chroma (U and V) components to [16,240]. This is exactly what Limiter() does. But the ATI codec scales the values to those ranges instead. So a clip that's all black (Y,U,V = 0,128,128) will be turned into (Y,U,V = 16,128,128) by Limiter(). Then when the ATI codec gets ahold of it, it will scale the ranges further, so the resultant will be (Y,U,V = 30,128,128). Similarly, something all white (Y,U,V = 255,128,128) will result in (Y,U,V = 217,128,128). You can already guess that this will reduce the contrast of the video.
Actually, the formula for scaling would be something like:
Code:
y' = y * (235 - 16) / 256 + 16
u' = u * (240 - 16) / 256 + 16
v' = v * (240 - 16) / 256 + 16
I saved the MPEG files created in Part 1 for each colourspace. I loaded the files into AviSynth using the following script:
Code:
yv12=DirectShowSource("yv12.m1v").ConvertToYV12().Histogram("Levels").Subtitle("YV12")
rgb24=DirectShowSource("rgb24.m1v").ConvertToYV12().Histogram("Levels").Subtitle("RGB24")
StackVertical(yv12,rgb24)
ConvertToRGB32()
The RGB24, RGB32, and YUY2 copies look the same, so I only loaded one for comparison. I convert to YV12 after loading the files (DirectShowSource() returns YUY2) to be able to use the Histogram("Levels") function, and convert to RGB32 at the end to avoid using the ATI codec.
Here's the output:
As you can see, the contrast is much lower in the YV12 version. Also look at the black bar on the right side of the image (between the image and the histogram), it's slightly brighter than the RGB24 version. And from the histogram, you can see that all three components are "compressed" into a smaller range (the leftmost bar on the Y component represents all the values clamped to 16 by Limiter(), but shifted over by the ATI codec).
Now, here's the same thing with Levels(16,1,235,0,255,false) added to the YV12 version:
The colours are almost back to the original, but obviously some information is lost (the black bars in the histogram). (The Levels() command given isn't perfect either, it doesn't rescale the chroma properly. Something with UToY()/VToY()/YToUV() could, though.)
Doing a more direct comparison, here's the results using the following script:
Code:
yv12=DirectShowSource("yv12.m1v").ConvertToYV12() #.Levels(16,1,235,0,255,false)
rgb24=DirectShowSource("rgb24.m1v").ConvertToYV12()
Subtract(yv12,rgb24)
ConvertToRGB32()
With Levels() commented out:
With Levels() uncommented:
In conclusion, don't use the ATI YUV12 Codec if you can avoid it. If you're stuck with it, and you're using TMPGEnc, add ConvertToRGB24() to the end of any AviSynth scripts you have returning results in the YV12 colourspace. If you're using CCE, using ConvertToYUY2() may or may not be an improvement...