PDA

View Full Version : YUY2toRGB filter


Wilbert
24th October 2004, 18:48
I'm trying to make my own YUY2toRGB filter using mpeg2 coefficients. I got problems getting it working:


if (rgb) { // YUY2 -> RGB24 using mpeg2 coefficients
const unsigned char* srcp = src->GetReadPtr();
unsigned char* dstp = dst->GetWritePtr();

for (int h=0; h < src_height; h++) {
for (int x=0; x < src_width-8; x+=2) { // not correct for src_width=4
// x=0,4,8,...
ConvToRGB(srcp[x], srcp[x+1], srcp[x+3], dstp + 3*x/2, dstp + 3*x/2 + 1, dstp + 3*x/2 + 2);
// x=2,6,10,...
x+=2;
ConvToRGB(srcp[x], int(0.5*(srcp[x-1]+srcp[x+1])), int(0.5*(srcp[x+3]+srcp[x+5])), dstp + 3*x/2, dstp + 3*x/2 + 1, dstp + 3*x/2 + 2);
}
x+=2;
ConvToRGB(srcp[x], srcp[x+1], srcp[x+3], dstp + 3*x/2, dstp + 3*x/2 + 1, dstp + 3*x/2 + 2);
ConvToRGB(srcp[x+2], srcp[x+1], srcp[x+3], dstp + 3*x/2, dstp + 3*x/2 + 1, dstp + 3*x/2 + 2); // copy last chroma value
srcp += src_pitch;
dstp += dst_pitch;
}
}

return dst;


I guess, now I have to add

vi.pixel_type = VideoInfo::CS_BGR24;

somewhere. But I don't know how or where?

Manao
24th October 2004, 19:02
In the filter's constructor.

Wilbert
24th October 2004, 19:57
Yeah, I know.

Besides the image shows upsidedown (I know, that makes sense), the image has wrong colors. Perhaps you can look at it if you have some time? I don't know what I'm doing wrong.

http://www.geocities.com/wilbertdijkhof/ColorMatrix_v14.zip

If you put rgb=true it should convert to RGB24 using mpeg1 coefficients.

Mug Funky
25th October 2004, 15:06
just thought of something: the coefficients should be selectable in avisynth's internal conversion filters. i wonder why they're not? it'd be a useful addition, even if they're not used all that much (extra options don't scare me - i practically live in the avs docs as it is).

i appreciate your efforts, wilbert :)

Wilbert
25th October 2004, 15:42
the coefficients should be selectable in avisynth's internal conversion filters.
If I could I would implement it :) I still don't speak (the required) MMX.

Perhaps IanB will do it one day :D

IanB
27th October 2004, 14:48
@Wilbert,

Your new YUY2 -> RGB look like it is the same as ConvertToRGB24(Matrix="Rec709") (bugs excepted).

Also your filter doesn't appear to have a gain of 1. Is this intensional or the result of inaccurate coefficient rendering. For U=128, V=128 shouldn't Yin == Yout??

I'm almost finished my current contract, I hope I can get back to AVS very soon.

IanB

Wilbert
27th October 2004, 15:14
Your new YUY2 -> RGB look like it is the same as ConvertToRGB24(Matrix="Rec709")

