View Full Version : colormatrix
Wilbert
4th September 2004, 23:36
I tried to make a filter to correct the problem in the following thread.
http://forum.doom9.org/showthread.php?s=&threadid=81191
My attempt can be found here (only YUY2):
http://www.geocities.com/wilbertdijkhof/ColorMatrix.zip
It should do the following:
It converts/upsamples to RGB using mpeg1 coefficients, and converts/subsamples back to YUY2 using mpeg2 coefficients. The idea is that DivX/XviD (also AviSynth) stuff assumes mpeg1 coefficients when decoding, while dvd-mpeg2 is created using mpeg2 coefficients. So the decoding is done incorrectly. This filter recalculates the correct YUV values.
The only problem is that it doesn't work. If I make one-color clips (using blankclip) and calculate everything, it seems to give the right corrections. I also believe that the color conversions themselves are correct. However, I added a short clip (in de zip-file) from the movie From Hell (fh.m2v), and the filter gives different output as when viewing the m2v file in VDubMod (fcchandler said that VDubMod uses the mpeg2 coefficients for this play), while it should give the same output.
Of course it can be coded 100 faster, but I give up. I can't figure out what I'm doing wrong. I hope some people can help me :)
Mug Funky
6th September 2004, 12:08
thanks for making this! i hope it will encourage people to take up the idea.
does Xvid use mpeg-1 coeffs? interesting. does that mean mpeg-4 does as well, or does it use mpeg-2, or one of it's own?
sh0dan
6th September 2004, 12:31
Why are you doing all these strange interpolation things?
Wilbert
6th September 2004, 13:16
I thought it was necessary to up and subsample to RGB .
YUY2 to RGB is sampled by interpolating the missing chroma horizontally. (50/50 on each side of the missing pixel)
I guess I'm doing this wrong then?
// MPEG2 coefficients -> MPEG1 coefficients
YUV2RGB2(srcp[x], srcp[x+1], 0.5*(srcp[x-1]+srcp[x+3]), &b, &g, &r); // left pixel: average V
RGB2YUV(r, g, b, &y, &u, &v);
// MPEG2 coefficients -> MPEG1 coefficients
YUV2RGB2(srcp[x+2], 0.5*(srcp[x+1]+srcp[x+5]), srcp[x+3], &b2, &g2, &r2); // right pixel: average U
RGB2YUV(r2, g2, b2, &y2, &u2, &v2);
RGB to YUY2 has two modes. Default mode is using a 1-2-1 kernel to interpolate chroma.
This I'm doing definately wrong. My mistake.
does Xvid use mpeg-1 coeffs? interesting.
Yes.
does that mean mpeg-4 does as well
I think so, but I'm not sure though.
Btw, it's a bit strange, at least for me. But varying luma (chroma constant) results in a varying luma and chroma when calculated with respect to the new set of coefficients.
sh0dan
6th September 2004, 13:42
Honestly I'd just keep it simple:
p0_rgb = YUV2RGB(p0) // No interpolation on left pixel
p1_rgb = YUV2RGB(p1.luma, p0.chroma) // Use left pixel chroma
p0_yuv = RGB2YUV(p0_rgb)
p1_yuv = RGB2YUV(p1_rgb)
p0_y = p0_yuv.luma
p1_y = p1_yuv.luma
p0_uv = p0_yuv.chroma + p1_yuv.choma / 2
This is inplace with no bleeding. I'm not even sure if the final UV-averaging is needed - It should be tested if the UV-components will actually be more different than +-2.
You somehow seem to assume that U and V components in YUY2 are placed differently spatially, which isn't the case (at least in common conception).
trevlac
7th September 2004, 17:25
@Wilbert
Can you clarify 1 thing for me? :)
Are you talking about:
A) Differences in the RGB<->YCbCr color matrix (like 601 vs 709)
B) Differences in sub/up sampling the chroma
-------------------------------------------
For (A), iirc you can pic 709 vs 601 in avs. But i guess if you have YUY2, you don't know how you got it. 601 is a good default ?
For (B) -- MPEG2 vs MPEG1 (JPEG) are clearly different. Interesting that mpeg4 would be like mpeg1.
Y0C0 Y1C1 Y2C2 Y3C3 Y4C4 Y5C5
MPEG2 4:4:4->4:2:2
Just drop the samples (which risks aliasing)
Y1 Y2C2 Y3 Y4C4
OR Filter (which is considered better but hard to say)
Cx = (C1+C2+C2+C3)/4
Cz = (C3+C4+C4+C5)/4
Y1 Y2Cx Y3 Y4Cz
MPEG2 4:2:2->4:4:4
C3 = (C2+C4)/2
or
C3 = (Cx+Cz)/2
----------------------------
Y0C0 Y1C1 Y2C2 Y3C3 Y4C4 Y5C5
MPEG1(JPEG) 4:4:4->4:2:2
Average the samples
Cx = C2 + C3 / 2
Cz = C4 + C5 / 2
Y1 Y2Cx Y3 Y4Cz
MPEG1 4:2:2->4:4:4
I have not idea how you are supposed to do this. There are 4 points on the 'curve' between Cx and Cz. They are Cx,C3,C4,Cz. I guess (Cx + Cz)/2 is between C3 & C4. So Cx+Cx+Cz /3 is a reasonable answer ... but damb hard to code.
==============
Frankly, I don't know much about MPEG1. But MPEG2 standards are easy to find.
I did play a bunch with chroma upsampling before. Somewhere over at everwicked. Visually, i didn't see much difference between 4:2:2 and 4:4:4 on normal source. But this was hard to test because normal source is really 4:2:0 or low bandwidth.
As I understand, for DV 4:1:1 Cb and Cr are cosited with the 1st (for Cb) and 3rd (for Cr) luma samples. AFAIK, Cb&Cr are positioned in the same spot of all other subsample types.
Wilbert
7th September 2004, 22:43
This is inplace with no bleeding. I'm not even sure if the final UV-averaging is needed - It should be tested if the UV-components will actually be more different than +-2.
If you don't round, the difference should be zero (all those transformations are linear). Stupid that I thought otherwise.
I implemented your suggestion, but I still got the same problem (output of the filter doesn't result in the same colors as opening the fh.m2v in VDubMod).
http://www.geocities.com/wilbertdijkhof/ColorMatrix.zip
You somehow seem to assume that U and V components in YUY2 are placed differently spatially, which isn't the case (at least in common conception).
Yes, I knew better. But, thanks for the reminder.
@Trev,
B) Differences in sub/up sampling the chroma
I thought you had to do this, but it's not necessary.
A) Differences in the RGB<->YCbCr color matrix (like 601 vs 709)
This is the real issue we were talking about.
vBulletin® v3.8.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.