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
{
......@@ -21,8 +50,17 @@ typedef struct vout_tables_s
struct { u32 *p_red, *p_green, *p_blue; } rgb32; /* color 24, 32 bpp */
struct { u16 *p_gray; } gray16; /* gray 15, 16 bpp */
struct { u32 *p_gray; } gray32; /* gray 24, 32 bpp */
} yuv;
} vout_tables_t;
} yuv;
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
......
......@@ -250,7 +250,7 @@ int intf_ProcessKey( intf_thread_t *p_intf, int i_key )
if( p_intf->p_vout != NULL )
{
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;
vlc_mutex_unlock( &p_intf->p_vout->change_lock );
}
......
......@@ -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_picture[i_index].i_type = EMPTY_PICTURE;
p_vout->p_picture[i_index].i_status = FREE_PICTURE;
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,
int i_size )
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,18 +728,19 @@ 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 )
{
/* Set picture dimensions and clear buffer */
......@@ -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 */