Are you saying that the above is simply YUV [16,235] -> RGB [0,255] using MPEG-2 coefficients? Never realized that it uses MPEG-2 coefficients (if that's indeed the case) ...

Or is it YUV [0,255] -> RGB [0,255] using MPEG-2 coefficients?


Also your filter doesn't appear to have a gain of 1. Is this intensional or the result of inaccurate coefficient rendering. For U=128, V=128 shouldn't Yin == Yout??
Are you referring to ColorMatrix? I will look at it tonight.

IanB
27th October 2004, 16:43
Originally posted by Wilbert
Are you saying that the above is simply YUV [16,235] -> RGB [0,255] using MPEG-2 coefficients? Never realized that it uses MPEG-2 coefficientsYes. Previous AVS versions had some silly restrictions with MMX, Width, RGB24 and Rec709. The current 2.56alpha already has most fixed.

Please try not to say "MPEG-2 coefficients" when you mean Rec.709, this can be misleading, Rec.709 are the Default coefficients but not the only ones allowed or used.

Have you had a chance to think how chroma scaling ([16,240] versus [1,255]) with YUV[0,255] <-> RGB[0,255] conversions would be most useful?

Are you referring to ColorMatrix? I will look at it tonight.Yes. I don't believe you should need to put Limiter in the chain if the gain is truely 1. For the chroma a few percent drop in saturation is infinitly preferable to clamping the values. Clamping causes noticable Hue shifts when it happens.

Do you still have a copy of your original "slow" source which used "Double" arithmetic I can have for comparison? It would be useful to document the current matrix coefficients back to the original values.

To cross check re-derive Kr, Kg & Kb from the values used in your matrix they should always sum to 1.0

IanB

Wilbert
27th October 2004, 21:25
Also your filter doesn't appear to have a gain of 1. Is this intensional or the result of inaccurate coefficient rendering. For U=128, V=128 shouldn't Yin == Yout??
Yes, you are right (didn't know that ...).


blankclip(width=720,height=576,pixel_type="YUY2",color_yuv=$yy 80 80)
ColorMatrix()
ColorYUV(analyze=true)

indeed always returns a clip with yuv=$yy8080.

Are you sure you checked it correctly?


Do you still have a copy of your original "slow" source which used "Double" arithmetic I can have for comparison? It would be useful to document the current matrix coefficients back to the original values.
http://www.geocities.com/wilbertdijkhof/conversions.zip (these are the coefficients I used ...)

(If you know Maple, I can also send you the Maple worksheet ...)

But, if you take Y=16, V=64, U=128 for example. Convert to RGB using Rec.709 and convert back to YUV using MPEG-1 coefficients (Rec.601 before you start complaining :)), you will get Y=5, V=64, U=145. So, you have to clamp at the end.

Have you had a chance to think how chroma scaling ([16,240] versus [0,255]) with YUV[0,255] <-> RGB[0,255] conversions would be most useful?
No, not yet :)

IanB
29th October 2004, 04:28
Originally posted by Wilbert
Are you sure you checked it correctly?Sorry, No, I just glanced thru the code, obviously a bit to quickly. I saw this/* mpeg2 to mpeg1 coefficients */

const int c11 = 65543;And this/* mpeg1 to mpeg2 coefficients */

const int d11 = 65536;The first has a gain of 1.0001068 which doesn't matter (200 -> 200.02) but indicates (very) slight rounding errors in the implementation.But, if you take Y=16, V=64, U=128 for example. Convert to RGB using Rec.709 and convert back to YUV using MPEG-1 coefficients (Rec.601 before you start complaining :)), you will get Y=5, V=64, U=145. So, you have to clamp at the end.Y=16 is Black so Both U & V should always be 128 in legal colour space. But the point is taken for Y >= 17.

However if U or V get clamped independantly you will get a hue shift. But examples when it will happen will probably only be for "out of spec" YUV values like your Black example. However if there are valid examples, when you clamp U(V) you will need to scale V(U) appropriatly to avoid the problem. I will ponder for some valid examples over the weekend. Take a peek at how levels works for some inspiration on fast clamping.

IanB

:Edit: Intuitive Proof :-

1. All valid YUV (Both Rec.601 and Rec.709) values will map within the RGB colour space.

2. All RGB values will map within the valid YUV colour spaces (Both Rec.601 and Rec.709).

3. Therefore all valid YUV (Rec.601) values will map within the valid YUV (Rec.709) colour space. And vice versa.

Only values outside a valid YUV colour spaces can map outside the other valid YUV colour space. And any such values were going to have strange results when displayed (on an RGB based display device) and will now have different strange results when displayed.

So my worry about the clamping causing Hue shifts is a moot point because such values were already invalid YUV values. It also means unconditional clamping is probably unnecessary.

IanB

Wilbert
30th October 2004, 01:27
I found out what the problem is.

I got the Rec.709 values from ISO/IEC 13818-2. But it contains some errors. I downloaded ITU-R_BT.709 and corrected the coefficients.

I had a few beers, so I will send you the right coefficients tomorrow (and a new version of ColorMatrix and answer the post above ...).

Wilbert
31st October 2004, 14:41
I put the corrected set of coefficients in the following file

http://www.geocities.com/wilbertdijkhof/coefficients.zip

So my worry about the clamping causing Hue shifts is a moot point because such values were already invalid YUV values. It also means unconditional clamping is probably unnecessary.
Ok, I think your proof is correct ...