Commit c4a60506 authored by Sam Hocevar's avatar Sam Hocevar

. gestion du gamma en 8bpp grayscale

 . optimisations dans la YUV 8bpp
 . l'output framebuffer ne bloque plus la console
 . rajout d'une fonction dans la structure vout pour allouer une palette
 . r�initialisation de l'ancienne palette en quittant

bugs restant:
 . pas d'allocation de palette en 8bits sous X11
 . bugs du scaling en 8bits sous X11 (sans doute d� � l'alignement sur 1
  octet au lieu de 2)
 . l'output framebuffer est toujours p�t�e pour 16 et 32 bits
 . pas de correction gamma en 8bits couleur
 . c'est tout moche pendant la fraction de seconde du changement de palette
parent f7217115
...@@ -41,7 +41,7 @@ typedef struct vout_yuv_s ...@@ -41,7 +41,7 @@ typedef struct vout_yuv_s
vout_yuv_convert_t * p_Convert444; /* YUV 4:4:4 converter */ vout_yuv_convert_t * p_Convert444; /* YUV 4:4:4 converter */
/* Pre-calculated convertion tables */ /* Pre-calculated convertion tables */
void * p_base; /* base for all convertion tables */ void * p_base; /* base for all conversion tables */
union union
{ {
u8 * p_gray8; /* gray 8 bits table */ u8 * p_gray8; /* gray 8 bits table */
...@@ -54,7 +54,7 @@ typedef struct vout_yuv_s ...@@ -54,7 +54,7 @@ typedef struct vout_yuv_s
/* Temporary convertion buffer and offset array */ /* Temporary convertion buffer and offset array */
void * p_buffer; /* convertion buffer */ void * p_buffer; /* convertion buffer */
int * p_offset; /* offset array */ int * p_offset; /* offset array */
} vout_yuv_t; } vout_yuv_t;
/******************************************************************************* /*******************************************************************************
...@@ -85,6 +85,9 @@ typedef struct vout_buffer_s ...@@ -85,6 +85,9 @@ typedef struct vout_buffer_s
* is represented by a video output thread, and described using following * is represented by a video output thread, and described using following
* structure. * structure.
*******************************************************************************/ *******************************************************************************/
typedef void (vout_set_palette_t)( p_vout_thread_t p_vout,
u16 *red, u16 *green, u16 *blue, u16 *transp );
typedef struct vout_thread_s typedef struct vout_thread_s
{ {
/* Thread properties and lock */ /* Thread properties and lock */
...@@ -123,15 +126,13 @@ typedef struct vout_thread_s ...@@ -123,15 +126,13 @@ typedef struct vout_thread_s
u32 i_black_pixel; /* black */ u32 i_black_pixel; /* black */
u32 i_gray_pixel; /* gray */ u32 i_gray_pixel; /* gray */
u32 i_blue_pixel; /* blue */ u32 i_blue_pixel; /* blue */
/* Palette */
u8 lookup[2176]; /* lookup table for 8 bpp palette */
/* Pictures and rendering properties */ /* Pictures and rendering properties */
boolean_t b_grayscale; /* color or grayscale display */ boolean_t b_grayscale; /* color or grayscale display */
boolean_t b_info; /* print additionnal informations */ boolean_t b_info; /* print additionnal informations */
boolean_t b_interface; /* render interface */ boolean_t b_interface; /* render interface */
boolean_t b_scale; /* allow picture scaling */ boolean_t b_scale; /* allow picture scaling */
vout_set_palette_t *p_set_palette; /* sets 8bpp palette */
/* Idle screens management */ /* Idle screens management */
mtime_t last_display_date; /* last non idle display date */ mtime_t last_display_date; /* last non idle display date */
......
...@@ -210,22 +210,23 @@ int intf_SelectChannel( intf_thread_t * p_intf, int i_channel ) ...@@ -210,22 +210,23 @@ int intf_SelectChannel( intf_thread_t * p_intf, int i_channel )
return( 1 ); return( 1 );
} }
/******************************************************************************* /*****************************************************************************
* intf_ProcessKey: process standard keys * intf_ProcessKey: process standard keys
******************************************************************************* *****************************************************************************
* This function will process standard keys and return non 0 if the key was * This function will process standard keys and return non 0 if the key was
* unknown. * unknown.
*******************************************************************************/ *****************************************************************************/
int intf_ProcessKey( intf_thread_t *p_intf, int i_key ) int intf_ProcessKey( intf_thread_t *p_intf, int i_key )
{ {
switch( i_key ) switch( i_key )
{ {
case 'Q': /* quit order */ case 'Q': /* quit order */
case 'q': case 'q':
case 27: /* escape key */ case 27: /* escape key */
case 3: /* ^C */
p_intf->b_die = 1; p_intf->b_die = 1;
break; break;
case '0': /* source change */ case '0': /* source change */
case '1': case '1':
case '2': case '2':
case '3': case '3':
...@@ -239,17 +240,17 @@ int intf_ProcessKey( intf_thread_t *p_intf, int i_key ) ...@@ -239,17 +240,17 @@ int intf_ProcessKey( intf_thread_t *p_intf, int i_key )
* its own error messages */ * its own error messages */
intf_SelectChannel( p_intf, i_key - '0' ); intf_SelectChannel( p_intf, i_key - '0' );
break; break;
case '+': /* volume + */ case '+': /* volume + */
// ?? // ??
break; break;
case '-': /* volume - */ case '-': /* volume - */
// ?? // ??
break; break;
case 'M': /* toggle mute */ case 'M': /* toggle mute */
case 'm': case 'm':
// ?? // ??
break; break;
case 'g': /* gamma - */ case 'g': /* gamma - */
if( (p_intf->p_vout != NULL) && (p_intf->p_vout->f_gamma > -INTF_GAMMA_LIMIT) ) if( (p_intf->p_vout != NULL) && (p_intf->p_vout->f_gamma > -INTF_GAMMA_LIMIT) )
{ {
vlc_mutex_lock( &p_intf->p_vout->change_lock ); vlc_mutex_lock( &p_intf->p_vout->change_lock );
...@@ -258,7 +259,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int i_key ) ...@@ -258,7 +259,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int i_key )
vlc_mutex_unlock( &p_intf->p_vout->change_lock ); vlc_mutex_unlock( &p_intf->p_vout->change_lock );
} }
break; break;
case 'G': /* gamma + */ case 'G': /* gamma + */
if( (p_intf->p_vout != NULL) && (p_intf->p_vout->f_gamma < INTF_GAMMA_LIMIT) ) if( (p_intf->p_vout != NULL) && (p_intf->p_vout->f_gamma < INTF_GAMMA_LIMIT) )
{ {
vlc_mutex_lock( &p_intf->p_vout->change_lock ); vlc_mutex_lock( &p_intf->p_vout->change_lock );
...@@ -267,7 +268,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int i_key ) ...@@ -267,7 +268,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int i_key )
vlc_mutex_unlock( &p_intf->p_vout->change_lock ); vlc_mutex_unlock( &p_intf->p_vout->change_lock );
} }
break; break;
case 'c': /* toggle grayscale */ case 'c': /* toggle grayscale */
if( p_intf->p_vout != NULL ) if( p_intf->p_vout != NULL )
{ {
vlc_mutex_lock( &p_intf->p_vout->change_lock ); vlc_mutex_lock( &p_intf->p_vout->change_lock );
...@@ -276,7 +277,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int i_key ) ...@@ -276,7 +277,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int i_key )
vlc_mutex_unlock( &p_intf->p_vout->change_lock ); vlc_mutex_unlock( &p_intf->p_vout->change_lock );
} }
break; break;
case ' ': /* toggle interface */ case ' ': /* toggle interface */
if( p_intf->p_vout != NULL ) if( p_intf->p_vout != NULL )
{ {
vlc_mutex_lock( &p_intf->p_vout->change_lock ); vlc_mutex_lock( &p_intf->p_vout->change_lock );
...@@ -285,7 +286,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int i_key ) ...@@ -285,7 +286,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int i_key )
vlc_mutex_unlock( &p_intf->p_vout->change_lock ); vlc_mutex_unlock( &p_intf->p_vout->change_lock );
} }
break; break;
case 'i': /* toggle info */ case 'i': /* toggle info */
if( p_intf->p_vout != NULL ) if( p_intf->p_vout != NULL )
{ {
vlc_mutex_lock( &p_intf->p_vout->change_lock ); vlc_mutex_lock( &p_intf->p_vout->change_lock );
...@@ -294,7 +295,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int i_key ) ...@@ -294,7 +295,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int i_key )
vlc_mutex_unlock( &p_intf->p_vout->change_lock ); vlc_mutex_unlock( &p_intf->p_vout->change_lock );
} }
break; break;
case 's': /* toggle scaling */ case 's': /* toggle scaling */
if( p_intf->p_vout != NULL ) if( p_intf->p_vout != NULL )
{ {
vlc_mutex_lock( &p_intf->p_vout->change_lock ); vlc_mutex_lock( &p_intf->p_vout->change_lock );
...@@ -303,7 +304,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int i_key ) ...@@ -303,7 +304,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int i_key )
vlc_mutex_unlock( &p_intf->p_vout->change_lock ); vlc_mutex_unlock( &p_intf->p_vout->change_lock );
} }
break; break;
default: /* unknown key */ default: /* unknown key */
return( 1 ); return( 1 );
} }
......
...@@ -67,8 +67,8 @@ typedef struct vout_sys_s ...@@ -67,8 +67,8 @@ typedef struct vout_sys_s
******************************************************************************/ ******************************************************************************/
static int FBOpenDisplay ( vout_thread_t *p_vout ); static int FBOpenDisplay ( vout_thread_t *p_vout );
static void FBCloseDisplay ( vout_thread_t *p_vout ); static void FBCloseDisplay ( vout_thread_t *p_vout );
static void FBInitBWPalette ( vout_thread_t *p_vout ); static void FBSetPalette ( p_vout_thread_t p_vout,
static void FBInitRGBPalette( vout_thread_t *p_vout ); u16 *red, u16 *green, u16 *blue, u16 *transp );
/****************************************************************************** /******************************************************************************
* vout_SysCreate: allocates FB video thread output method * vout_SysCreate: allocates FB video thread output method
...@@ -101,6 +101,7 @@ int vout_SysCreate( vout_thread_t *p_vout, char *psz_display, int i_root_window ...@@ -101,6 +101,7 @@ int vout_SysCreate( vout_thread_t *p_vout, char *psz_display, int i_root_window
******************************************************************************/ ******************************************************************************/
int vout_SysInit( vout_thread_t *p_vout ) int vout_SysInit( vout_thread_t *p_vout )
{ {
p_vout->p_set_palette = FBSetPalette;
return( 0 ); return( 0 );
} }
...@@ -230,8 +231,8 @@ static int FBOpenDisplay( vout_thread_t *p_vout ) ...@@ -230,8 +231,8 @@ static int FBOpenDisplay( vout_thread_t *p_vout )
ioctl( p_vout->p_sys->i_fb_dev, FBIOGETCMAP, &p_vout->p_sys->fb_cmap ); ioctl( p_vout->p_sys->i_fb_dev, FBIOGETCMAP, &p_vout->p_sys->fb_cmap );
/* initializes black & white palette */ /* initializes black & white palette */
//FBInitRGBPalette( p_vout );
//FBInitBWPalette( p_vout ); //FBInitBWPalette( p_vout );
FBInitRGBPalette( p_vout );
p_vout->i_bytes_per_pixel = 1; p_vout->i_bytes_per_pixel = 1;
p_vout->i_bytes_per_line = p_vout->i_width; p_vout->i_bytes_per_line = p_vout->i_width;
...@@ -301,116 +302,16 @@ static void FBCloseDisplay( vout_thread_t *p_vout ) ...@@ -301,116 +302,16 @@ static void FBCloseDisplay( vout_thread_t *p_vout )
close( p_vout->p_sys->i_fb_dev ); close( p_vout->p_sys->i_fb_dev );
} }
/***************************************************************************** /******************************************************************************
* FBInitRGBPalette: initialize color palette for 8 bpp * FBSetPalette: sets an 8 bpp palette
*****************************************************************************/ ******************************************************************************
static void FBInitRGBPalette( vout_thread_t *p_vout ) * This function is just a prototype that does nothing. Architectures that
* support palette allocation should override it.
******************************************************************************/
static void FBSetPalette ( p_vout_thread_t p_vout,
u16 *red, u16 *green, u16 *blue, u16 *transp )
{ {
#define SATURATE( x ) \
x = x + ( x >> 3 ) - 16; \
if( x < 0 ) x = 0; \
if( x > 255 ) x = 255;
int y,u,v;
int r,g,b;
int uvRed, uvGreen, uvBlue;
unsigned int counter = 0;
unsigned int allocated = 0;
unsigned short red[256], green[256], blue[256], transp[256];
unsigned char extralookup[2176];
struct fb_cmap cmap = { 0, 256, red, green, blue, transp }; struct fb_cmap cmap = { 0, 256, red, green, blue, transp };
for ( y = 0; y <= 256; y += 16 )
{
for ( u = 0; u <= 256; u += 32 )
for ( v = 0; v <= 256; v += 32 )
{
uvRed = (V_RED_COEF*(v-128)) >> SHIFT;
uvGreen = (U_GREEN_COEF*(u-128) + V_GREEN_COEF*(v-128)) >> SHIFT;
uvBlue = (U_BLUE_COEF*(u-128)) >> SHIFT;
r = y + uvRed;
g = y + uvGreen;
b = y + uvBlue;
if( r >= RGB_MIN && g >= RGB_MIN && b >= RGB_MIN
&& r <= RGB_MAX && g <= RGB_MAX && b <= RGB_MAX )
{
if(allocated == 256) { fprintf(stderr, "sorry, no colors left\n"); exit(1); }
/* saturate the colors */
SATURATE( r );
SATURATE( g );
SATURATE( b );
red[allocated] = r << 8;
green[allocated] = g << 8;
blue[allocated] = b << 8;
transp[allocated] = 0;
/* allocate color */
extralookup[counter] = 1;
p_vout->lookup[counter++] = allocated;
allocated++;
}
else
{
extralookup[counter] = 0;
p_vout->lookup[counter++] = 0;
}
}
counter += 128-81;
}
counter = 0;
for ( y = 0; y <= 256; y += 16 )
{
for ( u = 0; u <= 256; u += 32 )
for ( v = 0; v <= 256; v += 32 )
{
int y2, u2, v2;
int dist = 100000000;
if( p_vout->lookup[counter] || y==0)
{
counter++;
continue;
}
for( y2 = y-16; y2 <= y; y2+= 16 )
for( u2 = 0; u2 <= 256; u2 += 32 )
for( v2 = 0; v2 <= 256; v2 += 32 )
{
if( extralookup[((y2>>4)<<7) + (u2>>5)*9 + (v2>>5)])
/* find the nearest color */
if( 128*(y-y2) + (u-u2)*(u-u2) + (v-v2)*(v-v2) < dist )
{
p_vout->lookup[counter] = p_vout->lookup[((y2>>4)<<7) + (u2>>5)*9 + (v2>>5)];
dist = 128*(y-y2) + (u-u2)*(u-u2) + (v-v2)*(v-v2);
}
}
counter++;
}
counter += 128-81;
}
ioctl( p_vout->p_sys->i_fb_dev, FBIOPUTCMAP, &cmap );
}
/*****************************************************************************
* FBInitBWPalette: initialize grayscale palette for 8 bpp
*****************************************************************************/
static void FBInitBWPalette( vout_thread_t *p_vout )
{
unsigned int i;
unsigned short gamma[256], transp[256];
struct fb_cmap cmap = { 0, 256, gamma, gamma, gamma, transp };
for( i=0; i<256; i++ )
{
gamma[i] = i << 8;
transp[i] = 0;
}
ioctl( p_vout->p_sys->i_fb_dev, FBIOPUTCMAP, &cmap ); ioctl( p_vout->p_sys->i_fb_dev, FBIOPUTCMAP, &cmap );
} }
...@@ -54,6 +54,8 @@ static int Manage ( vout_thread_t *p_vout ); ...@@ -54,6 +54,8 @@ static int Manage ( vout_thread_t *p_vout );
static int Align ( vout_thread_t *p_vout, int *pi_x, static int Align ( vout_thread_t *p_vout, int *pi_x,
int *pi_y, int i_width, int i_height, int *pi_y, int i_width, int i_height,
int i_h_align, int i_v_align ); int i_h_align, int i_v_align );
static void SetPalette ( p_vout_thread_t p_vout, u16 *red,
u16 *green, u16 *blue, u16 *transp );
/****************************************************************************** /******************************************************************************
* vout_CreateThread: creates a new video output thread * vout_CreateThread: creates a new video output thread
...@@ -101,6 +103,8 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_ ...@@ -101,6 +103,8 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_
p_vout->b_info = 0; p_vout->b_info = 0;
p_vout->b_interface = 0; p_vout->b_interface = 0;
p_vout->b_scale = 0; p_vout->b_scale = 0;
p_vout->p_set_palette = SetPalette;
intf_DbgMsg("wished configuration: %dx%d, %d/%d bpp (%d Bpl)\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_width, p_vout->i_height, p_vout->i_screen_depth,
...@@ -146,12 +150,12 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_ ...@@ -146,12 +150,12 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_
MaskToShift( &p_vout->i_green_lshift, &p_vout->i_green_rshift, p_vout->i_green_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 ); MaskToShift( &p_vout->i_blue_lshift, &p_vout->i_blue_rshift, p_vout->i_blue_mask );
/* Set some usefull colors */ /* Set some useful colors */
p_vout->i_white_pixel = RGB2PIXEL( p_vout, 255, 255, 255 ); /* 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_black_pixel = RGB2PIXEL( p_vout, 0, 0, 0 );
p_vout->i_gray_pixel = RGB2PIXEL( p_vout, 128, 128, 128 ); p_vout->i_gray_pixel = RGB2PIXEL( p_vout, 128, 128, 128 );
p_vout->i_blue_pixel = RGB2PIXEL( p_vout, 0, 0, 50 ); p_vout->i_blue_pixel = RGB2PIXEL( p_vout, 0, 0, 50 );
*/
/* Load fonts - fonts must be initialized after the systme method since /* Load fonts - fonts must be initialized after the systme method since
* they may be dependant of screen depth and other thread properties */ * they may be dependant of screen depth and other thread properties */
p_vout->p_default_font = vout_LoadFont( VOUT_DEFAULT_FONT ); p_vout->p_default_font = vout_LoadFont( VOUT_DEFAULT_FONT );
...@@ -1880,3 +1884,15 @@ static int Align( vout_thread_t *p_vout, int *pi_x, int *pi_y, ...@@ -1880,3 +1884,15 @@ static int Align( vout_thread_t *p_vout, int *pi_x, int *pi_y,
(*pi_x + i_width > p_vout->i_width) || (*pi_y + i_height > p_vout->i_height) ); (*pi_x + i_width > p_vout->i_width) || (*pi_y + i_height > p_vout->i_height) );
} }
/******************************************************************************
* SetPalette: sets an 8 bpp palette
******************************************************************************
* This function is just a prototype that does nothing. Architectures that
* support palette allocation should override it.
******************************************************************************/
static void SetPalette ( p_vout_thread_t p_vout, u16 *red,
u16 *green, u16 *blue, u16 *transp )
{
intf_ErrMsg( "SetPalette: method does not support palette changing\n" );
}
...@@ -333,12 +333,12 @@ void vout_TextSize( vout_font_t *p_font, int i_style, const char *psz_text, int ...@@ -333,12 +333,12 @@ void vout_TextSize( vout_font_t *p_font, int i_style, const char *psz_text, int
} }
} }
/******************************************************************************* /*****************************************************************************
* vout_Print: low level printing function * vout_Print: low level printing function
******************************************************************************* *****************************************************************************
* This function prints a text, without clipping, in a buffer using a previously * This function prints a text, without clipping, in a buffer using a
* loaded bitmap font. * previously loaded bitmap font.
*******************************************************************************/ *****************************************************************************/
void vout_Print( vout_font_t *p_font, byte_t *p_pic, int i_bytes_per_pixel, int i_bytes_per_line, void vout_Print( vout_font_t *p_font, byte_t *p_pic, int i_bytes_per_pixel, int i_bytes_per_line,
u32 i_char_color, u32 i_border_color, u32 i_bg_color, int i_style, const char *psz_text ) u32 i_char_color, u32 i_border_color, u32 i_bg_color, int i_style, const char *psz_text )
{ {
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment