diff options
author | Pekka Paalanen <pekka.paalanen@collabora.com> | 2021-02-04 16:35:29 +0200 |
---|---|---|
committer | Pekka Paalanen <pekka.paalanen@collabora.com> | 2021-02-25 14:36:46 +0200 |
commit | 9a59303a4f5b2a626aac1e08ee029dec92bbb82a (patch) | |
tree | 54512a38a55d1d93c1cbec3e36676dd8931ee045 | |
parent | 2b5a863974e7e65634dc96ab0652697cf73a0eb3 (diff) |
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>
-rw-r--r-- | libweston/renderer-gl/fragment.glsl | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/libweston/renderer-gl/fragment.glsl b/libweston/renderer-gl/fragment.glsl index ffc138f4..b313f76f 100644 --- a/libweston/renderer-gl/fragment.glsl +++ b/libweston/renderer-gl/fragment.glsl @@ -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; |