Commit 28115de8 authored by Vincent Seguin's avatar Vincent Seguin

Mise place du scaling, episode II

Alignement am�lior�
Effacement 'intelligent' des zones modifi�es
Correction d'une memory corruption
Structure d'acceuil pour les subpictures
ggi et fb fonctionnent (pas mieux qu'avant, mais ils compilent)

Ca rame. C'est normal, c'est la YUV en C qui est utilis�e. C'est aussi normal
parce que l'effacement, �a prends un peu de temps (et �a c'est d�finitif).
Ce n'est pas beau: normal, il n'y a que du croping pour le moment, le scaling
arrive.
parent 46acf499
...@@ -260,7 +260,6 @@ ...@@ -260,7 +260,6 @@
/* Time during which the thread will sleep if it has nothing to /* Time during which the thread will sleep if it has nothing to
* display (in micro-seconds) */ * display (in micro-seconds) */
/* ?? this constant will probably evolve to a calculated value */
#define VOUT_IDLE_SLEEP 20000 #define VOUT_IDLE_SLEEP 20000
/* Maximum lap of time allowed between the beginning of rendering and /* Maximum lap of time allowed between the beginning of rendering and
...@@ -268,11 +267,10 @@ ...@@ -268,11 +267,10 @@
* late, the thread will perform an idle loop. This time should be * late, the thread will perform an idle loop. This time should be
* at least VOUT_IDLE_SLEEP plus the time required to render a few * at least VOUT_IDLE_SLEEP plus the time required to render a few
* images, to avoid trashing of decoded images */ * images, to avoid trashing of decoded images */
/* ?? this constant will probably evolve to a calculated value */
#define VOUT_DISPLAY_DELAY 500000 #define VOUT_DISPLAY_DELAY 500000
/* Delay (in microseconds) between increments in idle levels */ /* Delay (in microseconds) before an idle screen is displayed */
#define VOUT_IDLE_DELAY 5000000000000 #define VOUT_IDLE_DELAY 5000000
/* Number of pictures required to computes the FPS rate */ /* Number of pictures required to computes the FPS rate */
#define VOUT_FPS_SAMPLES 20 #define VOUT_FPS_SAMPLES 20
......
...@@ -87,14 +87,14 @@ typedef struct picture_s ...@@ -87,14 +87,14 @@ typedef struct picture_s
#define AR_221_1_PICTURE 4 /* 2.21:1 picture (movie) */ #define AR_221_1_PICTURE 4 /* 2.21:1 picture (movie) */
/******************************************************************************* /*******************************************************************************
* spu_t: video sub picture unit * subpicture_t: video sub picture unit
******************************************************************************* *******************************************************************************
* Any sub picture unit destined to be displayed by a video output thread should * Any sub picture unit destined to be displayed by a video output thread should
* be stored in this structure from it's creation to it's effective display. * be stored in this structure from it's creation to it's effective display.
* Subtitle type and flags should only be modified by the output thread. Note * Subtitle type and flags should only be modified by the output thread. Note
* that an empty subtitle MUST have its flags set to 0. * that an empty subtitle MUST have its flags set to 0.
*******************************************************************************/ *******************************************************************************/
typedef struct spu_s typedef struct subpicture_s
{ {
/* Type and flags - should NOT be modified except by the vout thread */ /* Type and flags - should NOT be modified except by the vout thread */
int i_type; /* spu type */ int i_type; /* spu type */
...@@ -104,18 +104,44 @@ typedef struct spu_s ...@@ -104,18 +104,44 @@ typedef struct spu_s
mtime_t begin_date; /* beginning of display date */ mtime_t begin_date; /* beginning of display date */
mtime_t end_date; /* end of display date */ mtime_t end_date; /* end of display date */
/* Display properties - these properties are only indicative and may be
* changed by the video output thread */
int i_x; /* offset from alignment position */
int i_y; /* offset from alignment position */
int i_width; /* picture width */
int i_height; /* picture height */
int i_horizontal_align; /* horizontal alignment */
int i_vertical_align; /* vertical alignment */
/* Sub picture unit data - data can always be freely modified. p_data itself /* Sub picture unit data - data can always be freely modified. p_data itself
* (the pointer) should NEVER be modified. */ * (the pointer) should NEVER be modified. */
void * p_data; /* spu data */ void * p_data; /* spu data */
} spu_t; } subpicture_t;
/* SPU types */ /* Subpicture type */
#define EMPTY_SPU 0 /* subtitle slot is empty and available */ #define EMPTY_SUBPICTURE 0 /* subtitle slot is empty and available */
#define RLE_SPU 100 /* RLE encoded subtitle */ #define RLE_SUBPICTURE 100 /* RLE encoded subtitle */
#define TEXT_SUBPICTURE 200 /* iso8859-1 text subtitle */
/* Subpicture status */ /* Subpicture status */
#define FREE_SPU 0 /* subtitle is free and not allocated */ #define FREE_SUBPICTURE 0 /* subpicture is free and not allocated */
#define RESERVED_SPU 1 /* subtitle is allocated and reserved */ #define RESERVED_SUBPICTURE 1 /* subpicture is allocated and reserved */
#define READY_SPU 2 /* subtitle is ready for display */ #define READY_SUBPICTURE 2 /* subpicture is ready for display */
#define DESTROYED_SPU 3 /* subtitle is allocated but no more used */ #define DESTROYED_SUBPICTURE 3 /* subpicture is allocated but no more used */
/* Alignment types */
#define RIGHT_ALIGN 10 /* x is absolute for right */
#define LEFT_ALIGN 11 /* x is absolute for left */
#define RIGHT_RALIGN 12 /* x is relative for right from right */
#define LEFT_RALIGN 13 /* x is relative for left from left */
#define CENTER_ALIGN 20 /* x, y are absolute for center */
#define CENTER_RALIGN 21 /* x, y are relative for center from center */
#define BOTTOM_ALIGN 30 /* y is absolute for bottom */
#define TOP_ALIGN 31 /* y is absolute for top */
#define BOTTOM_RALIGN 32 /* y is relative for bottom from bottom */
#define TOP_RALIGN 33 /* y is relative for top from top */
#define SUBTITLE_RALIGN 34 /* y is relative for center from subtitle */
...@@ -8,12 +8,41 @@ ...@@ -8,12 +8,41 @@
*******************************************************************************/ *******************************************************************************/
/******************************************************************************* /*******************************************************************************
* vout_tables_t: pre-calculated convertion tables * vout_yuv_convert_t: YUV convertion function
*******************************************************************************
* This is the prototype common to all convertion functions. The type of p_pic
* will change depending of the screen depth treated.
* Parameters:
* p_vout video output thread
* p_pic picture address
* p_y, p_u, p_v Y,U,V samples addresses
* i_width, i_height Y samples extension
* i_skip Y pixels to skip at the end of a line
* i_pic_width, i_pic_height picture extension
* i_pic_skip pixels to skip at the end of a line
* i_matrix_coefficients matrix coefficients
* Conditions:
* i_width % 16 == 0
*******************************************************************************/
typedef void (vout_yuv_convert_t)( 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_skip,
int i_pic_width, int i_pic_height, int i_pic_skip,
int i_matrix_coefficients );
/*******************************************************************************
* vout_yuv_t: pre-calculated YUV convertion tables
******************************************************************************* *******************************************************************************
* These tables are used by convertion and scaling functions. * These tables are used by convertion and scaling functions.
*******************************************************************************/ *******************************************************************************/
typedef struct vout_tables_s typedef struct vout_yuv_s
{ {
/* Convertion functions */
vout_yuv_convert_t * p_Convert420; /* YUV 4:2:0 converter */
vout_yuv_convert_t * p_Convert422; /* YUV 4:2:2 converter */
vout_yuv_convert_t * p_Convert444; /* YUV 4:4:4 converter */
/* Pre-calculated convertion tables */
void * p_base; /* base for all translation tables */ void * p_base; /* base for all translation tables */
union union
{ {
...@@ -21,8 +50,17 @@ typedef struct vout_tables_s ...@@ -21,8 +50,17 @@ typedef struct vout_tables_s
struct { u32 *p_red, *p_green, *p_blue; } rgb32; /* color 24, 32 bpp */ struct { u32 *p_red, *p_green, *p_blue; } rgb32; /* color 24, 32 bpp */
struct { u16 *p_gray; } gray16; /* gray 15, 16 bpp */ struct { u16 *p_gray; } gray16; /* gray 15, 16 bpp */
struct { u32 *p_gray; } gray32; /* gray 24, 32 bpp */ struct { u32 *p_gray; } gray32; /* gray 24, 32 bpp */
} yuv; } yuv;
} vout_tables_t; union
{
u16 * p_rgb16;
u32 * p_rgb32;
} yuv2;//??
/* Temporary convertion buffer - this buffer may be used by convertion
* functions and should be 2 screen lines width */
void * p_buffer; /* convertion buffer */
} vout_yuv_t;
/******************************************************************************* /*******************************************************************************
* vout_buffer_t: rendering buffer * vout_buffer_t: rendering buffer
...@@ -45,31 +83,6 @@ typedef struct vout_buffer_s ...@@ -45,31 +83,6 @@ typedef struct vout_buffer_s
byte_t * p_data; /* memory address */ byte_t * p_data; /* memory address */
} vout_buffer_t; } vout_buffer_t;
/*******************************************************************************
* vout_convert_t: convertion function
*******************************************************************************
* This is the prototype common to all convertion functions. The type of p_pic
* will change depending of the screen depth treated.
* Parameters:
* p_vout video output thread
* p_pic picture address (start address in picture)
* p_y, p_u, p_v Y,U,V samples addresses
* i_width Y samples width
* i_height Y samples height
* i_eol number of Y samples to reach the next line
* i_pic_eol number or pixels to reach the next line
* i_scale if non 0, vertical scaling is 1 - 1/i_scale
* i_matrix_coefficients matrix coefficients
* Conditions:
* start x + i_width < picture width
* start y + i_height * (scaling factor) < picture height
* i_width % 16 == 0
*******************************************************************************/
typedef void (vout_convert_t)( 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_eol, int i_pic_eol,
int i_scale, int i_matrix_coefficients );
/******************************************************************************* /*******************************************************************************
* vout_thread_t: video output thread descriptor * vout_thread_t: video output thread descriptor
******************************************************************************* *******************************************************************************
...@@ -85,12 +98,13 @@ typedef struct vout_thread_s ...@@ -85,12 +98,13 @@ typedef struct vout_thread_s
boolean_t b_active; /* `active' flag */ boolean_t b_active; /* `active' flag */
vlc_thread_t thread_id; /* id for pthread functions */ vlc_thread_t thread_id; /* id for pthread functions */
vlc_mutex_t picture_lock; /* picture heap lock */ vlc_mutex_t picture_lock; /* picture heap lock */
vlc_mutex_t spu_lock; /* subtitle heap lock */ vlc_mutex_t subpicture_lock; /* subpicture heap lock */
vlc_mutex_t change_lock; /* thread change lock */ vlc_mutex_t change_lock; /* thread change lock */
int * pi_status; /* temporary status flag */ int * pi_status; /* temporary status flag */
p_vout_sys_t p_sys; /* system output method */ p_vout_sys_t p_sys; /* system output method */
/* Current display properties */ /* Current display properties */
u16 i_changes; /* changes made to the thread */
int i_width; /* current output method width */ int i_width; /* current output method width */
int i_height; /* current output method height */ int i_height; /* current output method height */
int i_bytes_per_line;/* bytes per line (including virtual) */ int i_bytes_per_line;/* bytes per line (including virtual) */
...@@ -104,6 +118,10 @@ typedef struct vout_thread_s ...@@ -104,6 +118,10 @@ typedef struct vout_thread_s
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 */
/* Idle screens management */
mtime_t last_display_date; /* last non idle display date */
mtime_t last_idle_date; /* last idle display date */
#ifdef STATS #ifdef STATS
/* Statistics - these numbers are not supposed to be accurate, but are a /* Statistics - these numbers are not supposed to be accurate, but are a
* good indication of the thread status */ * good indication of the thread status */
...@@ -112,22 +130,14 @@ typedef struct vout_thread_s ...@@ -112,22 +130,14 @@ typedef struct vout_thread_s
mtime_t p_fps_sample[ VOUT_FPS_SAMPLES ]; /* FPS samples dates */ mtime_t p_fps_sample[ VOUT_FPS_SAMPLES ]; /* FPS samples dates */
#endif #endif
/* Running properties */
u16 i_changes; /* changes made to the thread */
mtime_t last_picture_date; /* last picture display date */
mtime_t last_display_date; /* last screen display date */
/* Rendering buffers */ /* Rendering buffers */
int i_buffer_index; /* buffer index */ int i_buffer_index; /* buffer index */
vout_buffer_t p_buffer[2]; /* buffers properties */ vout_buffer_t p_buffer[2]; /* buffers properties */
/* Videos heap and translation tables */ /* Videos heap and translation tables */
picture_t p_picture[VOUT_MAX_PICTURES]; /* pictures */ picture_t p_picture[VOUT_MAX_PICTURES]; /* pictures */
spu_t p_spu[VOUT_MAX_PICTURES]; /* subtitles */ subpicture_t p_subpicture[VOUT_MAX_PICTURES]; /* subpictures */
vout_tables_t tables; /* translation tables */ vout_yuv_t yuv; /* translation tables */
vout_convert_t * p_ConvertYUV420; /* YUV 4:2:0 converter */
vout_convert_t * p_ConvertYUV422; /* YUV 4:2:2 converter */
vout_convert_t * p_ConvertYUV444; /* YUV 4:4:4 converter */
/* Bitmap fonts */ /* Bitmap fonts */
p_vout_font_t p_default_font; /* default font */ p_vout_font_t p_default_font; /* default font */
...@@ -143,6 +153,7 @@ typedef struct vout_thread_s ...@@ -143,6 +153,7 @@ typedef struct vout_thread_s
#define VOUT_SIZE_CHANGE 0x0200 /* size changed */ #define VOUT_SIZE_CHANGE 0x0200 /* size changed */
#define VOUT_DEPTH_CHANGE 0x0400 /* depth changed */ #define VOUT_DEPTH_CHANGE 0x0400 /* depth changed */
#define VOUT_GAMMA_CHANGE 0x0010 /* gamma changed */ #define VOUT_GAMMA_CHANGE 0x0010 /* gamma changed */
#define VOUT_YUV_CHANGE 0x0800 /* change yuv tables */
#define VOUT_NODISPLAY_CHANGE 0xff00 /* changes which forbidden display */ #define VOUT_NODISPLAY_CHANGE 0xff00 /* changes which forbidden display */
/******************************************************************************* /*******************************************************************************
...@@ -158,15 +169,8 @@ void vout_DisplayPicture ( vout_thread_t *p_vout, picture_t *p_pi ...@@ -158,15 +169,8 @@ void vout_DisplayPicture ( vout_thread_t *p_vout, picture_t *p_pi
void vout_DatePicture ( vout_thread_t *p_vout, picture_t *p_pic, mtime_t date ); void vout_DatePicture ( vout_thread_t *p_vout, picture_t *p_pic, mtime_t date );
void vout_LinkPicture ( vout_thread_t *p_vout, picture_t *p_pic ); void vout_LinkPicture ( vout_thread_t *p_vout, picture_t *p_pic );
void vout_UnlinkPicture ( vout_thread_t *p_vout, picture_t *p_pic ); void vout_UnlinkPicture ( vout_thread_t *p_vout, picture_t *p_pic );
spu_t * vout_CreateSubPictureUnit ( vout_thread_t *p_vout, int i_type, int i_size ); subpicture_t * vout_CreateSubPicture ( vout_thread_t *p_vout, int i_type, int i_size );
void vout_DestroySubPictureUnit ( vout_thread_t *p_vout, spu_t *p_spu ); void vout_DestroySubPicture ( vout_thread_t *p_vout, subpicture_t *p_subpic );
void vout_DisplaySubPictureUnit ( vout_thread_t *p_vout, spu_t *p_spu ); void vout_DisplaySubPicture ( vout_thread_t *p_vout, subpicture_t *p_subpic );
void vout_ClearBuffer ( vout_thread_t *p_vout, vout_buffer_t *p_buffer );
void vout_SetBuffers ( vout_thread_t *p_vout, void *p_buf1, void *p_buf2 );
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* They may be ignored or interpreted by higher level functions */ * They may be ignored or interpreted by higher level functions */
#define WIDE_TEXT 1 /* interspacing is doubled */ #define WIDE_TEXT 1 /* interspacing is doubled */
#define ITALIC_TEXT 2 /* italic */ #define ITALIC_TEXT 2 /* italic */
#define TRANSPARENT_TEXT 4 /* transparent text */ #define OPAQUE_TEXT 4 /* text with background */
#define OUTLINED_TEXT 8 /* border around letters */ #define OUTLINED_TEXT 8 /* border around letters */
#define VOID_TEXT 16 /* no foreground */ #define VOID_TEXT 16 /* no foreground */
......
...@@ -9,9 +9,9 @@ ...@@ -9,9 +9,9 @@
/******************************************************************************* /*******************************************************************************
* Prototypes * Prototypes
*******************************************************************************/ *******************************************************************************/
int vout_InitTables ( vout_thread_t *p_vout ); int vout_InitYUV ( vout_thread_t *p_vout );
int vout_ResetTables ( vout_thread_t *p_vout ); int vout_ResetYUV ( vout_thread_t *p_vout );
void vout_EndTables ( vout_thread_t *p_vout ); void vout_EndYUV ( vout_thread_t *p_vout );
/******************************************************************************* /*******************************************************************************
* External prototypes * External prototypes
......
...@@ -250,7 +250,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int i_key ) ...@@ -250,7 +250,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int i_key )
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 );
p_intf->p_vout->b_scale = !p_intf->p_vout->b_scale; p_intf->p_vout->b_scale = !p_intf->p_vout->b_scale;
p_intf->p_vout->i_changes |= VOUT_SCALE_CHANGE; p_intf->p_vout->i_changes |= VOUT_SCALE_CHANGE;
vlc_mutex_unlock( &p_intf->p_vout->change_lock ); vlc_mutex_unlock( &p_intf->p_vout->change_lock );
} }
......
...@@ -53,8 +53,6 @@ typedef struct vout_sys_s ...@@ -53,8 +53,6 @@ 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 FBBlankDisplay ( vout_thread_t *p_vout );
/****************************************************************************** /******************************************************************************
* vout_SysCreate: allocates FB video thread output method * vout_SysCreate: allocates FB video thread output method
...@@ -221,7 +219,7 @@ static int FBOpenDisplay( vout_thread_t *p_vout ) ...@@ -221,7 +219,7 @@ static int FBOpenDisplay( vout_thread_t *p_vout )
break; break;
default: /* unsupported screen depth */ default: /* unsupported screen depth */
intf_ErrMsg("vout error: screen depth %i is not supported\n", intf_ErrMsg("vout error: screen depth %d is not supported\n",
p_vout->i_screen_depth); p_vout->i_screen_depth);
return( 1 ); return( 1 );
break; break;
...@@ -242,16 +240,10 @@ static int FBOpenDisplay( vout_thread_t *p_vout ) ...@@ -242,16 +240,10 @@ static int FBOpenDisplay( vout_thread_t *p_vout )
} }
/* Set and initialize buffers */ /* Set and initialize buffers */
p_vout->p_buffer[0].p_data = p_vout->p_sys->p_video; vout_SetBuffers( p_vout, p_vout->p_sys->p_video,
p_vout->p_buffer[1].p_data = p_vout->p_sys->p_video + p_vout->p_sys->i_page_size; p_vout->p_sys->p_video + p_vout->p_sys->i_page_size );
vout_ClearBuffer( p_vout, &p_vout->p_buffer[0] );
vout_ClearBuffer( p_vout, &p_vout->p_buffer[1] );
intf_DbgMsg("framebuffer type=%d, visual=%d, ypanstep=%d, ywrap=%d, accel=%d\n", intf_DbgMsg("framebuffer type=%d, visual=%d, ypanstep=%d, ywrap=%d, accel=%d\n",
fix_info.type, fix_info.visual, fix_info.ypanstep, fix_info.ywrapstep, fix_info.accel ); fix_info.type, fix_info.visual, fix_info.ypanstep, fix_info.ywrapstep, fix_info.accel );
intf_Msg("vout: framebuffer display initialized (%s), %dx%d depth=%d bpp\n",
fix_info.id, p_vout->i_width, p_vout->i_height, p_vout->i_screen_depth );
return( 0 ); return( 0 );
} }
......
...@@ -258,16 +258,6 @@ static int GGIOpenDisplay( vout_thread_t *p_vout, char *psz_display ) ...@@ -258,16 +258,6 @@ static int GGIOpenDisplay( vout_thread_t *p_vout, char *psz_display )
} }
#endif #endif
/* Get font size */
if( ggiGetCharSize( p_vout->p_sys->p_display, &p_vout->p_sys->i_char_width,
&p_vout->p_sys->i_char_height ) )
{
intf_ErrMsg("error: can't get font size\n");
ggiClose( p_vout->p_sys->p_display );
ggiExit();
return( 1 );
}
/* Set graphic context colors */ /* Set graphic context colors */
col_fg.r = col_fg.g = col_fg.b = -1; col_fg.r = col_fg.g = col_fg.b = -1;
col_bg.r = col_bg.g = col_bg.b = 0; col_bg.r = col_bg.g = col_bg.b = 0;
...@@ -323,10 +313,7 @@ static int GGIOpenDisplay( vout_thread_t *p_vout, char *psz_display ) ...@@ -323,10 +313,7 @@ static int GGIOpenDisplay( vout_thread_t *p_vout, char *psz_display )
} }
/* Set and initialize buffers */ /* Set and initialize buffers */
p_vout->p_buffer[0].p_data = p_vout->p_sys->p_buffer[ 0 ]->write; vout_SetBuffers( p_vout, p_vout->p_sys->p_buffer[ 0 ]->write, p_vout->p_sys->p_buffer[ 1 ]->write );
p_vout->p_buffer[1].p_data = p_vout->p_sys->p_buffer[ 1 ]->write;
vout_ClearBuffer( p_vout, &p_vout->p_buffer[0] );
vout_ClearBuffer( p_vout, &p_vout->p_buffer[1] );
return( 0 ); return( 0 );
} }
......
...@@ -35,17 +35,19 @@ static void RunThread ( vout_thread_t *p_vout ); ...@@ -35,17 +35,19 @@ static void RunThread ( vout_thread_t *p_vout );
static void ErrorThread ( vout_thread_t *p_vout ); static void ErrorThread ( vout_thread_t *p_vout );
static void EndThread ( vout_thread_t *p_vout ); static void EndThread ( vout_thread_t *p_vout );
static void DestroyThread ( vout_thread_t *p_vout, int i_status ); static void DestroyThread ( vout_thread_t *p_vout, int i_status );
static void Print ( vout_thread_t *p_vout, int i_x, int i_y, int i_halign, int i_valign, unsigned char *psz_text ); static void Print ( vout_thread_t *p_vout, int i_x, int i_y,
int i_h_align, int i_v_align, unsigned char *psz_text );
static void SetBufferArea ( vout_thread_t *p_vout, int i_x, int i_y, int i_w, int i_h ); static void SetBufferArea ( vout_thread_t *p_vout, int i_x, int i_y, int i_w, int i_h );
static void SetBufferPicture ( vout_thread_t *p_vout, picture_t *p_pic ); static void SetBufferPicture ( vout_thread_t *p_vout, picture_t *p_pic );
static void RenderPicture ( vout_thread_t *p_vout, picture_t *p_pic ); static void RenderPicture ( vout_thread_t *p_vout, picture_t *p_pic );
static void RenderPictureInfo ( vout_thread_t *p_vout, picture_t *p_pic ); static void RenderPictureInfo ( vout_thread_t *p_vout, picture_t *p_pic );
static void RenderSubPictureUnit ( vout_thread_t *p_vout, spu_t *p_spu ); static void RenderSubPicture ( vout_thread_t *p_vout, subpicture_t *p_subpic );
static void RenderInterface ( vout_thread_t *p_vout ); static void RenderInterface ( vout_thread_t *p_vout );
static void RenderIdle ( vout_thread_t *p_vout ); static int RenderIdle ( vout_thread_t *p_vout );
static void RenderInfo ( vout_thread_t *p_vout ); static void RenderInfo ( vout_thread_t *p_vout );
static int Manage ( vout_thread_t *p_vout ); static int Manage ( vout_thread_t *p_vout );
static int Align ( vout_thread_t *p_vout, int *pi_x, int *pi_y,
int i_width, int i_height, int i_h_align, int i_v_align );
/****************************************************************************** /******************************************************************************
* vout_CreateThread: creates a new video output thread * vout_CreateThread: creates a new video output thread
...@@ -81,6 +83,7 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_ ...@@ -81,6 +83,7 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_
/* Initialize some fields used by the system-dependant method - these fields will /* Initialize some fields used by the system-dependant method - these fields will
* probably be modified by the method, and are only preferences */ * probably be modified by the method, and are only preferences */
p_vout->i_changes = 0;
p_vout->i_width = i_width; p_vout->i_width = i_width;
p_vout->i_height = i_height; p_vout->i_height = i_height;
p_vout->i_bytes_per_line = i_width * 2; p_vout->i_bytes_per_line = i_width * 2;
...@@ -98,28 +101,27 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_ ...@@ -98,28 +101,27 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_
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,
p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line ); p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line );
/* Initialize idle screen */
p_vout->last_display_date = mdate();
p_vout->last_idle_date = 0;
#ifdef STATS #ifdef STATS
/* Initialize statistics fields */ /* Initialize statistics fields */
p_vout->render_time = 0; p_vout->render_time = 0;
p_vout->c_fps_samples = 0; p_vout->c_fps_samples = 0;
#endif #endif
/* Initialize running properties */
p_vout->i_changes = 0;
p_vout->last_picture_date = 0;
p_vout->last_display_date = 0;
/* Initialize buffer index */ /* Initialize buffer index */
p_vout->i_buffer_index = 0; p_vout->i_buffer_index = 0;
/* Initialize pictures and spus - translation tables and functions /* Initialize pictures and subpictures - translation tables and functions
* will be initialized later in InitThread */ * will be initialized later in InitThread */
for( i_index = 0; i_index < VOUT_MAX_PICTURES; i_index++) for( i_index = 0; i_index < VOUT_MAX_PICTURES; i_index++)
{ {
p_vout->p_picture[i_index].i_type = EMPTY_PICTURE; p_vout->p_picture[i_index].i_type = EMPTY_PICTURE;
p_vout->p_picture[i_index].i_status = FREE_PICTURE; p_vout->p_picture[i_index].i_status = FREE_PICTURE;
p_vout->p_spu[i_index].i_type = EMPTY_SPU; p_vout->p_subpicture[i_index].i_type = EMPTY_SUBPICTURE;
p_vout->p_spu[i_index].i_status= FREE_SPU; p_vout->p_subpicture[i_index].i_status= FREE_SUBPICTURE;
} }
/* Create and initialize system-dependant method - this function issues its /* Create and initialize system-dependant method - this function issues its
...@@ -153,7 +155,7 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_ ...@@ -153,7 +155,7 @@ vout_thread_t * vout_CreateThread ( char *psz_display, int i_root_
/* Create thread and set locks */ /* Create thread and set locks */
vlc_mutex_init( &p_vout->picture_lock ); vlc_mutex_init( &p_vout->picture_lock );
vlc_mutex_init( &p_vout->spu_lock ); vlc_mutex_init( &p_vout->subpicture_lock );
vlc_mutex_init( &p_vout->change_lock ); vlc_mutex_init( &p_vout->change_lock );
vlc_mutex_lock( &p_vout->change_lock ); vlc_mutex_lock( &p_vout->change_lock );
if( vlc_thread_create( &p_vout->thread_id, "video output", (void *) RunThread, (void *) p_vout) ) if( vlc_thread_create( &p_vout->thread_id, "video output", (void *) RunThread, (void *) p_vout) )
...@@ -217,13 +219,13 @@ void vout_DestroyThread( vout_thread_t *p_vout, int *pi_status ) ...@@ -217,13 +219,13 @@ void vout_DestroyThread( vout_thread_t *p_vout, int *pi_status )
} }
/****************************************************************************** /******************************************************************************
* vout_DisplaySubPictureUnit: display a sub picture unit * vout_DisplaySubPicture: display a subpicture unit
****************************************************************************** ******************************************************************************
* Remove the reservation flag of an spu, which will cause it to be ready for * Remove the reservation flag of an subpicture, which will cause it to be ready
* display. The picture does not need to be locked, since it is ignored by * for display. The picture does not need to be locked, since it is ignored by
* the output thread if is reserved. * the output thread if is reserved.
******************************************************************************/ ******************************************************************************/
void vout_DisplaySubPictureUnit( vout_thread_t *p_vout, spu_t *p_spu ) void vout_DisplaySubPicture( vout_thread_t *p_vout, subpicture_t *p_subpic )
{ {
#ifdef DEBUG_VIDEO #ifdef DEBUG_VIDEO
char psz_begin_date[MSTRTIME_MAX_SIZE]; /* buffer for date string */ char psz_begin_date[MSTRTIME_MAX_SIZE]; /* buffer for date string */
...@@ -232,59 +234,62 @@ void vout_DisplaySubPictureUnit( vout_thread_t *p_vout, spu_t *p_spu ) ...@@ -232,59 +234,62 @@ void vout_DisplaySubPictureUnit( vout_thread_t *p_vout, spu_t *p_spu )
#ifdef DEBUG #ifdef DEBUG
/* Check if status is valid */ /* Check if status is valid */
if( p_spu->i_status != RESERVED_SPU ) if( p_subpic->i_status != RESERVED_SUBPICTURE )
{ {
intf_DbgMsg("error: spu %p has invalid status %d\n", p_spu, p_spu->i_status ); intf_DbgMsg("error: subpicture %p has invalid status %d\n", p_subpic,
p_subpic->i_status );
} }
#endif #endif
/* Remove reservation flag */ /* Remove reservation flag */
p_spu->i_status = READY_SPU; p_subpic->i_status = READY_SUBPICTURE;
#ifdef DEBUG_VIDEO #ifdef DEBUG_VIDEO
/* Send subpicture informations */ /* Send subpicture informations */
intf_DbgMsg("spu %p: type=%d, begin date=%s, end date=%s\n", p_spu, p_spu->i_type, intf_DbgMsg("subpicture %p: type=%d, begin date=%s, end date=%s\n",
mstrtime( psz_begin_date, p_spu->begin_date ), p_subpic, p_subpic->i_type,
mstrtime( psz_end_date, p_spu->end_date ) ); mstrtime( psz_begin_date, p_subpic->begin_date ),
mstrtime( psz_end_date, p_subpic->end_date ) );
#endif #endif
} }
/****************************************************************************** /******************************************************************************
* vout_CreateSubPictureUnit: allocate an spu in the video output heap. * vout_CreateSubPicture: allocate an subpicture in the video output heap.
****************************************************************************** ******************************************************************************
* This function create a reserved spu in the video output heap. * This function create a reserved subpicture in the video output heap.
* A null pointer is returned if the function fails. This method provides an * A null pointer is returned if the function fails. This method provides an
* already allocated zone of memory in the spu data fields. It needs locking * already allocated zone of memory in the spu data fields. It needs locking
* since several pictures can be created by several producers threads. * since several pictures can be created by several producers threads.
******************************************************************************/ ******************************************************************************/
spu_t *vout_CreateSubPictureUnit( vout_thread_t *p_vout, int i_type, subpicture_t *vout_CreateSubPicture( vout_thread_t *p_vout, int i_type,
int i_size ) int i_size )
{ {
//?? //??
} }
/****************************************************************************** /******************************************************************************
* vout_DestroySubPictureUnit: remove a permanent or reserved spu from the heap * vout_DestroySubPicture: remove a subpicture from the heap
****************************************************************************** ******************************************************************************
* This function frees a previously reserved spu. * This function frees a previously reserved subpicture.
* It is meant to be used when the construction of a picture aborted. * It is meant to be used when the construction of a picture aborted.
* This function does not need locking since reserved spus are ignored by * This function does not need locking since reserved subpictures are ignored
* the output thread. * by the output thread.
******************************************************************************/ ******************************************************************************/
void vout_DestroySubPictureUnit( vout_thread_t *p_vout, spu_t *p_spu ) void vout_DestroySubPicture( vout_thread_t *p_vout, subpicture_t *p_subpic )
{ {
#ifdef DEBUG #ifdef DEBUG
/* Check if spu status is valid */ /* Check if status is valid */
if( p_spu->i_status != RESERVED_SPU ) if( p_subpic->i_status != RESERVED_SUBPICTURE )
{ {
intf_DbgMsg("error: spu %p has invalid status %d\n", p_spu, p_spu->i_status ); intf_DbgMsg("error: subpicture %p has invalid status %d\n",
p_subpic, p_subpic->i_status );
} }
#endif #endif
p_spu->i_status = DESTROYED_SPU; p_subpic->i_status = DESTROYED_SUBPICTURE;
#ifdef DEBUG_VIDEO #ifdef DEBUG_VIDEO
intf_DbgMsg("spu %p\n", p_spu); intf_DbgMsg("subpicture %p\n", p_subpic);
#endif #endif
} }
...@@ -575,23 +580,34 @@ void vout_UnlinkPicture( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -575,23 +580,34 @@ void vout_UnlinkPicture( vout_thread_t *p_vout, picture_t *p_pic )
} }
/****************************************************************************** /******************************************************************************
* vout_ClearBuffer: clear a whole buffer * vout_SetBuffers: set buffers adresses
****************************************************************************** ******************************************************************************
* This function is called when a buffer is initialized. It clears the whole * This function is called by system drivers to set buffers video memory
* buffer. * adresses.
******************************************************************************/ ******************************************************************************/
void vout_ClearBuffer( vout_thread_t *p_vout, vout_buffer_t *p_buffer ) void vout_SetBuffers( vout_thread_t *p_vout, void *p_buf1, void *p_buf2 )
{ {
/* No picture previously */ /* No picture previously */
p_buffer->i_pic_x = 0; p_vout->p_buffer[0].i_pic_x = 0;
p_buffer->i_pic_y = 0; p_vout->p_buffer[0].i_pic_y = 0;
p_buffer->i_pic_width = 0; p_vout->p_buffer[0].i_pic_width = 0;
p_buffer->i_pic_height = 0; p_vout->p_buffer[0].i_pic_height = 0;
p_vout->p_buffer[1].i_pic_x = 0;
p_vout->p_buffer[1].i_pic_y = 0;
p_vout->p_buffer[1].i_pic_width = 0;
p_vout->p_buffer[1].i_pic_height = 0;
/* The first area covers all the screen */ /* The first area covers all the screen */
p_buffer->i_areas = 1; p_vout->p_buffer[0].i_areas = 1;
p_buffer->pi_area_begin[0] = 0; p_vout->p_buffer[0].pi_area_begin[0] = 0;
p_buffer->pi_area_end[0] = p_vout->i_height - 1; p_vout->p_buffer[0].pi_area_end[0] = p_vout->i_height - 1;
p_vout->p_buffer[1].i_areas = 1;
p_vout->p_buffer[1].pi_area_begin[0] = 0;
p_vout->p_buffer[1].pi_area_end[0] = p_vout->i_height - 1;
/* Set adresses */
p_vout->p_buffer[0].p_data = p_buf1;
p_vout->p_buffer[1].p_data = p_buf2;
} }
/* following functions are local */ /* following functions are local */
...@@ -616,9 +632,9 @@ static int InitThread( vout_thread_t *p_vout ) ...@@ -616,9 +632,9 @@ static int InitThread( vout_thread_t *p_vout )
} }
/* Initialize convertion tables and functions */ /* Initialize convertion tables and functions */
if( vout_InitTables( p_vout ) ) if( vout_InitYUV( p_vout ) )
{ {
intf_ErrMsg("error: can't allocate translation tables\n"); intf_ErrMsg("error: can't allocate YUV translation tables\n");
return( 1 ); return( 1 );
} }
...@@ -643,7 +659,7 @@ static void RunThread( vout_thread_t *p_vout) ...@@ -643,7 +659,7 @@ static void RunThread( vout_thread_t *p_vout)
mtime_t display_date; /* display date */ mtime_t display_date; /* display date */
boolean_t b_display; /* display flag */ boolean_t b_display; /* display flag */
picture_t * p_pic; /* picture pointer */ picture_t * p_pic; /* picture pointer */
spu_t * p_spu; /* subpicture pointer */ subpicture_t * p_subpic; /* subpicture pointer */
/* /*
* Initialize thread * Initialize thread
...@@ -664,7 +680,7 @@ static void RunThread( vout_thread_t *p_vout) ...@@ -664,7 +680,7 @@ static void RunThread( vout_thread_t *p_vout)
{ {
/* Initialize loop variables */ /* Initialize loop variables */
p_pic = NULL; p_pic = NULL;
p_spu = NULL; p_subpic = NULL;
display_date = 0; display_date = 0;
current_date = mdate(); current_date = mdate();
...@@ -712,18 +728,19 @@ static void RunThread( vout_thread_t *p_vout) ...@@ -712,18 +728,19 @@ static void RunThread( vout_thread_t *p_vout)
/* /*
* Find the subpicture to display - this operation does not need lock, since * Find the subpicture to display - this operation does not need lock, since
* only READY_SPUs are handled. If no picture has been selected, * only READY_SUBPICTURES are handled. If no picture has been selected,
* display_date will depend on the spu * display_date will depend on the subpicture
*/ */
//?? //??
/* /*
* Perform rendering, sleep and display rendered picture * Perform rendering, sleep and display rendered picture
*/ */
if( p_pic ) /* picture and perhaps spu */ if( p_pic ) /* picture and perhaps subpicture */
{ {
b_display = p_vout->b_active; b_display = p_vout->b_active;
p_vout->last_display_date = display_date;
if( b_display ) if( b_display )
{ {
/* Set picture dimensions and clear buffer */ /* Set picture dimensions and clear buffer */
...@@ -743,35 +760,36 @@ static void RunThread( vout_thread_t *p_vout) ...@@ -743,35 +760,36 @@ static void RunThread( vout_thread_t *p_vout)
p_pic->i_status = p_pic->i_refcount ? DISPLAYED_PICTURE : DESTROYED_PICTURE; p_pic->i_status = p_pic->i_refcount ? DISPLAYED_PICTURE : DESTROYED_PICTURE;
vlc_mutex_unlock( &p_vout->picture_lock ); vlc_mutex_unlock( &p_vout->picture_lock );
/* Render interface and spus */ /* Render interface and subpicture */
if( b_display && p_vout->b_interface ) if( b_display && p_vout->b_interface )
{ {
RenderInterface( p_vout ); RenderInterface( p_vout );
} }
if( p_spu ) if( p_subpic )
{ {
if( b_display ) if( b_display )
{ {
RenderSubPictureUnit( p_vout, p_spu ); RenderSubPicture( p_vout, p_subpic );
} }
/* Remove spu from heap */ /* Remove subpicture from heap */
vlc_mutex_lock( &p_vout->spu_lock ); vlc_mutex_lock( &p_vout->subpicture_lock );
p_spu->i_status = DESTROYED_SPU; p_subpic->i_status = DESTROYED_SUBPICTURE;
vlc_mutex_unlock( &p_vout->spu_lock ); vlc_mutex_unlock( &p_vout->subpicture_lock );
} }
} }
else if( p_spu ) /* spu alone */ else if( p_subpic ) /* subpicture alone */
{ {
b_display = p_vout->b_active; b_display = p_vout->b_active;
p_vout->last_display_date = display_date;
if( b_display ) if( b_display )
{ {
/* Clear buffer */ /* Clear buffer */
SetBufferPicture( p_vout, NULL ); SetBufferPicture( p_vout, NULL );
/* Render informations, interface and spu */ /* Render informations, interface and subpicture */
if( p_vout->b_info ) if( p_vout->b_info )
{ {
RenderInfo( p_vout ); RenderInfo( p_vout );
...@@ -780,19 +798,41 @@ static void RunThread( vout_thread_t *p_vout) ...@@ -780,19 +798,41 @@ static void RunThread( vout_thread_t *p_vout)
{ {
RenderInterface( p_vout ); RenderInterface( p_vout );
} }
RenderSubPictureUnit( p_vout, p_spu ); RenderSubPicture( p_vout, p_subpic );
} }
/* Remove spu from heap */ /* Remove subpicture from heap */
vlc_mutex_lock( &p_vout->spu_lock ); vlc_mutex_lock( &p_vout->subpicture_lock );
p_spu->i_status = DESTROYED_SPU; p_subpic->i_status = DESTROYED_SUBPICTURE;
vlc_mutex_unlock( &p_vout->spu_lock ); vlc_mutex_unlock( &p_vout->subpicture_lock );
}
else /* idle screen alone */
{
//??? render on idle screen or interface change
b_display = 0; //???
} }
else if( p_vout->b_active ) /* idle or interface screen alone */
{
//?? clear: SetBufferPicture( p_vout, NULL );
if( p_vout->b_interface /* && ?? intf_change -> cause use of 100% CPU ! */ )
{
/* Interface has changed, so a new rendering is required - force
* it by setting last idle date to 0 */
p_vout->last_idle_date = 0;
}
/* Render idle screen and update idle date, then render interface if
* required */
b_display = RenderIdle( p_vout );
if( b_display )
{
p_vout->last_idle_date = current_date;
if( p_vout->b_interface )
{
RenderInterface( p_vout );
}
}
}
else
{
b_display = 0;
}
/* /*
* Sleep, wake up and display rendered picture * Sleep, wake up and display rendered picture
...@@ -820,7 +860,7 @@ static void RunThread( vout_thread_t *p_vout) ...@@ -820,7 +860,7 @@ static void RunThread( vout_thread_t *p_vout)
* then swap buffers */ * then swap buffers */
vlc_mutex_lock( &p_vout->change_lock ); vlc_mutex_lock( &p_vout->change_lock );
#ifdef DEBUG_VIDEO #ifdef DEBUG_VIDEO
intf_DbgMsg( "picture %p, spu %p\n", p_pic, p_spu ); intf_DbgMsg( "picture %p, subpicture %p\n", p_pic, p_subpic );
#endif #endif
if( b_display && !(p_vout->i_changes & VOUT_NODISPLAY_CHANGE) ) if( b_display && !(p_vout->i_changes & VOUT_NODISPLAY_CHANGE) )
{ {
...@@ -886,21 +926,21 @@ static void EndThread( vout_thread_t *p_vout ) ...@@ -886,21 +926,21 @@ static void EndThread( vout_thread_t *p_vout )
intf_DbgMsg("\n"); intf_DbgMsg("\n");
*p_vout->pi_status = THREAD_END; *p_vout->pi_status = THREAD_END;
/* Destroy all remaining pictures and spus */ /* Destroy all remaining pictures and subpictures */
for( i_index = 0; i_index < VOUT_MAX_PICTURES; i_index++ ) for( i_index = 0; i_index < VOUT_MAX_PICTURES; i_index++ )
{ {
if( p_vout->p_picture[i_index].i_status != FREE_PICTURE ) if( p_vout->p_picture[i_index].i_status != FREE_PICTURE )
{ {
free( p_vout->p_picture[i_index].p_data ); free( p_vout->p_picture[i_index].p_data );
} }
if( p_vout->p_spu[i_index].i_status != FREE_SPU ) if( p_vout->p_subpicture[i_index].i_status != FREE_SUBPICTURE )
{ {
free( p_vout->p_spu[i_index].p_data ); free( p_vout->p_subpicture[i_index].p_data );
} }
} }
/* Destroy translation tables */ /* Destroy translation tables */
vout_EndTables( p_vout ); vout_EndYUV( p_vout );
vout_SysEnd( p_vout ); vout_SysEnd( p_vout );
} }
...@@ -932,46 +972,22 @@ static void DestroyThread( vout_thread_t *p_vout, int i_status ) ...@@ -932,46 +972,22 @@ static void DestroyThread( vout_thread_t *p_vout, int i_status )
* This function will print a simple text on the picture. It is designed to * This function will print a simple text on the picture. It is designed to
* print debugging or general informations. * print debugging or general informations.
*******************************************************************************/ *******************************************************************************/
void Print( vout_thread_t *p_vout, int i_x, int i_y, int i_halign, int i_valign, unsigned char *psz_text ) void Print( vout_thread_t *p_vout, int i_x, int i_y, int i_h_align, int i_v_align, unsigned char *psz_text )
{ {
int i_text_height; /* total text height */ int i_text_height; /* total text height */
int i_text_width; /* total text width */ int i_text_width; /* total text width */
/* Update upper left coordinates according to alignment */ /* Update upper left coordinates according to alignment */
vout_TextSize( p_vout->p_default_font, 0, psz_text, &i_text_width, &i_text_height ); vout_TextSize( p_vout->p_default_font, 0, psz_text, &i_text_width, &i_text_height );
switch( i_halign ) if( !Align( p_vout, &i_x, &i_y, i_text_width, i_text_height, i_h_align, i_v_align ) )
{
case 0: /* centered */
i_x -= i_text_width / 2;
break;
case 1: /* right aligned */
i_x -= i_text_width;
break;
}
switch( i_valign )
{
case 0: /* centered */
i_y -= i_text_height / 2;
break;
case 1: /* bottom aligned */
i_y -= i_text_height;
break;
}
/* Check clipping */
if( (i_y < 0) || (i_y + i_text_height > p_vout->i_height) ||
(i_x < 0) || (i_x + i_text_width > p_vout->i_width) )
{ {
intf_DbgMsg("'%s' would print outside the screen\n", psz_text); /* Set area and print text */
return; SetBufferArea( p_vout, i_x, i_y, i_text_width, i_text_height );
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 );
} }
/* Set area and print text */
SetBufferArea( p_vout, i_x, i_y, i_text_width, i_text_height );
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, TRANSPARENT_TEXT, psz_text );
} }
/******************************************************************************* /*******************************************************************************
...@@ -1074,7 +1090,7 @@ static void SetBufferArea( vout_thread_t *p_vout, int i_x, int i_y, int i_w, int ...@@ -1074,7 +1090,7 @@ static void SetBufferArea( vout_thread_t *p_vout, int i_x, int i_y, int i_w, int
{ {
p_buffer->i_areas++; p_buffer->i_areas++;
} }
for( i_area_copy = p_buffer->i_areas - 1; i_area_copy > i_area; i_area_copy++ ) for( i_area_copy = p_buffer->i_areas - 1; i_area_copy > i_area; i_area_copy-- )
{ {
p_buffer->pi_area_begin[i_area_copy] = p_buffer->pi_area_begin[i_area_copy - 1]; p_buffer->pi_area_begin[i_area_copy] = p_buffer->pi_area_begin[i_area_copy - 1];
p_buffer->pi_area_end[i_area_copy] = p_buffer->pi_area_end[i_area_copy - 1]; p_buffer->pi_area_end[i_area_copy] = p_buffer->pi_area_end[i_area_copy - 1];
...@@ -1280,56 +1296,43 @@ static void SetBufferPicture( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -1280,56 +1296,43 @@ static void SetBufferPicture( vout_thread_t *p_vout, picture_t *p_pic )
static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic ) static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
{ {
vout_buffer_t * p_buffer; /* rendering buffer */ vout_buffer_t * p_buffer; /* rendering buffer */
byte_t * p_convert_dst; /* convertion destination */ byte_t * p_pic_data; /* convertion destination */
int i_width, i_height, i_eol, i_pic_eol, i_scale; /* ?? tmp variables*/
/* Get and set rendering informations */ /* Get and set rendering informations */
p_buffer = &p_vout->p_buffer[ p_vout->i_buffer_index ]; p_buffer = &p_vout->p_buffer[ p_vout->i_buffer_index ];
p_vout->last_picture_date = p_pic->date; p_pic_data = p_buffer->p_data +
p_convert_dst = p_buffer->p_data + p_buffer->i_pic_x * p_vout->i_bytes_per_pixel + p_buffer->i_pic_x * p_vout->i_bytes_per_pixel +
p_buffer->i_pic_y * p_vout->i_bytes_per_line; p_buffer->i_pic_y * p_vout->i_bytes_per_line;
// ?? temporary section: rebuild aspect scale from size informations.
// ?? when definitive convertion prototype will be used, those info will
// ?? no longer be required
i_width = MIN( p_pic->i_width, p_buffer->i_pic_width );
i_eol = p_pic->i_width - i_width / 16 * 16;
i_pic_eol = p_vout->i_bytes_per_line / p_vout->i_bytes_per_pixel - i_width;
if( p_pic->i_height == p_buffer->i_pic_height )
{
i_scale = 0;
}
else
{
i_scale = p_pic->i_height / (p_pic->i_height - p_buffer->i_pic_height);
}
i_eol = p_pic->i_width - p_buffer->i_pic_width;
i_height = p_pic->i_height * i_width / p_pic->i_width;
// ?? end of temporary code
/* /*
* Choose appropriate rendering function and render picture * Choose appropriate rendering function and render picture
*/ */
switch( p_pic->i_type ) switch( p_pic->i_type )
{ {
case YUV_420_PICTURE: case YUV_420_PICTURE:
p_vout->p_ConvertYUV420( p_vout, p_convert_dst, p_vout->yuv.p_Convert420( p_vout, p_pic_data,
p_pic->p_y, p_pic->p_u, p_pic->p_v, p_pic->p_y, p_pic->p_u, p_pic->p_v,
i_width, i_height, i_eol, i_pic_eol, i_scale, p_pic->i_width, p_pic->i_height, 0,
p_pic->i_matrix_coefficients ); p_buffer->i_pic_width, p_buffer->i_pic_height,
p_vout->i_bytes_per_line / p_vout->i_bytes_per_pixel - p_buffer->i_pic_width,
p_pic->i_matrix_coefficients );
break; break;
case YUV_422_PICTURE: case YUV_422_PICTURE:
p_vout->p_ConvertYUV422( p_vout, p_convert_dst, p_vout->yuv.p_Convert422( p_vout, p_pic_data,
p_pic->p_y, p_pic->p_u, p_pic->p_v, p_pic->p_y, p_pic->p_u, p_pic->p_v,
i_width, i_height, i_eol, i_pic_eol, i_scale, p_pic->i_width, p_pic->i_height, 0,
p_pic->i_matrix_coefficients ); p_buffer->i_pic_width, p_buffer->i_pic_height,
p_vout->i_bytes_per_line / p_vout->i_bytes_per_pixel - p_buffer->i_pic_width,
p_pic->i_matrix_coefficients );
break; break;
case YUV_444_PICTURE: case YUV_444_PICTURE:
p_vout->p_ConvertYUV444( p_vout, p_convert_dst, p_vout->yuv.p_Convert444( p_vout, p_pic_data,
p_pic->p_y, p_pic->p_u, p_pic->p_v, p_pic->p_y, p_pic->p_u, p_pic->p_v,
i_width, i_height, i_eol, i_pic_eol, i_scale, p_pic->i_width, p_pic->i_height, 0,
p_pic->i_matrix_coefficients ); p_buffer->i_pic_width, p_buffer->i_pic_height,
break; p_vout->i_bytes_per_line / p_vout->i_bytes_per_pixel - p_buffer->i_pic_width,
p_pic->i_matrix_coefficients );
break;
#ifdef DEBUG #ifdef DEBUG
default: default:
intf_DbgMsg("error: unknown picture type %d\n", p_pic->i_type ); intf_DbgMsg("error: unknown picture type %d\n", p_pic->i_type );
...@@ -1359,7 +1362,7 @@ static void RenderPictureInfo( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -1359,7 +1362,7 @@ static void RenderPictureInfo( vout_thread_t *p_vout, picture_t *p_pic )
sprintf( psz_buffer, "%.2f fps", (double) VOUT_FPS_SAMPLES * 1000000 / sprintf( psz_buffer, "%.2f fps", (double) VOUT_FPS_SAMPLES * 1000000 /
( p_vout->p_fps_sample[ (p_vout->c_fps_samples - 1) % VOUT_FPS_SAMPLES ] - ( p_vout->p_fps_sample[ (p_vout->c_fps_samples - 1) % VOUT_FPS_SAMPLES ] -
p_vout->p_fps_sample[ p_vout->c_fps_samples % VOUT_FPS_SAMPLES ] ) ); p_vout->p_fps_sample[ p_vout->c_fps_samples % VOUT_FPS_SAMPLES ] ) );
Print( p_vout, p_vout->i_width, 0, 1, -1, psz_buffer ); Print( p_vout, 0, 0, RIGHT_RALIGN, TOP_RALIGN, psz_buffer );
} }
/* /*
...@@ -1367,7 +1370,7 @@ static void RenderPictureInfo( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -1367,7 +1370,7 @@ static void RenderPictureInfo( vout_thread_t *p_vout, picture_t *p_pic )
*/ */
sprintf( psz_buffer, "%ld frames rendering: %ld us", sprintf( psz_buffer, "%ld frames rendering: %ld us",
(long) p_vout->c_fps_samples, (long) p_vout->render_time ); (long) p_vout->c_fps_samples, (long) p_vout->render_time );
Print( p_vout, 0, 0, -1, -1, psz_buffer ); Print( p_vout, 0, 0, LEFT_RALIGN, TOP_RALIGN, psz_buffer );
#endif #endif
#ifdef DEBUG #ifdef DEBUG
...@@ -1389,20 +1392,45 @@ static void RenderPictureInfo( vout_thread_t *p_vout, picture_t *p_pic ) ...@@ -1389,20 +1392,45 @@ static void RenderPictureInfo( vout_thread_t *p_vout, picture_t *p_pic )
p_vout->p_buffer[ p_vout->i_buffer_index ].i_pic_height, p_vout->p_buffer[ p_vout->i_buffer_index ].i_pic_height,
p_vout->p_buffer[ p_vout->i_buffer_index ].i_pic_x, p_vout->p_buffer[ p_vout->i_buffer_index ].i_pic_x,
p_vout->p_buffer[ p_vout->i_buffer_index ].i_pic_y ); p_vout->p_buffer[ p_vout->i_buffer_index ].i_pic_y );
Print( p_vout, p_vout->i_width, p_vout->i_height, 1, 1, psz_buffer ); Print( p_vout, 0, 0, RIGHT_RALIGN, BOTTOM_RALIGN, psz_buffer );
#endif #endif
} }
/****************************************************************************** /******************************************************************************
* RenderIdle: render idle picture * RenderIdle: render idle picture
****************************************************************************** ******************************************************************************
* This function will print something on the screen. * This function will print something on the screen. It will return 0 if
* nothing has been rendered, or 1 if something has been changed on the screen.
* Note that if you absolutely want something to be printed, you will have
* to force it by setting the last idle date to 0.
******************************************************************************/ ******************************************************************************/
static void RenderIdle( vout_thread_t *p_vout ) static int RenderIdle( vout_thread_t *p_vout )
{ {
//?? int i_x = 0, i_y = 0; /* text position */
Print( p_vout, p_vout->i_width / 2, p_vout->i_height / 2, 0, 0, int i_width, i_height; /* text size */
"no stream" ); //?? mtime_t current_date; /* current date */
const char *psz_text = "no stream"; /* text to display */
current_date = mdate();
if( (current_date - p_vout->last_display_date) > VOUT_IDLE_DELAY &&
(current_date - p_vout->last_idle_date) > VOUT_IDLE_DELAY )
{
vout_TextSize( p_vout->p_large_font, WIDE_TEXT | OUTLINED_TEXT, psz_text,
&i_width, &i_height );
if( !Align( p_vout, &i_x, &i_y, i_width, i_height, CENTER_RALIGN, CENTER_RALIGN ) )
{
vout_Print( p_vout->p_large_font,
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,
WIDE_TEXT | OUTLINED_TEXT, psz_text );
SetBufferArea( p_vout, i_x, i_y, i_width, i_height );
}
return( 1 );
}
return( 0 );
} }
/****************************************************************************** /******************************************************************************
...@@ -1440,16 +1468,16 @@ static void RenderInfo( vout_thread_t *p_vout ) ...@@ -1440,16 +1468,16 @@ static void RenderInfo( vout_thread_t *p_vout )
} }
sprintf( psz_buffer, "pic: %d/%d/%d", sprintf( psz_buffer, "pic: %d/%d/%d",
i_reserved_pic, i_ready_pic, VOUT_MAX_PICTURES ); i_reserved_pic, i_ready_pic, VOUT_MAX_PICTURES );
Print( p_vout, 0, p_vout->i_height, -1, 1, psz_buffer ); Print( p_vout, 0, 0, LEFT_RALIGN, BOTTOM_RALIGN, psz_buffer );
#endif #endif
} }
/******************************************************************************* /*******************************************************************************
* RenderSubPictureUnit: render an spu * RenderSubPicture: render a subpicture
******************************************************************************* *******************************************************************************
* This function render a sub picture unit. * This function render a sub picture unit.
*******************************************************************************/ *******************************************************************************/
static void RenderSubPictureUnit( vout_thread_t *p_vout, spu_t *p_spu ) static void RenderSubPicture( vout_thread_t *p_vout, subpicture_t *p_subpic )
{ {
//?? //??
} }
...@@ -1458,7 +1486,6 @@ static void RenderSubPictureUnit( vout_thread_t *p_vout, spu_t *p_spu ) ...@@ -1458,7 +1486,6 @@ static void RenderSubPictureUnit( vout_thread_t *p_vout, spu_t *p_spu )
* RenderInterface: render the interface * RenderInterface: render the interface
******************************************************************************* *******************************************************************************
* This function render the interface, if any. * This function render the interface, if any.
* ?? this is obviously only a temporary interface !
*******************************************************************************/ *******************************************************************************/
static void RenderInterface( vout_thread_t *p_vout ) static void RenderInterface( vout_thread_t *p_vout )
{ {
...@@ -1469,8 +1496,8 @@ static void RenderInterface( vout_thread_t *p_vout ) ...@@ -1469,8 +1496,8 @@ static void RenderInterface( vout_thread_t *p_vout )
const char *psz_text_2 = "[+/-] Volume [m]ute [s]caling [Q]uit"; const char *psz_text_2 = "[+/-] Volume [m]ute [s]caling [Q]uit";
/* Get text size */ /* Get text size */
vout_TextSize( p_vout->p_large_font, OUTLINED_TEXT | TRANSPARENT_TEXT, psz_text_1, &i_width_1, &i_height ); vout_TextSize( p_vout->p_large_font, OUTLINED_TEXT, psz_text_1, &i_width_1, &i_height );
vout_TextSize( p_vout->p_large_font, OUTLINED_TEXT | TRANSPARENT_TEXT, psz_text_2, &i_width_2, &i_text_height ); vout_TextSize( p_vout->p_large_font, OUTLINED_TEXT, psz_text_2, &i_width_2, &i_text_height );
i_height += i_text_height; i_height += i_text_height;
/* Render background - effective background color will depend of the screen /* Render background - effective background color will depend of the screen
...@@ -1489,7 +1516,7 @@ static void RenderInterface( vout_thread_t *p_vout ) ...@@ -1489,7 +1516,7 @@ static void RenderInterface( vout_thread_t *p_vout )
(p_vout->i_height - i_height) * p_vout->i_bytes_per_line, (p_vout->i_height - i_height) * p_vout->i_bytes_per_line,
p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line, p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line,
0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000,
OUTLINED_TEXT | TRANSPARENT_TEXT, psz_text_1 ); OUTLINED_TEXT, psz_text_1 );
} }
if( i_width_2 < p_vout->i_width ) if( i_width_2 < p_vout->i_width )
{ {
...@@ -1497,7 +1524,7 @@ static void RenderInterface( vout_thread_t *p_vout ) ...@@ -1497,7 +1524,7 @@ static void RenderInterface( vout_thread_t *p_vout )
(p_vout->i_height - i_height + i_text_height) * p_vout->i_bytes_per_line, (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, p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line,
0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000,
OUTLINED_TEXT | TRANSPARENT_TEXT, psz_text_2 ); OUTLINED_TEXT, psz_text_2 );
} }
/* Activate modified area */ /* Activate modified area */
...@@ -1520,14 +1547,21 @@ static int Manage( vout_thread_t *p_vout ) ...@@ -1520,14 +1547,21 @@ static int Manage( vout_thread_t *p_vout )
#endif #endif
/* On gamma or grayscale change, rebuild tables */ /* On gamma or grayscale change, rebuild tables */
if( p_vout->i_changes & (VOUT_GAMMA_CHANGE | VOUT_GRAYSCALE_CHANGE) ) if( p_vout->i_changes & (VOUT_GAMMA_CHANGE | VOUT_GRAYSCALE_CHANGE |
VOUT_YUV_CHANGE) )
{ {
vout_ResetTables( p_vout ); if( vout_ResetYUV( p_vout ) )
} {
intf_ErrMsg("error: can't rebuild convertion tables\n");
return( 1 );
}
}
/* Clear changes flags which does not need management or have been handled */ /* Clear changes flags which does not need management or have been
p_vout->i_changes &= ~(VOUT_GAMMA_CHANGE | VOUT_GRAYSCALE_CHANGE | * handled */
VOUT_INFO_CHANGE | VOUT_INTF_CHANGE | VOUT_SCALE_CHANGE ); p_vout->i_changes &= ~(VOUT_GAMMA_CHANGE | VOUT_GRAYSCALE_CHANGE |
VOUT_YUV_CHANGE | VOUT_INFO_CHANGE |
VOUT_INTF_CHANGE | VOUT_SCALE_CHANGE );
/* Detect unauthorized changes */ /* Detect unauthorized changes */
if( p_vout->i_changes ) if( p_vout->i_changes )
...@@ -1540,3 +1574,57 @@ static int Manage( vout_thread_t *p_vout ) ...@@ -1540,3 +1574,57 @@ static int Manage( vout_thread_t *p_vout )
return( 0 ); return( 0 );
} }
/******************************************************************************
* Align: align a subpicture in the screen
******************************************************************************
* This function is used for rendering text or subpictures. It returns non 0
* it the final aera is not fully included in display area. Return coordinates
* are absolute.
******************************************************************************/
static int Align( vout_thread_t *p_vout, int *pi_x, int *pi_y,
int i_width, int i_height, int i_h_align, int i_v_align )
{
/* Align horizontally */
switch( i_h_align )
{
case CENTER_ALIGN:
*pi_x -= i_width / 2;
break;
case CENTER_RALIGN:
*pi_x += (p_vout->i_width - i_width) / 2;
break;
case RIGHT_ALIGN:
*pi_x -= i_width;
break;
case RIGHT_RALIGN:
*pi_x += p_vout->i_width - i_width;
break;
}
/* Align vertically */
switch( i_v_align )
{
case CENTER_ALIGN:
*pi_y -= i_height / 2;
break;
case CENTER_RALIGN:
*pi_y += (p_vout->i_height - i_height) / 2;
break;
case BOTTOM_ALIGN:
*pi_y -= i_height;
break;
case BOTTOM_RALIGN:
*pi_y += p_vout->i_height - i_height;
break;
case SUBTITLE_RALIGN:
*pi_y += (p_vout->i_height + p_vout->p_buffer[ p_vout->i_buffer_index ].i_pic_y +
p_vout->p_buffer[ p_vout->i_buffer_index ].i_pic_height - i_height) / 2;
break;
}
/* Return non 0 if clipping failed */
return( (*pi_x < 0) || (*pi_y < 0) ||
(*pi_x + i_width > p_vout->i_width) || (*pi_y + i_height > p_vout->i_height) );
}
...@@ -369,9 +369,9 @@ void vout_Print( vout_font_t *p_font, byte_t *p_pic, int i_bytes_per_pixel, int ...@@ -369,9 +369,9 @@ void vout_Print( vout_font_t *p_font, byte_t *p_pic, int i_bytes_per_pixel, int
} }
/* Choose masks and copy font data to local variables */ /* Choose masks and copy font data to local variables */
i_char_mask = (i_style & VOID_TEXT) ? 0 : 0xff; i_char_mask = (i_style & VOID_TEXT) ? 0 : 0xff;
i_border_mask = (i_style & OUTLINED_TEXT) ? 0xff : 0; i_border_mask = (i_style & OUTLINED_TEXT) ? 0xff : 0;
i_bg_mask = (i_style & TRANSPARENT_TEXT) ? 0 : 0xff; i_bg_mask = (i_style & OPAQUE_TEXT) ? 0xff : 0;
i_font_bytes_per_line = p_font->i_bytes_per_line; i_font_bytes_per_line = p_font->i_bytes_per_line;
i_font_height = p_font->i_height; i_font_height = p_font->i_height;
......
...@@ -153,14 +153,10 @@ int vout_SysInit( vout_thread_t *p_vout ) ...@@ -153,14 +153,10 @@ int vout_SysInit( vout_thread_t *p_vout )
} }
} }
/* Set bytes per line */ /* Set bytes per line and initialize buffers */
p_vout->i_bytes_per_line = p_vout->p_sys->p_ximage[0]->bytes_per_line; p_vout->i_bytes_per_line = p_vout->p_sys->p_ximage[0]->bytes_per_line;
vout_SetBuffers( p_vout, p_vout->p_sys->p_ximage[ 0 ]->data,
/* Set and initialize buffers */ p_vout->p_sys->p_ximage[ 1 ]->data );
p_vout->p_buffer[0].p_data = p_vout->p_sys->p_ximage[ 0 ]->data;
p_vout->p_buffer[1].p_data = p_vout->p_sys->p_ximage[ 1 ]->data;
vout_ClearBuffer( p_vout, &p_vout->p_buffer[0] );
vout_ClearBuffer( p_vout, &p_vout->p_buffer[1] );
return( 0 ); return( 0 );
} }
...@@ -224,6 +220,10 @@ int vout_SysManage( vout_thread_t *p_vout ) ...@@ -224,6 +220,10 @@ int vout_SysManage( vout_thread_t *p_vout )
intf_ErrMsg("error: can't resize display\n"); intf_ErrMsg("error: can't resize display\n");
return( 1 ); return( 1 );
} }
/* Tell the video output thread that it will need to rebuild YUV
* tables. This is needed since convertion buffer size may have changed */
p_vout->i_changes |= VOUT_YUV_CHANGE;
intf_Msg("Video display resized (%dx%d)\n", p_vout->i_width, p_vout->i_height); intf_Msg("Video display resized (%dx%d)\n", p_vout->i_width, p_vout->i_height);
} }
......
...@@ -47,32 +47,49 @@ const int MATRIX_COEFFICIENTS_TABLE[8][4] = ...@@ -47,32 +47,49 @@ const int MATRIX_COEFFICIENTS_TABLE[8][4] =
static int BinaryLog ( u32 i ); static int BinaryLog ( u32 i );
static void MaskToShift ( int *pi_right, int *pi_left, u32 i_mask ); static void MaskToShift ( int *pi_right, int *pi_left, u32 i_mask );
static void SetGammaTable ( int *pi_table, double f_gamma ); static void SetGammaTable ( int *pi_table, double f_gamma );
static void SetTables ( vout_thread_t *p_vout ); static void SetYUV ( vout_thread_t *p_vout );
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, 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_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients ); int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_matrix_coefficients );
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, 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_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients ); int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_matrix_coefficients );
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, 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_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients ); int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_matrix_coefficients );
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, 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_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients ); int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_matrix_coefficients );
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, 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_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients ); int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_matrix_coefficients );
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, 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_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients ); int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_matrix_coefficients );
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, 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_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients ); int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_matrix_coefficients );
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, 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_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients ); int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_matrix_coefficients );
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, 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_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients ); int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_matrix_coefficients );
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, 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_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients ); int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_matrix_coefficients );
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, 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_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients ); int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_matrix_coefficients );
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, 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_eol, int i_pic_eol, int i_scale, int i_matrix_coefficients ); int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_matrix_coefficients );
//?? temporary prototypes, will be integrated to normal ones */
void yuv420ToRgb16_scaled (unsigned char * Y, unsigned char * U, unsigned char * V,
short * dest, short table[1935], int width , int dest_width,
int height, int dest_height, int skip, int dest_skip,short * buffer);
/******************************************************************************* /*******************************************************************************
* CLIP_BYTE macro: boundary detection * CLIP_BYTE macro: boundary detection
...@@ -111,17 +128,21 @@ for( i_x = 0; i_x < i_width; i_x+=16 ) \ ...@@ -111,17 +128,21 @@ for( i_x = 0; i_x < i_width; i_x+=16 ) \
*p_pic++ = *p_pic_src++; \ *p_pic++ = *p_pic_src++; \
*p_pic++ = *p_pic_src++; \ *p_pic++ = *p_pic_src++; \
} }
/******************************************************************************* /*******************************************************************************
* CONVERT_YUV_GRAY macro: grayscale YUV convertion * CONVERT_YUV_GRAY macro: grayscale YUV convertion
******************************************************************************* *******************************************************************************
* Variables: * This macro does not perform any scaling, but crops the picture. It is
* ...see vout_convert_t * provided as a temporary way of implementing an YUV convertion function.
* i_x, i_y coordinates
* i_pic_copy same type as p_pic
* p_gray gray translation table
*******************************************************************************/ *******************************************************************************/
#define CONVERT_YUV_GRAY \ #define CONVERT_YUV_GRAY \
/* Change boundaries according to picture size */ \
i_pic_skip += i_pic_width - MIN( i_width, i_pic_width ); \
i_skip += i_width - MIN( i_width, i_pic_width ); \
i_width = MIN( i_width, i_pic_width ); \
i_height = MIN( i_height, i_pic_height ); \
\
/* Loop */ \
for (i_y = 0; i_y < i_height ; i_y++) \ for (i_y = 0; i_y < i_height ; i_y++) \
{ \ { \
for (i_x = 0; i_x < i_width; i_x += 16) \ for (i_x = 0; i_x < i_width; i_x += 16) \
...@@ -145,47 +166,27 @@ for (i_y = 0; i_y < i_height ; i_y++) \ ...@@ -145,47 +166,27 @@ for (i_y = 0; i_y < i_height ; i_y++) \
*p_pic++ = p_gray[ *p_y++ ]; \ *p_pic++ = p_gray[ *p_y++ ]; \
} \ } \
\ \
/* Handle scale factor */ \
if( i_scale && ! (i_y % i_scale) ) \
{ \
if( i_scale < 0 ) \
{ \
/* Copy previous line */ \
p_pic_src = p_pic - i_width; \
p_pic += i_pic_eol; \
LINE_COPY \
} \
else \
{ \
/* Ignore next line */ \
p_y += i_eol + i_width; \
i_y++; \
} \
} \
\
/* Skip until beginning of next line */ \ /* Skip until beginning of next line */ \
p_pic += i_pic_eol; \ p_y += i_skip; \
p_y += i_eol; \ p_pic += i_pic_skip; \
} }
/******************************************************************************* /*******************************************************************************
* CONVERT_YUV_RGB: color YUV convertion * CONVERT_YUV_RGB: color YUV convertion
******************************************************************************* *******************************************************************************
* Parameters * This macro does not perform any scaling, but crops the picture. It is
* CHROMA 420, 422 or 444 * provided as a temporary way of implementing an YUV convertion function.
* Variables:
* ...see vout_convert_t
* i_x, i_y coordinates
* i_uval, i_yval, i_vval samples
* p_pic_src same type as p_pic
* i_chroma_width chroma width
* i_chroma_eol chroma eol
* p_red red translation table
* p_green green translation table
* p_blue blue translation table
* i_crv, i_cgu, i_cgv, i_cbu matrix coefficients
*******************************************************************************/ *******************************************************************************/
#define CONVERT_YUV_RGB( CHROMA ) \ #define CONVERT_YUV_RGB( CHROMA ) \
/* Change boundaries according to picture size */ \
i_pic_skip += i_pic_width - MIN( i_width, i_pic_width ); \
i_skip += i_width - MIN( i_width, i_pic_width ); \
i_width = MIN( i_width, i_pic_width ); \
i_height = MIN( i_height, i_pic_height ); \
i_chroma_skip = (CHROMA == 444) ? i_skip : i_skip / 2; \
i_chroma_width = (CHROMA == 444) ? i_width : i_width / 2; \
\
/* Loop */ \
for (i_y = 0; i_y < i_height ; i_y++) \ for (i_y = 0; i_y < i_height ; i_y++) \
{ \ { \
for (i_x = 0; i_x < i_width; i_x += 2 ) \ for (i_x = 0; i_x < i_width; i_x += 2 ) \
...@@ -211,59 +212,31 @@ for (i_y = 0; i_y < i_height ; i_y++) \ ...@@ -211,59 +212,31 @@ for (i_y = 0; i_y < i_height ; i_y++) \
p_blue [(i_yval+i_cbu*i_uval) >>16]; \ p_blue [(i_yval+i_cbu*i_uval) >>16]; \
} \ } \
\ \
/* Handle scale factor and rewind in 4:2:0 */ \ /* Rewind in 4:2:0 */ \
if( i_scale && ! (i_y % i_scale) ) \ if( (CHROMA == 420) && !(i_y & 0x1) ) \
{ \
if( i_scale < 0 ) \
{ \
/* Copy previous line, rewind if required */ \
p_pic_src = p_pic - i_width; \
p_pic += i_pic_eol; \
LINE_COPY \
if( (CHROMA == 420) && !(i_y & 0x1) ) \
{ \
p_u -= i_chroma_width; \
p_v -= i_chroma_width; \
} \
else \
{ \
p_u += i_chroma_eol; \
p_v += i_chroma_eol; \
} \
} \
else \
{ \
/* Ignore next line */ \
p_y += i_eol + i_width; \
p_u += i_chroma_eol; \
p_v += i_chroma_eol; \
i_y++; \
} \
} \
else if( (CHROMA == 420) && !(i_y & 0x1) ) \
{ \ { \
p_u -= i_chroma_width; \ p_u -= i_chroma_width; \
p_v -= i_chroma_width; \ p_v -= i_chroma_width; \
} \ } \
else \ else \
{ \ { \
p_u += i_chroma_eol; \ p_u += i_chroma_skip; \
p_v += i_chroma_eol; \ p_v += i_chroma_skip; \
} \ } \
\ \
/* Skip until beginning of next line */ \ /* Skip until beginning of next line */ \
p_pic += i_pic_eol; \ p_y += i_skip; \
p_y += i_eol; \ p_pic += i_pic_skip; \
} }
/******************************************************************************* /*******************************************************************************
* vout_InitTables: allocate and initialize translations tables * vout_InitYUV: allocate and initialize translations tables
******************************************************************************* *******************************************************************************
* This function will allocate memory to store translation tables, depending * This function will allocate memory to store translation tables, depending
* of the screen depth. * of the screen depth.
*******************************************************************************/ *******************************************************************************/
int vout_InitTables( vout_thread_t *p_vout ) int vout_InitYUV( vout_thread_t *p_vout )
{ {
size_t tables_size; /* tables size, in bytes */ size_t tables_size; /* tables size, in bytes */
...@@ -272,14 +245,14 @@ int vout_InitTables( vout_thread_t *p_vout ) ...@@ -272,14 +245,14 @@ int vout_InitTables( vout_thread_t *p_vout )
{ {
case 15: case 15:
case 16: case 16:
tables_size = sizeof( u16 ) * 1024 * (p_vout->b_grayscale ? 1 : 3); tables_size = sizeof( u16 ) * (1024 * (p_vout->b_grayscale ? 1 : 3) + 1935);
break; break;
case 24: case 24:
case 32: case 32:
#ifndef DEBUG #ifndef DEBUG
default: default:
#endif #endif
tables_size = sizeof( u32 ) * 1024 * (p_vout->b_grayscale ? 1 : 3); tables_size = sizeof( u32 ) * (1024 * (p_vout->b_grayscale ? 1 : 3) + 1935);
break; break;
#ifdef DEBUG #ifdef DEBUG
default: default:
...@@ -288,17 +261,21 @@ int vout_InitTables( vout_thread_t *p_vout ) ...@@ -288,17 +261,21 @@ int vout_InitTables( vout_thread_t *p_vout )
break; break;
#endif #endif
} }
/* Add conversion buffer size. The conversions functions need one comple line
* plus one pixel, so we give them two. */
tables_size += p_vout->i_bytes_per_line * 2;
/* Allocate memory */ /* Allocate memory */
p_vout->tables.p_base = malloc( tables_size ); p_vout->yuv.p_base = malloc( tables_size );
if( p_vout->tables.p_base == NULL ) if( p_vout->yuv.p_base == NULL )
{ {
intf_ErrMsg("error: %s\n", strerror(ENOMEM)); intf_ErrMsg("error: %s\n", strerror(ENOMEM));
return( 1 ); return( 1 );
} }
/* Initialize tables */ /* Initialize tables */
SetTables( p_vout ); SetYUV( p_vout );
return( 0 ); return( 0 );
} }
...@@ -308,20 +285,20 @@ int vout_InitTables( vout_thread_t *p_vout ) ...@@ -308,20 +285,20 @@ int vout_InitTables( vout_thread_t *p_vout )
* This function will initialize the tables allocated by vout_CreateTables and * This function will initialize the tables allocated by vout_CreateTables and
* set functions pointers. * set functions pointers.
*******************************************************************************/ *******************************************************************************/
int vout_ResetTables( vout_thread_t *p_vout ) int vout_ResetYUV( vout_thread_t *p_vout )
{ {
vout_EndTables( p_vout ); vout_EndYUV( p_vout );
return( vout_InitTables( p_vout ) ); return( vout_InitYUV( p_vout ) );
} }
/******************************************************************************* /*******************************************************************************
* vout_EndTables: destroy translations tables * vout_EndYUV: destroy translations tables
******************************************************************************* *******************************************************************************
* Free memory allocated by vout_CreateTables. * Free memory allocated by vout_CreateTables.
*******************************************************************************/ *******************************************************************************/
void vout_EndTables( vout_thread_t *p_vout ) void vout_EndYUV( vout_thread_t *p_vout )
{ {
free( p_vout->tables.p_base ); free( p_vout->yuv.p_base );
} }
/* following functions are local */ /* following functions are local */
...@@ -407,9 +384,9 @@ static void SetGammaTable( int *pi_table, double f_gamma ) ...@@ -407,9 +384,9 @@ static void SetGammaTable( int *pi_table, double f_gamma )
} }
/******************************************************************************* /*******************************************************************************
* SetTables: compute tables and set function pointers * SetYUV: compute tables and set function pointers
+ *******************************************************************************/ + *******************************************************************************/
static void SetTables( vout_thread_t *p_vout ) static void SetYUV( vout_thread_t *p_vout )
{ {
int pi_gamma[256]; /* gamma table */ int pi_gamma[256]; /* gamma table */
int i_index; /* index in tables */ int i_index; /* index in tables */
...@@ -458,24 +435,24 @@ static void SetTables( vout_thread_t *p_vout ) ...@@ -458,24 +435,24 @@ static void SetTables( vout_thread_t *p_vout )
{ {
case 15: case 15:
case 16: case 16:
p_vout->tables.yuv.gray16.p_gray = (u16 *)p_vout->tables.p_base + 384; p_vout->yuv.yuv.gray16.p_gray = (u16 *)p_vout->yuv.p_base + 384;
for( i_index = -384; i_index < 640; i_index++) for( i_index = -384; i_index < 640; i_index++)
{ {
p_vout->tables.yuv.gray16.p_gray[ i_index ] = p_vout->yuv.yuv.gray16.p_gray[ i_index ] =
((pi_gamma[CLIP_BYTE( i_index )] >> i_red_right) << i_red_left) | ((pi_gamma[CLIP_BYTE( i_index )] >> i_red_right) << i_red_left) |
((pi_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) | ((pi_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
((pi_gamma[CLIP_BYTE( i_index )] >> i_blue_right) << i_blue_left); ((pi_gamma[CLIP_BYTE( i_index )] >> i_blue_right) << i_blue_left);
} }
break; break;
case 24: case 24:
case 32: case 32:
p_vout->tables.yuv.gray32.p_gray = (u32 *)p_vout->tables.p_base + 384; p_vout->yuv.yuv.gray32.p_gray = (u32 *)p_vout->yuv.p_base + 384;
for( i_index = -384; i_index < 640; i_index++) for( i_index = -384; i_index < 640; i_index++)
{ {
p_vout->tables.yuv.gray32.p_gray[ i_index ] = p_vout->yuv.yuv.gray32.p_gray[ i_index ] =
((pi_gamma[CLIP_BYTE( i_index )] >> i_red_right) << i_red_left) | ((pi_gamma[CLIP_BYTE( i_index )] >> i_red_right) << i_red_left) |
((pi_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) | ((pi_gamma[CLIP_BYTE( i_index )] >> i_green_right) << i_green_left) |
((pi_gamma[CLIP_BYTE( i_index )] >> i_blue_right) << i_blue_left); ((pi_gamma[CLIP_BYTE( i_index )] >> i_blue_right) << i_blue_left);
} }
break; break;
} }
...@@ -487,31 +464,57 @@ static void SetTables( vout_thread_t *p_vout ) ...@@ -487,31 +464,57 @@ static void SetTables( vout_thread_t *p_vout )
{ {
case 15: case 15:
case 16: case 16:
p_vout->tables.yuv.rgb16.p_red = (u16 *)p_vout->tables.p_base + 384; p_vout->yuv.yuv.rgb16.p_red = (u16 *)p_vout->yuv.p_base + 384;
p_vout->tables.yuv.rgb16.p_green = (u16 *)p_vout->tables.p_base + 1024 + 384; p_vout->yuv.yuv.rgb16.p_green = (u16 *)p_vout->yuv.p_base + 1024 + 384;
p_vout->tables.yuv.rgb16.p_blue = (u16 *)p_vout->tables.p_base + 2*1024 + 384; p_vout->yuv.yuv.rgb16.p_blue = (u16 *)p_vout->yuv.p_base + 2*1024 + 384;
p_vout->yuv.yuv2.p_rgb16 = (u16 *)p_vout->yuv.p_base + 3*1024;
p_vout->yuv.p_buffer = (u16 *)p_vout->yuv.p_base + 3*1024 + 1935;
for( i_index = -384; i_index < 640; i_index++) for( i_index = -384; i_index < 640; i_index++)
{ {
p_vout->tables.yuv.rgb16.p_red[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left; p_vout->yuv.yuv.rgb16.p_red[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left;
p_vout->tables.yuv.rgb16.p_green[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_left; p_vout->yuv.yuv.rgb16.p_green[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_left;
p_vout->tables.yuv.rgb16.p_blue[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_blue_right)<<i_blue_left; p_vout->yuv.yuv.rgb16.p_blue[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_blue_right)<<i_blue_left;
}
for( i_index = 0; i_index < 178; i_index++ )
{
p_vout->yuv.yuv2.p_rgb16[1501 - 178 + i_index] = (pi_gamma[0]>>i_red_right)<<i_red_left;
p_vout->yuv.yuv2.p_rgb16[1501 + 256 + i_index] = (pi_gamma[255]>>i_red_right)<<i_red_left;
} }
for( i_index = 0; i_index < 135; i_index++ )
{
p_vout->yuv.yuv2.p_rgb16[135 - 135 + i_index] = (pi_gamma[0]>>i_green_right)<<i_green_left;
p_vout->yuv.yuv2.p_rgb16[135 + 256 + i_index] = (pi_gamma[255]>>i_green_right)<<i_green_left;
}
for( i_index = 0; i_index < 224; i_index++ )
{
p_vout->yuv.yuv2.p_rgb16[818 - 224 + i_index] = (pi_gamma[0]>>i_blue_right)<<i_blue_left;
p_vout->yuv.yuv2.p_rgb16[818 + 256 + i_index] = (pi_gamma[255]>>i_blue_right)<<i_blue_left;
}
for( i_index = 0; i_index < 256; i_index++ )
{
p_vout->yuv.yuv2.p_rgb16[1501 + i_index] = (pi_gamma[i_index]>>i_red_right)<<i_red_left;
p_vout->yuv.yuv2.p_rgb16[135 + i_index] = (pi_gamma[i_index]>>i_green_right)<<i_green_left;
p_vout->yuv.yuv2.p_rgb16[818 + i_index] = (pi_gamma[i_index]>>i_blue_right)<<i_blue_left;
}
break; break;
case 24: case 24:
case 32: case 32:
p_vout->tables.yuv.rgb32.p_red = (u32 *)p_vout->tables.p_base + 384; p_vout->yuv.yuv.rgb32.p_red = (u32 *)p_vout->yuv.p_base + 384;
p_vout->tables.yuv.rgb32.p_green = (u32 *)p_vout->tables.p_base + 1024 + 384; p_vout->yuv.yuv.rgb32.p_green = (u32 *)p_vout->yuv.p_base + 1024 + 384;
p_vout->tables.yuv.rgb32.p_blue = (u32 *)p_vout->tables.p_base + 2*1024 + 384; p_vout->yuv.yuv.rgb32.p_blue = (u32 *)p_vout->yuv.p_base + 2*1024 + 384;
p_vout->yuv.yuv2.p_rgb32 = (u32 *)p_vout->yuv.p_base + 3*1024;
p_vout->yuv.p_buffer = (u32 *)p_vout->yuv.p_base + 3*1024 + 1935;
for( i_index = -384; i_index < 640; i_index++) for( i_index = -384; i_index < 640; i_index++)
{ {
p_vout->tables.yuv.rgb32.p_red[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left; p_vout->yuv.yuv.rgb32.p_red[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left;
p_vout->tables.yuv.rgb32.p_green[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_left; p_vout->yuv.yuv.rgb32.p_green[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_left;
p_vout->tables.yuv.rgb32.p_blue[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_blue_right)<<i_blue_left; p_vout->yuv.yuv.rgb32.p_blue[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_blue_right)<<i_blue_left;
} }
//?? walken's yuv
break; break;
} }
} }
/* /*
* Set functions pointers * Set functions pointers
*/ */
...@@ -522,19 +525,19 @@ static void SetTables( vout_thread_t *p_vout ) ...@@ -522,19 +525,19 @@ static void SetTables( vout_thread_t *p_vout )
{ {
case 15: case 15:
case 16: case 16:
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16; p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16; p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16; p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;
break; break;
case 24: case 24:
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24; p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray24;
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24; p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray24;
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24; p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray24;
break; break;
case 32: case 32:
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32; p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray32;
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32; p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray32;
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32; p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray32;
break; break;
} }
} }
...@@ -545,19 +548,19 @@ static void SetTables( vout_thread_t *p_vout ) ...@@ -545,19 +548,19 @@ static void SetTables( vout_thread_t *p_vout )
{ {
case 15: case 15:
case 16: case 16:
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB16; p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB16;
p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB16; p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB16;
p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB16; p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB16;
break; break;
case 24: case 24:
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB24; p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB24;
p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB24; p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB24;
p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB24; p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB24;
break; break;
case 32: case 32:
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB32; p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB32;
p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB32; p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB32;
p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB32; p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB32;
break; break;
} }
} }
...@@ -566,26 +569,23 @@ static void SetTables( vout_thread_t *p_vout ) ...@@ -566,26 +569,23 @@ static void SetTables( vout_thread_t *p_vout )
/******************************************************************************* /*******************************************************************************
* ConvertY4Gray16: grayscale YUV 4:x:x to RGB 15 or 16 bpp * ConvertY4Gray16: grayscale YUV 4:x:x to RGB 15 or 16 bpp
*******************************************************************************/ *******************************************************************************/
static void ConvertY4Gray16( p_vout_thread_t p_vout, u16 *p_pic, 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,
yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_width, int i_height, int i_eol, int i_pic_eol, int i_matrix_coefficients )
int i_scale, int i_matrix_coefficients )
{ {
u16 * p_pic_src; /* source pointer in case of copy */
u16 * p_gray; /* gray table */ u16 * p_gray; /* gray table */
int i_x, i_y; /* picture coordinates */ int i_x, i_y; /* picture coordinates */
p_gray = p_vout->tables.yuv.gray16.p_gray; p_gray = p_vout->yuv.yuv.gray16.p_gray;
CONVERT_YUV_GRAY CONVERT_YUV_GRAY
} }
/******************************************************************************* /*******************************************************************************
* ConvertY4Gray24: grayscale YUV 4:x:x to RGB 24 bpp * ConvertY4Gray24: grayscale YUV 4:x:x to RGB 24 bpp
*******************************************************************************/ *******************************************************************************/
static void ConvertY4Gray24( p_vout_thread_t p_vout, void *p_pic, 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,
yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_width, int i_height, int i_eol, int i_pic_eol, int i_matrix_coefficients )
int i_scale, int i_matrix_coefficients )
{ {
//?? //??
} }
...@@ -593,56 +593,57 @@ static void ConvertY4Gray24( p_vout_thread_t p_vout, void *p_pic, ...@@ -593,56 +593,57 @@ static void ConvertY4Gray24( p_vout_thread_t p_vout, void *p_pic,
/******************************************************************************* /*******************************************************************************
* ConvertY4Gray32: grayscale YUV 4:x:x to RGB 32 bpp * ConvertY4Gray32: grayscale YUV 4:x:x to RGB 32 bpp
*******************************************************************************/ *******************************************************************************/
static void ConvertY4Gray32( p_vout_thread_t p_vout, u32 *p_pic, 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,
yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_width, int i_height, int i_eol, int i_pic_eol, int i_matrix_coefficients )
int i_scale, int i_matrix_coefficients )
{ {
u32 * p_pic_src; /* source pointer in case of copy */
u32 * p_gray; /* gray table */ u32 * p_gray; /* gray table */
int i_x, i_y; /* picture coordinates */ int i_x, i_y; /* picture coordinates */
p_gray = p_vout->tables.yuv.gray32.p_gray; p_gray = p_vout->yuv.yuv.gray32.p_gray;
CONVERT_YUV_GRAY CONVERT_YUV_GRAY
} }
/******************************************************************************* /*******************************************************************************
* ConvertYUV420RGB16: color YUV 4:2:0 to RGB 15 or 16 bpp * ConvertYUV420RGB16: color YUV 4:2:0 to RGB 15 or 16 bpp
*******************************************************************************/ *******************************************************************************/
static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic, 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,
yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_width, int i_height, int i_eol, int i_pic_eol, int i_matrix_coefficients )
int i_scale, int i_matrix_coefficients )
{ {
#ifdef HAVE_MMX //?? gloups: find a good one !
int i_chroma_width, i_chroma_eol; /* width and eol for chroma */ #if 0
intf_DbgMsg("%dx%d-%d -> %dx%d-%d\n", i_width, i_height, i_skip, i_pic_width, i_pic_height, i_pic_skip );
yuv420ToRgb16_scaled ( p_y, p_u, p_v, p_pic, p_vout->yuv.yuv2.p_rgb16,
i_width , i_pic_width, i_height, i_pic_height, i_skip, i_pic_skip,
p_vout->yuv.p_buffer);
#elif 0
//#ifdef HAVE_MMX
int i_chroma_width, i_chroma_skip; /* width and eol for chroma */
i_chroma_width = i_width / 2; i_chroma_width = i_width / 2;
i_chroma_eol = i_eol / 2; i_chroma_skip = i_skip / 2;
ConvertYUV420RGB16MMX( p_y, p_u, p_v, i_width, i_height, ConvertYUV420RGB16MMX( p_y, p_u, p_v, i_width, i_height,
(i_width + i_eol) * sizeof( yuv_data_t ), (i_width + i_skip) * sizeof( yuv_data_t ),
(i_chroma_width + i_chroma_eol) * sizeof( yuv_data_t), (i_chroma_width + i_chroma_skip) * sizeof( yuv_data_t),
i_scale, (u8 *)p_pic, 0, 0, (i_width + i_pic_eol) * sizeof( u16 ), i_scale, (u8 *)p_pic, 0, 0, (i_width + i_pic_eol) * sizeof( u16 ),
p_vout->i_screen_depth == 15 ); p_vout->i_screen_depth == 15 );
#else #else
u16 * p_pic_src; /* source pointer in case of copy */
u16 * p_red; /* red table */ u16 * p_red; /* red table */
u16 * p_green; /* green table */ u16 * p_green; /* green table */
u16 * p_blue; /* blue table */ u16 * p_blue; /* blue table */
int i_uval, i_yval, i_vval; /* samples */ int i_uval, i_yval, i_vval; /* samples */
int i_x, i_y; /* picture coordinates */ int i_x, i_y; /* picture coordinates */
int i_chroma_width, i_chroma_eol; /* width and eol for chroma */ int i_chroma_width, i_chroma_skip; /* width and eol for chroma */
int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */ int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0]; i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1]; i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2]; i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3]; i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
p_red = p_vout->tables.yuv.rgb16.p_red; p_red = p_vout->yuv.yuv.rgb16.p_red;
p_green = p_vout->tables.yuv.rgb16.p_green; p_green = p_vout->yuv.yuv.rgb16.p_green;
p_blue = p_vout->tables.yuv.rgb16.p_blue; p_blue = p_vout->yuv.yuv.rgb16.p_blue;
i_chroma_width = i_width / 2;
i_chroma_eol = i_eol / 2;
CONVERT_YUV_RGB( 420 ) CONVERT_YUV_RGB( 420 )
#endif #endif
} }
...@@ -650,68 +651,29 @@ static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic, ...@@ -650,68 +651,29 @@ static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic,
/******************************************************************************* /*******************************************************************************
* ConvertYUV422RGB16: color YUV 4:2:2 to RGB 15 or 16 bpp * ConvertYUV422RGB16: color YUV 4:2:2 to RGB 15 or 16 bpp
*******************************************************************************/ *******************************************************************************/
static void ConvertYUV422RGB16( p_vout_thread_t p_vout, u16 *p_pic, 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,
yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_width, int i_height, int i_eol, int i_pic_eol, int i_matrix_coefficients )
int i_scale, int i_matrix_coefficients )
{ {
u16 * p_pic_src; /* source pointer in case of copy */ //??
u16 * p_red; /* red table */
u16 * p_green; /* green table */
u16 * p_blue; /* blue table */
int i_uval, i_yval, i_vval; /* samples */
int i_x, i_y; /* picture coordinates */
int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
p_red = p_vout->tables.yuv.rgb16.p_red;
p_green = p_vout->tables.yuv.rgb16.p_green;
p_blue = p_vout->tables.yuv.rgb16.p_blue;
i_chroma_width = i_width / 2;
i_chroma_eol = i_eol / 2;
CONVERT_YUV_RGB( 422 )
} }
/******************************************************************************* /*******************************************************************************
* ConvertYUV444RGB16: color YUV 4:4:4 to RGB 15 or 16 bpp * ConvertYUV444RGB16: color YUV 4:4:4 to RGB 15 or 16 bpp
*******************************************************************************/ *******************************************************************************/
static void ConvertYUV444RGB16( p_vout_thread_t p_vout, u16 *p_pic, 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,
yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_width, int i_height, int i_eol, int i_pic_eol, int i_matrix_coefficients )
int i_scale, int i_matrix_coefficients )
{ {
u16 * p_pic_src; /* source pointer in case of copy */ //??
u16 * p_red; /* red table */
u16 * p_green; /* green table */
u16 * p_blue; /* blue table */
int i_uval, i_yval, i_vval; /* samples */
int i_x, i_y; /* picture coordinates */
int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
p_red = p_vout->tables.yuv.rgb16.p_red;
p_green = p_vout->tables.yuv.rgb16.p_green;
p_blue = p_vout->tables.yuv.rgb16.p_blue;
i_chroma_width = i_width;
i_chroma_eol = i_eol;
CONVERT_YUV_RGB( 444 )
} }
/******************************************************************************* /*******************************************************************************
* ConvertYUV420RGB24: color YUV 4:2:0 to RGB 24 bpp * ConvertYUV420RGB24: color YUV 4:2:0 to RGB 24 bpp
*******************************************************************************/ *******************************************************************************/
static void ConvertYUV420RGB24( p_vout_thread_t p_vout, void *p_pic, 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,
yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_width, int i_height, int i_eol, int i_pic_eol, int i_matrix_coefficients )
int i_scale, int i_matrix_coefficients )
{ {
//??? //???
} }
...@@ -719,10 +681,9 @@ static void ConvertYUV420RGB24( p_vout_thread_t p_vout, void *p_pic, ...@@ -719,10 +681,9 @@ static void ConvertYUV420RGB24( p_vout_thread_t p_vout, void *p_pic,
/******************************************************************************* /*******************************************************************************
* ConvertYUV422RGB24: color YUV 4:2:2 to RGB 24 bpp * ConvertYUV422RGB24: color YUV 4:2:2 to RGB 24 bpp
*******************************************************************************/ *******************************************************************************/
static void ConvertYUV422RGB24( p_vout_thread_t p_vout, void *p_pic, 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,
yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_width, int i_height, int i_eol, int i_pic_eol, int i_matrix_coefficients )
int i_scale, int i_matrix_coefficients )
{ {
//??? //???
} }
...@@ -730,10 +691,9 @@ static void ConvertYUV422RGB24( p_vout_thread_t p_vout, void *p_pic, ...@@ -730,10 +691,9 @@ static void ConvertYUV422RGB24( p_vout_thread_t p_vout, void *p_pic,
/******************************************************************************* /*******************************************************************************
* ConvertYUV444RGB24: color YUV 4:4:4 to RGB 24 bpp * ConvertYUV444RGB24: color YUV 4:4:4 to RGB 24 bpp
*******************************************************************************/ *******************************************************************************/
static void ConvertYUV444RGB24( p_vout_thread_t p_vout, void *p_pic, 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,
yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_width, int i_height, int i_eol, int i_pic_eol, int i_matrix_coefficients )
int i_scale, int i_matrix_coefficients )
{ {
//??? //???
} }
...@@ -741,88 +701,31 @@ static void ConvertYUV444RGB24( p_vout_thread_t p_vout, void *p_pic, ...@@ -741,88 +701,31 @@ static void ConvertYUV444RGB24( p_vout_thread_t p_vout, void *p_pic,
/******************************************************************************* /*******************************************************************************
* ConvertYUV420RGB32: color YUV 4:2:0 to RGB 32 bpp * ConvertYUV420RGB32: color YUV 4:2:0 to RGB 32 bpp
*******************************************************************************/ *******************************************************************************/
static void ConvertYUV420RGB32( p_vout_thread_t p_vout, u32 *p_pic, 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,
yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_width, int i_height, int i_eol, int i_pic_eol, int i_matrix_coefficients )
int i_scale, int i_matrix_coefficients )
{ {
u32 * p_pic_src; /* source pointer in case of copy */ //??
u32 * p_red; /* red table */
u32 * p_green; /* green table */
u32 * p_blue; /* blue table */
int i_uval, i_yval, i_vval; /* samples */
int i_x, i_y; /* picture coordinates */
int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
p_red = p_vout->tables.yuv.rgb32.p_red;
p_green = p_vout->tables.yuv.rgb32.p_green;
p_blue = p_vout->tables.yuv.rgb32.p_blue;
i_chroma_width = i_width / 2;
i_chroma_eol = i_eol / 2;
CONVERT_YUV_RGB( 420 )
} }
/******************************************************************************* /*******************************************************************************
* ConvertYUV422RGB32: color YUV 4:2:2 to RGB 32 bpp * ConvertYUV422RGB32: color YUV 4:2:2 to RGB 32 bpp
*******************************************************************************/ *******************************************************************************/
static void ConvertYUV422RGB32( p_vout_thread_t p_vout, u32 *p_pic, 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,
yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_width, int i_height, int i_eol, int i_pic_eol, int i_matrix_coefficients )
int i_scale, int i_matrix_coefficients )
{ {
u32 * p_pic_src; /* source pointer in case of copy */ //??
u32 * p_red; /* red table */
u32 * p_green; /* green table */
u32 * p_blue; /* blue table */
int i_uval, i_yval, i_vval; /* samples */
int i_x, i_y; /* picture coordinates */
int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
p_red = p_vout->tables.yuv.rgb32.p_red;
p_green = p_vout->tables.yuv.rgb32.p_green;
p_blue = p_vout->tables.yuv.rgb32.p_blue;
i_chroma_width = i_width / 2;
i_chroma_eol = i_eol / 2;
CONVERT_YUV_RGB( 422 )
} }
/******************************************************************************* /*******************************************************************************
* ConvertYUV444RGB32: color YUV 4:4:4 to RGB 32 bpp * ConvertYUV444RGB32: color YUV 4:4:4 to RGB 32 bpp
*******************************************************************************/ *******************************************************************************/
static void ConvertYUV444RGB32( p_vout_thread_t p_vout, u32 *p_pic, 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,
yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v, int i_width, int i_height, int i_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_width, int i_height, int i_eol, int i_pic_eol, int i_matrix_coefficients )
int i_scale, int i_matrix_coefficients )
{ {
u32 * p_pic_src; /* source pointer in case of copy */ //??
u32 * p_red; /* red table */
u32 * p_green; /* green table */
u32 * p_blue; /* blue table */
int i_uval, i_yval, i_vval; /* samples */
int i_x, i_y; /* picture coordinates */
int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
int i_crv, i_cbu, i_cgu, i_cgv; /* transformation coefficients */
i_crv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][0];
i_cbu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][1];
i_cgu = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][2];
i_cgv = MATRIX_COEFFICIENTS_TABLE[i_matrix_coefficients][3];
p_red = p_vout->tables.yuv.rgb32.p_red;
p_green = p_vout->tables.yuv.rgb32.p_green;
p_blue = p_vout->tables.yuv.rgb32.p_blue;
i_chroma_width = i_width;
i_chroma_eol = i_eol;
CONVERT_YUV_RGB( 444 )
} }
//-------------------- walken code follow --------------------------------------- //-------------------- walken code follow ---------------------------------------
......
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