#version 130 uniform sampler2D UYVYtex; vec4 rec709YCbCr2rgba(float Y, float Cb, float Cr, float a) { float r, g, b; Y = (Y * 256.0 - 16.0) / 219.0; Cb = (Cb * 256.0 - 16.0) / 224.0 - 0.5; Cr = (Cr * 256.0 - 16.0) / 224.0 - 0.5; r = Y + 1.5748 * Cr; g = Y - 0.1873 * Cb - 0.4681 * Cr; b = Y + 1.8556 * Cb; return vec4(r, g, b, a); } vec4 bilinear(vec4 W, vec4 X, vec4 Y, vec4 Z, vec2 weight) { vec4 m0 = mix(W, Z, weight.x); vec4 m1 = mix(X, Y, weight.x); return mix(m0, m1, weight.y); } void textureGatherYUV(sampler2D UYVYsampler, vec2 tc, out vec4 W, out vec4 X, out vec4 Y, out vec4 Z) { ivec2 tx = ivec2(tc * textureSize(UYVYsampler, 0)); ivec2 tmin = ivec2(0, 0); ivec2 tmax = textureSize(UYVYsampler, 0) - ivec2(1, 1); W = texelFetch(UYVYsampler, tx, 0); X = texelFetch(UYVYsampler, clamp(tx + ivec2(0, 1), tmin, tmax), 0); Y = texelFetch(UYVYsampler, clamp(tx + ivec2(1, 1), tmin, tmax), 0); Z = texelFetch(UYVYsampler, clamp(tx + ivec2(1, 0), tmin, tmax), 0); } void main(void) { vec2 tc = gl_TexCoord[0].st; float alpha = 0.7; vec4 macro, macro_u, macro_r, macro_ur; vec4 pixel, pixel_r, pixel_u, pixel_ur; textureGatherYUV(UYVYtex, tc, macro, macro_u, macro_ur, macro_r); vec2 off = fract(tc * textureSize(UYVYtex, 0)); if (off.x > 0.5) { pixel = rec709YCbCr2rgba(macro.a, macro.b, macro.r, alpha); pixel_r = rec709YCbCr2rgba(macro_r.g, macro_r.b, macro_r.r, alpha); pixel_u = rec709YCbCr2rgba(macro_u.a, macro_u.b, macro_u.r, alpha); pixel_ur = rec709YCbCr2rgba(macro_ur.g, macro_ur.b, macro_ur.r, alpha); } else { pixel = rec709YCbCr2rgba(macro.g, macro.b, macro.r, alpha); pixel_r = rec709YCbCr2rgba(macro.a, macro.b, macro.r, alpha); pixel_u = rec709YCbCr2rgba(macro_u.g, macro_u.b, macro_u.r, alpha); pixel_ur = rec709YCbCr2rgba(macro_u.a, macro_u.b, macro_u.r, alpha); } gl_FragColor = bilinear(pixel, pixel_u, pixel_ur, pixel_r, off); }