* but exported to plug-ins
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: input_ext-plugins.h,v 1.8 2001/12/10 04:53:10 sam Exp $
+ * $Id: input_ext-plugins.h,v 1.9 2001/12/12 11:18:38 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
void input_NetlistEnd( struct input_thread_s * );
+/*
+ * Optional Next Generation buffer manager
+ *
+ * Either buffers can only be used in one data packet (PS case), or buffers
+ * contain several data packets (DVD case). In the first case, buffers are
+ * embedded into data packets, otherwise they are allocated separately and
+ * shared with a refcount. --Meuuh
+ */
+
+/* Number of buffers for the calculation of the mean */
+#define INPUT_BRESENHAM_NB 50
+
+/* Flags */
+#define BUFFERS_NOFLAGS 0
+#define BUFFERS_SHARED 1
+#define BUFFERS_UNIQUE_SIZE 2
+
+/*****************************************************************************
+ * input_buffers_t: defines a LIFO per data type to keep
+ *****************************************************************************/
+#define PACKETS_LIFO( TYPE, NAME ) \
+struct \
+{ \
+ TYPE * p_stack; \
+ unsigned int i_depth; \
+} NAME;
+
+#define BUFFERS_LIFO( TYPE, NAME ) \
+struct \
+{ \
+ TYPE * p_stack; /* First item in the LIFO */ \
+ unsigned int i_depth; /* Number of items in the LIFO */ \
+ unsigned int i_average_size; /* Average size of the items (Bresenham) */\
+} NAME;
+
+#define DECLARE_BUFFERS_EMBEDDED( FLAGS, NB_LIFO ) \
+typedef struct input_buffers_s \
+{ \
+ vlc_mutex_t lock; \
+ PACKETS_LIFO( pes_packet_t, pes ) \
+ BUFFERS_LIFO( data_packet_t, data[NB_LIFO] ) \
+ size_t i_allocated; \
+} input_buffers_t;
+
+#define DECLARE_BUFFERS_SHARED( FLAGS, NB_LIFO ) \
+typedef struct data_buffer_s \
+{ \
+ int i_refcount; \
+ int i_size; \
+ struct data_buffers_s * p_next; \
+ byte_t payload_start; \
+} data_buffer_t; \
+ \
+typedef struct input_buffers_s \
+{ \
+ vlc_mutex_t lock; \
+ PACKETS_LIFO( pes_packet_t, pes ) \
+ PACKETS_LIFO( data_packet_t, data ) \
+ BUFFERS_LIFO( data_buffers_t, buffers[NB_LIFO] ) \
+ size_t i_allocated; \
+} input_buffers_t;
+
+
+/*****************************************************************************
+ * input_BuffersInit: initialize the cache structures, return a pointer to it
+ *****************************************************************************/
+#define DECLARE_BUFFERS_INIT( FLAGS, NB_LIFO ) \
+static void * input_BuffersInit( void ) \
+{ \
+ input_buffers_t * p_buffers = malloc( sizeof( input_buffers_t ) ); \
+ \
+ if( p_buffers == NULL ) \
+ { \
+ return( NULL ); \
+ } \
+ \
+ memset( p_buffers, 0, sizeof( input_buffers_t ) ); \
+ vlc_mutex_init( &p_buffers->lock ); \
+ \
+ return (void *)p_buffers; \
+}
+
+/*****************************************************************************
+ * input_BuffersEnd: free all cached structures
+ *****************************************************************************/
+#define DECLARE_BUFFERS_END( FLAGS, NB_LIFO ) \
+static void input_BuffersEnd( void * _p_buffers ) \
+{ \
+ input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
+ \
+ if( _p_buffers != NULL ) \
+ { \
+ pes_packet_t * p_pes = p_buffers->pes.p_stack; \
+ int i; \
+ \
+ if( p_main->b_stats ) \
+ { \
+ int i; \
+ for( i = 0; i < NB_LIFO; i++ ) \
+ { \
+ intf_StatMsg( \
+ "input buffers stats: data[%d]: %d bytes, %d packets", \
+ i, p_buffers->data[i].i_average_size, \
+ p_buffers->data[i].i_depth ); \
+ } \
+ } \
+ \
+ /* Free PES */ \
+ while( p_pes != NULL ) \
+ { \
+ pes_packet_t * p_next = p_pes->p_next; \
+ free( p_pes ); \
+ p_pes = p_next; \
+ } \
+ \
+ for( i = 0; i < NB_LIFO; i++ ) \
+ { \
+ data_packet_t * p_data = p_buffers->data[i].p_stack; \
+ \
+ /* Free data packets */ \
+ while( p_data != NULL ) \
+ { \
+ data_packet_t * p_next = p_data->p_next; \
+ p_buffers->i_allocated -= p_data->p_buffer_end \
+ - p_data->p_buffer; \
+ free( p_data ); \
+ p_data = p_next; \
+ } \
+ } \
+ \
+ if( p_buffers->i_allocated ) \
+ { \
+ intf_ErrMsg( "input buffers error: %d bytes have not been" \
+ " freed, expect memory leak", \
+ p_buffers->i_allocated ); \
+ } \
+ \
+ vlc_mutex_destroy( &p_buffers->lock ); \
+ free( _p_buffers ); \
+ } \
+}
+
+/*****************************************************************************
+ * input_NewPacket: return a pointer to a data packet of the appropriate size
+ *****************************************************************************/
+#define DECLARE_BUFFERS_NEWPACKET( FLAGS, NB_LIFO ) \
+static data_packet_t * input_NewPacket( void * _p_buffers, size_t i_size ) \
+{ \
+ input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
+ int i_select; \
+ data_packet_t * p_data; \
+ \
+ /* Safety checks */ \
+ if( i_size > INPUT_MAX_PACKET_SIZE ) \
+ { \
+ intf_ErrMsg( "Packet too big (%d)", i_size ); \
+ return NULL; \
+ } \
+ \
+ vlc_mutex_lock( &p_buffers->lock ); \
+ \
+ if( p_buffers->i_allocated > INPUT_MAX_ALLOCATION ) \
+ { \
+ vlc_mutex_unlock( &p_buffers->lock ); \
+ intf_ErrMsg( "INPUT_MAX_ALLOCATION reached (%d)", \
+ p_buffers->i_allocated ); \
+ return NULL; \
+ } \
+ \
+ for( i_select = 0; i_select < NB_LIFO - 1; i_select++ ) \
+ { \
+ if( i_size <= (2 * p_buffers->data[i_select].i_average_size \
+ + p_buffers->data[i_select + 1].i_average_size) / 3 ) \
+ { \
+ break; \
+ } \
+ } \
+ \
+ if( p_buffers->data[i_select].p_stack != NULL ) \
+ { \
+ /* Take the packet from the cache */ \
+ p_data = p_buffers->data[i_select].p_stack; \
+ p_buffers->data[i_select].p_stack = p_data->p_next; \
+ p_buffers->data[i_select].i_depth--; \
+ \
+ /* Reallocate the packet if it is too small or too large */ \
+ if( p_data->p_buffer_end - p_data->p_buffer < i_size || \
+ p_data->p_buffer_end - p_data->p_buffer > 3 * i_size ) \
+ { \
+ p_buffers->i_allocated -= p_data->p_buffer_end \
+ - p_data->p_buffer; \
+ p_data = realloc( p_data, sizeof( data_packet_t ) + i_size ); \
+ if( p_data == NULL ) \
+ { \
+ vlc_mutex_unlock( &p_buffers->lock ); \
+ intf_ErrMsg( "Out of memory" ); \
+ return NULL; \
+ } \
+ p_data->p_buffer = (byte_t *)p_data + sizeof( data_packet_t ); \
+ p_data->p_buffer_end = p_data->p_buffer + i_size; \
+ p_buffers->i_allocated += i_size; \
+ } \
+ } \
+ else \
+ { \
+ /* Allocate a new packet */ \
+ p_data = malloc( sizeof( data_packet_t ) + i_size ); \
+ if( p_data == NULL ) \
+ { \
+ vlc_mutex_unlock( &p_buffers->lock ); \
+ intf_ErrMsg( "Out of memory" ); \
+ return NULL; \
+ } \
+ p_data->p_buffer = (byte_t *)p_data + sizeof( data_packet_t ); \
+ p_data->p_buffer_end = p_data->p_buffer + i_size; \
+ p_buffers->i_allocated += i_size; \
+ } \
+ \
+ vlc_mutex_unlock( &p_buffers->lock ); \
+ \
+ /* Initialize data */ \
+ p_data->p_next = NULL; \
+ p_data->b_discard_payload = 0; \
+ p_data->p_payload_start = p_data->p_buffer; \
+ p_data->p_payload_end = p_data->p_buffer + i_size; \
+ \
+ return( p_data ); \
+}
+
+/*****************************************************************************
+ * input_DeletePacket: put a packet back into the cache
+ *****************************************************************************/
+#define DECLARE_BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \
+static __inline__ void _input_DeletePacket( void * _p_buffers, \
+ data_packet_t * p_data ) \
+{ \
+ input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
+ int i_select, i_size; \
+ \
+ i_size = p_data->p_buffer_end - p_data->p_buffer; \
+ for( i_select = 0; i_select < NB_LIFO - 1; i_select++ ) \
+ { \
+ if( i_size <= (2 * p_buffers->data[i_select].i_average_size \
+ + p_buffers->data[i_select + 1].i_average_size) / 3 ) \
+ { \
+ break; \
+ } \
+ } \
+ \
+ if( p_buffers->data[i_select].i_depth < DATA_CACHE_SIZE ) \
+ { \
+ /* Cache not full : store the packet in it */ \
+ p_data->p_next = p_buffers->data[i_select].p_stack; \
+ p_buffers->data[i_select].p_stack = p_data; \
+ p_buffers->data[i_select].i_depth++; \
+ \
+ /* Update Bresenham mean (very approximative) */ \
+ p_buffers->data[i_select].i_average_size = ( i_size \
+ + p_buffers->data[i_select].i_average_size \
+ * (INPUT_BRESENHAM_NB - 1) ) \
+ / INPUT_BRESENHAM_NB; \
+ } \
+ else \
+ { \
+ p_buffers->i_allocated -= p_data->p_buffer_end - p_data->p_buffer; \
+ free( p_data ); \
+ } \
+} \
+ \
+static void input_DeletePacket( void * _p_buffers, data_packet_t * p_data ) \
+{ \
+ input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
+ \
+ vlc_mutex_lock( &p_buffers->lock ); \
+ _input_DeletePacket( _p_buffers, p_data ); \
+ vlc_mutex_unlock( &p_buffers->lock ); \
+}
+
+/*****************************************************************************
+ * input_NewPES: return a pointer to a new PES packet
+ *****************************************************************************/
+#define DECLARE_BUFFERS_NEWPES( FLAGS, NB_LIFO ) \
+static pes_packet_t * input_NewPES( void * _p_buffers ) \
+{ \
+ input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
+ pes_packet_t * p_pes; \
+ \
+ vlc_mutex_lock( &p_buffers->lock ); \
+ \
+ if( p_buffers->pes.p_stack != NULL ) \
+ { \
+ p_pes = p_buffers->pes.p_stack; \
+ p_buffers->pes.p_stack = p_pes->p_next; \
+ p_buffers->pes.i_depth--; \
+ } \
+ else \
+ { \
+ p_pes = malloc( sizeof( pes_packet_t ) ); \
+ if( p_pes == NULL ) \
+ { \
+ intf_ErrMsg( "Out of memory" ); \
+ vlc_mutex_unlock( &p_buffers->lock ); \
+ return( NULL ); \
+ } \
+ } \
+ \
+ vlc_mutex_unlock( &p_buffers->lock ); \
+ \
+ /* Initialize data */ \
+ p_pes->p_next = NULL; \
+ p_pes->b_data_alignment = p_pes->b_discontinuity = \
+ p_pes->i_pts = p_pes->i_dts = 0; \
+ p_pes->i_pes_size = 0; \
+ p_pes->p_first = NULL; \
+ \
+ return( p_pes ); \
+}
+
+/*****************************************************************************
+ * input_DeletePES: put a pes and all data packets back into the cache
+ *****************************************************************************/
+#define DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, PES_CACHE_SIZE ) \
+static void input_DeletePES( void * _p_buffers, pes_packet_t * p_pes ) \
+{ \
+ input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
+ data_packet_t * p_data; \
+ \
+ vlc_mutex_lock( &p_buffers->lock ); \
+ \
+ p_data = p_pes->p_first; \
+ while( p_data != NULL ) \
+ { \
+ data_packet_t * p_next = p_data->p_next; \
+ _input_DeletePacket( _p_buffers, p_data ); \
+ p_data = p_next; \
+ } \
+ \
+ if( p_buffers->pes.i_depth < PES_CACHE_SIZE ) \
+ { \
+ /* Cache not full : store the packet in it */ \
+ p_pes->p_next = p_buffers->pes.p_stack; \
+ p_buffers->pes.p_stack = p_pes; \
+ p_buffers->pes.i_depth++; \
+ } \
+ else \
+ { \
+ free( p_pes ); \
+ } \
+ \
+ vlc_mutex_unlock( &p_buffers->lock ); \
+}
+
+
/*
* Optional MPEG demultiplexing
*/
* input_ps.c: PS demux and packet management
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: input_ps.c,v 1.2 2001/12/10 04:53:11 sam Exp $
+ * $Id: input_ps.c,v 1.3 2001/12/12 11:18:38 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Cyril Deguet <asmax@via.ecp.fr>
static void PSEnd ( struct input_thread_s * );
static int PSSetProgram ( struct input_thread_s * , pgrm_descriptor_t * );
static void PSSeek ( struct input_thread_s *, off_t );
-static struct pes_packet_s * NewPES ( void * );
-static struct data_packet_s * NewPacket ( void *, size_t );
-static void DeletePacket ( void *, struct data_packet_s * );
-static void DeletePES ( void *, struct pes_packet_s * );
+
+/*****************************************************************************
+ * Declare a buffer manager
+ *****************************************************************************/
+#define FLAGS BUFFERS_NOFLAGS
+#define NB_LIFO 2
+DECLARE_BUFFERS_EMBEDDED( FLAGS, NB_LIFO );
+DECLARE_BUFFERS_INIT( FLAGS, NB_LIFO );
+DECLARE_BUFFERS_END( FLAGS, NB_LIFO );
+DECLARE_BUFFERS_NEWPACKET( FLAGS, NB_LIFO );
+DECLARE_BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, 150 );
+DECLARE_BUFFERS_NEWPES( FLAGS, NB_LIFO );
+DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, 150 );
+
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
input.pf_set_program = PSSetProgram;
input.pf_read = PSRead;
input.pf_demux = input_DemuxPS;
- input.pf_new_packet = NewPacket;
- input.pf_new_pes = NewPES;
- input.pf_delete_packet = DeletePacket;
- input.pf_delete_pes = DeletePES;
+ input.pf_new_packet = input_NewPacket;
+ input.pf_new_pes = input_NewPES;
+ input.pf_delete_packet = input_DeletePacket;
+ input.pf_delete_pes = input_DeletePES;
input.pf_rewind = NULL;
input.pf_seek = PSSeek;
#undef input
*****************************************************************************/
static void PSInit( input_thread_t * p_input )
{
- packet_cache_t * p_packet_cache;
-
- /* creates the packet cache structure */
- p_packet_cache = malloc( sizeof(packet_cache_t) );
- if ( p_packet_cache == NULL )
+ if( (p_input->p_method_data = input_BuffersInit()) == NULL )
{
- intf_ErrMsg( "Out of memory" );
p_input->b_error = 1;
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 *
- sizeof(data_packet_t*) );
- if ( p_packet_cache->data.p_stack == NULL )
- {
- intf_ErrMsg( "Out of memory" );
- p_input->b_error = 1;
- return;
- }
- p_packet_cache->data.l_index = 0;
-
- /* allocates the PES cache */
- p_packet_cache->pes.p_stack = malloc( PES_CACHE_SIZE *
- sizeof(pes_packet_t*) );
- if ( p_packet_cache->pes.p_stack == NULL )
- {
- intf_ErrMsg( "Out of memory" );
- p_input->b_error = 1;
- return;
- }
- p_packet_cache->pes.l_index = 0;
-
- /* allocates the small buffer cache */
- p_packet_cache->smallbuffer.p_stack = malloc( SMALL_CACHE_SIZE *
- sizeof(packet_buffer_t) );
- if ( p_packet_cache->smallbuffer.p_stack == NULL )
- {
- intf_ErrMsg( "Out of memory" );
- p_input->b_error = 1;
- return;
- }
- p_packet_cache->smallbuffer.l_index = 0;
-
- /* allocates the large buffer cache */
- p_packet_cache->largebuffer.p_stack = malloc( LARGE_CACHE_SIZE *
- sizeof(packet_buffer_t) );
- if ( p_packet_cache->largebuffer.p_stack == NULL )
- {
- intf_ErrMsg( "Out of memory" );
- p_input->b_error = 1;
- return;
- }
- p_packet_cache->largebuffer.l_index = 0;
-
if( p_input->p_stream == NULL )
{
/* Re-open the socket as a buffered FILE stream */
{
/* FIXME: use i_p_config_t */
input_ParsePS( p_input, pp_packets[i] );
- DeletePacket( p_input->p_method_data, pp_packets[i] );
+ p_input->pf_delete_packet( p_input->p_method_data, pp_packets[i] );
}
/* File too big. */
*****************************************************************************/
static void PSEnd( input_thread_t * p_input )
{
-#define p_packet_cache ((packet_cache_t *)p_input->p_method_data)
-
- vlc_mutex_destroy( &p_packet_cache->lock );
-
- if( p_packet_cache->data.p_stack )
- free( p_packet_cache->data.p_stack );
- if( p_packet_cache->pes.p_stack )
- free( p_packet_cache->pes.p_stack );
- if( p_packet_cache->smallbuffer.p_stack )
- free( p_packet_cache->smallbuffer.p_stack );
- if( p_packet_cache->largebuffer.p_stack )
- free( p_packet_cache->largebuffer.p_stack );
-
-#undef p_packet_cache
-
- free( p_input->p_method_data );
+ input_BuffersEnd( p_input->p_method_data );
}
/*****************************************************************************
}
/* Fetch a packet of the appropriate size. */
- p_data = NewPacket( p_input->p_method_data, i_packet_size + 6 );
+ p_data = p_input->pf_new_packet( p_input->p_method_data,
+ i_packet_size + 6 );
if( p_data == NULL )
{
intf_ErrMsg( "Out of memory" );
p_input->stream.p_selected_area->i_tell = i_position;
}
-/*
- * Packet management utilities
- */
-
-
-/*****************************************************************************
- * NewPacket: allocates a data packet
- *****************************************************************************/
-static struct data_packet_s * NewPacket( void * p_packet_cache,
- size_t l_size )
-{
- packet_cache_t * p_cache;
- data_packet_t * p_data;
- long l_index;
-
- p_cache = (packet_cache_t *)p_packet_cache;
-
-#ifdef DEBUG
- if ( p_cache == NULL )
- {
- intf_ErrMsg( "PPacket cache not initialized" );
- return NULL;
- }
-#endif
-
- /* Safety check */
- if( l_size > INPUT_MAX_PACKET_SIZE )
- {
- intf_ErrMsg( "Packet too big (%d)", l_size );
- return NULL;
- }
-
- vlc_mutex_lock( &p_cache->lock );
-
- /* Checks whether the data cache is empty */
- if( p_cache->data.l_index == 0 )
- {
- /* Allocates a new packet */
- p_data = malloc( sizeof(data_packet_t) );
- if( p_data == NULL )
- {
- intf_ErrMsg( "Out of memory" );
- vlc_mutex_unlock( &p_cache->lock );
- return NULL;
- }
-#ifdef TRACE_INPUT
- intf_DbgMsg( "PS input: data packet allocated" );
-#endif
- }
- else
- {
- /* Takes the packet out from the cache */
- if( (p_data = p_cache->data.p_stack[ -- p_cache->data.l_index ])
- == NULL )
- {
- intf_ErrMsg( "NULL packet in the data cache" );
- vlc_mutex_unlock( &p_cache->lock );
- return NULL;
- }
- }
-
- if( l_size < MAX_SMALL_SIZE )
- {
- /* Small buffer */
-
- /* Checks whether the buffer cache is empty */
- if( p_cache->smallbuffer.l_index == 0 )
- {
- /* Allocates a new packet */
- p_data->p_buffer = malloc( l_size );
- if( p_data->p_buffer == NULL )
- {
- intf_DbgMsg( "Out of memory" );
- free( p_data );
- vlc_mutex_unlock( &p_cache->lock );
- return NULL;
- }
-#ifdef TRACE_INPUT
- intf_DbgMsg( "PS input: small buffer allocated" );
-#endif
- p_data->l_size = l_size;
- }
- else
- {
- /* Takes the packet out from the cache */
- l_index = -- p_cache->smallbuffer.l_index;
- if( (p_data->p_buffer = p_cache->smallbuffer.p_stack[l_index].p_data)
- == NULL )
- {
- 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 */
- if( p_cache->smallbuffer.p_stack[l_index].l_size < l_size ||
- p_cache->smallbuffer.p_stack[l_index].l_size > 2*l_size )
- {
- p_data->p_buffer = realloc( p_data->p_buffer, l_size );
- p_data->l_size = l_size;
- }
- else
- {
- p_data->l_size = p_cache->smallbuffer.p_stack[l_index].l_size;
- }
- }
- }
- else
- {
- /* Large buffer */
-
- /* Checks whether the buffer cache is empty */
- if( p_cache->largebuffer.l_index == 0 )
- {
- /* Allocates a new packet */
- p_data->p_buffer = malloc( l_size );
- if ( p_data->p_buffer == NULL )
- {
- intf_ErrMsg( "Out of memory" );
- free( p_data );
- vlc_mutex_unlock( &p_cache->lock );
- return NULL;
- }
-#ifdef TRACE_INPUT
- intf_DbgMsg( "PS input: large buffer allocated" );
-#endif
- p_data->l_size = l_size;
- }
- else
- {
- /* Takes the packet out from the cache */
- l_index = -- p_cache->largebuffer.l_index;
- p_data->p_buffer = p_cache->largebuffer.p_stack[l_index].p_data;
- if( p_data->p_buffer == NULL )
- {
- 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 */
- if( p_cache->largebuffer.p_stack[l_index].l_size < l_size ||
- p_cache->largebuffer.p_stack[l_index].l_size > 2*l_size )
- {
- p_data->p_buffer = realloc( p_data->p_buffer, l_size );
- p_data->l_size = l_size;
- }
- else
- {
- p_data->l_size = p_cache->largebuffer.p_stack[l_index].l_size;
- }
- }
- }
-
- vlc_mutex_unlock( &p_cache->lock );
-
- /* Initialize data */
- p_data->p_next = NULL;
- p_data->b_discard_payload = 0;
- p_data->p_payload_start = p_data->p_buffer;
- p_data->p_payload_end = p_data->p_buffer + l_size;
-
- return( p_data );
-
-}
-
-
-/*****************************************************************************
- * NewPES: allocates a pes packet
- *****************************************************************************/
-static pes_packet_t * NewPES( void * p_packet_cache )
-{
- packet_cache_t * p_cache;
- pes_packet_t * p_pes;
-
- p_cache = (packet_cache_t *)p_packet_cache;
-
-#ifdef DEBUG
- if ( p_cache == NULL )
- {
- intf_ErrMsg( "Packet cache not initialized" );
- return NULL;
- }
-#endif
-
- vlc_mutex_lock( &p_cache->lock );
-
- /* Checks whether the PES cache is empty */
- if( p_cache->pes.l_index == 0 )
- {
- /* Allocates a new packet */
- p_pes = malloc( sizeof(pes_packet_t) );
- if( p_pes == NULL )
- {
- intf_DbgMsg( "Out of memory" );
- vlc_mutex_unlock( &p_cache->lock );
- return NULL;
- }
-#ifdef TRACE_INPUT
- intf_DbgMsg( "PS input: PES packet allocated" );
-#endif
- }
- else
- {
- /* Takes the packet out from the cache */
- p_pes = p_cache->pes.p_stack[ -- p_cache->pes.l_index ];
- if( p_pes == 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;
- p_pes->p_first = NULL;
-
- return( p_pes );
-
-}
-
-/*****************************************************************************
- * DeletePacket: deletes a data packet
- *****************************************************************************/
-static void DeletePacket( void * p_packet_cache,
- data_packet_t * p_data )
-{
- packet_cache_t * p_cache;
-
- p_cache = (packet_cache_t *)p_packet_cache;
-
-#ifdef DEBUG
- if ( p_cache == NULL )
- {
- intf_ErrMsg( "Packet cache not initialized" );
- return;
- }
-#endif
-
- 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 )
- {
- /* Cache not full: store the packet in it */
- p_cache->data.p_stack[ p_cache->data.l_index ++ ] = p_data;
- /* Small buffer or large buffer? */
- if ( p_data->l_size < MAX_SMALL_SIZE )
- {
- /* Checks whether the small buffer cache is full */
- if ( p_cache->smallbuffer.l_index < SMALL_CACHE_SIZE )
- {
- p_cache->smallbuffer.p_stack[
- p_cache->smallbuffer.l_index ].l_size = p_data->l_size;
- p_cache->smallbuffer.p_stack[
- p_cache->smallbuffer.l_index++ ].p_data = p_data->p_buffer;
- }
- else
- {
- ASSERT( p_data->p_buffer );
- free( p_data->p_buffer );
-#ifdef TRACE_INPUT
- intf_DbgMsg( "PS input: small buffer freed" );
-#endif
- }
- }
- else
- {
- /* Checks whether the large buffer cache is full */
- if ( p_cache->largebuffer.l_index < LARGE_CACHE_SIZE )
- {
- p_cache->largebuffer.p_stack[
- p_cache->largebuffer.l_index ].l_size = p_data->l_size;
- p_cache->largebuffer.p_stack[
- p_cache->largebuffer.l_index++ ].p_data = p_data->p_buffer;
- }
- else
- {
- ASSERT( p_data->p_buffer );
- free( p_data->p_buffer );
-#ifdef TRACE_INPUT
- intf_DbgMsg( "PS input: large buffer freed" );
-#endif
- }
- }
- }
- else
- {
- /* Cache full: the packet must be freed */
- free( p_data->p_buffer );
- free( p_data );
-#ifdef TRACE_INPUT
- intf_DbgMsg( "PS input: data packet freed" );
-#endif
- }
-
- vlc_mutex_unlock( &p_cache->lock );
-}
-
-/*****************************************************************************
- * DeletePES: deletes a PES packet and associated data packets
- *****************************************************************************/
-static void DeletePES( void * p_packet_cache, pes_packet_t * p_pes )
-{
- packet_cache_t * p_cache;
- data_packet_t * p_data;
- data_packet_t * p_next;
-
- p_cache = (packet_cache_t *)p_packet_cache;
-
-#ifdef DEBUG
- if ( p_cache == NULL )
- {
- intf_ErrMsg( "Packet cache not initialized" );
- return;
- }
-#endif
-
- ASSERT( p_pes);
-
- p_data = p_pes->p_first;
-
- while( p_data != NULL )
- {
- p_next = p_data->p_next;
- DeletePacket( p_cache, p_data );
- 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 )
- {
- /* Cache not full: store the packet in it */
- p_cache->pes.p_stack[ p_cache->pes.l_index ++ ] = p_pes;
- }
- else
- {
- /* Cache full: the packet must be freed */
- free( p_pes );
-#ifdef TRACE_INPUT
- intf_DbgMsg( "PS input: PES packet freed" );
-#endif
- }
-
- vlc_mutex_unlock( &p_cache->lock );
-}
-