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 @@
/* Time during which the thread will sleep if it has nothing to
* display (in micro-seconds) */
/* ?? this constant will probably evolve to a calculated value */
#define VOUT_IDLE_SLEEP 20000
/* Maximum lap of time allowed between the beginning of rendering and
......@@ -268,11 +267,10 @@
* 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
* images, to avoid trashing of decoded images */
/* ?? this constant will probably evolve to a calculated value */
#define VOUT_DISPLAY_DELAY 500000
/* Delay (in microseconds) between increments in idle levels */
#define VOUT_IDLE_DELAY 5000000000000
/* Delay (in microseconds) before an idle screen is displayed */
#define VOUT_IDLE_DELAY 5000000
/* Number of pictures required to computes the FPS rate */
#define VOUT_FPS_SAMPLES 20
......
......@@ -87,14 +87,14 @@ typedef struct picture_s
#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
* 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
* 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 */
int i_type; /* spu type */
......@@ -104,18 +104,44 @@ typedef struct spu_s
mtime_t begin_date; /* beginning 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
* (the pointer) should NEVER be modified. */
void * p_data; /* spu data */
} spu_t;
} subpicture_t;
/* SPU types */
#define EMPTY_SPU 0 /* subtitle slot is empty and available */
#define RLE_SPU 100 /* RLE encoded subtitle */
/* Subpicture type */
#define EMPTY_SUBPICTURE 0 /* subtitle slot is empty and available */
#define RLE_SUBPICTURE 100 /* RLE encoded subtitle */
#define TEXT_SUBPICTURE 200 /* iso8859-1 text subtitle */
/* Subpicture status */
#define FREE_SPU 0 /* subtitle is free and not allocated */
#define RESERVED_SPU 1 /* subtitle is allocated and reserved */
#define READY_SPU 2 /* subtitle is ready for display */
#define DESTROYED_SPU 3 /* subtitle is allocated but no more used */
#define FREE_SUBPICTURE 0 /* subpicture is free and not allocated */
#define RESERVED_SUBPICTURE 1 /* subpicture is allocated and reserved */
#define READY_SUBPICTURE 2 /* subpicture is ready for display */
#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 @@
*******************************************************************************/
/*******************************************************************************
* 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.
*******************************************************************************/
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 */
union
{
......@@ -22,7 +51,16 @@ typedef struct vout_tables_s
struct { u16 *p_gray; } gray16; /* gray 15, 16 bpp */
struct { u32 *p_gray; } gray32; /* gray 24, 32 bpp */
} 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
......@@ -45,31 +83,6 @@ typedef struct vout_buffer_s
byte_t * p_data; /* memory address */
} 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
*******************************************************************************
......@@ -85,12 +98,13 @@ typedef struct vout_thread_s
boolean_t b_active; /* `active' flag */
vlc_thread_t thread_id; /* id for pthread functions */
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 */
int * pi_status; /* temporary status flag */
p_vout_sys_t p_sys; /* system output method */
/* Current display properties */
u16 i_changes; /* changes made to the thread */
int i_width; /* current output method width */
int i_height; /* current output method height */
int i_bytes_per_line;/* bytes per line (including virtual) */
......@@ -104,6 +118,10 @@ typedef struct vout_thread_s
boolean_t b_interface; /* render interface */
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
/* Statistics - these numbers are not supposed to be accurate, but are a
* good indication of the thread status */
......@@ -112,22 +130,14 @@ typedef struct vout_thread_s
mtime_t p_fps_sample[ VOUT_FPS_SAMPLES ]; /* FPS samples dates */
#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 */
int i_buffer_index; /* buffer index */
vout_buffer_t p_buffer[2]; /* buffers properties */
/* Videos heap and translation tables */
picture_t p_picture[VOUT_MAX_PICTURES]; /* pictures */
spu_t p_spu[VOUT_MAX_PICTURES]; /* subtitles */
vout_tables_t tables; /* 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 */
subpicture_t p_subpicture[VOUT_MAX_PICTURES]; /* subpictures */
vout_yuv_t yuv; /* translation tables */
/* Bitmap fonts */
p_vout_font_t p_default_font; /* default font */
......@@ -143,6 +153,7 @@ typedef struct vout_thread_s
#define VOUT_SIZE_CHANGE 0x0200 /* size changed */
#define VOUT_DEPTH_CHANGE 0x0400 /* depth 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 */
/*******************************************************************************
......@@ -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_LinkPicture ( 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 );
void vout_DestroySubPictureUnit ( vout_thread_t *p_vout, spu_t *p_spu );
void vout_DisplaySubPictureUnit ( vout_thread_t *p_vout, spu_t *p_spu );
void vout_ClearBuffer ( vout_thread_t *p_vout, vout_buffer_t *p_buffer );
subpicture_t * vout_CreateSubPicture ( vout_thread_t *p_vout, int i_type, int i_size );
void vout_DestroySubPicture ( vout_thread_t *p_vout, subpicture_t *p_subpic );
void vout_DisplaySubPicture ( vout_thread_t *p_vout, subpicture_t *p_subpic );
void vout_SetBuffers ( vout_thread_t *p_vout, void *p_buf1, void *p_buf2 );
......@@ -7,7 +7,7 @@
* They may be ignored or interpreted by higher level functions */
#define WIDE_TEXT 1 /* interspacing is doubled */
#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 VOID_TEXT 16 /* no foreground */
......
......@@ -9,9 +9,9 @@
/*******************************************************************************
* Prototypes
*******************************************************************************/
int vout_InitTables ( vout_thread_t *p_vout );
int vout_ResetTables ( vout_thread_t *p_vout );
void vout_EndTables ( vout_thread_t *p_vout );
int vout_InitYUV ( vout_thread_t *p_vout );
int vout_ResetYUV ( vout_thread_t *p_vout );
void vout_EndYUV ( vout_thread_t *p_vout );
/*******************************************************************************
* External prototypes
......
......@@ -53,8 +53,6 @@ typedef struct vout_sys_s
******************************************************************************/
static int FBOpenDisplay ( 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
......@@ -221,7 +219,7 @@ static int FBOpenDisplay( vout_thread_t *p_vout )
break;
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);
return( 1 );
break;
......@@ -242,16 +240,10 @@ static int FBOpenDisplay( vout_thread_t *p_vout )
}
/* Set and initialize buffers */
p_vout->p_buffer[0].p_data = 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;
vout_ClearBuffer( p_vout, &p_vout->p_buffer[0] );
vout_ClearBuffer( p_vout, &p_vout->p_buffer[1] );
vout_SetBuffers( p_vout, p_vout->p_sys->p_video,
p_vout->p_sys->p_video + p_vout->p_sys->i_page_size );
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 );
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 );
}
......
......@@ -258,16 +258,6 @@ static int GGIOpenDisplay( vout_thread_t *p_vout, char *psz_display )
}
#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 */
col_fg.r = col_fg.g = col_fg.b = -1;
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 )
}
/* Set and initialize buffers */
p_vout->p_buffer[0].p_data = p_vout->p_sys->p_buffer[ 0 ]->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] );
vout_SetBuffers( p_vout, p_vout->p_sys->p_buffer[ 0 ]->write, p_vout->p_sys->p_buffer[ 1 ]->write );
return( 0 );
}
......
......@@ -35,17 +35,19 @@ static void RunThread ( vout_thread_t *p_vout );
static void ErrorThread ( 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 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 SetBufferPicture ( 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 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 RenderIdle ( vout_thread_t *p_vout );
static int RenderIdle ( vout_thread_t *p_vout );
static void RenderInfo ( 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
......@@ -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
* probably be modified by the method, and are only preferences */
p_vout->i_changes = 0;
p_vout->i_width = i_width;
p_vout->i_height = i_height;
p_vout->i_bytes_per_line = i_width * 2;
......@@ -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_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
/* Initialize statistics fields */
p_vout->render_time = 0;
p_vout->c_fps_samples = 0;
#endif
/* Initialize running properties */
p_vout->i_changes = 0;
p_vout->last_picture_date = 0;
p_vout->last_display_date = 0;
/* Initialize buffer index */
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 */
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_status = FREE_PICTURE;
p_vout->p_spu[i_index].i_type = EMPTY_SPU;
p_vout->p_spu[i_index].i_status= FREE_SPU;
p_vout->p_subpicture[i_index].i_type = EMPTY_SUBPICTURE;
p_vout->p_subpicture[i_index].i_status= FREE_SUBPICTURE;
}
/* 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_
/* Create thread and set locks */
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_lock( &p_vout->change_lock );
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 )
}
/******************************************************************************
* 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
* display. The picture does not need to be locked, since it is ignored by
* Remove the reservation flag of an subpicture, which will cause it to be ready
* for display. The picture does not need to be locked, since it is ignored by
* 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
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 )
#ifdef DEBUG
/* 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
/* Remove reservation flag */
p_spu->i_status = READY_SPU;
p_subpic->i_status = READY_SUBPICTURE;
#ifdef DEBUG_VIDEO
/* Send subpicture informations */
intf_DbgMsg("spu %p: type=%d, begin date=%s, end date=%s\n", p_spu, p_spu->i_type,
mstrtime( psz_begin_date, p_spu->begin_date ),
mstrtime( psz_end_date, p_spu->end_date ) );
intf_DbgMsg("subpicture %p: type=%d, begin date=%s, end date=%s\n",
p_subpic, p_subpic->i_type,
mstrtime( psz_begin_date, p_subpic->begin_date ),
mstrtime( psz_end_date, p_subpic->end_date ) );
#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
* already allocated zone of memory in the spu data fields. It needs locking
* 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 )
{
//??
}
/******************************************************************************
* 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.
* This function does not need locking since reserved spus are ignored by
* the output thread.
* This function does not need locking since reserved subpictures are ignored
* 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
/* Check if spu status is valid */
if( p_spu->i_status != RESERVED_SPU )
/* Check if status is valid */
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
p_spu->i_status = DESTROYED_SPU;
p_subpic->i_status = DESTROYED_SUBPICTURE;
#ifdef DEBUG_VIDEO
intf_DbgMsg("spu %p\n", p_spu);
intf_DbgMsg("subpicture %p\n", p_subpic);
#endif
}
......@@ -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
* buffer.
* This function is called by system drivers to set buffers video memory
* 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 */
p_buffer->i_pic_x = 0;
p_buffer->i_pic_y = 0;
p_buffer->i_pic_width = 0;
p_buffer->i_pic_height = 0;
p_vout->p_buffer[0].i_pic_x = 0;
p_vout->p_buffer[0].i_pic_y = 0;
p_vout->p_buffer[0].i_pic_width = 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 */
p_buffer->i_areas = 1;
p_buffer->pi_area_begin[0] = 0;
p_buffer->pi_area_end[0] = p_vout->i_height - 1;
p_vout->p_buffer[0].i_areas = 1;
p_vout->p_buffer[0].pi_area_begin[0] = 0;
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 */
......@@ -616,9 +632,9 @@ static int InitThread( vout_thread_t *p_vout )
}
/* 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 );
}
......@@ -643,7 +659,7 @@ static void RunThread( vout_thread_t *p_vout)
mtime_t display_date; /* display date */
boolean_t b_display; /* display flag */
picture_t * p_pic; /* picture pointer */
spu_t * p_spu; /* subpicture pointer */
subpicture_t * p_subpic; /* subpicture pointer */
/*
* Initialize thread
......@@ -664,7 +680,7 @@ static void RunThread( vout_thread_t *p_vout)
{
/* Initialize loop variables */
p_pic = NULL;
p_spu = NULL;
p_subpic = NULL;
display_date = 0;
current_date = mdate();
......@@ -712,17 +728,18 @@ static void RunThread( vout_thread_t *p_vout)
/*
* Find the subpicture to display - this operation does not need lock, since
* only READY_SPUs are handled. If no picture has been selected,
* display_date will depend on the spu
* only READY_SUBPICTURES are handled. If no picture has been selected,
* display_date will depend on the subpicture
*/
//??
/*
* 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;
p_vout->last_display_date = display_date;
if( b_display )
{
......@@ -743,35 +760,36 @@ static void RunThread( vout_thread_t *p_vout)
p_pic->i_status = p_pic->i_refcount ? DISPLAYED_PICTURE : DESTROYED_PICTURE;
vlc_mutex_unlock( &p_vout->picture_lock );
/* Render interface and spus */
/* Render interface and subpicture */
if( b_display && p_vout->b_interface )
{
RenderInterface( p_vout );
}
if( p_spu )
if( p_subpic )
{
if( b_display )
{
RenderSubPictureUnit( p_vout, p_spu );
RenderSubPicture( p_vout, p_subpic );
}
/* Remove spu from heap */
vlc_mutex_lock( &p_vout->spu_lock );
p_spu->i_status = DESTROYED_SPU;
vlc_mutex_unlock( &p_vout->spu_lock );
/* Remove subpicture from heap */
vlc_mutex_lock( &p_vout->subpicture_lock );
p_subpic->i_status = DESTROYED_SUBPICTURE;
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;
p_vout->last_display_date = display_date;
if( b_display )
{
/* Clear buffer */
SetBufferPicture( p_vout, NULL );
/* Render informations, interface and spu */
/* Render informations, interface and subpicture */
if( p_vout->b_info )
{
RenderInfo( p_vout );
......@@ -780,18 +798,40 @@ static void RunThread( vout_thread_t *p_vout)
{
RenderInterface( p_vout );
}
RenderSubPictureUnit( p_vout, p_spu );
RenderSubPicture( p_vout, p_subpic );
}
/* Remove spu from heap */
vlc_mutex_lock( &p_vout->spu_lock );
p_spu->i_status = DESTROYED_SPU;
vlc_mutex_unlock( &p_vout->spu_lock );
/* Remove subpicture from heap */
vlc_mutex_lock( &p_vout->subpicture_lock );
p_subpic->i_status = DESTROYED_SUBPICTURE;
vlc_mutex_unlock( &p_vout->subpicture_lock );
}
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;
}
else /* idle screen alone */
/* Render idle screen and update idle date, then render interface if
* required */
b_display = RenderIdle( p_vout );
if( b_display )
{
//??? render on idle screen or interface change
b_display = 0; //???
p_vout->last_idle_date = current_date;
if( p_vout->b_interface )
{
RenderInterface( p_vout );
}
}
}
else
{
b_display = 0;
}
/*
......@@ -820,7 +860,7 @@ static void RunThread( vout_thread_t *p_vout)
* then swap buffers */
vlc_mutex_lock( &p_vout->change_lock );
#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
if( b_display && !(p_vout->i_changes & VOUT_NODISPLAY_CHANGE) )
{
......@@ -886,21 +926,21 @@ static void EndThread( vout_thread_t *p_vout )
intf_DbgMsg("\n");
*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++ )
{
if( p_vout->p_picture[i_index].i_status != FREE_PICTURE )
{
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 */
vout_EndTables( p_vout );
vout_EndYUV( p_vout );
vout_SysEnd( p_vout );
}
......@@ -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
* 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_width; /* total text width */
/* Update upper left coordinates according to alignment */
vout_TextSize( p_vout->p_default_font, 0, psz_text, &i_text_width, &i_text_height );
switch( i_halign )
{
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) )
if( !Align( p_vout, &i_x, &i_y, i_text_width, i_text_height, i_h_align, i_v_align ) )
{
intf_DbgMsg("'%s' would print outside the screen\n", psz_text);
return;
}
/* 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 );
0xffffffff, 0x00000000, 0x00000000, 0, psz_text );
}
}
/*******************************************************************************
......@@ -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++;
}
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_end[i_area_copy] = p_buffer->pi_area_end[i_area_copy - 1];
......@@ -1280,54 +1296,41 @@ static void SetBufferPicture( 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 */
byte_t * p_convert_dst; /* convertion destination */
int i_width, i_height, i_eol, i_pic_eol, i_scale; /* ?? tmp variables*/
byte_t * p_pic_data; /* convertion destination */
/* Get and set rendering informations */
p_buffer = &p_vout->p_buffer[ p_vout->i_buffer_index ];
p_vout->last_picture_date = p_pic->date;
p_convert_dst = p_buffer->p_data + p_buffer->i_pic_x * p_vout->i_bytes_per_pixel +
p_pic_data = p_buffer->p_data +
p_buffer->i_pic_x * p_vout->i_bytes_per_pixel +
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
*/
switch( p_pic->i_type )
{
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,
i_width, i_height, i_eol, i_pic_eol, i_scale,
p_pic->i_width, p_pic->i_height, 0,
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;
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,
i_width, i_height, i_eol, i_pic_eol, i_scale,
p_pic->i_width, p_pic->i_height, 0,
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;
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,
i_width, i_height, i_eol, i_pic_eol, i_scale,
p_pic->i_width, p_pic->i_height, 0,
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;
#ifdef DEBUG
......@@ -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 /
( 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 ] ) );
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 )
*/
sprintf( psz_buffer, "%ld frames rendering: %ld us",
(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
#ifdef DEBUG
......@@ -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_x,
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
}
/******************************************************************************
* 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 )
{
//??
Print( p_vout, p_vout->i_width / 2, p_vout->i_height / 2, 0, 0,
"no stream" ); //??
int i_x = 0, i_y = 0; /* text position */
int i_width, i_height; /* text size */
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 )
}
sprintf( psz_buffer, "pic: %d/%d/%d",
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
}
/*******************************************************************************
* RenderSubPictureUnit: render an spu
* RenderSubPicture: render a subpicture
*******************************************************************************
* 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 )
* RenderInterface: render the interface
*******************************************************************************
* This function render the interface, if any.
* ?? this is obviously only a temporary interface !
*******************************************************************************/
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";
/* 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 | TRANSPARENT_TEXT, psz_text_2, &i_width_2, &i_text_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, psz_text_2, &i_width_2, &i_text_height );
i_height += i_text_height;
/* Render background - effective background color will depend of the screen
......@@ -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_bytes_per_pixel, p_vout->i_bytes_per_line,
0xffffffff, 0x00000000, 0x00000000,
OUTLINED_TEXT | TRANSPARENT_TEXT, psz_text_1 );
OUTLINED_TEXT, psz_text_1 );
}
if( i_width_2 < p_vout->i_width )
{
......@@ -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_bytes_per_pixel, p_vout->i_bytes_per_line,
0xffffffff, 0x00000000, 0x00000000,
OUTLINED_TEXT | TRANSPARENT_TEXT, psz_text_2 );
OUTLINED_TEXT, psz_text_2 );
}
/* Activate modified area */
......@@ -1520,14 +1547,21 @@ static int Manage( vout_thread_t *p_vout )
#endif
/* 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
* handled */
p_vout->i_changes &= ~(VOUT_GAMMA_CHANGE | VOUT_GRAYSCALE_CHANGE |
VOUT_INFO_CHANGE | VOUT_INTF_CHANGE | VOUT_SCALE_CHANGE );
VOUT_YUV_CHANGE | VOUT_INFO_CHANGE |
VOUT_INTF_CHANGE | VOUT_SCALE_CHANGE );
/* Detect unauthorized changes */
if( p_vout->i_changes )
......@@ -1540,3 +1574,57 @@ static int Manage( vout_thread_t *p_vout )
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) );
}
......@@ -371,7 +371,7 @@ 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 */
i_char_mask = (i_style & VOID_TEXT) ? 0 : 0xff;
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_height = p_font->i_height;
......
......@@ -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;
/* Set and initialize buffers */
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] );
vout_SetBuffers( p_vout, p_vout->p_sys->p_ximage[ 0 ]->data,
p_vout->p_sys->p_ximage[ 1 ]->data );
return( 0 );
}
......@@ -224,6 +220,10 @@ int vout_SysManage( vout_thread_t *p_vout )
intf_ErrMsg("error: can't resize display\n");
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);
}
......
......@@ -47,32 +47,49 @@ const int MATRIX_COEFFICIENTS_TABLE[8][4] =
static int BinaryLog ( u32 i );
static void MaskToShift ( int *pi_right, int *pi_left, u32 i_mask );
static void SetGammaTable ( int *pi_table, double f_gamma );
static void 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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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
......@@ -115,13 +132,17 @@ for( i_x = 0; i_x < i_width; i_x+=16 ) \
/*******************************************************************************
* CONVERT_YUV_GRAY macro: grayscale YUV convertion
*******************************************************************************
* Variables:
* ...see vout_convert_t
* i_x, i_y coordinates
* i_pic_copy same type as p_pic
* p_gray gray translation table
* This macro does not perform any scaling, but crops the picture. It is
* provided as a temporary way of implementing an YUV convertion function.
*******************************************************************************/
#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_x = 0; i_x < i_width; i_x += 16) \
......@@ -145,47 +166,27 @@ for (i_y = 0; i_y < i_height ; i_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 */ \
p_pic += i_pic_eol; \
p_y += i_eol; \
p_y += i_skip; \
p_pic += i_pic_skip; \
}
/*******************************************************************************
* CONVERT_YUV_RGB: color YUV convertion
*******************************************************************************
* Parameters
* CHROMA 420, 422 or 444
* 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
* This macro does not perform any scaling, but crops the picture. It is
* provided as a temporary way of implementing an YUV convertion function.
*******************************************************************************/
#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_x = 0; i_x < i_width; i_x += 2 ) \
......@@ -211,15 +212,7 @@ for (i_y = 0; i_y < i_height ; i_y++) \
p_blue [(i_yval+i_cbu*i_uval) >>16]; \
} \
\
/* Handle scale factor and rewind in 4:2:0 */ \
if( i_scale && ! (i_y % i_scale) ) \
{ \
if( i_scale < 0 ) \
{ \
/* Copy previous line, rewind if required */ \
p_pic_src = p_pic - i_width; \
p_pic += i_pic_eol; \
LINE_COPY \
/* Rewind in 4:2:0 */ \
if( (CHROMA == 420) && !(i_y & 0x1) ) \
{ \
p_u -= i_chroma_width; \
......@@ -227,43 +220,23 @@ for (i_y = 0; i_y < i_height ; i_y++) \
} \
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_v -= i_chroma_width; \
} \
else \
{ \
p_u += i_chroma_eol; \
p_v += i_chroma_eol; \
p_u += i_chroma_skip; \
p_v += i_chroma_skip; \
} \
\
/* Skip until beginning of next line */ \
p_pic += i_pic_eol; \
p_y += i_eol; \
p_y += i_skip; \
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
* 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 */
......@@ -272,14 +245,14 @@ int vout_InitTables( vout_thread_t *p_vout )
{
case 15:
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;
case 24:
case 32:
#ifndef DEBUG
default:
#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;
#ifdef DEBUG
default:
......@@ -289,16 +262,20 @@ int vout_InitTables( vout_thread_t *p_vout )
#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 */
p_vout->tables.p_base = malloc( tables_size );
if( p_vout->tables.p_base == NULL )
p_vout->yuv.p_base = malloc( tables_size );
if( p_vout->yuv.p_base == NULL )
{
intf_ErrMsg("error: %s\n", strerror(ENOMEM));
return( 1 );
}
/* Initialize tables */
SetTables( p_vout );
SetYUV( p_vout );
return( 0 );
}
......@@ -308,20 +285,20 @@ int vout_InitTables( vout_thread_t *p_vout )
* This function will initialize the tables allocated by vout_CreateTables and
* set functions pointers.
*******************************************************************************/
int vout_ResetTables( vout_thread_t *p_vout )
int vout_ResetYUV( vout_thread_t *p_vout )
{
vout_EndTables( p_vout );
return( vout_InitTables( p_vout ) );
vout_EndYUV( p_vout );
return( vout_InitYUV( p_vout ) );
}
/*******************************************************************************
* vout_EndTables: destroy translations tables
* vout_EndYUV: destroy translations tables
*******************************************************************************
* 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 */
......@@ -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 i_index; /* index in tables */
......@@ -458,10 +435,10 @@ static void SetTables( vout_thread_t *p_vout )
{
case 15:
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++)
{
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_green_right) << i_green_left) |
((pi_gamma[CLIP_BYTE( i_index )] >> i_blue_right) << i_blue_left);
......@@ -469,10 +446,10 @@ static void SetTables( vout_thread_t *p_vout )
break;
case 24:
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++)
{
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_green_right) << i_green_left) |
((pi_gamma[CLIP_BYTE( i_index )] >> i_blue_right) << i_blue_left);
......@@ -487,27 +464,53 @@ static void SetTables( vout_thread_t *p_vout )
{
case 15:
case 16:
p_vout->tables.yuv.rgb16.p_red = (u16 *)p_vout->tables.p_base + 384;
p_vout->tables.yuv.rgb16.p_green = (u16 *)p_vout->tables.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_red = (u16 *)p_vout->yuv.p_base + 384;
p_vout->yuv.yuv.rgb16.p_green = (u16 *)p_vout->yuv.p_base + 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++)
{
p_vout->tables.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->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_red[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left;
p_vout->yuv.yuv.rgb16.p_green[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_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;
case 24:
case 32:
p_vout->tables.yuv.rgb32.p_red = (u32 *)p_vout->tables.p_base + 384;
p_vout->tables.yuv.rgb32.p_green = (u32 *)p_vout->tables.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_red = (u32 *)p_vout->yuv.p_base + 384;
p_vout->yuv.yuv.rgb32.p_green = (u32 *)p_vout->yuv.p_base + 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++)
{
p_vout->tables.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->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_red[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_red_right)<<i_red_left;
p_vout->yuv.yuv.rgb32.p_green[i_index] = (pi_gamma[CLIP_BYTE(i_index)]>>i_green_right)<<i_green_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;
}
}
......@@ -522,19 +525,19 @@ static void SetTables( vout_thread_t *p_vout )
{
case 15:
case 16:
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray16;
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray16;
break;
case 24:
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray24;
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray24;
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray24;
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray24;
break;
case 32:
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertY4Gray32;
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray32;
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray32;
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertY4Gray32;
break;
}
}
......@@ -545,19 +548,19 @@ static void SetTables( vout_thread_t *p_vout )
{
case 15:
case 16:
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB16;
p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB16;
p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB16;
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB16;
p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB16;
p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB16;
break;
case 24:
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB24;
p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB24;
p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB24;
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB24;
p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB24;
p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB24;
break;
case 32:
p_vout->p_ConvertYUV420 = (vout_convert_t *) ConvertYUV420RGB32;
p_vout->p_ConvertYUV422 = (vout_convert_t *) ConvertYUV422RGB32;
p_vout->p_ConvertYUV444 = (vout_convert_t *) ConvertYUV444RGB32;
p_vout->yuv.p_Convert420 = (vout_yuv_convert_t *) ConvertYUV420RGB32;
p_vout->yuv.p_Convert422 = (vout_yuv_convert_t *) ConvertYUV422RGB32;
p_vout->yuv.p_Convert444 = (vout_yuv_convert_t *) ConvertYUV444RGB32;
break;
}
}
......@@ -566,26 +569,23 @@ static void SetTables( vout_thread_t *p_vout )
/*******************************************************************************
* ConvertY4Gray16: grayscale YUV 4:x:x to RGB 15 or 16 bpp
*******************************************************************************/
static void ConvertY4Gray16( p_vout_thread_t p_vout, u16 *p_pic,
yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
int i_width, int i_height, int i_eol, int i_pic_eol,
int i_scale, int i_matrix_coefficients )
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_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_matrix_coefficients )
{
u16 * p_pic_src; /* source pointer in case of copy */
u16 * p_gray; /* gray table */
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
}
/*******************************************************************************
* ConvertY4Gray24: grayscale YUV 4:x:x to RGB 24 bpp
*******************************************************************************/
static void ConvertY4Gray24( p_vout_thread_t p_vout, void *p_pic,
yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
int i_width, int i_height, int i_eol, int i_pic_eol,
int i_scale, 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,
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 )
{
//??
}
......@@ -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
*******************************************************************************/
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 )
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_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_matrix_coefficients )
{
u32 * p_pic_src; /* source pointer in case of copy */
u32 * p_gray; /* gray table */
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
}
/*******************************************************************************
* ConvertYUV420RGB16: color YUV 4:2:0 to RGB 15 or 16 bpp
*******************************************************************************/
static void ConvertYUV420RGB16( p_vout_thread_t p_vout, u16 *p_pic,
yuv_data_t *p_y, yuv_data_t *p_u, yuv_data_t *p_v,
int i_width, int i_height, int i_eol, int i_pic_eol,
int i_scale, 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,
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 )
{
#ifdef HAVE_MMX
int i_chroma_width, i_chroma_eol; /* width and eol for chroma */
//?? gloups: find a good one !
#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_eol = i_eol / 2;
i_chroma_skip = i_skip / 2;
ConvertYUV420RGB16MMX( p_y, p_u, p_v, i_width, i_height,
(i_width + i_eol) * sizeof( yuv_data_t ),
(i_chroma_width + i_chroma_eol) * sizeof( yuv_data_t),
(i_width + i_skip) * 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 ),
p_vout->i_screen_depth == 15 );
#else
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_chroma_width, i_chroma_skip; /* 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;
p_red = p_vout->yuv.yuv.rgb16.p_red;
p_green = p_vout->yuv.yuv.rgb16.p_green;
p_blue = p_vout->yuv.yuv.rgb16.p_blue;
CONVERT_YUV_RGB( 420 )
#endif
}
......@@ -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
*******************************************************************************/
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 )
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_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
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
*******************************************************************************/
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 )
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_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
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
*******************************************************************************/
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 )
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_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_matrix_coefficients )
{
//???
}
......@@ -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
*******************************************************************************/
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 )
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_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_matrix_coefficients )
{
//???
}
......@@ -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
*******************************************************************************/
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 )
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_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
int i_matrix_coefficients )
{
//???
}
......@@ -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
*******************************************************************************/
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 )
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_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
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
*******************************************************************************/
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 )
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_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
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
*******************************************************************************/
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 )
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_skip, int i_pic_width, int i_pic_height, int i_pic_skip,
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 ---------------------------------------
......
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