changeset 30293:aeab18b1923d

Add support for adjustable TV <-> PC level conversion. This could also be done by modifying contrast and brightness, but this seems a bit more flexible and easier to use.
author reimar
date Sat, 16 Jan 2010 19:59:31 +0000
parents 9086459837a0
children a32c2d542ae0
files libvo/csputils.c libvo/csputils.h libvo/vo_gl.c libvo/vo_gl2.c
diffstat 4 files changed, 32 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/libvo/csputils.c	Sat Jan 16 19:51:26 2010 +0000
+++ b/libvo/csputils.c	Sat Jan 16 19:59:31 2010 +0000
@@ -60,10 +60,15 @@
   float uvcos = params->saturation * cos(params->hue);
   float uvsin = params->saturation * sin(params->hue);
   int format = params->format;
+  int levelconv = params->levelconv;
   int i;
   const float (*uv_coeffs)[3];
   const float *level_adjust;
-  static const float yuv_pc_level_adjust[4] = {-16 / 255.0, -128 / 255.0, -128 / 255.0, 1.164};
+  static const float yuv_level_adjust[MP_CSP_LEVELCONV_COUNT][4] = {
+    {-16 / 255.0, -128 / 255.0, -128 / 255.0, 1.164},
+    { 16 / 255.0 * 1.164, -128 / 255.0, -128 / 255.0, 1.0/1.164},
+    { 0, -128 / 255.0, -128 / 255.0, 1},
+  };
   static const float xyz_level_adjust[4] = {0, 0, 0, 0};
   static const float uv_coeffs_table[MP_CSP_COUNT][3][3] = {
     [MP_CSP_DEFAULT] = {
@@ -101,7 +106,9 @@
   if (format < 0 || format >= MP_CSP_COUNT)
     format = MP_CSP_DEFAULT;
   uv_coeffs = uv_coeffs_table[format];
-  level_adjust = yuv_pc_level_adjust;
+  if (levelconv < 0 || levelconv >= MP_CSP_LEVELCONV_COUNT)
+    levelconv = MP_CSP_LEVELCONV_TV_TO_PC;
+  level_adjust = yuv_level_adjust[levelconv];
   if (format == MP_CSP_XYZ)
     level_adjust = xyz_level_adjust;
 
--- a/libvo/csputils.h	Sat Jan 16 19:51:26 2010 +0000
+++ b/libvo/csputils.h	Sat Jan 16 19:59:31 2010 +0000
@@ -31,8 +31,16 @@
   MP_CSP_COUNT
 };
 
+enum mp_csp_levelconv {
+  MP_CSP_LEVELCONV_TV_TO_PC,
+  MP_CSP_LEVELCONV_PC_TO_TV,
+  MP_CSP_LEVELCONV_NONE,
+  MP_CSP_LEVELCONV_COUNT
+};
+
 struct mp_csp_params {
   enum mp_csp_standard format;
+  enum mp_csp_levelconv levelconv;
   float brightness;
   float contrast;
   float hue;
--- a/libvo/vo_gl.c	Sat Jan 16 19:51:26 2010 +0000
+++ b/libvo/vo_gl.c	Sat Jan 16 19:59:31 2010 +0000
@@ -94,6 +94,7 @@
 #define MASK_GAMMA_SUPPORT (MASK_NOT_COMBINERS & ~(1 << YUV_CONVERSION_FRAGMENT))
 static int use_yuv;
 static int colorspace;
+static int levelconv;
 static int is_yuv;
 static int lscale;
 static int cscale;
@@ -217,7 +218,7 @@
   float ggamma = exp(log(8.0) * eq_ggamma / 100.0);
   float bgamma = exp(log(8.0) * eq_bgamma / 100.0);
   gl_conversion_params_t params = {gl_target, yuvconvtype,
-      {colorspace, bri, cont, hue, sat, rgamma, ggamma, bgamma},
+      {colorspace, levelconv, bri, cont, hue, sat, rgamma, ggamma, bgamma},
       texture_width, texture_height, 0, 0, filter_strength};
   mp_get_chroma_shift(image_format, &xs, &ys);
   params.chrom_texw = params.texw >> xs;
@@ -1007,6 +1008,12 @@
   return *csp >= -1 && *csp < MP_CSP_COUNT;
 }
 
+static int valid_csp_lvl(void *p)
+{
+  int *lvl = p;
+  return *lvl >= -1 && *lvl < MP_CSP_LEVELCONV_COUNT;
+}
+
 static const opt_t subopts[] = {
   {"manyfmts",     OPT_ARG_BOOL, &many_fmts,    NULL},
   {"osd",          OPT_ARG_BOOL, &use_osd,      NULL},
@@ -1017,6 +1024,7 @@
   {"rectangle",    OPT_ARG_INT,  &use_rectangle,int_non_neg},
   {"yuv",          OPT_ARG_INT,  &use_yuv,      int_non_neg},
   {"colorspace",   OPT_ARG_INT,  &colorspace,   valid_csp},
+  {"levelconv",    OPT_ARG_INT,  &levelconv,    valid_csp_lvl},
   {"lscale",       OPT_ARG_INT,  &lscale,       int_non_neg},
   {"cscale",       OPT_ARG_INT,  &cscale,       int_non_neg},
   {"filter-strength", OPT_ARG_FLOAT, &filter_strength, NULL},
@@ -1048,6 +1056,7 @@
     use_ycbcr = 0;
     use_yuv = 0;
     colorspace = -1;
+    levelconv = -1;
     lscale = 0;
     cscale = 0;
     filter_strength = 0.5;
@@ -1110,6 +1119,10 @@
               "    3: YUV to RGB according to SMPT-240M\n"
               "    4: YUV to RGB according to EBU\n"
               "    5: XYZ to RGB\n"
+              "  levelconv=<n>\n"
+              "    0: YUV to RGB converting TV to PC levels\n"
+              "    1: YUV to RGB converting PC to TV levels\n"
+              "    2: YUV to RGB without converting levels\n"
               "  lscale=<n>\n"
               "    0: use standard bilinear scaling for luma.\n"
               "    1: use improved bicubic scaling for luma.\n"
--- a/libvo/vo_gl2.c	Sat Jan 16 19:51:26 2010 +0000
+++ b/libvo/vo_gl2.c	Sat Jan 16 19:59:31 2010 +0000
@@ -571,7 +571,7 @@
   if (is_yuv) {
     int xs, ys;
     gl_conversion_params_t params = {GL_TEXTURE_2D, use_yuv,
-          {MP_CSP_DEFAULT, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0},
+          {-1, -1, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0},
           texture_width, texture_height, 0, 0, 0};
     switch (use_yuv) {
       case YUV_CONVERSION_FRAGMENT_LOOKUP: