changeset 33414:9bc9e1851a13

Support 9- and 10-bit YUV input for OpenGL vos.
author reimar
date Tue, 24 May 2011 20:52:27 +0000
parents 08da81bcc970
children 53073a44a899
files libvo/csputils.c libvo/csputils.h libvo/gl_common.h libvo/vo_gl.c libvo/vo_gl2.c
diffstat 5 files changed, 30 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/libvo/csputils.c	Tue May 24 19:53:20 2011 +0000
+++ b/libvo/csputils.c	Tue May 24 20:52:27 2011 +0000
@@ -62,6 +62,9 @@
  * not with e.g. MP_CSP_XYZ
  */
 void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float yuv2rgb[3][4]) {
+  float depth_multiplier = params->input_shift >= 0 ?
+                           (1 << params->input_shift) :
+                           (1.0 / (1 << -params->input_shift));
   float uvcos = params->saturation * cos(params->hue);
   float uvsin = params->saturation * sin(params->hue);
   int format = params->format;
@@ -128,6 +131,9 @@
     // 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;
+    yuv2rgb[i][COL_Y] *= depth_multiplier;
+    yuv2rgb[i][COL_U] *= depth_multiplier;
+    yuv2rgb[i][COL_V] *= depth_multiplier;
   }
 }
 
--- a/libvo/csputils.h	Tue May 24 19:53:20 2011 +0000
+++ b/libvo/csputils.h	Tue May 24 20:52:27 2011 +0000
@@ -53,6 +53,7 @@
   float rgamma;
   float ggamma;
   float bgamma;
+  int input_shift;
 };
 
 void mp_gen_gamma_map(unsigned char *map, int size, float gamma);
--- a/libvo/gl_common.h	Tue May 24 19:53:20 2011 +0000
+++ b/libvo/gl_common.h	Tue May 24 20:52:27 2011 +0000
@@ -351,6 +351,20 @@
 #define SET_YUV_CONVERSION(c)   ((c) & YUV_CONVERSION_MASK)
 #define SET_YUV_LUM_SCALER(s)   (((s) & YUV_SCALER_MASK) << YUV_LUM_SCALER_SHIFT)
 #define SET_YUV_CHROM_SCALER(s) (((s) & YUV_SCALER_MASK) << YUV_CHROM_SCALER_SHIFT)
+//! returns whether the yuv conversion supports large brightness range etc.
+static inline int glYUVLargeRange(int conv)
+{
+  switch (conv)
+  {
+  case YUV_CONVERSION_NONE:
+  case YUV_CONVERSION_COMBINERS:
+  case YUV_CONVERSION_COMBINERS_ATI:
+  case YUV_CONVERSION_FRAGMENT_LOOKUP3D:
+  case YUV_CONVERSION_TEXT_FRAGMENT:
+    return 0;
+  }
+  return 1;
+}
 /** \} */
 
 typedef struct {
--- a/libvo/vo_gl.c	Tue May 24 19:53:20 2011 +0000
+++ b/libvo/vo_gl.c	Tue May 24 20:52:27 2011 +0000
@@ -230,7 +230,7 @@
 //! maximum size of custom fragment program
 #define MAX_CUSTOM_PROG_SIZE (1024 * 1024)
 static void update_yuvconv(void) {
-  int xs, ys;
+  int xs, ys, depth;
   float bri = eq_bri / 100.0;
   float cont = (eq_cont + 100) / 100.0;
   float hue = eq_hue / 100.0 * 3.1415927;
@@ -239,11 +239,12 @@
   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, levelconv, bri, cont, hue, sat, rgamma, ggamma, bgamma},
+      {colorspace, levelconv, bri, cont, hue, sat, rgamma, ggamma, bgamma, 0},
       texture_width, texture_height, 0, 0, filter_strength};
-  mp_get_chroma_shift(image_format, &xs, &ys, NULL);
+  mp_get_chroma_shift(image_format, &xs, &ys, &depth);
   params.chrom_texw = params.texw >> xs;
   params.chrom_texh = params.texh >> ys;
+  params.csp_params.input_shift = -depth & 7;
   glSetupYUVConversion(&params);
   if (custom_prog) {
     FILE *f = fopen(custom_prog, "rb");
@@ -1081,7 +1082,7 @@
     if (format == IMGFMT_RGB24 || format == IMGFMT_RGBA)
         return caps;
     if (use_yuv && mp_get_chroma_shift(format, NULL, NULL, &depth) &&
-        (depth == 8 || depth == 16) &&
+        (depth == 8 || depth == 16 || glYUVLargeRange(use_yuv)) &&
         (IMGFMT_IS_YUVP16_NE(format) || !IMGFMT_IS_YUVP16(format)))
         return caps;
     // HACK, otherwise we get only b&w with some filters (e.g. -vf eq)
--- a/libvo/vo_gl2.c	Tue May 24 19:53:20 2011 +0000
+++ b/libvo/vo_gl2.c	Tue May 24 20:52:27 2011 +0000
@@ -560,7 +560,7 @@
   glDisable(GL_CULL_FACE);
   glEnable (GL_TEXTURE_2D);
   if (is_yuv) {
-    int xs, ys;
+    int xs, ys, depth;
     gl_conversion_params_t params = {GL_TEXTURE_2D, use_yuv,
           {-1, -1, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0},
           texture_width, texture_height, 0, 0, 0};
@@ -581,9 +581,10 @@
         mpglBindProgram(GL_FRAGMENT_PROGRAM, fragprog);
         break;
     }
-    mp_get_chroma_shift(image_format, &xs, &ys, NULL);
+    mp_get_chroma_shift(image_format, &xs, &ys, &depth);
     params.chrom_texw = params.texw >> xs;
     params.chrom_texh = params.texh >> ys;
+    params.csp_params.input_shift = -depth & 7;
     glSetupYUVConversion(&params);
   }
 
@@ -807,7 +808,7 @@
 {
   int depth;
   if (use_yuv && mp_get_chroma_shift(format, NULL, NULL, &depth) &&
-      (depth == 8 || depth == 16) &&
+      (depth == 8 || depth == 16 || glYUVLargeRange(use_yuv)) &&
       (IMGFMT_IS_YUVP16_NE(format) || !IMGFMT_IS_YUVP16(format)))
     return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD |
            VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE;