changeset 6781:924263b4df10

eq reworked
author alex
date Wed, 24 Jul 2002 18:19:39 +0000
parents 5bf3ed8a17c4
children be9ab9dcd653
files libvo/video_out.c libvo/video_out.h libvo/vo_xv.c mplayer.c
diffstat 4 files changed, 142 insertions(+), 302 deletions(-) [+]
line wrap: on
line diff
--- a/libvo/video_out.c	Wed Jul 24 18:14:21 2002 +0000
+++ b/libvo/video_out.c	Wed Jul 24 18:19:39 2002 +0000
@@ -63,16 +63,7 @@
 
 char *vo_subdevice = NULL;
 int vo_directrendering=0;
-/****************************************
-*	GAMMA CORRECTION		*
-****************************************/
-int vo_gamma_brightness=-101;
-int vo_gamma_saturation=-101;
-int vo_gamma_contrast=-101;
-int vo_gamma_hue=-101;
-int vo_gamma_red_intensity=0;
-int vo_gamma_green_intensity=0;
-int vo_gamma_blue_intensity=0;
+
 //
 // Externally visible list of all vo drivers
 //
--- a/libvo/video_out.h	Wed Jul 24 18:14:21 2002 +0000
+++ b/libvo/video_out.h	Wed Jul 24 18:19:39 2002 +0000
@@ -3,6 +3,7 @@
  *
  *      Copyright (C) Aaron Holtzman - Aug 1999
  *	Strongly modified, most parts rewritten: A'rpi/ESP-team - 2000-2001
+ *	(C) MPlayer Developers
  *
  */
  
@@ -22,7 +23,7 @@
 
 /* takes a pointer to a vo_vaa_s struct */
 #define VOCTRL_QUERY_VAA 1
-/* takes a pointer to uint32_t fourcc */
+/* does the device support the required format */
 #define VOCTRL_QUERY_FORMAT 2
 /* signal a device reset seek */
 #define VOCTRL_RESET 3
@@ -30,7 +31,6 @@
 #define VOCTRL_GUISUPPORT 4
 /* used to switch to fullscreen */
 #define VOCTRL_FULLSCREEN 5
-/* user wants to have screen shot. (currently without args)*/
 #define VOCTRL_SCREENSHOT 6
 /* signal a device pause */
 #define VOCTRL_PAUSE 7
@@ -46,6 +46,9 @@
 #define VOCTRL_SET_FRAME_NUM  12
 #define VOCTRL_GET_PANSCAN 15
 #define VOCTRL_SET_PANSCAN 16
+/* equalizer controls */
+#define VOCTRL_SET_EQUALIZER 17
+#define VOCTRL_GET_EQUALIZER 18
 
 #define VO_TRUE		1
 #define VO_FALSE	0
--- a/libvo/vo_xv.c	Wed Jul 24 18:14:21 2002 +0000
+++ b/libvo/vo_xv.c	Wed Jul 24 18:19:39 2002 +0000
@@ -61,12 +61,10 @@
 {
         "X11/Xv",
         "xv",
-        "Gerd Knorr <kraxel@goldbach.in-berlin.de>",
+        "Gerd Knorr <kraxel@goldbach.in-berlin.de> and others",
         ""
 };
 
-extern int verbose;
-
 /* local data */
 static unsigned char *ImageData;
 
@@ -101,9 +99,7 @@
 static int Shmem_Flag;
 #endif
 
-//static int Quiet_Flag; <-- What is that for ? Albeu.
 static int gXErrorFlag;
-static int CompletionType = -1;
 
 static uint32_t image_width;
 static uint32_t image_height;
@@ -140,13 +136,16 @@
 static void draw_alpha_null(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){
 }
 
-static int __xv_set_video_eq( const vidix_video_eq_t *info,int use_reset)
+static int xv_set_eq(char *name, int value, int use_reset)
 {
- XvAttribute *attributes;
- int howmany, xv_min,xv_max,xv_atomka;
- static int was_reset = 0;
-/* get available attributes */
-     attributes = XvQueryPortAttributes(mDisplay, xv_port, &howmany);
+    XvAttribute *attributes;
+    int howmany, xv_min, xv_max, xv_atom;
+    static int was_reset = 0;
+
+    mp_dbg(MSGT_VO, MSGL_V, "xv_set_eq called! (%s, %d, %d)\n", name, value, use_reset);
+
+    /* get available attributes */
+    attributes = XvQueryPortAttributes(mDisplay, xv_port, &howmany);
      /* first pass try reset */
      if(use_reset)
      {
@@ -156,12 +155,12 @@
             {
 		was_reset = 1;
 		mp_msg(MSGT_VO,MSGL_V,"vo_xv: reset gamma correction\n");
-                xv_atomka = XInternAtom(mDisplay, attributes[i].name, True);
-                XvSetPortAttribute(mDisplay, xv_port, xv_atomka, attributes[i].max_value);
+                xv_atom = XInternAtom(mDisplay, attributes[i].name, True);
+                XvSetPortAttribute(mDisplay, xv_port, xv_atom, attributes[i].max_value);
 	    }
         }
 	/* for safety purposes */
-	if(!was_reset) return ENOSYS;
+	if(!was_reset) return(VO_FALSE);
      }
      for (i = 0; i < howmany && attributes; i++)
      {
@@ -169,40 +168,41 @@
             {
                 xv_min = attributes[i].min_value;
                 xv_max = attributes[i].max_value;
-                xv_atomka = XInternAtom(mDisplay, attributes[i].name, True);
+                xv_atom = XInternAtom(mDisplay, attributes[i].name, True);
 /* since we have SET_DEFAULTS first in our list, we can check if it's available
    then trigger it if it's ok so that the other values are at default upon query */
-                if (xv_atomka != None)
+                if (xv_atom != None)
                 {
 		    int hue = 0,port_value,port_min,port_max,port_mid;
-		    if(strcmp(attributes[i].name,"XV_BRIGHTNESS") == 0
-			      && (info->cap & VEQ_CAP_BRIGHTNESS))
-				port_value = info->brightness;
-		    else
-		    if(strcmp(attributes[i].name,"XV_SATURATION") == 0
-			      && (info->cap & VEQ_CAP_SATURATION))
-				port_value = info->saturation;
+
+		    if(!strcmp(attributes[i].name,"XV_BRIGHTNESS") &&
+			(!strcasecmp(name, "brightness")))
+				port_value = value;
 		    else
-		    if(strcmp(attributes[i].name,"XV_CONTRAST") == 0
-			      && (info->cap & VEQ_CAP_CONTRAST))
-				port_value = info->contrast;
+		    if(!strcmp(attributes[i].name,"XV_CONTRAST") &&
+			(!strcasecmp(name, "contrast")))
+				port_value = value;
 		    else
-		    if(strcmp(attributes[i].name,"XV_HUE") == 0
-			      && (info->cap & VEQ_CAP_HUE))
-				{ port_value = info->hue; hue=1; }
+		    if(!strcmp(attributes[i].name,"XV_SATURATION") &&
+			(!strcasecmp(name, "saturation")))
+				port_value = value;
+		    else
+		    if(!strcmp(attributes[i].name,"XV_HUE") &&
+			(!strcasecmp(name, "hue")))
+				{ port_value = value; hue=1; }
 		    else
                     /* Note: since 22.01.2002 GATOS supports these attrs for radeons (NK) */
-		    if(strcmp(attributes[i].name,"XV_RED_INTENSITY") == 0
-			      && (info->cap & VEQ_CAP_RGB_INTENSITY))
-				port_value = info->red_intensity;
+		    if(!strcmp(attributes[i].name,"XV_RED_INTENSITY") &&
+			(!strcasecmp(name, "red_intensity")))
+				port_value = value;
 		    else
-		    if(strcmp(attributes[i].name,"XV_GREEN_INTENSITY") == 0
-			      && (info->cap & VEQ_CAP_RGB_INTENSITY))
-				port_value = info->green_intensity;
+		    if(!strcmp(attributes[i].name,"XV_GREEN_INTENSITY") &&
+			(!strcasecmp(name, "green_intensity")))
+				port_value = value;
 		    else
-		    if(strcmp(attributes[i].name,"XV_BLUE_INTENSITY") == 0
-			      && (info->cap & VEQ_CAP_RGB_INTENSITY))
-				port_value = info->blue_intensity;
+		    if(!strcmp(attributes[i].name,"XV_BLUE_INTENSITY") &&
+			(!strcasecmp(name, "blue_intensity")))
+				port_value = value;
 		    else continue;
 		    /* means that user has untouched this parameter since
 		       NVidia driver has default == min for XV_HUE but not mid */
@@ -211,130 +211,21 @@
 		    port_max = xv_max;
 		    port_mid = (port_min + port_max) / 2;
 
+		    /* nvidia hue workaround */
 		    if ( hue && port_min == 0 && port_max == 360 )
 		     {
 		      port_value=( port_value * port_mid ) / 1000;
 		      if ( port_value < 0 ) port_value+=port_max - 1;
 		     } else port_value = port_mid + (port_value * (port_max - port_min)) / 2000;
-		    
-                    XvSetPortAttribute(mDisplay, xv_port, xv_atomka, port_value);
+		     
+                    XvSetPortAttribute(mDisplay, xv_port, xv_atom, port_value);
+		    return(VO_TRUE);
                 }
         }
     }
-    return 0;
-}
-
-
-static int xv_set_video_eq( const vidix_video_eq_t *info)
-{
-    return __xv_set_video_eq(info,0);
+    return(VO_FALSE);
 }
 
-static int xv_get_video_eq( vidix_video_eq_t *info)
-{
- XvAttribute *attributes;
- int howmany, xv_min,xv_max,xv_atomka;
-/* get available attributes */
-     memset(info,0,sizeof(vidix_video_eq_t));
-     attributes = XvQueryPortAttributes(mDisplay, xv_port, &howmany);
-     for (i = 0; i < howmany && attributes; i++)
-     {
-            if (attributes[i].flags & XvGettable)
-            {
-                xv_min = attributes[i].min_value;
-                xv_max = attributes[i].max_value;
-                xv_atomka = XInternAtom(mDisplay, attributes[i].name, True);
-/* since we have SET_DEFAULTS first in our list, we can check if it's available
-   then trigger it if it's ok so that the other values are at default upon query */
-                if (xv_atomka != None)
-                {
-		    int value,port_value,port_min,port_max,port_mid;
-                    XvGetPortAttribute(mDisplay, xv_port, xv_atomka, &port_value);
-		    mp_msg(MSGT_VO,MSGL_V,"vo_xv: get: %s = %i\n",attributes[i].name,port_value);
-
-		    port_min = xv_min;
-		    port_max = xv_max;
-		    port_mid = (port_min + port_max) / 2;
-		    
-                    value = ((port_value - port_mid)*2000)/(port_max-port_min);
-		    
-		    mp_msg(MSGT_VO,MSGL_V,"vo_xv: assume: %s = %i\n",attributes[i].name,port_value);
-		    
-		    if(strcmp(attributes[i].name,"XV_BRIGHTNESS") == 0)
-		    {
-			info->cap |= VEQ_CAP_BRIGHTNESS;
-			info->brightness = value;
-		    }
-		    else
-		    if(strcmp(attributes[i].name,"XV_SATURATION") == 0)
-		    {
-			info->cap |= VEQ_CAP_SATURATION;
-			info->saturation = value;
-		    }
-		    else
-		    if(strcmp(attributes[i].name,"XV_CONTRAST") == 0)
-		    {
-			info->cap |= VEQ_CAP_CONTRAST;
-			info->contrast = value;
-		    }
-		    else
-		    if(strcmp(attributes[i].name,"XV_HUE") == 0)
-		    {
-		        if ( port_min == 0 && port_max == 360 )
-		         {
-		          if ( port_value > port_mid - 1 ) value=( port_value - port_max + 1 ) * 1000 / port_mid;
-			   else value=port_value * 1000 / port_mid;
-		         }
-//		        mp_msg(MSGT_VO,MSGL_STATUS,"vo_xv: assume: %s = %d (%d)\n",attributes[i].name,value,port_value);
-			info->cap |= VEQ_CAP_HUE;
-			info->hue = value;
-		    }
-		    else
-                    /* Note: since 22.01.2002 GATOS supports these attrs for radeons (NK) */
-		    if(strcmp(attributes[i].name,"XV_RED_INTENSITY") == 0)
-		    {
-			info->cap |= VEQ_CAP_RGB_INTENSITY;
-			info->red_intensity = port_value;
-		    }
-		    else
-		    if(strcmp(attributes[i].name,"XV_GREEN_INTENSITY") == 0)
-		    {
-			info->cap |= VEQ_CAP_RGB_INTENSITY;
-			info->green_intensity = port_value;
-		    }
-		    else
-		    if(strcmp(attributes[i].name,"XV_BLUE_INTENSITY") == 0)
-		    {
-			info->cap |= VEQ_CAP_RGB_INTENSITY;
-			info->blue_intensity = port_value;
-		    }
-		    else continue;
-                }
-        }
-    }
-    return 0;
-}
-
-#if 0
-static void set_gamma_correction( void )
-{
-  vidix_video_eq_t info;
-  /* try all */
-  info.cap = VEQ_CAP_BRIGHTNESS | VEQ_CAP_CONTRAST | VEQ_CAP_SATURATION |
-	     VEQ_CAP_HUE | VEQ_CAP_RGB_INTENSITY;
-  info.flags = 0; /* doesn't matter for xv */
-  info.brightness = vo_gamma_brightness;
-  info.contrast = vo_gamma_contrast;
-  info.saturation = vo_gamma_saturation;
-  info.hue = vo_gamma_hue;
-  info.red_intensity = vo_gamma_red_intensity;
-  info.green_intensity = vo_gamma_green_intensity;
-  info.blue_intensity = vo_gamma_blue_intensity;
-  /* reset with XV_SET_DEFAULTS only once */
-  __xv_set_video_eq(&info,1);
-}
-#endif
-
 /*
  * connect to server, create and map window,
  * allocate colors and (shared) memory
@@ -897,19 +788,9 @@
     return 0;
 }
 
-static void query_vaa(vo_vaa_t *vaa)
-{
-  memset(vaa,0,sizeof(vo_vaa_t));
-  vaa->get_video_eq = xv_get_video_eq;
-  vaa->set_video_eq = xv_set_video_eq;
-}
-
 static uint32_t control(uint32_t request, void *data, ...)
 {
   switch (request) {
-  case VOCTRL_QUERY_VAA:
-    query_vaa((vo_vaa_t*)data);
-    return VO_TRUE;
   case VOCTRL_QUERY_FORMAT:
     return query_format(*((uint32_t*)data));
   case VOCTRL_GET_IMAGE:
@@ -937,6 +818,17 @@
        }
      }
     return VO_TRUE;
+  case VOCTRL_SET_EQUALIZER:
+  {
+    va_list ap;
+    int value;
+    
+    va_start(ap, data);
+    value = va_arg(ap, int);
+    va_end(ap);
+    
+    return(xv_set_eq(data, value, 0));
+  }
   }
   return VO_NOTIMPL;
 }
--- a/mplayer.c	Wed Jul 24 18:14:21 2002 +0000
+++ b/mplayer.c	Wed Jul 24 18:19:39 2002 +0000
@@ -269,36 +269,11 @@
 
 char* current_module=NULL; // for debugging
 
-int v_hw_equ_cap=0;
-/*
-For future:
-int v_red_intensity=0;
-int v_green_intensity=0;
-int v_blue_intensity=0;
-*/
-
-void set_video_eq( int cap )
-{
- mp_cmd_t    * mp_cmd;
- 
- v_hw_equ_cap=cap;
- 
- mp_cmd = (mp_cmd_t *)calloc( 1,sizeof( *mp_cmd ) );
-  mp_cmd->id=MP_CMD_CONTRAST; mp_cmd->name=strdup( "contrast" ); 
-  mp_cmd->args[0].v.i=vo_gamma_contrast; mp_cmd->args[1].v.i=1; mp_input_queue_cmd( mp_cmd );
-
- mp_cmd = (mp_cmd_t *)calloc( 1,sizeof( *mp_cmd ) );
-  mp_cmd->id=MP_CMD_BRIGHTNESS; mp_cmd->name=strdup( "brightness" );
-  mp_cmd->args[0].v.i=vo_gamma_brightness; mp_cmd->args[1].v.i=1; mp_input_queue_cmd( mp_cmd );
-
- mp_cmd = (mp_cmd_t *)calloc( 1,sizeof( *mp_cmd ) );
-  mp_cmd->id=MP_CMD_HUE;        mp_cmd->name=strdup( "hue" );
-  mp_cmd->args[0].v.i=vo_gamma_hue; mp_cmd->args[1].v.i=1; mp_input_queue_cmd( mp_cmd );
-
- mp_cmd = (mp_cmd_t *)calloc( 1,sizeof( *mp_cmd ) );
-  mp_cmd->id=MP_CMD_SATURATION; mp_cmd->name=strdup( "saturation" );
-  mp_cmd->args[0].v.i=vo_gamma_saturation; mp_cmd->args[1].v.i=1; mp_input_queue_cmd( mp_cmd );
-}
+int vo_gamma_brightness = 0;
+int vo_gamma_contrast = 0;
+int vo_gamma_saturation = 0;
+int vo_gamma_hue = 0;
+
 // ---
 
 #ifdef HAVE_RTC
@@ -1354,37 +1329,12 @@
 
 // ========== Init display (sh_video->disp_w*sh_video->disp_h/out_fmt) ============
 
-current_module="init_vo_vaa";
-
-   if(video_out->control(VOCTRL_QUERY_VAA, &vo_vaa)==VO_NOTIMPL)
-     memset(&vo_vaa,0,sizeof(vo_vaa_t));
-   /*
-	get_hw_eq
-   */
-   if(vo_vaa.get_video_eq)
-   {
-	vidix_video_eq_t veq;
-	if( vo_vaa.get_video_eq(&veq) == 0)
-	{
-	    v_hw_equ_cap = veq.cap;
-	    if ( ( vo_gamma_brightness == -101 )&&( veq.cap & VEQ_CAP_BRIGHTNESS ) ) vo_gamma_brightness = veq.brightness / 10;
-	    if ( ( vo_gamma_contrast == -101 )&&( veq.cap & VEQ_CAP_CONTRAST ) ) vo_gamma_contrast = veq.contrast / 10;
-	    if ( ( vo_gamma_hue == -101 )&&( veq.cap & VEQ_CAP_HUE ) ) vo_gamma_hue = veq.hue / 10;
-	    if ( ( vo_gamma_saturation == -101 )&&( veq.cap & VEQ_CAP_SATURATION ) ) vo_gamma_saturation=veq.saturation / 10;
-	    /*
-	    v_red_intensity=veq.red_intensity/10;
-	    v_green_intensity=veq.green_intensity/10;
-	    v_blue_intensity=veq.blue_intensity/10;
-	    */
-	}
-   }
-
-   if ( vo_gamma_brightness == -101 ) vo_gamma_brightness=0.0f;
-   if ( vo_gamma_contrast == -101 ) vo_gamma_contrast=0.0f;
-   if ( vo_gamma_hue == -101 ) vo_gamma_hue=0.0f;
-   if ( vo_gamma_saturation == -101 ) vo_gamma_saturation=0.0f;
-
-   set_video_eq( v_hw_equ_cap );
+current_module="init_vo";
+    /* set defaults */
+    set_video_colors(sh_video, "brightness", vo_gamma_brightness);
+    set_video_colors(sh_video, "contrast", vo_gamma_contrast);
+    set_video_colors(sh_video, "saturation", vo_gamma_saturation);
+    set_video_colors(sh_video, "hue", vo_gamma_hue);
 
    if(vo_flags & 0x08 && vo_spudec)
       spudec_set_hw_spu(vo_spudec,video_out);
@@ -2439,40 +2389,19 @@
     }
     case MP_CMD_MIXER_USEMASTER :  {
     } break;
-    case MP_CMD_CONTRAST :  {
-      int v = cmd->args[0].v.i, abs = cmd->args[1].v.i;
-      int e;
-      if(abs)
-	vo_gamma_contrast = v > 100 ? 100 : v;
-      else {
-	if ( (vo_gamma_contrast += v) > 100 ) vo_gamma_contrast = 100;
-      }
-      if(vo_gamma_contrast < -100) vo_gamma_contrast = -100;
-      if(v_hw_equ_cap & VEQ_CAP_CONTRAST) e=vo_gamma_contrast;
-        else e=( vo_gamma_contrast + 100 ) / 2;
-      if(set_video_colors(sh_video,"Contrast",e)){
-#ifdef USE_OSD
-	if(osd_level){
-	  osd_visible=sh_video->fps; // 1 sec
-	  vo_osd_progbar_type=OSD_CONTRAST;
-	  vo_osd_progbar_value=(vo_gamma_contrast<<7)/100 + 128;
-	  vo_osd_changed(OSDTYPE_PROGBAR);
-	}
-#endif
-      }
-    } break;
     case MP_CMD_BRIGHTNESS :  {
       int v = cmd->args[0].v.i, abs = cmd->args[1].v.i;
-      int e;
-      if(abs)
-	vo_gamma_brightness = v > 100 ? 100 : v;
-      else {
-	if ( (vo_gamma_brightness += v) > 100 ) vo_gamma_brightness = 100;
-      }
-      if ( vo_gamma_brightness < -100 ) vo_gamma_brightness = -100;
-      if ( v_hw_equ_cap & VEQ_CAP_BRIGHTNESS ) e=vo_gamma_brightness;
-       else e=( vo_gamma_brightness + 100 ) / 2;
-      if(set_video_colors(sh_video,"Brightness",e)){
+     
+      if (abs)
+        vo_gamma_brightness = v;
+      else
+        vo_gamma_brightness += v;
+
+      if (vo_gamma_brightness > 100)
+        vo_gamma_brightness = 100;
+      else if (vo_gamma_brightness < -100)
+        vo_gamma_brightness = -100;
+      if(set_video_colors(sh_video, "brightness", vo_gamma_brightness)){
 #ifdef USE_OSD
        if(osd_level){
 	 osd_visible=sh_video->fps; // 1 sec
@@ -2483,48 +2412,73 @@
 #endif // USE_OSD
       }
     } break;
-    case MP_CMD_HUE :  {
+    case MP_CMD_CONTRAST :  {
       int v = cmd->args[0].v.i, abs = cmd->args[1].v.i;
-      int e;
-      if(abs)
-	vo_gamma_hue = v > 100 ? 100 : v;
-      else {
-	if ( (vo_gamma_hue += v) > 100 ) vo_gamma_hue = 100;
+     
+      if (abs)
+        vo_gamma_contrast = v;
+      else
+        vo_gamma_contrast += v;
+
+      if (vo_gamma_contrast > 100)
+        vo_gamma_contrast = 100;
+      else if (vo_gamma_contrast < -100)
+        vo_gamma_contrast = -100;
+      if(set_video_colors(sh_video, "contrast", vo_gamma_contrast)){
+#ifdef USE_OSD
+       if(osd_level){
+	 osd_visible=sh_video->fps; // 1 sec
+	 vo_osd_progbar_type=OSD_CONTRAST;
+	 vo_osd_progbar_value=(vo_gamma_contrast<<7)/100 + 128;
+	 vo_osd_changed(OSDTYPE_PROGBAR);
+       }
+#endif // USE_OSD
       }
-      if ( vo_gamma_hue < -100 ) vo_gamma_hue = -100;
-      if(v_hw_equ_cap & VEQ_CAP_HUE) e=vo_gamma_hue;
-        else e=( vo_gamma_hue + 100 ) / 2;
-      if(set_video_colors(sh_video,"Hue",e)){
-#ifdef USE_OSD
-	if(osd_level){
-	  osd_visible=sh_video->fps; // 1 sec
-	  vo_osd_progbar_type=OSD_HUE;
-	  vo_osd_progbar_value=(vo_gamma_hue<<7)/100 + 128;
-	  vo_osd_changed(OSDTYPE_PROGBAR);
-	}
-#endif
-      }	
     } break;
     case MP_CMD_SATURATION :  {
       int v = cmd->args[0].v.i, abs = cmd->args[1].v.i;
-      int e;
-      if(abs)
-	vo_gamma_saturation = v > 100 ? 100 : v;
-      else {
-	if ( (vo_gamma_saturation += v) > 100 ) vo_gamma_saturation = 100;
+     
+      if (abs)
+        vo_gamma_saturation = v;
+      else
+        vo_gamma_saturation += v;
+
+      if (vo_gamma_saturation > 100)
+        vo_gamma_saturation = 100;
+      else if (vo_gamma_saturation < -100)
+        vo_gamma_saturation = -100;
+      if(set_video_colors(sh_video, "saturation", vo_gamma_saturation)){
+#ifdef USE_OSD
+       if(osd_level){
+	 osd_visible=sh_video->fps; // 1 sec
+	 vo_osd_progbar_type=OSD_SATURATION;
+	 vo_osd_progbar_value=(vo_gamma_saturation<<7)/100 + 128;
+	 vo_osd_changed(OSDTYPE_PROGBAR);
+       }
+#endif // USE_OSD
       }
-      if ( vo_gamma_saturation < -100 ) vo_gamma_saturation = -100;
-      if(v_hw_equ_cap & VEQ_CAP_SATURATION) e=vo_gamma_saturation;
-        else e=( vo_gamma_saturation + 100 ) / 2;
-      if(set_video_colors(sh_video,"Saturation",e)){
+    } break;
+    case MP_CMD_HUE :  {
+      int v = cmd->args[0].v.i, abs = cmd->args[1].v.i;
+     
+      if (abs)
+        vo_gamma_hue = v;
+      else
+        vo_gamma_hue += v;
+
+      if (vo_gamma_hue > 100)
+        vo_gamma_hue = 100;
+      else if (vo_gamma_hue < -100)
+        vo_gamma_hue = -100;
+      if(set_video_colors(sh_video, "hue", vo_gamma_hue)){
 #ifdef USE_OSD
-	if(osd_level){
-	  osd_visible=sh_video->fps; // 1 sec
-	  vo_osd_progbar_type=OSD_SATURATION;
-	  vo_osd_progbar_value=(vo_gamma_saturation<<7)/100 + 128;
-	  vo_osd_changed(OSDTYPE_PROGBAR);
-	}
-#endif
+       if(osd_level){
+	 osd_visible=sh_video->fps; // 1 sec
+	 vo_osd_progbar_type=OSD_HUE;
+	 vo_osd_progbar_value=(vo_gamma_hue<<7)/100 + 128;
+	 vo_osd_changed(OSDTYPE_PROGBAR);
+       }
+#endif // USE_OSD
       }
     } break;
     case MP_CMD_FRAMEDROPPING :  {