changeset 30108:0898adc64a6f

Extract functions to generate yuv->rgb matrices and lookup tables into a separate file.
author reimar
date Thu, 31 Dec 2009 18:25:35 +0000
parents 11e3ee8cd05e
children 0f25d3062987
files Makefile libvo/csputils.c libvo/csputils.h libvo/gl_common.c libvo/gl_common.h
diffstat 5 files changed, 169 insertions(+), 112 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Thu Dec 31 18:07:37 2009 +0000
+++ b/Makefile	Thu Dec 31 18:25:35 2009 +0000
@@ -543,7 +543,7 @@
 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvo/csputils.c	Thu Dec 31 18:25:35 2009 +0000
@@ -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;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libvo/csputils.h	Thu Dec 31 18:25:35 2009 +0000
@@ -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 */
--- a/libvo/gl_common.c	Thu Dec 31 18:07:37 2009 +0000
+++ b/libvo/gl_common.c	Thu Dec 31 18:25:35 2009 +0000
@@ -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 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 @@
       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 @@
         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 @@
              '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 @@
 }
 
 /**
- * \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, ...
--- a/libvo/gl_common.h	Thu Dec 31 18:07:37 2009 +0000
+++ b/libvo/gl_common.h	Thu Dec 31 18:25:35 2009 +0000
@@ -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 @@
 #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;