aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2009-12-31 18:25:35 +0000
committerGravatar reimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2009-12-31 18:25:35 +0000
commit0ecf324ac56d58230bcd34faecd92d8749f090a6 (patch)
tree6b7fdd6766a0a985b34aa2ce0d2b7849d7359310
parentc4c806a9d743ec917450515db15b270981930259 (diff)
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
-rw-r--r--Makefile2
-rw-r--r--libvo/csputils.c116
-rw-r--r--libvo/csputils.h45
-rw-r--r--libvo/gl_common.c107
-rw-r--r--libvo/gl_common.h11
5 files changed, 169 insertions, 112 deletions
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 <Reimar.Doeffinger@gmx.de>
+ *
+ * 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 <stdint.h>
+#include <math.h>
+#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 <stdint.h>
+
+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 <ctype.h>
#include <math.h>
#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(&params->csp_params, lookup_data, LOOKUP_3DRES);
+ mp_gen_yuv2rgb_map(&params->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(&params->csp_params, yuv2rgb);
+ mp_get_yuv2rgb_coeffs(&params->csp_params, yuv2rgb);
switch (YUV_CONVERSION(type)) {
case YUV_CONVERSION_FRAGMENT:
snprintf(prog_pos, prog_remain, yuv_prog_template,
@@ -1368,29 +1296,6 @@ static void glSetupYUVFragprog(gl_conversion_params_t *params) {
}
/**
- * \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,
* brightness, ...
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 <windows.h>
@@ -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;