Mercurial > mplayer.hg
diff libvo/gl_common.c @ 18655:6aa0b26d584b
Add yuv to rgb conversion using a 3D lookup texture
author | reimar |
---|---|
date | Thu, 08 Jun 2006 19:02:56 +0000 |
parents | 5af43a16abc3 |
children | e813d4014acd |
line wrap: on
line diff
--- a/libvo/gl_common.c Thu Jun 08 18:56:33 2006 +0000 +++ b/libvo/gl_common.c Thu Jun 08 19:02:56 2006 +0000 @@ -723,6 +723,10 @@ "TEX result.color.b, res.baaa, texture[%c], 2D;" "END"; +static const char *yuv_lookup3d_prog_template = + "TEX result.color, yuv, texture[%c], 3D;" + "END"; + static void create_scaler_textures(int scaler, int *texu, char *texs) { switch (scaler) { case YUV_SCALER_BILIN: @@ -737,10 +741,50 @@ } } +static void gen_yuv2rgb_map(unsigned char *map, int size, float brightness, + float contrast, float uvcos, float uvsin, + float rgamma, float ggamma, float bgamma) { + int i, j, k; + float step = 1.0 / size; + float y, u, v, u_, v_; + float r, g, b; + v = -0.5; + for (i = -1; i <= size; i++) { + u = -0.5; + for (j = -1; j <= size; j++) { + y = -(16.0 / 255.0); + for (k = -1; k <= size; k++) { + u_ = uvcos * u + uvsin * v; + v_ = uvcos * v + uvsin * u; + r = 1.164 * y + 1.596 * v_; + g = 1.164 * y - 0.391 * u_ - 0.813 * v_; + b = 1.164 * y + 2.018 * u_ ; + r = pow(contrast * (r - 0.5) + 0.5 + brightness, 1.0 / rgamma); + g = pow(contrast * (g - 0.5) + 0.5 + brightness, 1.0 / ggamma); + b = pow(contrast * (b - 0.5) + 0.5 + brightness, 1.0 / bgamma); + if (r > 1) r = 1; + if (r < 0) r = 0; + if (g > 1) g = 1; + if (g < 0) g = 0; + if (b > 1) b = 1; + if (b < 0) b = 0; + *map++ = 255 * r; + *map++ = 255 * g; + *map++ = 255 * b; + y += (k == -1 || k == size - 1) ? step / 2 : step; + } + u += (j == -1 || j == size - 1) ? step / 2 : step; + } + v += (i == -1 || i == size - 1) ? step / 2 : step; + } +} + static void gen_gamma_map(unsigned char *map, int size, float gamma); //! resolution of texture for gamma lookup table #define LOOKUP_RES 512 +//! resolution for 3D yuv->rgb conversion lookup table +#define LOOKUP_3DRES 32 static void create_conv_textures(int conv, int *texu, char *texs, int brightness, int contrast, int uvcos, int uvsin, int rgamma, int ggamma, int bgamma) { @@ -763,6 +807,32 @@ ActiveTexture(GL_TEXTURE0); texs[0] += '0'; break; + case YUV_CONVERSION_FRAGMENT_LOOKUP3D: + { + int sz = LOOKUP_3DRES + 2; // texture size including borders + if (!TexImage3D) { + mp_msg(MSGT_VO, MSGL_ERR, "[gl] Missing 3D texture function!\n"); + break; + } + texs[0] = (*texu)++; + ActiveTexture(GL_TEXTURE0 + texs[0]); + lookup_data = malloc(3 * sz * sz * sz); + gen_yuv2rgb_map(lookup_data, LOOKUP_3DRES, brightness, contrast, + uvcos, uvsin, rgamma, ggamma, bgamma); + glAdjustAlignment(sz); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + TexImage3D(GL_TEXTURE_3D, 0, 3, sz, sz, sz, 1, + GL_RGB, GL_UNSIGNED_BYTE, lookup_data); + glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_PRIORITY, 1.0); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP); + ActiveTexture(GL_TEXTURE0); + texs[0] += '0'; + } + break; default: mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown conversion type %i\n", conv); } @@ -929,6 +999,9 @@ ry, gy, by, ru, gu, bu, rv, gv, bv, rc, gc, bc, conv_texs[0], conv_texs[0], conv_texs[0]); break; + case YUV_CONVERSION_FRAGMENT_LOOKUP3D: + snprintf(prog_pos, prog_remain, yuv_lookup3d_prog_template, conv_texs[0]); + break; default: mp_msg(MSGT_VO, MSGL_ERR, "[gl] unknown conversion type %i\n", YUV_CONVERSION(type)); break; @@ -983,6 +1056,7 @@ glSetupYUVCombinersATI(uvcos, uvsin); break; case YUV_CONVERSION_FRAGMENT_LOOKUP: + case YUV_CONVERSION_FRAGMENT_LOOKUP3D: case YUV_CONVERSION_FRAGMENT: case YUV_CONVERSION_FRAGMENT_POW: glSetupYUVFragprog(brightness, contrast, uvcos, uvsin, @@ -1020,6 +1094,7 @@ ActiveTexture(GL_TEXTURE0); glEnable(GL_FRAGMENT_SHADER_ATI); break; + case YUV_CONVERSION_FRAGMENT_LOOKUP3D: case YUV_CONVERSION_FRAGMENT_LOOKUP: case YUV_CONVERSION_FRAGMENT_POW: case YUV_CONVERSION_FRAGMENT: @@ -1053,6 +1128,7 @@ ActiveTexture(GL_TEXTURE0); glDisable(GL_FRAGMENT_SHADER_ATI); break; + case YUV_CONVERSION_FRAGMENT_LOOKUP3D: case YUV_CONVERSION_FRAGMENT_LOOKUP: case YUV_CONVERSION_FRAGMENT_POW: case YUV_CONVERSION_FRAGMENT: