]> git.sesse.net Git - vlc/commitdiff
IMPORTANT:
authorVincent Seguin <seguin@videolan.org>
Sun, 6 Feb 2000 13:13:10 +0000 (13:13 +0000)
committerVincent Seguin <seguin@videolan.org>
Sun, 6 Feb 2000 13:13:10 +0000 (13:13 +0000)
p_vout->i_depth est maintenant la profondeur SIGNIFICATIVE de
l'�cran (8, 15, 16 ou 24)
p_vout->i_bytes_per_pixel est la profondeur r�elle (1, 2, 3 ou 4)

Ajout du calcul des d�calages � video_output.
Refonte de l'initialisation des tables.
D�tection correcte des profondeurs 24/24 et 24/32 en X11
Correction de bugs dans le scaling en 1, 3 et 4 Bpp.
R�cup�ration des masques depuis le materiel en X11 et GGI.

FrameBuffer cass� pour le moment: il faut rajouter les masques de couleur
(des valeurs par d�faut sont au d�but de video_yuv.c) et le calcul des
nouvelles profondeurs d'�cran.

include/video_output.h
src/video_output/video_ggi.c
src/video_output/video_output.c
src/video_output/video_text.c
src/video_output/video_x11.c
src/video_output/video_yuv.c

index ef4348eb12f23b4ff52a0365457808d39a3672ae..5ee33da9e22b036e27c08177ca7dd3b452c45cea 100644 (file)
@@ -103,10 +103,27 @@ typedef struct vout_thread_s
     int                 i_width;               /* current output method width */
     int                 i_height;             /* current output method height */
     int                 i_bytes_per_line;   /* bytes per line (incl. virtual) */
-    int                 i_screen_depth;                     /* bits per pixel */
-    int                 i_bytes_per_pixel;               /* real screen depth */
+    int                 i_screen_depth;   /* significant bpp: 8, 15, 16 or 24 */
+    int                 i_bytes_per_pixel; /* real screen depth: 1, 2, 3 or 4 */
     float               f_gamma;                                     /* gamma */
 
+    /* Color masks and shifts in RGB mode - masks are set by system 
+     * initialization, shifts are calculated. A pixel color value can be 
+     * obtained using the formula ((value >> rshift) << lshift) */
+    u32                 i_red_mask;                               /* red mask */
+    u32                 i_green_mask;                           /* green mask */
+    u32                 i_blue_mask;                             /* blue mask */
+    int                 i_red_lshift, i_red_rshift;             /* red shifts */
+    int                 i_green_lshift, i_green_rshift;       /* green shifts */
+    int                 i_blue_lshift, i_blue_rshift;          /* blue shifts */
+
+    /* Usefull pre-calculated pixel values - these are not supposed to be 
+     * accurate values, but rather values looking nice, given their usage. */
+    u32                 i_white_pixel;                               /* white */
+    u32                 i_black_pixel;                               /* black */
+    u32                 i_gray_pixel;                                 /* gray */
+    u32                 i_blue_pixel;                                 /* blue */
+
     /* Pictures and rendering properties */
     boolean_t           b_grayscale;            /* color or grayscale display */
     boolean_t           b_info;             /* print additionnal informations */
@@ -151,6 +168,17 @@ typedef struct vout_thread_s
 #define VOUT_YUV_CHANGE         0x0800                   /* change yuv tables */
 #define VOUT_NODISPLAY_CHANGE   0xff00     /* changes which forbidden display */
 
+/*******************************************************************************
+ * Macros
+ *******************************************************************************/
+
+/* RGB2PIXEL: assemble RGB components to a pixel value, returns a u32 */
+#define RGB2PIXEL( p_vout, i_red, i_green, i_blue )                            \
+    (((((u32)i_red)   >> p_vout->i_red_rshift)   << p_vout->i_red_lshift)   |  \
+     ((((u32)i_green) >> p_vout->i_green_rshift) << p_vout->i_green_lshift) |  \
+     ((((u32)i_blue)  >> p_vout->i_blue_rshift)  << p_vout->i_blue_lshift))
+
+
 /*******************************************************************************
  * Prototypes
  *******************************************************************************/
@@ -169,3 +197,4 @@ void            vout_DestroySubPicture  ( vout_thread_t *p_vout, subpicture_t *p
 void            vout_DisplaySubPicture  ( vout_thread_t *p_vout, subpicture_t *p_subpic );
 
 void            vout_SetBuffers         ( vout_thread_t *p_vout, void *p_buf1, void *p_buf2 );
+
index cce62907652d522a932cd0fb000a5afe57325686..2438e87549699f978f4d550cee918375b35cb3f4 100644 (file)
@@ -119,6 +119,7 @@ void vout_SysDestroy( vout_thread_t *p_vout )
  *******************************************************************************/
 int vout_SysManage( vout_thread_t *p_vout )
 {
+    //?? 8bpp: change palette
     return( 0 );    
 }
 
@@ -286,32 +287,13 @@ static int GGIOpenDisplay( vout_thread_t *p_vout, char *psz_display )
     p_vout->i_width =           mode.visible.x;    
     p_vout->i_height =          mode.visible.y;
     p_vout->i_bytes_per_line =  p_vout->p_sys->p_buffer[ 0 ]->buffer.plb.stride;    
-    switch( mode.graphtype )
-    {
-    case GT_15BIT:
-        p_vout->i_screen_depth =        15;
-        p_vout->i_bytes_per_pixel =     2;
-        break;        
-    case GT_16BIT:
-        p_vout->i_screen_depth =        16;
-        p_vout->i_bytes_per_pixel =     2;
-        break;        
-    case GT_24BIT:
-        p_vout->i_screen_depth =        24;
-        p_vout->i_bytes_per_pixel =     3;
-        break;        
-    case GT_32BIT:
-        p_vout->i_screen_depth =        32;
-        p_vout->i_bytes_per_pixel =     4;
-       break;        
-    default:
-        intf_ErrMsg("error: unsupported screen depth\n");        
-        ggiClose( p_vout->p_sys->p_display );
-        ggiExit();        
-        return( 1 );        
-        break;        
-    }
-
+    p_vout->i_screen_depth =    p_vout->p_sys->p_buffer[ 0 ]->buffer.plb->pixelformat.depth;
+    p_vout->i_bytes_per_pixel = p_vout->p_sys->p_buffer[ 0 ]->buffer.plb->pixelformat.size / 8;    
+    p_vout->i_red_mask =        p_vout->p_sys->p_buffer[ 0 ]->buffer.plb->pixelformat.red_mask;
+    p_vout->i_green_mask =      p_vout->p_sys->p_buffer[ 0 ]->buffer.plb->pixelformat.green_mask;
+    p_vout->i_blue_mask =       p_vout->p_sys->p_buffer[ 0 ]->buffer.plb->pixelformat.blue_mask;            
+    //?? palette in 8bpp
+    
     /* Set and initialize buffers */
     vout_SetBuffers( p_vout, p_vout->p_sys->p_buffer[ 0 ]->write, p_vout->p_sys->p_buffer[ 1 ]->write );
 
index 9d226d655a08320afef0a94928b423dc755ade5d..ec4fa366996a3485a10b1453c25230a8c8844db3 100644 (file)
@@ -30,6 +30,8 @@
 /******************************************************************************
  * Local prototypes
  ******************************************************************************/
+static int      BinaryLog         ( u32 i );
+static void     MaskToShift       ( int *pi_left, int *pi_right, u32 i_mask );
 static int      InitThread        ( vout_thread_t *p_vout );
 static void     RunThread         ( vout_thread_t *p_vout );
 static void     ErrorThread       ( vout_thread_t *p_vout );
@@ -95,15 +97,14 @@ vout_thread_t * vout_CreateThread               ( char *psz_display, int i_root_
     p_vout->i_bytes_per_pixel   = 2;
     p_vout->f_gamma             = VOUT_GAMMA;    
 
-    p_vout->b_grayscale         = main_GetIntVariable( VOUT_GRAYSCALE_VAR, 
-                                                       VOUT_GRAYSCALE_DEFAULT );
+    p_vout->b_grayscale         = main_GetIntVariable( VOUT_GRAYSCALE_VAR, VOUT_GRAYSCALE_DEFAULT );
     p_vout->b_info              = 0;    
     p_vout->b_interface         = 0;
     p_vout->b_scale             = 0;
     
-    intf_DbgMsg("wished configuration: %dx%d,%d (%d bytes/pixel, %d bytes/line)\n",
+    intf_DbgMsg("wished configuration: %dx%d, %d/%d bpp (%d Bpl)\n",
                 p_vout->i_width, p_vout->i_height, p_vout->i_screen_depth,
-                p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line );
+                p_vout->i_bytes_per_pixel * 8, p_vout->i_bytes_per_line );
 
     /* Initialize idle screen */
     p_vout->last_display_date   = mdate();
@@ -135,9 +136,21 @@ vout_thread_t * vout_CreateThread               ( char *psz_display, int i_root_
       free( p_vout );
       return( NULL );
     }
-    intf_DbgMsg("actual configuration: %dx%d,%d (%d bytes/pixel, %d bytes/line)\n",
+    intf_DbgMsg("actual configuration: %dx%d, %d/%d bpp (%d Bpl), masks: 0x%x/0x%x/0x%x\n",
                 p_vout->i_width, p_vout->i_height, p_vout->i_screen_depth,
-                p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line );
+                p_vout->i_bytes_per_pixel * 8, p_vout->i_bytes_per_line,
+                p_vout->i_red_mask, p_vout->i_green_mask, p_vout->i_blue_mask );
+
+    /* Calculate shifts from system-updated masks */
+    MaskToShift( &p_vout->i_red_lshift,   &p_vout->i_red_rshift,   p_vout->i_red_mask );
+    MaskToShift( &p_vout->i_green_lshift, &p_vout->i_green_rshift, p_vout->i_green_mask );
+    MaskToShift( &p_vout->i_blue_lshift,  &p_vout->i_blue_rshift,  p_vout->i_blue_mask );
+
+    /* Set some usefull colors */
+    p_vout->i_white_pixel = RGB2PIXEL( p_vout, 255, 255, 255 );
+    p_vout->i_black_pixel = RGB2PIXEL( p_vout, 0, 0, 0 );
+    p_vout->i_gray_pixel  = RGB2PIXEL( p_vout, 128, 128, 128 );
+    p_vout->i_blue_pixel  = RGB2PIXEL( p_vout, 0, 0, 50 );    
 
     /* Load fonts - fonts must be initialized after the systme method since
      * they may be dependant of screen depth and other thread properties */
@@ -172,8 +185,8 @@ vout_thread_t * vout_CreateThread               ( char *psz_display, int i_root_
         return( NULL );
     }   
 
-    intf_Msg("Video display initialized (%dx%d, %d bpp)\n"
-             p_vout->i_width, p_vout->i_height, p_vout->i_screen_depth );    
+    intf_Msg("Video display initialized (%dx%d, %d/%d bpp)\n", p_vout->i_width
+             p_vout->i_height, p_vout->i_screen_depth, p_vout->i_bytes_per_pixel * 8 );
 
     /* If status is NULL, wait until the thread is created */
     if( pi_status == NULL )
@@ -717,8 +730,82 @@ void vout_SetBuffers( vout_thread_t *p_vout, void *p_buf1, void *p_buf2 )
     p_vout->p_buffer[1].p_data = p_buf2;    
 }
 
+/*****************************************************************************
+ * vout_Pixel2RGB: return red, green and blue from pixel value
+ *****************************************************************************
+ * Return color values, in 0-255 range, of the decomposition of a pixel. This
+ * is a slow routine and should only be used for initialization phase.
+ *****************************************************************************/
+void vout_Pixel2RGB( vout_thread_t *p_vout, u32 i_pixel, int *pi_red, int *pi_green, int *pi_blue )
+{
+    *pi_red =   i_pixel & p_vout->i_red_mask;
+    *pi_green = i_pixel & p_vout->i_green_mask;
+    *pi_blue =  i_pixel & p_vout->i_blue_mask;
+}
+
 /* following functions are local */
 
+/*****************************************************************************
+ * BinaryLog: computes the base 2 log of a binary value
+ *****************************************************************************
+ * This functions is used by MaskToShift, to get a bit index from a binary 
+ * value.
+ *****************************************************************************/
+static int BinaryLog(u32 i)
+{
+    int i_log;
+
+    i_log = 0;
+    if (i & 0xffff0000) 
+    {        
+        i_log = 16;
+    }    
+    if (i & 0xff00ff00) 
+    {        
+        i_log += 8;
+    }    
+    if (i & 0xf0f0f0f0) 
+    {        
+        i_log += 4;
+    }    
+    if (i & 0xcccccccc) 
+    {        
+        i_log += 2;
+    }    
+    if (i & 0xaaaaaaaa) 
+    {        
+        i_log++;
+    }    
+    if (i != ((u32)1 << i_log))
+    {        
+       intf_ErrMsg("internal error: binary log overflow\n");        
+    }    
+
+    return( i_log );
+}
+
+/*****************************************************************************
+ * MaskToShift: transform a color mask into right and left shifts
+ *****************************************************************************
+ * This function is used for obtaining color shifts from masks.
+ *****************************************************************************/
+static void MaskToShift( int *pi_left, int *pi_right, u32 i_mask )
+{
+    u32 i_low, i_high;                 /* lower hand higher bits of the mask */
+
+    /* Get bits */
+    i_low =  i_mask & (- i_mask);                   /* lower bit of the mask */
+    i_high = i_mask + i_low;                       /* higher bit of the mask */
+
+    /* Transform bits into an index */
+    i_low =  BinaryLog (i_low);
+    i_high = BinaryLog (i_high);
+
+    /* Update pointers and return */
+    *pi_left =   i_low;
+    *pi_right = (8 - i_high + i_low);
+}
+
 /******************************************************************************
  * InitThread: initialize video output thread
  ******************************************************************************
@@ -1093,7 +1180,8 @@ void Print( vout_thread_t *p_vout, int i_x, int i_y, int i_h_align, int i_v_alig
         vout_Print( p_vout->p_default_font, p_vout->p_buffer[ p_vout->i_buffer_index ].p_data + 
                     i_y * p_vout->i_bytes_per_line + i_x * p_vout->i_bytes_per_pixel,
                     p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line, 
-                    0xffffffff, 0x00000000, 0x00000000, 0, psz_text );
+                    p_vout->i_white_pixel, 0, 0, 
+                    0, psz_text );
     }    
 }
 
@@ -1397,34 +1485,6 @@ static void SetBufferPicture( vout_thread_t *p_vout, picture_t *p_pic )
      * Clear areas array
      */
     p_buffer->i_areas = 0;
-
-#ifdef DEBUG_VIDEO
-    /*
-     * In DEBUG_VIDEO mode, draw white pixels at the beginning and the end of
-     * the picture area. These pixels should not be erased by rendering functions,
-     * otherwise segmentation fault is menacing !
-     */
-    if( i_pic_x > 0 )
-    {
-        *(u16*)(p_buffer->p_data + p_vout->i_bytes_per_line * i_pic_y + 
-                p_vout->i_bytes_per_pixel * (i_pic_x - 1)) = 0xffff;
-    }
-    if( i_pic_y > 0 )
-    {
-        *(u16*)(p_buffer->p_data + p_vout->i_bytes_per_line * (i_pic_y - 1) + 
-                p_vout->i_bytes_per_pixel * i_pic_x ) = 0xffff;
-    }
-    if( i_pic_x + i_pic_width < p_vout->i_width )
-    {
-        *(u16*)(p_buffer->p_data + p_vout->i_bytes_per_line * (i_pic_y + i_pic_height - 1) + 
-                p_vout->i_bytes_per_pixel * (i_pic_x + i_pic_width) ) = 0xffff;
-    }    
-    if( i_pic_y + i_pic_height < p_vout->i_height )
-    {
-        *(u16*)(p_buffer->p_data + p_vout->i_bytes_per_line * (i_pic_y + i_pic_height) + 
-                p_vout->i_bytes_per_pixel * (i_pic_x + i_pic_width - 1) ) = 0xffff;
-    }    
-#endif
 }
 
 /******************************************************************************
@@ -1583,7 +1643,7 @@ static int RenderIdle( vout_thread_t *p_vout )
                         p_vout->p_buffer[ p_vout->i_buffer_index ].p_data +
                         i_x * p_vout->i_bytes_per_pixel + i_y * p_vout->i_bytes_per_line,
                         p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line,
-                        0xffffffff, 0x33333333, 0,
+                        p_vout->i_white_pixel, p_vout->i_gray_pixel, 0,
                         WIDE_TEXT | OUTLINED_TEXT, psz_text );        
             SetBufferArea( p_vout, i_x, i_y, i_width, i_height );
         }        
@@ -1683,7 +1743,7 @@ static void RenderInterface( vout_thread_t *p_vout )
 {
     int         i_height, i_text_height;              /* total and text height */
     int         i_width_1, i_width_2;                            /* text width */
-    int         i_byte;                                          /* byte index */    
+    int         i_byte;                                          /* byte index */
     const char *psz_text_1 = "[1-9] Channel   [i]nfo   [c]olor     [g/G]amma";
     const char *psz_text_2 = "[+/-] Volume    [m]ute   [s]caling   [Q]uit";    
 
@@ -1692,13 +1752,13 @@ static void RenderInterface( vout_thread_t *p_vout )
     vout_TextSize( p_vout->p_large_font, OUTLINED_TEXT, psz_text_2, &i_width_2, &i_text_height );
     i_height += i_text_height;
 
