changeset 28725:b9c26620ada7

Support brightness, contrast, hue and saturation adjustments via custom color space conversion matrices in VDPAU. Patch by Grigori Goronzy, greg A chown D ath D cx
author cehoyos
date Sat, 28 Feb 2009 13:20:01 +0000
parents 307da077861c
children 591e21684b50
files libvo/vo_vdpau.c
diffstat 1 files changed, 54 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/libvo/vo_vdpau.c	Sat Feb 28 13:02:52 2009 +0000
+++ b/libvo/vo_vdpau.c	Sat Feb 28 13:20:01 2009 +0000
@@ -140,6 +140,8 @@
 static VdpDecoderDestroy                         *vdp_decoder_destroy;
 static VdpDecoderRender                          *vdp_decoder_render;
 
+static VdpGenerateCSCMatrix                      *vdp_generate_csc_matrix;
+
 static void                              *vdpau_lib_handle;
 /* output_surfaces[NUM_OUTPUT_SURFACES] is misused for OSD. */
 #define osd_surface output_surfaces[NUM_OUTPUT_SURFACES]
@@ -193,6 +195,9 @@
 static int eosd_render_count;
 static int eosd_surface_count;
 
+// Video equalizer
+static VdpProcamp procamp;
+
 /*
  * X11 specific
  */
@@ -339,6 +344,7 @@
                         &vdp_bitmap_surface_putbits_native},
         {VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_BITMAP_SURFACE,
                         &vdp_output_surface_render_bitmap_surface},
+        {VDP_FUNC_ID_GENERATE_CSC_MATRIX,       &vdp_generate_csc_matrix},
         {0, NULL}
     };
 
@@ -1018,9 +1024,55 @@
     eosd_surfaces = NULL;
     eosd_targets  = NULL;
 
+    procamp.struct_version = VDP_PROCAMP_VERSION;
+    procamp.brightness = 0.0;
+    procamp.contrast   = 1.0;
+    procamp.saturation = 1.0;
+    procamp.hue        = 0.0;
+
     return 0;
 }
 
+static int get_equalizer(char *name, int *value) {
+    if (!strcasecmp(name, "brightness"))
+        *value = procamp.brightness * 100;
+    else if (!strcasecmp(name, "contrast"))
+        *value = (procamp.contrast-1.0) * 100;
+    else if (!strcasecmp(name, "saturation"))
+        *value = (procamp.saturation-1.0) * 100;
+    else if (!strcasecmp(name, "hue"))
+        *value = procamp.hue * 100 / 3.141592;
+    else
+        return VO_NOTIMPL;
+    return VO_TRUE;
+}
+
+static int set_equalizer(char *name, int value) {
+    VdpStatus vdp_st;
+    VdpCSCMatrix matrix;
+    VdpVideoMixerAttribute attributes[] = {VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX};
+    const void *attribute_values[] = {&matrix};
+
+    if (!strcasecmp(name, "brightness"))
+        procamp.brightness = value / 100.0;
+    else if (!strcasecmp(name, "contrast"))
+        procamp.contrast = value / 100.0 + 1.0;
+    else if (!strcasecmp(name, "saturation"))
+        procamp.saturation = value / 100.0 + 1.0;
+    else if (!strcasecmp(name, "hue"))
+        procamp.hue = value / 100.0 * 3.141592;
+    else
+        return VO_NOTIMPL;
+
+    vdp_st = vdp_generate_csc_matrix(&procamp, VDP_COLOR_STANDARD_ITUR_BT_601,
+                                     &matrix);
+    CHECK_ST_WARNING("Error when generating CSC matrix")
+    vdp_st = vdp_video_mixer_set_attribute_values(video_mixer, 1, attributes,
+                                                  attribute_values);
+    CHECK_ST_WARNING("Error when setting CSC matrix")
+    return VO_TRUE;
+}
+
 static int control(uint32_t request, void *data, ...)
 {
     switch (request) {
@@ -1065,7 +1117,7 @@
             value = va_arg(ap, int);
 
             va_end(ap);
-            return vo_x11_set_equalizer(data, value);
+            return set_equalizer(data, value);
         }
         case VOCTRL_GET_EQUALIZER: {
             va_list ap;
@@ -1075,7 +1127,7 @@
             value = va_arg(ap, int *);
 
             va_end(ap);
-            return vo_x11_get_equalizer(data, value);
+            return get_equalizer(data, value);
         }
         case VOCTRL_ONTOP:
             vo_x11_ontop();