mirror of
https://github.com/videolan/vlc.git
synced 2024-12-03 23:04:35 +08:00
* Speed optimization in the handling of the unusual ephemer DVD subtitles.
* Little optimization to bozo's UnalignedShowBits fix. * Race fix in the packet cache by Jon Lech Johansen <jon-vl@nanocrew.net>.
This commit is contained in:
parent
37ee07f3f9
commit
abe5a7d0c0
4
AUTHORS
4
AUTHORS
@ -112,6 +112,10 @@ E: bbp@via.ecp.fr
|
||||
C: bbp
|
||||
D: Bug fixes
|
||||
|
||||
N: Jon Lech Johansen
|
||||
E: jon-vl@nanocrew.net
|
||||
D: PS input fixes
|
||||
|
||||
N: Michel Kaempf
|
||||
E: maxx@via.ecp.fr
|
||||
C: maxx
|
||||
|
18
ChangeLog
18
ChangeLog
@ -3,6 +3,24 @@
|
||||
#===================#
|
||||
|
||||
HEAD
|
||||
* Speed optimization in the handling of the unusual ephemer DVD subtitles.
|
||||
* Little optimization to bozo's UnalignedShowBits fix.
|
||||
* Race fix in the packet cache by Jon Lech Johansen <jon-vl@nanocrew.net>.
|
||||
* Fixed a bug in UnalignedShowBits that makes some unaligned streams
|
||||
not wotk correctly (for instance VLS' generated TS streams)
|
||||
* Added support for some terribly braindead DVD subtitles in Kenshin
|
||||
which do not have a "stop display" command. Anime fans rejoice!
|
||||
* Fixed the BeOS interface to use p_aout_bank instead of p_main->p_aout.
|
||||
* Coding-style butchery (mostly tabs).
|
||||
* Changed the level arg in intf_WarnMsg so that it makes more sense.
|
||||
* Beginning of the backport of Gnome to Gtk.
|
||||
* Improved ac3 spdif output ( and made it work again :)).
|
||||
* Added p_input->stream.p_selected_area->i_tell in input TS so that the
|
||||
slider work with Transport Stream files.
|
||||
* Moved b_fullscreen from p_vout->p_sys to p_vout and unified way of
|
||||
toggling fullscreen.
|
||||
* Tuned the Gnome interface appearance, added a Preferences window and
|
||||
a Jump window, added Oct's playlist.
|
||||
* Fixed a few warnings with gcc 3.0.
|
||||
* aout and vout are now allocated in banks, making it possible to have
|
||||
several of them at the same time.
|
||||
|
@ -2,7 +2,7 @@
|
||||
* input_ps.c: PS demux and packet management
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1998, 1999, 2000 VideoLAN
|
||||
* $Id: input_ps.c,v 1.22 2001/05/07 04:42:42 sam Exp $
|
||||
* $Id: input_ps.c,v 1.23 2001/05/08 00:43:57 sam Exp $
|
||||
*
|
||||
* Authors: Christophe Massiot <massiot@via.ecp.fr>
|
||||
* Cyril Deguet <asmax@via.ecp.fr>
|
||||
@ -166,6 +166,9 @@ static void PSInit( input_thread_t * p_input )
|
||||
return;
|
||||
}
|
||||
p_input->p_method_data = (void *)p_packet_cache;
|
||||
|
||||
/* Initialize packet cache mutex */
|
||||
vlc_mutex_init( &p_packet_cache->lock );
|
||||
|
||||
/* allocates the data cache */
|
||||
p_packet_cache->data.p_stack = malloc( DATA_CACHE_SIZE *
|
||||
@ -362,6 +365,7 @@ static void PSInit( input_thread_t * p_input )
|
||||
*****************************************************************************/
|
||||
static void PSEnd( input_thread_t * p_input )
|
||||
{
|
||||
vlc_mutex_destroy( &((packet_cache_t *)p_input->p_plugin_data)->lock );
|
||||
free( p_input->p_plugin_data );
|
||||
}
|
||||
|
||||
@ -571,6 +575,8 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vlc_mutex_lock( &p_cache->lock );
|
||||
|
||||
/* Checks whether the data cache is empty */
|
||||
if( p_cache->data.l_index == 0 )
|
||||
{
|
||||
@ -578,6 +584,7 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
|
||||
if ( (p_data = malloc( sizeof(data_packet_t) )) == NULL )
|
||||
{
|
||||
intf_ErrMsg( "Out of memory" );
|
||||
vlc_mutex_unlock( &p_cache->lock );
|
||||
return NULL;
|
||||
}
|
||||
#ifdef TRACE_INPUT
|
||||
@ -591,6 +598,7 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
|
||||
== NULL )
|
||||
{
|
||||
intf_ErrMsg( "NULL packet in the data cache" );
|
||||
vlc_mutex_unlock( &p_cache->lock );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -607,6 +615,7 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
|
||||
{
|
||||
intf_DbgMsg( "Out of memory" );
|
||||
free( p_data );
|
||||
vlc_mutex_unlock( &p_cache->lock );
|
||||
return NULL;
|
||||
}
|
||||
#ifdef TRACE_INPUT
|
||||
@ -623,6 +632,7 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
|
||||
{
|
||||
intf_ErrMsg( "NULL packet in the small buffer cache" );
|
||||
free( p_data );
|
||||
vlc_mutex_unlock( &p_cache->lock );
|
||||
return NULL;
|
||||
}
|
||||
/* Reallocates the packet if it is too small or too large */
|
||||
@ -650,6 +660,7 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
|
||||
{
|
||||
intf_ErrMsg( "Out of memory" );
|
||||
free( p_data );
|
||||
vlc_mutex_unlock( &p_cache->lock );
|
||||
return NULL;
|
||||
}
|
||||
#ifdef TRACE_INPUT
|
||||
@ -666,6 +677,7 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
|
||||
{
|
||||
intf_ErrMsg( "NULL packet in the small buffer cache" );
|
||||
free( p_data );
|
||||
vlc_mutex_unlock( &p_cache->lock );
|
||||
return NULL;
|
||||
}
|
||||
/* Reallocates the packet if it is too small or too large */
|
||||
@ -682,6 +694,8 @@ static struct data_packet_s * NewPacket( void * p_packet_cache,
|
||||
}
|
||||
}
|
||||
|
||||
vlc_mutex_unlock( &p_cache->lock );
|
||||
|
||||
/* Initialize data */
|
||||
p_data->p_next = NULL;
|
||||
p_data->b_discard_payload = 0;
|
||||
@ -711,6 +725,8 @@ static pes_packet_t * NewPES( void * p_packet_cache )
|
||||
}
|
||||
#endif
|
||||
|
||||
vlc_mutex_lock( &p_cache->lock );
|
||||
|
||||
/* Checks whether the PES cache is empty */
|
||||
if( p_cache->pes.l_index == 0 )
|
||||
{
|
||||
@ -718,6 +734,7 @@ static pes_packet_t * NewPES( void * p_packet_cache )
|
||||
if ( (p_pes = malloc( sizeof(pes_packet_t) )) == NULL )
|
||||
{
|
||||
intf_DbgMsg( "Out of memory" );
|
||||
vlc_mutex_unlock( &p_cache->lock );
|
||||
return NULL;
|
||||
}
|
||||
#ifdef TRACE_INPUT
|
||||
@ -731,10 +748,13 @@ static pes_packet_t * NewPES( void * p_packet_cache )
|
||||
== NULL )
|
||||
{
|
||||
intf_ErrMsg( "NULL packet in the data cache" );
|
||||
vlc_mutex_unlock( &p_cache->lock );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
vlc_mutex_unlock( &p_cache->lock );
|
||||
|
||||
p_pes->b_data_alignment = p_pes->b_discontinuity =
|
||||
p_pes->i_pts = p_pes->i_dts = 0;
|
||||
p_pes->i_pes_size = 0;
|
||||
@ -764,6 +784,8 @@ static void DeletePacket( void * p_packet_cache,
|
||||
|
||||
ASSERT( p_data );
|
||||
|
||||
vlc_mutex_lock( &p_cache->lock );
|
||||
|
||||
/* Checks whether the data cache is full */
|
||||
if ( p_cache->data.l_index < DATA_CACHE_SIZE )
|
||||
{
|
||||
@ -819,6 +841,7 @@ static void DeletePacket( void * p_packet_cache,
|
||||
#endif
|
||||
}
|
||||
|
||||
vlc_mutex_unlock( &p_cache->lock );
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@ -851,6 +874,8 @@ static void DeletePES( void * p_packet_cache, pes_packet_t * p_pes )
|
||||
p_data = p_next;
|
||||
}
|
||||
|
||||
vlc_mutex_lock( &p_cache->lock );
|
||||
|
||||
/* Checks whether the PES cache is full */
|
||||
if ( p_cache->pes.l_index < PES_CACHE_SIZE )
|
||||
{
|
||||
@ -865,5 +890,7 @@ static void DeletePES( void * p_packet_cache, pes_packet_t * p_pes )
|
||||
intf_DbgMsg( "PS input: PES packet freed" );
|
||||
#endif
|
||||
}
|
||||
|
||||
vlc_mutex_unlock( &p_cache->lock );
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
* input_ps.h: thread structure of the PS plugin
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1999, 2000 VideoLAN
|
||||
* $Id: input_ps.h,v 1.5 2001/04/16 12:34:28 asmax Exp $
|
||||
* $Id: input_ps.h,v 1.6 2001/05/08 00:43:57 sam Exp $
|
||||
*
|
||||
* Authors: Christophe Massiot <massiot@via.ecp.fr>
|
||||
* Cyril Deguet <asmax@via.ecp.fr>
|
||||
@ -75,6 +75,7 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vlc_mutex_t lock;
|
||||
data_packet_cache_t data;
|
||||
pes_packet_cache_t pes;
|
||||
small_buffer_cache_t small;
|
||||
|
@ -2,7 +2,7 @@
|
||||
* input_ext-dec.c: services to the decoders
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1998, 1999, 2000 VideoLAN
|
||||
* $Id: input_ext-dec.c,v 1.15 2001/05/07 13:52:39 bozo Exp $
|
||||
* $Id: input_ext-dec.c,v 1.16 2001/05/08 00:43:57 sam Exp $
|
||||
*
|
||||
* Authors: Christophe Massiot <massiot@via.ecp.fr>
|
||||
*
|
||||
@ -181,20 +181,19 @@ u32 UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
|
||||
* of the packet in a temporary buffer, and we'll see
|
||||
* later. */
|
||||
int i;
|
||||
/* number of bytes to trash from the last payload */
|
||||
|
||||
/* sizeof(WORD_TYPE) - number of bytes to trash
|
||||
* from the last payload */
|
||||
int j;
|
||||
|
||||
p_bit_stream->i_showbits_buffer = 0;
|
||||
|
||||
/* is this initialization really usefull ? -- bozo */
|
||||
j = sizeof(WORD_TYPE);
|
||||
|
||||
for( i = 0; i < sizeof(WORD_TYPE) ; i++ )
|
||||
for( j = i = 0 ; i < sizeof(WORD_TYPE) ; i++ )
|
||||
{
|
||||
if( p_bit_stream->p_byte >= p_bit_stream->p_end )
|
||||
{
|
||||
j = i;
|
||||
p_bit_stream->pf_next_data_packet( p_bit_stream );
|
||||
j = sizeof(WORD_TYPE) - i;
|
||||
}
|
||||
((byte_t *)&p_bit_stream->i_showbits_buffer)[i] =
|
||||
* p_bit_stream->p_byte;
|
||||
@ -202,7 +201,8 @@ u32 UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
|
||||
}
|
||||
|
||||
/* This is kind of kludgy. */
|
||||
p_bit_stream->p_data->p_payload_start += j;
|
||||
p_bit_stream->p_data->p_payload_start +=
|
||||
sizeof(WORD_TYPE) - j;
|
||||
p_bit_stream->p_byte =
|
||||
(byte_t *)&p_bit_stream->i_showbits_buffer;
|
||||
p_bit_stream->p_end =
|
||||
|
@ -5,7 +5,7 @@
|
||||
* thread, and destroy a previously oppened video output thread.
|
||||
*****************************************************************************
|
||||
* Copyright (C) 2000 VideoLAN
|
||||
* $Id: video_output.c,v 1.126 2001/05/07 04:42:42 sam Exp $
|
||||
* $Id: video_output.c,v 1.127 2001/05/08 00:43:57 sam Exp $
|
||||
*
|
||||
* Authors: Vincent Seguin <seguin@via.ecp.fr>
|
||||
*
|
||||
@ -108,7 +108,7 @@ void vout_EndBank ( void )
|
||||
{
|
||||
vout_DestroyThread(
|
||||
p_vout_bank->pp_vout[ --p_vout_bank->i_count ], NULL );
|
||||
}
|
||||
}
|
||||
|
||||
vlc_mutex_destroy( &p_vout_bank->lock );
|
||||
}
|
||||
@ -181,11 +181,11 @@ vout_thread_t * vout_CreateThread ( int *pi_status )
|
||||
p_vout->i_screen_depth = main_GetIntVariable( VOUT_DEPTH_VAR,
|
||||
VOUT_DEPTH_DEFAULT );
|
||||
p_vout->i_bytes_per_pixel = 2;
|
||||
p_vout->f_gamma = VOUT_GAMMA_DEFAULT; // FIXME: replace with
|
||||
p_vout->f_gamma = VOUT_GAMMA_DEFAULT; // FIXME: replace with
|
||||
// variable
|
||||
p_vout->b_need_render = 1;
|
||||
p_vout->b_YCbr = 0;
|
||||
|
||||
|
||||
p_vout->b_grayscale = main_GetIntVariable( VOUT_GRAYSCALE_VAR,
|
||||
VOUT_GRAYSCALE_DEFAULT );
|
||||
p_vout->b_info = 0;
|
||||
@ -415,8 +415,8 @@ subpicture_t *vout_CreateSubPicture( vout_thread_t *p_vout, int i_type,
|
||||
}
|
||||
else if( p_destroyed_subpic == NULL )
|
||||
{
|
||||
/* Memory size do not match, but subpicture index will be kept in
|
||||
* case no other place are left */
|
||||
/* Memory size do not match, but subpicture index will be kept
|
||||
* in case we find no other place */
|
||||
p_destroyed_subpic = &p_vout->p_subpicture[i_subpic];
|
||||
}
|
||||
}
|
||||
@ -731,7 +731,7 @@ picture_t *vout_CreatePicture( vout_thread_t *p_vout, int i_type,
|
||||
|
||||
/* Initialize mutex */
|
||||
vlc_mutex_init( &(p_free_picture->lock_deccount) );
|
||||
|
||||
|
||||
return( p_free_picture );
|
||||
}
|
||||
|
||||
@ -771,7 +771,7 @@ void vout_DestroyPicture( vout_thread_t *p_vout, picture_t *p_pic )
|
||||
|
||||
/* destroy the lock that had been initialized in CreatePicture */
|
||||
vlc_mutex_destroy( &(p_pic->lock_deccount) );
|
||||
|
||||
|
||||
vlc_mutex_unlock( &p_vout->picture_lock );
|
||||
}
|
||||
|
||||
@ -966,7 +966,7 @@ static int InitThread( vout_thread_t *p_vout )
|
||||
p_vout->b_active = 1;
|
||||
*p_vout->pi_status = THREAD_READY;
|
||||
|
||||
|
||||
|
||||
intf_DbgMsg("thread ready");
|
||||
return( 0 );
|
||||
}
|
||||
@ -984,8 +984,12 @@ static void RunThread( vout_thread_t *p_vout)
|
||||
mtime_t current_date; /* current date */
|
||||
mtime_t display_date; /* display date */
|
||||
boolean_t b_display; /* display flag */
|
||||
|
||||
picture_t * p_pic; /* picture pointer */
|
||||
|
||||
subpicture_t * p_subpic; /* subpicture pointer */
|
||||
subpicture_t * p_ephemer; /* youngest ephemer subpicture pointer */
|
||||
mtime_t ephemer_date; /* earliest subpicture date */
|
||||
|
||||
/*
|
||||
* Initialize thread
|
||||
@ -1006,6 +1010,8 @@ static void RunThread( vout_thread_t *p_vout)
|
||||
/* Initialize loop variables */
|
||||
p_pic = NULL;
|
||||
p_subpic = NULL;
|
||||
p_ephemer = NULL;
|
||||
ephemer_date = 0;
|
||||
display_date = 0;
|
||||
current_date = mdate();
|
||||
#ifdef STATS
|
||||
@ -1073,6 +1079,11 @@ static void RunThread( vout_thread_t *p_vout)
|
||||
* Find the subpictures to display - this operation does not need
|
||||
* lock, since only READY_SUBPICTURE are handled. If no picture
|
||||
* has been selected, display_date will depend on the subpicture.
|
||||
*
|
||||
* We also check for ephemer DVD subpictures (subpictures that have
|
||||
* to be removed if a newer one is available), which makes it a lot
|
||||
* more difficult to guess if a subpicture has to be rendered or not.
|
||||
*
|
||||
* We get an easily parsable chained list of subpictures which
|
||||
* ends with NULL since p_subpic was initialized to NULL.
|
||||
*/
|
||||
@ -1080,8 +1091,86 @@ static void RunThread( vout_thread_t *p_vout)
|
||||
{
|
||||
if( p_vout->p_subpicture[i_index].i_status == READY_SUBPICTURE )
|
||||
{
|
||||
p_vout->p_subpicture[i_index].p_next = p_subpic;
|
||||
p_subpic = &p_vout->p_subpicture[i_index];
|
||||
/* If it is a DVD subpicture, check its date */
|
||||
if( p_vout->p_subpicture[i_index].i_type == DVD_SUBPICTURE )
|
||||
{
|
||||
if( display_date > p_vout->p_subpicture[i_index].i_stop )
|
||||
{
|
||||
/* Too late, destroy the subpic */
|
||||
vout_DestroySubPicture( p_vout,
|
||||
&p_vout->p_subpicture[i_index] );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( display_date < p_vout->p_subpicture[i_index].i_start )
|
||||
{
|
||||
/* Too early, come back next monday */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If this is an ephemer subpic, see if it's the
|
||||
* youngest we have */
|
||||
if( p_vout->p_subpicture[i_index].b_ephemer )
|
||||
{
|
||||
if( p_ephemer == NULL )
|
||||
{
|
||||
p_ephemer = &p_vout->p_subpicture[i_index];
|
||||
continue;
|
||||
}
|
||||
|
||||
if( p_vout->p_subpicture[i_index].i_start
|
||||
< p_ephemer->i_start )
|
||||
{
|
||||
/* Link the previous ephemer subpicture and
|
||||
* replace it with the current one */
|
||||
p_ephemer->p_next = p_subpic;
|
||||
p_subpic = p_ephemer;
|
||||
p_ephemer = &p_vout->p_subpicture[i_index];
|
||||
|
||||
/* If it's the 2nd youngest subpicture,
|
||||
* register its date */
|
||||
if( !ephemer_date
|
||||
|| ephemer_date > p_subpic->i_start )
|
||||
{
|
||||
ephemer_date = p_subpic->i_start;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
p_vout->p_subpicture[i_index].p_next = p_subpic;
|
||||
p_subpic = &p_vout->p_subpicture[i_index];
|
||||
|
||||
/* If it's the 2nd youngest subpicture, register its date */
|
||||
if( !ephemer_date || ephemer_date > p_subpic->i_start )
|
||||
{
|
||||
ephemer_date = p_subpic->i_start;
|
||||
}
|
||||
}
|
||||
/* If it's not a DVD subpicture, just register it */
|
||||
else
|
||||
{
|
||||
p_vout->p_subpicture[i_index].p_next = p_subpic;
|
||||
p_subpic = &p_vout->p_subpicture[i_index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If we found an ephemer subpicture, check if it has to be
|
||||
* displayed */
|
||||
if( p_ephemer != NULL )
|
||||
{
|
||||
if( p_ephemer->i_start < ephemer_date )
|
||||
{
|
||||
/* Ephemer subpicture has lived too long */
|
||||
vout_DestroySubPicture( p_vout, p_ephemer );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Ephemer subpicture can still live a bit */
|
||||
p_ephemer->p_next = p_subpic;
|
||||
p_subpic = p_ephemer;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1122,7 +1211,7 @@ static void RunThread( vout_thread_t *p_vout)
|
||||
}
|
||||
|
||||
}
|
||||
else if( p_vout->b_active && p_vout->b_need_render
|
||||
else if( p_vout->b_active && p_vout->b_need_render
|
||||
&& p_vout->init_display_date == 0)
|
||||
{
|
||||
/* Idle or interface screen alone */
|
||||
@ -1157,21 +1246,21 @@ static void RunThread( vout_thread_t *p_vout)
|
||||
* Check for the current time and
|
||||
* display splash screen if everything is on time
|
||||
*/
|
||||
if( p_vout->init_display_date > 0 && p_vout->b_need_render )
|
||||
if( p_vout->init_display_date > 0 && p_vout->b_need_render )
|
||||
{
|
||||
if( p_vout->b_active &&
|
||||
if( p_vout->b_active &&
|
||||
mdate()-p_vout->init_display_date < 5000000)
|
||||
{
|
||||
/* there is something to display ! */
|
||||
b_display = 1;
|
||||
RenderSplash( p_vout );
|
||||
|
||||
|
||||
} else {
|
||||
/* no splash screen ! */
|
||||
p_vout->init_display_date=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Sleep, wake up and display rendered picture
|
||||
@ -1342,7 +1431,7 @@ static void DestroyThread( vout_thread_t *p_vout, int i_status )
|
||||
vlc_mutex_destroy( &p_vout->picture_lock );
|
||||
vlc_mutex_destroy( &p_vout->subpicture_lock );
|
||||
vlc_mutex_destroy( &p_vout->change_lock );
|
||||
|
||||
|
||||
/* Release the module */
|
||||
module_Unneed( p_vout->p_module );
|
||||
|
||||
@ -1705,9 +1794,9 @@ static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
|
||||
#ifdef TRACE_VOUT
|
||||
render_time = mdate();
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Choose appropriate rendering function and render picture
|
||||
*/
|
||||
@ -1869,8 +1958,8 @@ int RenderIdle( vout_thread_t *p_vout )
|
||||
|
||||
|
||||
current_date = mdate();
|
||||
if( (current_date - p_vout->last_display_date) > VOUT_IDLE_DELAY
|
||||
// && (current_date - p_vout->last_idle_date) > VOUT_IDLE_DELAY
|
||||
if( (current_date - p_vout->last_display_date) > VOUT_IDLE_DELAY
|
||||
// && (current_date - p_vout->last_idle_date) > VOUT_IDLE_DELAY
|
||||
)
|
||||
{
|
||||
/* FIXME: idle screen disabled */
|
||||
@ -1880,7 +1969,7 @@ int RenderIdle( vout_thread_t *p_vout )
|
||||
&i_width, &i_height );
|
||||
if( !Align( p_vout, &i_x, &i_y, i_width, i_height * 2, CENTER_RALIGN, CENTER_RALIGN ) )
|
||||
{
|
||||
i_amount = (int) ((current_date - p_vout->last_display_date ) / 5000LL);
|
||||
i_amount = (int) ((current_date - p_vout->last_display_date ) / 5000LL);
|
||||
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,
|
||||
@ -1894,7 +1983,7 @@ int RenderIdle( vout_thread_t *p_vout )
|
||||
p_vout->i_bytes_per_pixel, p_vout->i_bytes_per_line,
|
||||
p_vout->i_white_pixel, p_vout->i_gray_pixel, 0,
|
||||
WIDE_TEXT | OUTLINED_TEXT, psz_wtext, (i_amount/5)%110 );
|
||||
|
||||
|
||||
|
||||
SetBufferArea( p_vout, i_x, i_y, i_width, i_height * 2 );
|
||||
}
|
||||
@ -1952,61 +2041,12 @@ static void RenderSubPicture( vout_thread_t *p_vout, subpicture_t *p_subpic )
|
||||
{
|
||||
p_vout_font_t p_font; /* text font */
|
||||
int i_width, i_height; /* subpicture dimensions */
|
||||
mtime_t i_date = mdate();
|
||||
|
||||
subpicture_t *p_ephemer = NULL;
|
||||
subpicture_t *p_tmp = p_subpic;
|
||||
|
||||
/* Look for the youngest ephemer */
|
||||
while( p_tmp != NULL )
|
||||
{
|
||||
if( p_tmp->i_type == DVD_SUBPICTURE && p_tmp->b_ephemer
|
||||
&& i_date >= p_tmp->i_start && i_date <= p_tmp->i_stop )
|
||||
{
|
||||
if( p_ephemer == NULL || p_tmp->i_start < p_ephemer->i_start )
|
||||
{
|
||||
p_ephemer = p_tmp;
|
||||
}
|
||||
}
|
||||
|
||||
p_tmp = p_tmp->p_next;
|
||||
}
|
||||
|
||||
/* If we found an ephemer, kill it if we find a more recent one */
|
||||
if( p_ephemer != NULL )
|
||||
{
|
||||
p_tmp = p_subpic;
|
||||
|
||||
while( p_tmp != NULL )
|
||||
{
|
||||
if( p_tmp->i_type == DVD_SUBPICTURE
|
||||
&& i_date >= p_tmp->i_start && i_date >= p_tmp->i_start
|
||||
&& p_tmp != p_ephemer && p_tmp->i_start > p_ephemer->i_start )
|
||||
{
|
||||
p_ephemer->i_stop = 0;
|
||||
}
|
||||
|
||||
p_tmp = p_tmp->p_next;
|
||||
}
|
||||
}
|
||||
|
||||
while( p_subpic != NULL )
|
||||
{
|
||||
switch( p_subpic->i_type )
|
||||
{
|
||||
case DVD_SUBPICTURE: /* DVD subpicture unit */
|
||||
/* test if the picture really has to be displayed */
|
||||
if( i_date < p_subpic->i_start )
|
||||
{
|
||||
/* not yet, see you later */
|
||||
break;
|
||||
}
|
||||
if( i_date > p_subpic->i_stop )
|
||||
{
|
||||
/* too late, destroying the subpic */
|
||||
vout_DestroySubPicture( p_vout, p_subpic );
|
||||
break;
|
||||
}
|
||||
vout_RenderSPU( &p_vout->p_buffer[ p_vout->i_buffer_index ],
|
||||
p_subpic, p_vout->i_bytes_per_pixel,
|
||||
p_vout->i_bytes_per_line );
|
||||
|
Loading…
Reference in New Issue
Block a user