gl-renderer: doc YCbCr-RGB conversion
I have verified that the conversion here follows ITU-R BT.601 except for
the offsets 16/256 and 128/256 which should be 16/255 and 128/255
respectively.
I used to following octave script to verify this:
rf = 0.299;
gf = 0.587;
bf = 0.114;
crdiv = 1.402;
cbdiv = 1.772;
M = [ rf, gf, bf ;
-rf / cbdiv, -gf / cbdiv, (1 - bf) / cbdiv;
(1 - rf) / crdiv, -gf / crdiv, -bf / crdiv ];
YCbCr = [ 'Y'; 'Cb'; 'Cr' ];
RGB = [ 'R'; 'G'; 'B' ];
eq = [ ' '; '='; ' ' ];
l = [ ' [ '; ' [ '; ' [ ' ];
r = [ ' ] '; ' ] '; ' ] ' ];
mat = [
sprintf('%9f %9f %9f', M(1,:));
sprintf('%9f %9f %9f', M(2,:));
sprintf('%9f %9f %9f', M(3,:));
];
[ l YCbCr r eq l mat r l RGB r ]
R = inv(M);
mat = [
sprintf('%9f %9f %9f', R(1,:));
sprintf('%9f %9f %9f', R(2,:));
sprintf('%9f %9f %9f', R(3,:));
];
[ l RGB r eq l mat r l YCbCr r ]
[ R(:,1), R(:,2:3) .* (255/224) ]
The final matrix printed is what the shader uses down to +/- one digit,
so at least 7 correct decimals.
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
@@ -58,10 +58,20 @@ yuva2rgba(vec4 yuva)
|
||||
vec4 color_out;
|
||||
float Y, su, sv;
|
||||
|
||||
/* ITU-R BT.601 & BT.709 quantization (limited range) */
|
||||
|
||||
/* Y = 255/219 * (x - 16/256) */
|
||||
Y = 1.16438356 * (yuva.x - 0.0625);
|
||||
|
||||
/* Remove offset 128/256, but the 255/224 multiplier comes later */
|
||||
su = yuva.y - 0.5;
|
||||
sv = yuva.z - 0.5;
|
||||
|
||||
/*
|
||||
* ITU-R BT.601 encoding coefficients (inverse), with the
|
||||
* 255/224 limited range multiplier already included in the
|
||||
* factors for su (Cb) and sv (Cr).
|
||||
*/
|
||||
color_out.r = Y + 1.59602678 * sv;
|
||||
color_out.g = Y - 0.39176229 * su - 0.81296764 * sv;
|
||||
color_out.b = Y + 2.01723214 * su;
|
||||
|
||||
Reference in New Issue
Block a user