From 0ecf324ac56d58230bcd34faecd92d8749f090a6 Mon Sep 17 00:00:00 2001 From: reimar Date: Thu, 31 Dec 2009 18:25:35 +0000 Subject: Extract functions to generate yuv->rgb matrices and lookup tables into a separate file. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@30150 b3059339-0415-0410-9bf9-f77b7e298cf2 --- Makefile | 2 +- libvo/csputils.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ libvo/csputils.h | 45 +++++++++++++++++++++ libvo/gl_common.c | 107 +++---------------------------------------------- libvo/gl_common.h | 11 +----- 5 files changed, 169 insertions(+), 112 deletions(-) create mode 100644 libvo/csputils.c create mode 100644 libvo/csputils.h diff --git a/Makefile b/Makefile index d0c780c7d9..33db0b7ab1 100644 --- a/Makefile +++ b/Makefile @@ -543,7 +543,7 @@ SRCS_MPLAYER-$(ESD) += libao2/ao_esd.c SRCS_MPLAYER-$(FBDEV) += libvo/vo_fbdev.c libvo/vo_fbdev2.c SRCS_MPLAYER-$(GGI) += libvo/vo_ggi.c SRCS_MPLAYER-$(GIF) += libvo/vo_gif89a.c -SRCS_MPLAYER-$(GL) += libvo/gl_common.c libvo/vo_gl.c libvo/vo_gl2.c +SRCS_MPLAYER-$(GL) += libvo/gl_common.c libvo/vo_gl.c libvo/vo_gl2.c libvo/csputils.c SRCS_MPLAYER-$(GL_WIN32) += libvo/w32_common.c SRCS_MPLAYER-$(GL_X11) += libvo/x11_common.c SRCS_MPLAYER-$(GUI) += gui/bitmap.c diff --git a/libvo/csputils.c b/libvo/csputils.c new file mode 100644 index 0000000000..55ef66d7d4 --- /dev/null +++ b/libvo/csputils.c @@ -0,0 +1,116 @@ +/* + * Common code related to colorspaces and conversion + * + * Copyleft (C) 2009 Reimar Döffinger + * + * This file is part of MPlayer. + * + * MPlayer is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * MPlayer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include "libavutil/common.h" +#include "csputils.h" + +/** + * \brief little helper function to create a lookup table for gamma + * \param map buffer to create map into + * \param size size of buffer + * \param gamma gamma value + */ +void mp_gen_gamma_map(uint8_t *map, int size, float gamma) { + int i; + if (gamma == 1.0) { + for (i = 0; i < size; i++) + map[i] = 255 * i / (size - 1); + return; + } + gamma = 1.0 / gamma; + for (i = 0; i < size; i++) { + float tmp = (float)i / (size - 1.0); + tmp = pow(tmp, gamma); + if (tmp > 1.0) tmp = 1.0; + if (tmp < 0.0) tmp = 0.0; + map[i] = 255 * tmp; + } +} + +/** + * \brief get the coefficients of the yuv -> rgb conversion matrix + * \param params struct specifying the properties of the conversion like brightness, ... + * \param yuv2rgb array to store coefficients into + */ +void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float yuv2rgb[3][4]) { + float uvcos = params->saturation * cos(params->hue); + float uvsin = params->saturation * sin(params->hue); + int i; + float uv_coeffs[3][2] = { + { 0.000, 1.596}, + {-0.391, -0.813}, + { 2.018, 0.000} + }; + for (i = 0; i < 3; i++) { + yuv2rgb[i][COL_C] = params->brightness; + yuv2rgb[i][COL_Y] = 1.164 * params->contrast; + yuv2rgb[i][COL_C] += (-16 / 255.0) * yuv2rgb[i][COL_Y]; + yuv2rgb[i][COL_U] = uv_coeffs[i][0] * uvcos + uv_coeffs[i][1] * uvsin; + yuv2rgb[i][COL_C] += (-128 / 255.0) * yuv2rgb[i][COL_U]; + yuv2rgb[i][COL_V] = uv_coeffs[i][0] * uvsin + uv_coeffs[i][1] * uvcos; + yuv2rgb[i][COL_C] += (-128 / 255.0) * yuv2rgb[i][COL_V]; + // this "centers" contrast control so that e.g. a contrast of 0 + // leads to a grey image, not a black one + yuv2rgb[i][COL_C] += 0.5 - params->contrast / 2.0; + } +} + +//! size of gamma map use to avoid slow exp function in gen_yuv2rgb_map +#define GMAP_SIZE (1024) +/** + * \brief generate a 3D YUV -> RGB map + * \param params struct containing parameters like brightness, gamma, ... + * \param map where to store map. Must provide space for (size + 2)^3 elements + * \param size size of the map, excluding border + */ +void mp_gen_yuv2rgb_map(struct mp_csp_params *params, unsigned char *map, int size) { + int i, j, k, l; + float step = 1.0 / size; + float y, u, v; + float yuv2rgb[3][4]; + unsigned char gmaps[3][GMAP_SIZE]; + mp_gen_gamma_map(gmaps[0], GMAP_SIZE, params->rgamma); + mp_gen_gamma_map(gmaps[1], GMAP_SIZE, params->ggamma); + mp_gen_gamma_map(gmaps[2], GMAP_SIZE, params->bgamma); + mp_get_yuv2rgb_coeffs(params, yuv2rgb); + for (i = 0; i < 3; i++) + for (j = 0; j < 4; j++) + yuv2rgb[i][j] *= GMAP_SIZE - 1; + v = 0; + for (i = -1; i <= size; i++) { + u = 0; + for (j = -1; j <= size; j++) { + y = 0; + for (k = -1; k <= size; k++) { + for (l = 0; l < 3; l++) { + float rgb = yuv2rgb[l][COL_Y] * y + yuv2rgb[l][COL_U] * u + yuv2rgb[l][COL_V] * v + yuv2rgb[l][COL_C]; + *map++ = gmaps[l][av_clip(rgb, 0, GMAP_SIZE - 1)]; + } + 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; + } +} diff --git a/libvo/csputils.h b/libvo/csputils.h new file mode 100644 index 0000000000..1218b1a473 --- /dev/null +++ b/libvo/csputils.h @@ -0,0 +1,45 @@ +/* + * This file is part of MPlayer. + * + * MPlayer is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * MPlayer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with MPlayer; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPLAYER_CSPUTILS_H +#define MPLAYER_CSPUTILS_H + +#include + +struct mp_csp_params { + float brightness; + float contrast; + float hue; + float saturation; + float rgamma; + float ggamma; + float bgamma; +}; + +void mp_gen_gamma_map(unsigned char *map, int size, float gamma); +#define ROW_R 0 +#define ROW_G 1 +#define ROW_B 2 +#define COL_Y 0 +#define COL_U 1 +#define COL_V 2 +#define COL_C 3 +void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float yuv2rgb[3][4]); +void mp_gen_yuv2rgb_map(struct mp_csp_params *params, uint8_t *map, int size); + +#endif /* MPLAYER_CSPUTILS_H */ diff --git a/libvo/gl_common.c b/libvo/gl_common.c index 0b63cc6390..2571959640 100644 --- a/libvo/gl_common.c +++ b/libvo/gl_common.c @@ -33,7 +33,7 @@ #include #include #include "gl_common.h" -#include "libavutil/common.h" +#include "csputils.h" void (GLAPIENTRY *Begin)(GLenum); void (GLAPIENTRY *End)(void); @@ -1008,78 +1008,6 @@ static void create_scaler_textures(int scaler, int *texu, char *texs) { } } -static void gen_gamma_map(unsigned char *map, int size, float gamma); - -#define ROW_R 0 -#define ROW_G 1 -#define ROW_B 2 -#define COL_Y 0 -#define COL_U 1 -#define COL_V 2 -#define COL_C 3 - -static void get_yuv2rgb_coeffs(struct mp_csp_params *params, float yuv2rgb[3][4]) { - float uvcos = params->saturation * cos(params->hue); - float uvsin = params->saturation * sin(params->hue); - int i; - float uv_coeffs[3][2] = { - { 0.000, 1.596}, - {-0.391, -0.813}, - { 2.018, 0.000} - }; - for (i = 0; i < 3; i++) { - yuv2rgb[i][COL_C] = params->brightness; - yuv2rgb[i][COL_Y] = 1.164 * params->contrast; - yuv2rgb[i][COL_C] += (-16 / 255.0) * yuv2rgb[i][COL_Y]; - yuv2rgb[i][COL_U] = uv_coeffs[i][0] * uvcos + uv_coeffs[i][1] * uvsin; - yuv2rgb[i][COL_C] += (-128 / 255.0) * yuv2rgb[i][COL_U]; - yuv2rgb[i][COL_V] = uv_coeffs[i][0] * uvsin + uv_coeffs[i][1] * uvcos; - yuv2rgb[i][COL_C] += (-128 / 255.0) * yuv2rgb[i][COL_V]; - // this "centers" contrast control so that e.g. a contrast of 0 - // leads to a grey image, not a black one - yuv2rgb[i][COL_C] += 0.5 - params->contrast / 2.0; - } -} - -//! size of gamma map use to avoid slow exp function in gen_yuv2rgb_map -#define GMAP_SIZE (1024) -/** - * \brief generate a 3D YUV -> RGB map - * \param params struct containing parameters like brightness, gamma, ... - * \param map where to store map. Must provide space for (size + 2)^3 elements - * \param size size of the map, excluding border - */ -static void gen_yuv2rgb_map(struct mp_csp_params *params, unsigned char *map, int size) { - int i, j, k, l; - float step = 1.0 / size; - float y, u, v; - float yuv2rgb[3][4]; - unsigned char gmaps[3][GMAP_SIZE]; - gen_gamma_map(gmaps[0], GMAP_SIZE, params->rgamma); - gen_gamma_map(gmaps[1], GMAP_SIZE, params->ggamma); - gen_gamma_map(gmaps[2], GMAP_SIZE, params->bgamma); - get_yuv2rgb_coeffs(params, yuv2rgb); - for (i = 0; i < 3; i++) - for (j = 0; j < 4; j++) - yuv2rgb[i][j] *= GMAP_SIZE - 1; - v = 0; - for (i = -1; i <= size; i++) { - u = 0; - for (j = -1; j <= size; j++) { - y = 0; - for (k = -1; k <= size; k++) { - for (l = 0; l < 3; l++) { - float rgb = yuv2rgb[l][COL_Y] * y + yuv2rgb[l][COL_U] * u + yuv2rgb[l][COL_V] * v + yuv2rgb[l][COL_C]; - *map++ = gmaps[l][av_clip(rgb, 0, GMAP_SIZE - 1)]; - } - 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; - } -} - //! resolution of texture for gamma lookup table #define LOOKUP_RES 512 //! resolution for 3D yuv->rgb conversion lookup table @@ -1101,9 +1029,9 @@ static void create_conv_textures(gl_conversion_params_t *params, int *texu, char texs[0] = (*texu)++; ActiveTexture(GL_TEXTURE0 + texs[0]); lookup_data = malloc(4 * LOOKUP_RES); - gen_gamma_map(lookup_data, LOOKUP_RES, params->csp_params.rgamma); - gen_gamma_map(&lookup_data[LOOKUP_RES], LOOKUP_RES, params->csp_params.ggamma); - gen_gamma_map(&lookup_data[2 * LOOKUP_RES], LOOKUP_RES, params->csp_params.bgamma); + mp_gen_gamma_map(lookup_data, LOOKUP_RES, params->csp_params.rgamma); + mp_gen_gamma_map(&lookup_data[LOOKUP_RES], LOOKUP_RES, params->csp_params.ggamma); + mp_gen_gamma_map(&lookup_data[2 * LOOKUP_RES], LOOKUP_RES, params->csp_params.bgamma); glCreateClearTex(GL_TEXTURE_2D, GL_LUMINANCE8, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LINEAR, LOOKUP_RES, 4, 0); glUploadTex(GL_TEXTURE_2D, GL_LUMINANCE, GL_UNSIGNED_BYTE, lookup_data, @@ -1121,7 +1049,7 @@ static void create_conv_textures(gl_conversion_params_t *params, int *texu, char texs[0] = (*texu)++; ActiveTexture(GL_TEXTURE0 + texs[0]); lookup_data = malloc(3 * sz * sz * sz); - gen_yuv2rgb_map(¶ms->csp_params, lookup_data, LOOKUP_3DRES); + mp_gen_yuv2rgb_map(¶ms->csp_params, lookup_data, LOOKUP_3DRES); glAdjustAlignment(sz); PixelStorei(GL_UNPACK_ROW_LENGTH, 0); TexImage3D(GL_TEXTURE_3D, 0, 3, sz, sz, sz, 1, @@ -1330,7 +1258,7 @@ static void glSetupYUVFragprog(gl_conversion_params_t *params) { '1', 'g', rect, params->chrom_texw, params->chrom_texh, params->filter_strength); add_scaler(YUV_CHROM_SCALER(type), &prog_pos, &prog_remain, chrom_scale_texs, '2', 'b', rect, params->chrom_texw, params->chrom_texh, params->filter_strength); - get_yuv2rgb_coeffs(¶ms->csp_params, yuv2rgb); + mp_get_yuv2rgb_coeffs(¶ms->csp_params, yuv2rgb); switch (YUV_CONVERSION(type)) { case YUV_CONVERSION_FRAGMENT: snprintf(prog_pos, prog_remain, yuv_prog_template, @@ -1367,29 +1295,6 @@ static void glSetupYUVFragprog(gl_conversion_params_t *params) { free(yuv_prog); } -/** - * \brief little helper function to create a lookup table for gamma - * \param map buffer to create map into - * \param size size of buffer - * \param gamma gamma value - */ -static void gen_gamma_map(unsigned char *map, int size, float gamma) { - int i; - if (gamma == 1.0) { - for (i = 0; i < size; i++) - map[i] = 255 * i / (size - 1); - return; - } - gamma = 1.0 / gamma; - for (i = 0; i < size; i++) { - float tmp = (float)i / (size - 1.0); - tmp = pow(tmp, gamma); - if (tmp > 1.0) tmp = 1.0; - if (tmp < 0.0) tmp = 0.0; - map[i] = 255 * tmp; - } -} - /** * \brief setup YUV->RGB conversion * \param parms struct containing parameters like conversion and scaler type, diff --git a/libvo/gl_common.h b/libvo/gl_common.h index 8410c4c954..db3bb4d8bc 100644 --- a/libvo/gl_common.h +++ b/libvo/gl_common.h @@ -26,6 +26,7 @@ #include "mp_msg.h" #include "video_out.h" +#include "csputils.h" #ifdef CONFIG_GL_WIN32 #include @@ -328,16 +329,6 @@ int loadGPUProgram(GLenum target, char *prog); #define YUV_CHROM_SCALER(t) ((t >> YUV_CHROM_SCALER_SHIFT) & YUV_SCALER_MASK) /** \} */ -struct mp_csp_params { - float brightness; - float contrast; - float hue; - float saturation; - float rgamma; - float ggamma; - float bgamma; -}; - typedef struct { GLenum target; int type; -- cgit v1.2.3