-    /* Render background - effective background color will depend of the screen
-     * depth */
+    /* Render background */
     for( i_byte = (p_vout->i_height - i_height) * p_vout->i_bytes_per_line;
          i_byte < p_vout->i_height * p_vout->i_bytes_per_line;
          i_byte++ )
     {
-        p_vout->p_buffer[ p_vout->i_buffer_index ].p_data[ i_byte ] = 0x33;        
+        //?? noooo !
+        p_vout->p_buffer[ p_vout->i_buffer_index ].p_data[ i_byte ] = p_vout->i_blue_pixel;
     }    
 
     /* Render text, if not larger than screen */
@@ -1707,7 +1767,7 @@ static void RenderInterface( vout_thread_t *p_vout )
         vout_Print( p_vout->p_large_font, p_vout->p_buffer[ p_vout->i_buffer_index ].p_data +
                     (p_vout->i_height - i_height) * p_vout->i_bytes_per_line,
                     p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line,
-                    0xffffffff, 0x00000000, 0x00000000,
+                    p_vout->i_white_pixel, p_vout->i_black_pixel, 0,
                     OUTLINED_TEXT, psz_text_1 );
     }
     if( i_width_2 < p_vout->i_width )
@@ -1715,7 +1775,7 @@ static void RenderInterface( vout_thread_t *p_vout )
         vout_Print( p_vout->p_large_font, p_vout->p_buffer[ p_vout->i_buffer_index ].p_data +
                     (p_vout->i_height - i_height + i_text_height) * p_vout->i_bytes_per_line,
                     p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line,
-                    0xffffffff, 0x00000000, 0x00000000,
+                    p_vout->i_white_pixel, p_vout->i_black_pixel, 0,
                     OUTLINED_TEXT, psz_text_2 );
     }    
 
index 9ecba36c091dca9a4468d6fa26e8962d96d6db4f..900ffce8b5c35c72fb9a370d1667727766e988a3 100644 (file)
@@ -60,8 +60,9 @@ typedef void (vout_put_byte_t)( void *p_pic, int i_byte, int i_char, int i_borde
  *******************************************************************************/
 
 /* PUT_BYTE_MASK: put pixels from a byte-wide mask. It uses a branching tree
- * to optimize the number of tests. It is used in the PutByte functions. */
-#define TREE( i_mask, i_mask_color )                                          \
+ * to optimize the number of tests. It is used in the PutByte functions. 
+ * This macro works for 1, 2 and 4 Bpp. */
+#define PUT_BYTE_MASK( i_mask, i_mask_color )                                 \
 if( i_mask & 0xf0 )                                       /* one from 1111 */ \
 {                                                                             \
     if( i_mask & 0xc0 )                                   /* one from 1100 */ \
@@ -364,17 +365,9 @@ void vout_Print( vout_font_t *p_font, byte_t *p_pic, int i_bytes_per_pixel, int
         p_PutByte = (vout_put_byte_t *) PutByte24;
         break;
     case 4:
-#ifndef DEBUG
     default:
-#endif
         p_PutByte = (vout_put_byte_t *) PutByte32;
         break;
-#ifdef DEBUG
-    default:
-        intf_DbgMsg("error: invalid bytes per pixel %d\n", i_bytes_per_pixel );
-        p_PutByte = NULL;
-        break;
-#endif
     }
 
     /* Choose masks and copy font data to local variables */
@@ -447,7 +440,7 @@ void vout_Print( vout_font_t *p_font, byte_t *p_pic, int i_bytes_per_pixel, int
 /* following functions are local */
 
 /*****************************************************************************
- * PutByte8: print a fixed width font character byte in 15 or 16 bpp
+ * PutByte8: print a fixed width font character byte in 1 Bpp
  *****************************************************************************/
 static void PutByte8( u8 *p_pic, int i_byte, int i_char, int i_border,
                        int i_bg, u32 i_char_color, u32 i_border_color,
@@ -458,13 +451,13 @@ static void PutByte8( u8 *p_pic, int i_byte, int i_char, int i_border,
     i_bg &= ~(i_char | i_border);
 
     /* Put character bits */
-    TREE(i_char, i_char_color);
-    TREE(i_border, i_border_color);
-    TREE(i_bg, i_bg_color);
+    PUT_BYTE_MASK(i_char, i_char_color);
+    PUT_BYTE_MASK(i_border, i_border_color);
+    PUT_BYTE_MASK(i_bg, i_bg_color);
 }
 
 /*****************************************************************************
- * PutByte16: print a fixed width font character byte in 15 or 16 bpp
+ * PutByte16: print a fixed width font character byte in 2 Bpp
  *****************************************************************************/
 static void PutByte16( u16 *p_pic, int i_byte, int i_char, int i_border,
                        int i_bg, u32 i_char_color, u32 i_border_color,
@@ -475,13 +468,13 @@ static void PutByte16( u16 *p_pic, int i_byte, int i_char, int i_border,
     i_bg &= ~(i_char | i_border);
 
     /* Put character bits */
-    TREE(i_char, i_char_color);
-    TREE(i_border, i_border_color);
-    TREE(i_bg, i_bg_color);
+    PUT_BYTE_MASK(i_char, i_char_color);
+    PUT_BYTE_MASK(i_border, i_border_color);
+    PUT_BYTE_MASK(i_bg, i_bg_color);
 }
 
 /*****************************************************************************
- * PutByte24: print a fixed width font character byte in 24 bpp
+ * PutByte24: print a fixed width font character byte in 3 Bpp
  *****************************************************************************/
 static void PutByte24( void *p_pic, int i_byte, byte_t i_char, byte_t i_border, byte_t i_bg, 
                        u32 i_char_color, u32 i_border_color, u32 i_bg_color )
@@ -490,7 +483,7 @@ static void PutByte24( void *p_pic, int i_byte, byte_t i_char, byte_t i_border,
 }
 
 /*****************************************************************************
- * PutByte32: print a fixed width font character byte in 32 bpp
+ * PutByte32: print a fixed width font character byte in 4 Bpp
  *****************************************************************************/
 static void PutByte32( u32 *p_pic, int i_byte, byte_t i_char, byte_t i_border, byte_t i_bg, 
                        u32 i_char_color, u32 i_border_color, u32 i_bg_color )
@@ -500,8 +493,8 @@ static void PutByte32( u32 *p_pic, int i_byte, byte_t i_char, byte_t i_border, b
     i_bg &= ~(i_char | i_border);
 
     /* Put character bits */
-    TREE(i_char, i_char_color);
-    TREE(i_border, i_border_color);
-    TREE(i_bg, i_bg_color);
+    PUT_BYTE_MASK(i_char, i_char_color);
+    PUT_BYTE_MASK(i_border, i_border_color);
+    PUT_BYTE_MASK(i_bg, i_bg_color);
 }
 
index 84ce73c308ba1b37ea5a8d82ad556ad5fb7cc001..61388b39e128934654fcd6b2db3218bf0eacefbd 100644 (file)
@@ -25,6 +25,7 @@
 #include "video.h"
 #include "video_output.h"
 #include "video_sys.h"
+#include "video_yuv.h"
 #include "intf_msg.h"
 
 /*******************************************************************************
 typedef struct vout_sys_s
 {
     /* User settings */
-    boolean_t           b_shm;                 /* shared memory extension flag */
+    boolean_t           b_shm;               /* shared memory extension flag */
 
     /* Internal settings and properties */
-    Display *           p_display;                          /* display pointer */
-    int                 i_screen;                             /* screen number */
-    Window              root_window;                            /* root window */
-    Window              window;                     /* window instance handler */
-    GC                  gc;                /* graphic context instance handler */    
+    Display *           p_display;                        /* display pointer */
+    Visual *            p_visual;                          /* visual pointer */    
+    int                 i_screen;                           /* screen number */
+    Window              root_window;                          /* root window */
+    Window              window;                   /* window instance handler */
+    GC                  gc;              /* graphic context instance handler */    
+    Colormap            colormap;               /* colormap used (8bpp only) */
 
     /* Display buffers and shared memory information */
-    XImage *            p_ximage[2];                         /* XImage pointer */   
-    XShmSegmentInfo     shm_info[2];         /* shared memory zone information */
+    XImage *            p_ximage[2];                       /* XImage pointer */   
+    XShmSegmentInfo     shm_info[2];       /* shared memory zone information */
 } vout_sys_t;
 
-/*******************************************************************************
+/*****************************************************************************
  * Local prototypes
- *******************************************************************************/
+ *****************************************************************************/
 static int  X11OpenDisplay      ( vout_thread_t *p_vout, char *psz_display, Window root_window );
 static void X11CloseDisplay     ( vout_thread_t *p_vout );
 static int  X11CreateWindow     ( vout_thread_t *p_vout );
@@ -66,7 +69,6 @@ static int  X11CreateShmImage   ( vout_thread_t *p_vout, XImage **pp_ximage,
 static void X11DestroyShmImage  ( vout_thread_t *p_vout, XImage *p_ximage, 
                                   XShmSegmentInfo *p_shm_info );
 
-
 /*******************************************************************************
  * vout_SysCreate: allocate X11 video thread output method
  *******************************************************************************
@@ -202,6 +204,18 @@ void vout_SysDestroy( vout_thread_t *p_vout )
  *******************************************************************************/
 int vout_SysManage( vout_thread_t *p_vout )
 {
+    /*
+     * Color/Grayscale or gamma change: in 8bpp, just change the colormap
+     */
+    if( (p_vout->i_changes & VOUT_GRAYSCALE_CHANGE) && (p_vout->i_screen_depth == 8) )
+    {
+        //??
+        //?? clear flags
+    }
+    
+    /*
+     * Size change
+     */
     if( p_vout->i_changes & VOUT_SIZE_CHANGE )
     {        
         intf_DbgMsg("resizing window\n");      
@@ -265,14 +279,19 @@ void vout_SysDisplay( vout_thread_t *p_vout )
 
 /* following functions are local */
 
-/*******************************************************************************
+/*****************************************************************************
  * X11OpenDisplay: open and initialize X11 device 
- *******************************************************************************
+ *****************************************************************************
  * Create a window according to video output given size, and set other 
  * properties according to the display properties.
- *******************************************************************************/
+ *****************************************************************************/
 static int X11OpenDisplay( vout_thread_t *p_vout, char *psz_display, Window root_window )
 {
+    XPixmapFormatValues *       p_xpixmap_format;           /* pixmap formats */    
+    XVisualInfo *               p_xvisual;            /* visuals informations */
+    XVisualInfo                 xvisual_template;          /* visual template */
+    int                         i_count;                        /* array size */    
+
     /* Open display */
     p_vout->p_sys->p_display = XOpenDisplay( psz_display );
     if( p_vout->p_sys->p_display == NULL )
@@ -290,31 +309,65 @@ static int X11OpenDisplay( vout_thread_t *p_vout, char *psz_display, Window root
         intf_Msg("XShm video extension is not available\n");    
     }    
 
-    /* Get the screen depth */
-    p_vout->i_screen_depth = DefaultDepth( p_vout->p_sys->p_display, 
-                                           p_vout->p_sys->i_screen );
+    /* Get screen depth */
+    p_vout->i_screen_depth = XDefaultDepth( p_vout->p_sys->p_display, p_vout->p_sys->i_screen );    
     switch( p_vout->i_screen_depth )
     {
-    case 8:                                    /* 24 bpp (millions of colors) */
-        p_vout->i_bytes_per_pixel = 1;
-        break;
-    case 15:                       /* 15 bpp (16bpp with a missing green bit) */
-    case 16:                                         /* 16 bpp (65536 colors) */
-        p_vout->i_bytes_per_pixel = 2;
-        break;
-    case 24:                                   /* 24 bpp (millions of colors) */
-        p_vout->i_bytes_per_pixel = 3;
-        break;
-    case 32:                                   /* 32 bpp (millions of colors) */
-        p_vout->i_bytes_per_pixel = 4;
+    case 8:
+        /*
+         * Screen depth is 8bpp. Use PseudoColor visual with private colormap.
+         */
+        xvisual_template.screen =   p_vout->p_sys->i_screen;
+        xvisual_template.class =    DirectColor;
+        p_xvisual = XGetVisualInfo( p_vout->p_sys->p_display, VisualScreenMask | VisualClassMask, 
+                                    &xvisual_template, &i_count );
+        if( p_xvisual == NULL )
+        {
+            intf_ErrMsg("error: no PseudoColor visual available\n");
+            XCloseDisplay( p_vout->p_sys->p_display );
+            return( 1 );        
+        }
+        //??
+        //?? SetColormap;
+        p_vout->i_bytes_per_pixel = 1;        
         break;
-    default:                                      /* unsupported screen depth */
-        intf_ErrMsg("error: screen depth %d is not supported\n", 
-                    p_vout->i_screen_depth);    
-        XCloseDisplay( p_vout->p_sys->p_display );        
-        return( 1  );
+    case 15:
+    case 16:
+    case 24:
+    default:        
+        /*
+         * Screen depth is higher than 8bpp. TrueColor visual is used.
+         */
+        xvisual_template.screen =   p_vout->p_sys->i_screen;
+        xvisual_template.class =    TrueColor;
+        p_xvisual = XGetVisualInfo( p_vout->p_sys->p_display, VisualScreenMask | VisualClassMask, 
+                                    &xvisual_template, &i_count );
+        if( p_xvisual == NULL )
+        {
+            intf_ErrMsg("error: no TrueColor visual available\n");
+            XCloseDisplay( p_vout->p_sys->p_display );
+            return( 1 );        
+        }
+        p_vout->i_red_mask =        p_xvisual->red_mask;
+        p_vout->i_green_mask =      p_xvisual->green_mask;
+        p_vout->i_blue_mask =       p_xvisual->blue_mask;
+
+        /* There is no difference yet between 3 and 4 Bpp. The only way to find
+         * the actual number of bytes per pixel is to list supported pixmap 
+         * formats. */
+        p_xpixmap_format = XListPixmapFormats( p_vout->p_sys->p_display, &i_count );
+        p_vout->i_bytes_per_pixel = 0;        
+        for( ; i_count--; p_xpixmap_format++ )
+        {
+            if( p_xpixmap_format->bits_per_pixel / 8 > p_vout->i_bytes_per_pixel )
+            {
+                p_vout->i_bytes_per_pixel = p_xpixmap_format->bits_per_pixel / 8;                
+            }
+        }
         break;
-    }    
+    }
+    p_vout->p_sys->p_visual = p_xvisual->visual;
+    XFree( p_xvisual );
 
     /* Create a window */
     if( X11CreateWindow( p_vout ) )
@@ -334,29 +387,35 @@ static int X11OpenDisplay( vout_thread_t *p_vout, char *psz_display, Window root
  *******************************************************************************/
 static void X11CloseDisplay( vout_thread_t *p_vout )
 {
+    /* Destroy colormap */
+    if( p_vout->i_screen_depth == 8 )
+    {
+        XFreeColormap( p_vout->p_sys->p_display, p_vout->p_sys->colormap );
+    }
+
     /* Destroy window and close display */
     X11DestroyWindow( p_vout );
     XCloseDisplay( p_vout->p_sys->p_display );    
 }
 
-/*******************************************************************************
+/******************************************************************************
  * X11CreateWindow: create X11 vout window
- *******************************************************************************
+ ******************************************************************************
  * The video output window will be created. Normally, this window is wether 
  * full screen or part of a parent window. Therefore, it does not need a 
  * title or other hints. Thery are still supplied in case the window would be
  * spawned as a standalone one by the interface.
- *******************************************************************************/
+ ******************************************************************************/
 static int X11CreateWindow( vout_thread_t *p_vout )
 {
-    XSetWindowAttributes    xwindow_attributes;
-    XGCValues               xgcvalues;
-    XEvent                  xevent;
-    boolean_t               b_expose;
-    boolean_t               b_map_notify;    
+    XSetWindowAttributes    xwindow_attributes;          /* window attributes */
+    XGCValues               xgcvalues;       /* graphic context configuration */
+    XEvent                  xevent;                           /* first events */
+    boolean_t               b_expose;              /* 'expose' event received */
+    boolean_t               b_map_notify;      /* 'map_notify' event received */
 
     /* Prepare window attributes */
-    xwindow_attributes.backing_store = Always;         /* save the hidden part */
+    xwindow_attributes.backing_store = Always;        /* save the hidden part */
  
     /* Create the window and set hints */
     p_vout->p_sys->window = XCreateSimpleWindow( p_vout->p_sys->p_display,
@@ -453,8 +512,7 @@ static int X11CreateImage( vout_thread_t *p_vout, XImage **pp_ximage )
     }
     
     /* Create XImage */
-    *pp_ximage = XCreateImage( p_vout->p_sys->p_display, 
-                               DefaultVisual(p_vout->p_sys->p_display, p_vout->p_sys->i_screen),
+    *pp_ximage = XCreateImage( p_vout->p_sys->p_display, p_vout->p_sys->p_visual,
                                p_vout->i_screen_depth, ZPixmap, 0, pb_data, 
                                p_vout->i_width, p_vout->i_height, i_quantum, 0);
     if(! *pp_ximage )                                                 /* error */
@@ -479,8 +537,7 @@ static int X11CreateShmImage( vout_thread_t *p_vout, XImage **pp_ximage,
                               XShmSegmentInfo *p_shm_info)
 {
     /* Create XImage */
-    *pp_ximage = XShmCreateImage( p_vout->p_sys->p_display, 
-                                  DefaultVisual(p_vout->p_sys->p_display, p_vout->p_sys->i_screen),
+    *pp_ximage = XShmCreateImage( p_vout->p_sys->p_display, p_vout->p_sys->p_visual, 
                                   p_vout->i_screen_depth, ZPixmap, 0, 
                                   p_shm_info, p_vout->i_width, p_vout->i_height );
     if(! *pp_ximage )                                                 /* error */
index d3c414411670c4bb4d483262bc3ad356451341fa..c67ee33840ea0a6987c4125fa835110ad7ae0eca 100644 (file)
  * Constants
  *******************************************************************************/
 
+/* Color masks for different color depths - 8bpp masks can be choosen, since 
+ * colormaps instead of hardware-defined colors are used. */
+//?? remove
+#define RED_8BPP_MASK           0xe0
+#define GREEN_8BPP_MASK         0x1c
+#define BLUE_8BPP_MASK          0x03
+
+#define RED_15BPP_MASK          0xf800
+#define GREEN_15BPP_MASK        0x03e0
+#define BLUE_15BPP_MASK         0x001f
+
+#define RED_16BPP_MASK          0xf800
+#define GREEN_16BPP_MASK        0x07e0
+#define BLUE_16BPP_MASK         0x001f
+
+#define RED_24BPP_MASK          0xff0000
+#define GREEN_24BPP_MASK        0x00ff00
+#define BLUE_24BPP_MASK         0x0000ff
+
 /* RGB/YUV inversion matrix (ISO/IEC 13818-2 section 6.3.6, table 6.9) */
 //?? no more used ?
 const int MATRIX_COEFFICIENTS_TABLE[8][4] =
@@ -67,8 +86,6 @@ const int MATRIX_COEFFICIENTS_TABLE[8][4] =
 /*******************************************************************************
  * Local prototypes
  *******************************************************************************/
-static int      BinaryLog         ( u32 i );
-static void     MaskToShift       ( int *pi_right, int *pi_left, u32 i_mask );
 static void     SetGammaTable     ( int *pi_table, double f_gamma );
 static void     SetYUV            ( vout_thread_t *p_vout );
 static void     SetOffset         ( int i_width, int i_height, int i_pic_width, int i_pic_height, 
@@ -130,26 +147,27 @@ static void     ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data
  * Convertion are made from p_y, p_u, p_v, which are modified, to p_buffer,
  * which is also modified.
  *****************************************************************************/
-#define CONVERT_Y_PIXEL                                                       \
+#define CONVERT_Y_PIXEL( BPP )                                                \
     /* Only Y sample is present */                                            \
     p_ybase = p_yuv + *p_y++;                                                 \
     *p_buffer++ = p_ybase[RED_OFFSET-((V_RED_COEF*128)>>SHIFT) + i_red] |     \
         p_ybase[GREEN_OFFSET-(((U_GREEN_COEF+V_GREEN_COEF)*128)>>SHIFT)       \
         + i_green ] | p_ybase[BLUE_OFFSET-((U_BLUE_COEF*128)>>SHIFT) + i_blue];
 
-#define CONVERT_YUV_PIXEL                                                     \
+#define CONVERT_YUV_PIXEL( BPP )                                              \
     /* Y, U and V samples are present */                                      \
     i_uval =    *p_u++;                                                       \
     i_vval =    *p_v++;                                                       \
     i_red =     (V_RED_COEF * i_vval) >> SHIFT;                               \
     i_green =   (U_GREEN_COEF * i_uval + V_GREEN_COEF * i_vval) >> SHIFT;     \
     i_blue =    (U_BLUE_COEF * i_uval) >> SHIFT;                              \
-    CONVERT_Y_PIXEL                                                           \
+    CONVERT_Y_PIXEL( BPP )                                                    \
 
 /*****************************************************************************
  * SCALE_WIDTH: scale a line horizontally
  *****************************************************************************
- * This macro scale a line using rendering buffer and offset array.
+ * This macro scale a line using rendering buffer and offset array. It works
+ * for 1, 2 and 4 Bpp.
  *****************************************************************************/
 #define SCALE_WIDTH                                                           \
     if( b_horizontal_scaling )                                                \
@@ -190,9 +208,10 @@ static void     ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data
  * SCALE_HEIGHT: handle vertical scaling
  *****************************************************************************
  * This macro handle vertical scaling for a picture. CHROMA may be 420, 422 or
- * 444 for RGB convertion, or 400 for gray convertion.
+ * 444 for RGB convertion, or 400 for gray convertion. It works for 1, 2, 3
+ * and 4 Bpp.
  *****************************************************************************/
-#define SCALE_HEIGHT( CHROMA )                                                \
+#define SCALE_HEIGHT( CHROMA, BPP )                                           \
     /* If line is odd, rewind 4:2:0 U and V samples */                        \
     if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) )                \
     {                                                                         \
@@ -236,8 +255,21 @@ static void     ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data
             {                                                                 \
                 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );           \
                 *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );           \
-                *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );           \
-                *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );           \
+                if( BPP > 1 )                               /* 2, 3, 4 Bpp */ \
+                {                                                             \
+                    *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );       \
+                    *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );       \
+                }                                                             \
+                if( BPP > 2 )                                  /* 3, 4 Bpp */ \
+                {                                                             \
+                    *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );       \
+                    *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );       \
+                }                                                             \
+                if( BPP > 3 )                                     /* 4 Bpp */ \
+                {                                                             \
+                    *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );       \
+                    *(((u64 *) p_pic)++) = *(((u64 *) p_pic_start)++ );       \
+                }                                                             \
             }                                                                 \
             p_pic +=        i_pic_line_width;                                 \
             p_pic_start +=  i_pic_line_width;                                 \
@@ -256,29 +288,20 @@ int vout_InitYUV( vout_thread_t *p_vout )
 {
     size_t      tables_size;                        /* tables size, in bytes */
     
-    /* Computes tables size */
-    switch( p_vout->i_screen_depth )
+    /* Computes tables size - 3 Bpp use 32 bits pixel entries in tables */
+    switch( p_vout->i_bytes_per_pixel )
     {
-    case 8:
+    case 1:
         tables_size = sizeof( u8 ) * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);
         break;        
-    case 15:
-    case 16:
+    case 2:
         tables_size = sizeof( u16 ) * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);
         break;        
-    case 24:        
-    case 32:
-#ifndef DEBUG
-    default:        
-#endif
+    case 3:        
+    case 4:
+    default:         
         tables_size = sizeof( u32 ) * (p_vout->b_grayscale ? GRAY_TABLE_SIZE : RGB_TABLE_SIZE);        
         break;        
-#ifdef DEBUG
-    default:
-        intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
-        tables_size = 0;
-        break;        
-#endif      
     }
     
     /* Allocate memory */
@@ -337,67 +360,6 @@ void vout_EndYUV( vout_thread_t *p_vout )
 
 /* following functions are local */
 
-/*****************************************************************************
- * BinaryLog: computes the base 2 log of a binary value
- *****************************************************************************
- * This functions is used by MaskToShift during tables initialisation, to
- * get a bit index from a binary value.
- *****************************************************************************/
-static int BinaryLog(u32 i)
-{
-    int i_log;
-
-    i_log = 0;
-    if (i & 0xffff0000) 
-    {        
-        i_log = 16;
-    }    
-    if (i & 0xff00ff00) 
-    {        
-        i_log += 8;
-    }    
-    if (i & 0xf0f0f0f0) 
-    {        
-        i_log += 4;
-    }    
-    if (i & 0xcccccccc) 
-    {        
-        i_log += 2;
-    }    
-    if (i & 0xaaaaaaaa) 
-    {        
-        i_log++;
-    }    
-    if (i != ((u32)1 << i_log))
-    {        
-       intf_ErrMsg("internal error: binary log overflow\n");        
-    }    
-
-    return( i_log );
-}
-
-/*****************************************************************************
- * MaskToShift: Transform a color mask into right and left shifts
- *****************************************************************************
- * This function is used during table initialisation. It can return a value
- *****************************************************************************/
-static void MaskToShift (int *pi_right, int *pi_left, u32 i_mask)
-{
-    u32 i_low, i_high;                 /* lower hand higher bits of the mask */
-
-    /* Get bits */
-    i_low =  i_mask & (- i_mask);                   /* lower bit of the mask */
-    i_high = i_mask + i_low;                       /* higher bit of the mask */
-
-    /* Transform bits into an index */
-    i_low =  BinaryLog (i_low);
-    i_high = BinaryLog (i_high);
-
-    /* Update pointers and return */
-    *pi_left =   i_low;
-    *pi_right = (8 - i_high + i_low);
-}
-
 /*****************************************************************************
  * SetGammaTable: return intensity table transformed by gamma curve.
  *****************************************************************************
@@ -424,99 +386,53 @@ static void SetYUV( vout_thread_t *p_vout )
 {
     int         pi_gamma[256];                                /* gamma table */
     int         i_index;                                  /* index in tables */
-    int         i_red_right, i_red_left;                       /* red shifts */
-    int         i_green_right, i_green_left;                 /* green shifts */
-    int         i_blue_right, i_blue_left;                    /* blue shifts */
 
     /* Build gamma table */    
     SetGammaTable( pi_gamma, p_vout->f_gamma );
     
-    /*          
-     * Set color masks and shifts
-     */
-    switch( p_vout->i_screen_depth )
-    {
-    case 8:
-        MaskToShift( &i_red_right,   &i_red_left,   0xe0 );
-        MaskToShift( &i_green_right, &i_green_left, 0x1c );
-        MaskToShift( &i_blue_right,  &i_blue_left,  0x03 );        
-        break;        
-    case 15:
-        MaskToShift( &i_red_right,   &i_red_left,   0xf800 );
-        MaskToShift( &i_green_right, &i_green_left, 0x03e0 );
-        MaskToShift( &i_blue_right,  &i_blue_left,  0x001f );        
-        break;        
-    case 16:
-        MaskToShift( &i_red_right,   &i_red_left,   0xf800 );
-        MaskToShift( &i_green_right, &i_green_left, 0x07e0 );
-        MaskToShift( &i_blue_right,  &i_blue_left,  0x001f );
-        break;        
-    case 24:
-    case 32:        
-        MaskToShift( &i_red_right,   &i_red_left,   0x00ff0000 );
-        MaskToShift( &i_green_right, &i_green_left, 0x0000ff00 );
-        MaskToShift( &i_blue_right,  &i_blue_left,  0x000000ff );
-        break;
-#ifdef DEBUG
-    default:
-        intf_DbgMsg("error: invalid screen depth %d\n", p_vout->i_screen_depth );
-        break;        
-#endif      
-    }
-
     /*
      * Set pointers and build YUV tables
      */        
     if( p_vout->b_grayscale )
     {
         /* Grayscale: build gray table */
-        switch( p_vout->i_screen_depth )
+        switch( p_vout->i_bytes_per_pixel )
         {
-        case 8:
+        case 1:
             p_vout->yuv.yuv.p_gray8 =  (u8 *)p_vout->yuv.p_base + GRAY_MARGIN;
+            for( i_index = 0; i_index < GRAY_MARGIN; i_index++ )
+            {
+                p_vout->yuv.yuv.p_gray8[ -i_index ] =      RGB2PIXEL( p_vout, pi_gamma[0], pi_gamma[0], pi_gamma[0] );
+                p_vout->yuv.yuv.p_gray8[ 256 + i_index ] = RGB2PIXEL( p_vout, pi_gamma[255], pi_gamma[255], pi_gamma[255] );
+            }            
+            for( i_index = 0; i_index < 256; i_index++) 
+            {
+                p_vout->yuv.yuv.p_gray8[ i_index ] = RGB2PIXEL( p_vout, pi_gamma[i_index], pi_gamma[i_index], pi_gamma[i_index] );
+            }
             break;        
-        case 15:
-        case 16:         
+        case 2:
             p_vout->yuv.yuv.p_gray16 =  (u16 *)p_vout->yuv.p_base + GRAY_MARGIN;
             for( i_index = 0; i_index < GRAY_MARGIN; i_index++ )
             {
-                p_vout->yuv.yuv.p_gray16[ -i_index ] = 
-                    ((pi_gamma[ 0 ] >> i_red_right)   << i_red_left)   |
-                    ((pi_gamma[ 0 ] >> i_green_right) << i_green_left) |
-                    ((pi_gamma[ 0 ] >> i_blue_right)  << i_blue_left);
-                p_vout->yuv.yuv.p_gray16[ 256 + i_index ] = 
-                    ((pi_gamma[ 255 ] >> i_red_right)   << i_red_left)   |
-                    ((pi_gamma[ 255 ] >> i_green_right) << i_green_left) |
-                    ((pi_gamma[ 255 ] >> i_blue_right)  << i_blue_left);
+                p_vout->yuv.yuv.p_gray16[ -i_index ] =      RGB2PIXEL( p_vout, pi_gamma[0], pi_gamma[0], pi_gamma[0] );
+                p_vout->yuv.yuv.p_gray16[ 256 + i_index ] = RGB2PIXEL( p_vout, pi_gamma[255], pi_gamma[255], pi_gamma[255] );
             }            
             for( i_index = 0; i_index < 256; i_index++) 
             {
-                p_vout->yuv.yuv.p_gray16[ i_index ] = 
-                    ((pi_gamma[ i_index ] >> i_red_right)   << i_red_left)   |
-                    ((pi_gamma[ i_index ] >> i_green_right) << i_green_left) |
-                    ((pi_gamma[ i_index ] >> i_blue_right)  << i_blue_left);
+                p_vout->yuv.yuv.p_gray16[ i_index ] = RGB2PIXEL( p_vout, pi_gamma[i_index], pi_gamma[i_index], pi_gamma[i_index] );
             }
             break;        
-        case 24:
-        case 32:        
+        case 3:
+        case 4:        
             p_vout->yuv.yuv.p_gray32 =  (u32 *)p_vout->yuv.p_base + GRAY_MARGIN;
             for( i_index = 0; i_index < GRAY_MARGIN; i_index++ )
             {
-                p_vout->yuv.yuv.p_gray32[ -i_index ] = 
-                    ((pi_gamma[ 0 ] >> i_red_right)   << i_red_left)   |
-                    ((pi_gamma[ 0 ] >> i_green_right) << i_green_left) |
-                    ((pi_gamma[ 0 ] >> i_blue_right)  << i_blue_left);
-                p_vout->yuv.yuv.p_gray32[ 256 + i_index ] = 
-                    ((pi_gamma[ 255 ] >> i_red_right)   << i_red_left)   |
-                    ((pi_gamma[ 255 ] >> i_green_right) << i_green_left) |
-                    ((pi_gamma[ 255 ] >> i_blue_right)  << i_blue_left);
+                p_vout->yuv.yuv.p_gray32[ -i_index ] =      RGB2PIXEL( p_vout, pi_gamma[0], pi_gamma[0], pi_gamma[0] );
+                p_vout->yuv.yuv.p_gray32[ 256 + i_index ] = RGB2PIXEL( p_vout, pi_gamma[255], pi_gamma[255], pi_gamma[255] );
             }            
             for( i_index = 0; i_index < 256; i_index++) 
             {
-                p_vout->yuv.yuv.p_gray32[ i_index ] = 
-                    ((pi_gamma[ i_index ] >> i_red_right)   << i_red_left)   |
-                    ((pi_gamma[ i_index ] >> i_green_right) << i_green_left) |
-                    ((pi_gamma[ i_index ] >> i_blue_right)  << i_blue_left);
+                p_vout->yuv.yuv.p_gray32[ i_index ] = RGB2PIXEL( p_vout, pi_gamma[i_index], pi_gamma[i_index], pi_gamma[i_index] );
             }
             break;        
          }
@@ -524,59 +440,79 @@ static void SetYUV( vout_thread_t *p_vout )
     else
     {
         /* Color: build red, green and blue tables */
-        switch( p_vout->i_screen_depth )
+        switch( p_vout->i_bytes_per_pixel )
         {
-        case 8:
+        case 1:
             p_vout->yuv.yuv.p_rgb8 = (u8 *)p_vout->yuv.p_base;
+            for( i_index = 0; i_index < RED_MARGIN; i_index++ )
+            {
+                p_vout->yuv.yuv.p_rgb8[RED_OFFSET - RED_MARGIN + i_index] = RGB2PIXEL( p_vout, pi_gamma[0], 0, 0 );
+                p_vout->yuv.yuv.p_rgb8[RED_OFFSET + 256 + i_index] =        RGB2PIXEL( p_vout, pi_gamma[255], 0, 0 );
+            }
+            for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
+            {
+                p_vout->yuv.yuv.p_rgb8[GREEN_OFFSET - GREEN_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[0], 0 );
+                p_vout->yuv.yuv.p_rgb8[GREEN_OFFSET + 256 + i_index] =          RGB2PIXEL( p_vout, 0, pi_gamma[255], 0 );
+            }
+            for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
+            {
+                p_vout->yuv.yuv.p_rgb8[BLUE_OFFSET - BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[0] );
+                p_vout->yuv.yuv.p_rgb8[BLUE_OFFSET + BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[255] );
+            }
+            for( i_index = 0; i_index < 256; i_index++ )
+            {
+                p_vout->yuv.yuv.p_rgb8[RED_OFFSET + i_index] =   RGB2PIXEL( p_vout, pi_gamma[ i_index ], 0, 0 );
+                p_vout->yuv.yuv.p_rgb8[GREEN_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[ i_index ], 0 );
+                p_vout->yuv.yuv.p_rgb8[BLUE_OFFSET + i_index] =  RGB2PIXEL( p_vout, 0, 0, pi_gamma[ i_index ] ); 
+            }            
             break;        
-        case 15:
-        case 16:            
+        case 2:
             p_vout->yuv.yuv.p_rgb16 = (u16 *)p_vout->yuv.p_base;
             for( i_index = 0; i_index < RED_MARGIN; i_index++ )
             {
-                p_vout->yuv.yuv.p_rgb16[RED_OFFSET - RED_MARGIN + i_index] = (pi_gamma[0]>>i_red_right)<<i_red_left;
-                p_vout->yuv.yuv.p_rgb16[RED_OFFSET + 256 + i_index] = (pi_gamma[255]>>i_red_right)<<i_red_left;                
+                p_vout->yuv.yuv.p_rgb16[RED_OFFSET - RED_MARGIN + i_index] = RGB2PIXEL( p_vout, pi_gamma[0], 0, 0 );
+                p_vout->yuv.yuv.p_rgb16[RED_OFFSET + 256 + i_index] =        RGB2PIXEL( p_vout, pi_gamma[255], 0, 0 );
             }
             for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
             {
-                p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET - GREEN_MARGIN + i_index] = (pi_gamma[0]>>i_green_right) <<i_green_left;
-                p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET + 256 + i_index] = (pi_gamma[255]>>i_green_right)<<i_green_left;
+                p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET - GREEN_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[0], 0 );
+                p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET + 256 + i_index] =          RGB2PIXEL( p_vout, 0, pi_gamma[255], 0 );
             }
             for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
             {
-                p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET - BLUE_MARGIN + i_index] = (pi_gamma[0]>>i_blue_right)<<i_blue_left;
-                p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET + BLUE_MARGIN + i_index] = (pi_gamma[255]>>i_blue_right)<<i_blue_left;                
+                p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET - BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[0] );
+                p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET + BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[255] );
             }
             for( i_index = 0; i_index < 256; i_index++ )
             {
-                p_vout->yuv.yuv.p_rgb16[RED_OFFSET + i_index] = (pi_gamma[i_index]>>i_red_right)<<i_red_left;
-                p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET + i_index] = (pi_gamma[i_index]>>i_green_right)<<i_green_left;
-                p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET + i_index] = (pi_gamma[i_index]>>i_blue_right)<<i_blue_left;
+                p_vout->yuv.yuv.p_rgb16[RED_OFFSET + i_index] =   RGB2PIXEL( p_vout, pi_gamma[ i_index ], 0, 0 );
+                p_vout->yuv.yuv.p_rgb16[GREEN_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[ i_index ], 0 );
+                p_vout->yuv.yuv.p_rgb16[BLUE_OFFSET + i_index] =  RGB2PIXEL( p_vout, 0, 0, pi_gamma[ i_index ] ); 
             }            
             break;        
-        case 24:
-        case 32:
+        case 3:
+        case 4:
             p_vout->yuv.yuv.p_rgb32 = (u32 *)p_vout->yuv.p_base;
             for( i_index = 0; i_index < RED_MARGIN; i_index++ )
             {
-                p_vout->yuv.yuv.p_rgb32[RED_OFFSET - RED_MARGIN + i_index] = (pi_gamma[0]>>i_red_right)<<i_red_left;
-                p_vout->yuv.yuv.p_rgb32[RED_OFFSET + 256 + i_index] = (pi_gamma[255]>>i_red_right)<<i_red_left;                
+                p_vout->yuv.yuv.p_rgb32[RED_OFFSET - RED_MARGIN + i_index] = RGB2PIXEL( p_vout, pi_gamma[0], 0, 0 );
+                p_vout->yuv.yuv.p_rgb32[RED_OFFSET + 256 + i_index] =        RGB2PIXEL( p_vout, pi_gamma[255], 0, 0 );
             }
             for( i_index = 0; i_index < GREEN_MARGIN; i_index++ )
             {
-                p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET - GREEN_MARGIN + i_index] = (pi_gamma[0]>>i_green_right)<<i_green_left;
-                p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET + 256 + i_index] = (pi_gamma[255]>>i_green_right)<<i_green_left;
+                p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET - GREEN_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[0], 0 );
+                p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET + 256 + i_index] =          RGB2PIXEL( p_vout, 0, pi_gamma[255], 0 );
             }
             for( i_index = 0; i_index < BLUE_MARGIN; i_index++ )
             {
-                p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET - BLUE_MARGIN + i_index] = (pi_gamma[0]>>i_blue_right)<<i_blue_left;
-                p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET + BLUE_MARGIN + i_index] = (pi_gamma[255]>>i_blue_right)<<i_blue_left;                
+                p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET - BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[0] );
+                p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET + BLUE_MARGIN + i_index] = RGB2PIXEL( p_vout, 0, 0, pi_gamma[255] );
             }
             for( i_index = 0; i_index < 256; i_index++ )
             {
-                p_vout->yuv.yuv.p_rgb32[RED_OFFSET + i_index] = (pi_gamma[i_index]>>i_red_right)<<i_red_left;
-                p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET + i_index] = (pi_gamma[i_index]>>i_green_right)<<i_green_left;
-                p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET + i_index] = (pi_gamma[i_index]>>i_blue_right)<<i_blue_left;
+                p_vout->yuv.yuv.p_rgb32[RED_OFFSET + i_index] =   RGB2PIXEL( p_vout, pi_gamma[ i_index ], 0, 0 );
+                p_vout->yuv.yuv.p_rgb32[GREEN_OFFSET + i_index] = RGB2PIXEL( p_vout, 0, pi_gamma[ i_index ], 0 );
+                p_vout->yuv.yuv.p_rgb32[BLUE_OFFSET + i_index] =  RGB2PIXEL( p_vout, 0, 0, pi_gamma[ i_index ] ); 
             }            
             break;        
         }
@@ -588,25 +524,24 @@ static void SetYUV( vout_thread_t *p_vout )
     if( p_vout->b_grayscale )
     {
         /* Grayscale */
-        switch( p_vout->i_screen_depth )
+        switch( p_vout->i_bytes_per_pixel )
         {
-        case 8:
+        case 1:
             p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray8;        
             p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray8;        
             p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray8;        
             break;        
-        case 15:
-        case 16:  
+        case 2:
             p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;        
             p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray16;        
             p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray16;        
             break;        
-        case 24:
+        case 3:
             p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray24;        
             p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray24;        
             p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray24;        
             break;        
-        case 32:        
+        case 4:        
             p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray32;        
             p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertY4Gray32;        
             p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertY4Gray32;        
@@ -616,25 +551,24 @@ static void SetYUV( vout_thread_t *p_vout )
     else
     {
         /* Color */
-        switch( p_vout->i_screen_depth )
+        switch( p_vout->i_bytes_per_pixel )
         {
-        case 8:
+        case 1:
             p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB8;
             p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB8;
             p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB8;
             break;        
-        case 15:
-        case 16:  
+        case 2:
             p_vout->yuv.p_Convert420 =   (vout_yuv_convert_t *) ConvertYUV420RGB16;        
             p_vout->yuv.p_Convert422 =   (vout_yuv_convert_t *) ConvertYUV422RGB16;        
             p_vout->yuv.p_Convert444 =   (vout_yuv_convert_t *) ConvertYUV444RGB16;        
             break;        
-        case 24:
+        case 3:
             p_vout->yuv.p_Convert420 =   (vout_yuv_convert_t *) ConvertYUV420RGB24;        
             p_vout->yuv.p_Convert422 =   (vout_yuv_convert_t *) ConvertYUV422RGB24;        
             p_vout->yuv.p_Convert444 =   (vout_yuv_convert_t *) ConvertYUV444RGB24;        
             break;        
-        case 32:        
+        case 4:        
             p_vout->yuv.p_Convert420 =   (vout_yuv_convert_t *) ConvertYUV420RGB32;        
             p_vout->yuv.p_Convert422 =   (vout_yuv_convert_t *) ConvertYUV422RGB32;        
             p_vout->yuv.p_Convert444 =   (vout_yuv_convert_t *) ConvertYUV444RGB32;        
@@ -777,12 +711,12 @@ static void ConvertY4Gray8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_y,
 
         /* Do horizontal and vertical scaling */
         SCALE_WIDTH;
-        SCALE_HEIGHT(400);        
+        SCALE_HEIGHT(400, 1);        
     }
 }
 
 /*****************************************************************************
- * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 15 or 16 bpp
+ * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 2 Bpp
  *****************************************************************************/
 static void ConvertY4Gray16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
                              int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
@@ -845,12 +779,12 @@ static void ConvertY4Gray16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y
 
         /* Do horizontal and vertical scaling */
         SCALE_WIDTH;
-        SCALE_HEIGHT(400);        
+        SCALE_HEIGHT(400, 2);        
     }
 }
 
 /*****************************************************************************
- * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 24 bpp
+ * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 3 Bpp
  *****************************************************************************/
 static void ConvertY4Gray24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
                              int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
@@ -860,7 +794,7 @@ static void ConvertY4Gray24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_
 }
 
 /*****************************************************************************
- * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 32 bpp
+ * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 4 Bpp
  *****************************************************************************/
 static void ConvertY4Gray32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
                              int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
@@ -923,7 +857,7 @@ static void ConvertY4Gray32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y
 
         /* Do horizontal and vertical scaling */
         SCALE_WIDTH;
-        SCALE_HEIGHT(400);        
+        SCALE_HEIGHT(400, 4);        
     }
 }
 
@@ -975,19 +909,19 @@ static void ConvertYUV420RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_
          * pixels wide blocks */
         for( i_x = i_width / 16; i_x--;  )
         {
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
+            CONVERT_YUV_PIXEL(1);  CONVERT_Y_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_Y_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_Y_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_Y_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_Y_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_Y_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_Y_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_Y_PIXEL(1);
         }             
 
         /* Do horizontal and vertical scaling */
         SCALE_WIDTH;
-        SCALE_HEIGHT(420);        
+        SCALE_HEIGHT(420, 1);        
     }
 }
 
@@ -1039,19 +973,19 @@ static void ConvertYUV422RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_
          * pixels wide blocks */
         for( i_x = i_width / 16; i_x--;  )
         {
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
+            CONVERT_YUV_PIXEL(1);  CONVERT_Y_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_Y_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_Y_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_Y_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_Y_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_Y_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_Y_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_Y_PIXEL(1);
         }             
 
         /* Do horizontal and vertical scaling */
         SCALE_WIDTH;
-        SCALE_HEIGHT(422);        
+        SCALE_HEIGHT(422, 1);        
     }
 }
 
@@ -1102,24 +1036,24 @@ static void ConvertYUV444RGB8( p_vout_thread_t p_vout, u8 *p_pic, yuv_data_t *p_
          * pixels wide blocks */
         for( i_x = i_width / 16; i_x--;  )
         {
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
+            CONVERT_YUV_PIXEL(1);  CONVERT_YUV_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_YUV_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_YUV_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_YUV_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_YUV_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_YUV_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_YUV_PIXEL(1);
+            CONVERT_YUV_PIXEL(1);  CONVERT_YUV_PIXEL(1);
         }             
 
         /* Do horizontal and vertical scaling */
         SCALE_WIDTH;
-        SCALE_HEIGHT(444);        
+        SCALE_HEIGHT(444, 1);        
     }
 }
 
 /*****************************************************************************
- * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 15 or 16 bpp
+ * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 2 Bpp
  *****************************************************************************/
 static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
                                 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
@@ -1177,24 +1111,24 @@ static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *
          * pixels wide blocks */
         for( i_x = i_width / 16; i_x--;  )
         {
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
+            CONVERT_YUV_PIXEL(2);  CONVERT_Y_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_Y_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_Y_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_Y_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_Y_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_Y_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_Y_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_Y_PIXEL(2);
         }             
 
         /* Do horizontal and vertical scaling */
         SCALE_WIDTH;
-        SCALE_HEIGHT(420);        
+        SCALE_HEIGHT(420, 2);        
     }
 }
 
 /*****************************************************************************
- * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 15 or 16 bpp
+ * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 2 Bpp
  *****************************************************************************/
 static void ConvertYUV422RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
                                 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
@@ -1241,24 +1175,24 @@ static void ConvertYUV422RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *
          * pixels wide blocks */
         for( i_x = i_width / 16; i_x--;  )
         {
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
+            CONVERT_YUV_PIXEL(2);  CONVERT_Y_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_Y_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_Y_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_Y_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_Y_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_Y_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_Y_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_Y_PIXEL(2);
         }             
 
         /* Do horizontal and vertical scaling */
         SCALE_WIDTH;
-        SCALE_HEIGHT(422);        
+        SCALE_HEIGHT(422, 2);        
     }
 }
 
 /*****************************************************************************
- * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 15 or 16 bpp
+ * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 2 Bpp
  *****************************************************************************/
 static void ConvertYUV444RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
                                 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
@@ -1304,24 +1238,24 @@ static void ConvertYUV444RGB16( p_vout_thread_t p_vout, u16 *p_pic, yuv_data_t *
          * pixels wide blocks */
         for( i_x = i_width / 16; i_x--;  )
         {
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
+            CONVERT_YUV_PIXEL(2);  CONVERT_YUV_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_YUV_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_YUV_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_YUV_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_YUV_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_YUV_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_YUV_PIXEL(2);
+            CONVERT_YUV_PIXEL(2);  CONVERT_YUV_PIXEL(2);
         }             
 
         /* Do horizontal and vertical scaling */
         SCALE_WIDTH;
-        SCALE_HEIGHT(444);        
+        SCALE_HEIGHT(444, 2);        
     }
 }
 
 /*****************************************************************************
- * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 24 bpp
+ * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 3 Bpp
  *****************************************************************************/
 static void ConvertYUV420RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
                                 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
@@ -1331,7 +1265,7 @@ static void ConvertYUV420RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t
 }
 
 /*****************************************************************************
- * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 24 bpp
+ * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 3 Bpp
  *****************************************************************************/
 static void ConvertYUV422RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
                                 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
@@ -1341,7 +1275,7 @@ static void ConvertYUV422RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t
 }
 
 /*****************************************************************************
- * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 24 bpp
+ * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 3 Bpp
  *****************************************************************************/
 static void ConvertYUV444RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
                                 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
@@ -1351,7 +1285,7 @@ static void ConvertYUV444RGB24( p_vout_thread_t p_vout, void *p_pic, yuv_data_t
 }
 
 /*****************************************************************************
- * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 32 bpp
+ * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 4 Bpp
  *****************************************************************************/
 static void ConvertYUV420RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
                                 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
@@ -1398,24 +1332,24 @@ static void ConvertYUV420RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *
          * pixels wide blocks */
         for( i_x = i_width / 16; i_x--;  )
         {
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
+            CONVERT_YUV_PIXEL(4);  CONVERT_Y_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_Y_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_Y_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_Y_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_Y_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_Y_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_Y_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_Y_PIXEL(4);
         }             
 
         /* Do horizontal and vertical scaling */
         SCALE_WIDTH;
-        SCALE_HEIGHT(420);        
+        SCALE_HEIGHT(420, 4);        
     }
 }
 
 /*****************************************************************************
- * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 32 bpp
+ * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 4 Bpp
  *****************************************************************************/
 static void ConvertYUV422RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
                                 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
@@ -1462,24 +1396,24 @@ static void ConvertYUV422RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *
          * pixels wide blocks */
         for( i_x = i_width / 16; i_x--;  )
         {
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_Y_PIXEL;
+            CONVERT_YUV_PIXEL(4);  CONVERT_Y_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_Y_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_Y_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_Y_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_Y_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_Y_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_Y_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_Y_PIXEL(4);
         }             
 
         /* Do horizontal and vertical scaling */
         SCALE_WIDTH;
-        SCALE_HEIGHT(422);        
+        SCALE_HEIGHT(422, 4);        
     }
 }
 
 /*****************************************************************************
- * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 32 bpp
+ * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 4 Bpp
  *****************************************************************************/
 static void ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
                                 int i_width, int i_height, int i_pic_width, int i_pic_height, int i_pic_line_width,
@@ -1525,19 +1459,19 @@ static void ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *
          * pixels wide blocks */
         for( i_x = i_width / 16; i_x--;  )
         {
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
-            CONVERT_YUV_PIXEL;  CONVERT_YUV_PIXEL;
+            CONVERT_YUV_PIXEL(4);  CONVERT_YUV_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_YUV_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_YUV_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_YUV_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_YUV_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_YUV_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_YUV_PIXEL(4);
+            CONVERT_YUV_PIXEL(4);  CONVERT_YUV_PIXEL(4);
         }             
 
         /* Do horizontal and vertical scaling */
         SCALE_WIDTH;
-        SCALE_HEIGHT(444);        
+        SCALE_HEIGHT(444, 4);        
     }
 }
 
@@ -1567,6 +1501,7 @@ static void ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic, yuv_data_t *
  */
 
 #if 0
+//??
 static void yuvToRgb24 (unsigned char * Y,
                        unsigned char * U, unsigned char * V,
                        char * dest, int table[1935], int width)