From 18c4a9bbd184a660b862ba233cf07aaf3a7db068 Mon Sep 17 00:00:00 2001 From: Torsten Jager Date: Tue, 10 Dec 2013 15:25:30 +0100 Subject: YCgCo: enable VDPAU video out. Possibly only theory. Most real life YCgCo files are 4:4:4 what VDPAU dislikes. --- src/video_out/video_out_vdpau.c | 95 ++++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/video_out/video_out_vdpau.c b/src/video_out/video_out_vdpau.c index 06476ef20..aa6fb951e 100644 --- a/src/video_out/video_out_vdpau.c +++ b/src/video_out/video_out_vdpau.c @@ -429,6 +429,7 @@ typedef struct { } vdpau_driver_t; /* import common color matrix stuff */ +#define CM_HAVE_YCGCO_SUPPORT 1 #define CM_DRIVER_T vdpau_driver_t #include "color_matrix.c" @@ -1603,49 +1604,65 @@ static void vdpau_update_csc_matrix (vdpau_driver_t *that, vdpau_frame_t *frame) float brightness = that->brightness; float uvcos = saturation * cos( hue ); float uvsin = saturation * sin( hue ); - float kb, kr; - float vr, vg, ug, ub; - float ygain, yoffset; int i; - switch (color_matrix >> 1) { - case 1: kb = 0.0722; kr = 0.2126; /* ITU-R 709 */ - break; - case 4: kb = 0.1100; kr = 0.3000; /* FCC */ - break; - case 7: kb = 0.0870; kr = 0.2120; /* SMPTE 240 */ - break; - default: kb = 0.1140; kr = 0.2990; /* ITU-R 601 */ - } - vr = 2.0 * (1.0 - kr); - vg = -2.0 * kr * (1.0 - kr) / (1.0 - kb - kr); - ug = -2.0 * kb * (1.0 - kb) / (1.0 - kb - kr); - ub = 2.0 * (1.0 - kb); - - if (color_matrix & 1) { - /* fullrange mode */ - yoffset = brightness; - ygain = contrast; - uvcos *= contrast * 255.0 / 254.0; - uvsin *= contrast * 255.0 / 254.0; + if ((color_matrix >> 1) == 8) { + /* YCgCo. This is really quite simple. */ + uvsin *= contrast; + uvcos *= contrast; + /* matrix[rgb][yuv1] */ + matrix[0][1] = -1.0 * uvcos - 1.0 * uvsin; + matrix[0][2] = 1.0 * uvcos - 1.0 * uvsin; + matrix[1][1] = 1.0 * uvcos; + matrix[1][2] = 1.0 * uvsin; + matrix[2][1] = -1.0 * uvcos + 1.0 * uvsin; + matrix[2][2] = -1.0 * uvcos - 1.0 * uvsin; + for (i = 0; i < 3; i++) { + matrix[i][0] = contrast; + matrix[i][3] = (brightness * contrast - 128.0 * (matrix[i][1] + matrix[i][2])) / 255.0; + } } else { - /* mpeg range */ - yoffset = brightness - 16.0; - ygain = contrast * 255.0 / 219.0; - uvcos *= contrast * 255.0 / 224.0; - uvsin *= contrast * 255.0 / 224.0; - } + /* YCbCr */ + float kb, kr; + float vr, vg, ug, ub; + float ygain, yoffset; + + switch (color_matrix >> 1) { + case 1: kb = 0.0722; kr = 0.2126; break; /* ITU-R 709 */ + case 4: kb = 0.1100; kr = 0.3000; break; /* FCC */ + case 7: kb = 0.0870; kr = 0.2120; break; /* SMPTE 240 */ + default: kb = 0.1140; kr = 0.2990; /* ITU-R 601 */ + } + vr = 2.0 * (1.0 - kr); + vg = -2.0 * kr * (1.0 - kr) / (1.0 - kb - kr); + ug = -2.0 * kb * (1.0 - kb) / (1.0 - kb - kr); + ub = 2.0 * (1.0 - kb); + + if (color_matrix & 1) { + /* fullrange mode */ + yoffset = brightness; + ygain = contrast; + uvcos *= contrast * 255.0 / 254.0; + uvsin *= contrast * 255.0 / 254.0; + } else { + /* mpeg range */ + yoffset = brightness - 16.0; + ygain = contrast * 255.0 / 219.0; + uvcos *= contrast * 255.0 / 224.0; + uvsin *= contrast * 255.0 / 224.0; + } - /* matrix[rgb][yuv1] */ - matrix[0][1] = -uvsin * vr; - matrix[0][2] = uvcos * vr; - matrix[1][1] = uvcos * ug - uvsin * vg; - matrix[1][2] = uvcos * vg + uvsin * ug; - matrix[2][1] = uvcos * ub; - matrix[2][2] = uvsin * ub; - for (i = 0; i < 3; i++) { - matrix[i][0] = ygain; - matrix[i][3] = (yoffset * ygain - 128.0 * (matrix[i][1] + matrix[i][2])) / 255.0; + /* matrix[rgb][yuv1] */ + matrix[0][1] = -uvsin * vr; + matrix[0][2] = uvcos * vr; + matrix[1][1] = uvcos * ug - uvsin * vg; + matrix[1][2] = uvcos * vg + uvsin * ug; + matrix[2][1] = uvcos * ub; + matrix[2][2] = uvsin * ub; + for (i = 0; i < 3; i++) { + matrix[i][0] = ygain; + matrix[i][3] = (yoffset * ygain - 128.0 * (matrix[i][1] + matrix[i][2])) / 255.0; + } } that->color_matrix = color_matrix; -- cgit v1.2.3