# C Objects
#
INTERFACE := main interface intf_msg intf_playlist intf_channels
-INPUT := input input_ext-dec input_ext-intf input_dec input_programs input_netlist input_clock mpeg_system
+INPUT := input input_ext-dec input_ext-intf input_dec input_programs input_clock mpeg_system
VIDEO_OUTPUT := video_output video_text video_spu video_yuv
AUDIO_OUTPUT := audio_output aout_ext-dec aout_u8 aout_s8 aout_u16 aout_s16 aout_spdif
MISC := mtime tests modules netutils iso_lang
* Collection of useful common types and macros definitions
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: common.h,v 1.53.2.1 2001/12/30 06:06:00 sam Exp $
+ * $Id: common.h,v 1.53.2.2 2001/12/31 01:21:44 massiot Exp $
*
* Authors: Samuel Hocevar <sam@via.ecp.fr>
* Vincent Seguin <seguin@via.ecp.fr>
struct pgrm_descriptor_s *,
mtime_t );
- int ( * input_NetlistInit ) ( struct input_thread_s *,
- int, int, int, size_t, int );
- struct iovec * ( * input_NetlistGetiovec ) ( void * p_method_data );
- void ( * input_NetlistMviovec ) ( void * , int,
- struct data_packet_s **);
- struct data_packet_s * ( * input_NetlistNewPacket ) ( void *, size_t );
- struct data_packet_s * ( * input_NetlistNewPtr ) ( void * );
- struct pes_packet_s * ( * input_NetlistNewPES ) ( void * );
- void ( * input_NetlistDeletePacket ) ( void *, struct data_packet_s * );
- void ( * input_NetlistDeletePES ) ( void *, struct pes_packet_s * );
- void ( * input_NetlistEnd ) ( struct input_thread_s * );
-
struct aout_fifo_s * ( * aout_CreateFifo )
( int, int, long, long, long, void * );
void ( * aout_DestroyFifo ) ( struct aout_fifo_s * );
/* Environment variable containing the memcpy method */
#define MEMCPY_METHOD_VAR "vlc_memcpy"
-/*
- * Decoders FIFO configuration
- */
-
-/* Size of the FIFO. FIFO_SIZE+1 must be a power of 2 */
-#define FIFO_SIZE 1023
-
/*
* Paths
*/
/* Maximum length of a hostname or source name */
#define INPUT_MAX_SOURCE_LENGTH 100
+/* Maximum memory the input is allowed to use (20 MB) */
+#define INPUT_MAX_ALLOCATION 20971520
+
/* Default network protocol */
#define INPUT_NETWORK_PROTOCOL_VAR "vlc_network_protocol"
#define INPUT_NETWORK_PROTOCOL_DEFAULT "ts"
* input_ext-dec.h: structures exported to the VideoLAN decoders
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_ext-dec.h,v 1.41.2.1 2001/12/30 06:06:00 sam Exp $
+ * $Id: input_ext-dec.h,v 1.41.2.2 2001/12/31 01:21:44 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Kaempf <maxx@via.ecp.fr>
*****************************************************************************
* Describe a data packet.
*****************************************************************************/
+#define DATA_PACKET \
+ /* start of the PS or TS packet */ \
+ byte_t * p_demux_start; \
+ /* start of the PES payload in this packet */ \
+ byte_t * p_payload_start; \
+ byte_t * p_payload_end; /* guess ? :-) */ \
+ /* is the packet messed up ? */ \
+ boolean_t b_discard_payload;
+
typedef struct data_packet_s
{
- /* Nothing before this line, the code relies on that */
- byte_t * p_buffer; /* raw data packet */
- long l_size; /* buffer size */
-
- /* Decoders information */
- byte_t * p_payload_start;
- /* start of the PES payload in this packet */
- byte_t * p_payload_end; /* guess ? :-) */
- boolean_t b_discard_payload; /* is the packet messed up ? */
+ /* Used to chain the packets that carry data for a same PES or PSI */
+ struct data_packet_s * p_next;
- int * pi_refcount;
+ DATA_PACKET
- /* Used to chain the TS packets that carry data for a same PES or PSI */
- struct data_packet_s * p_next;
+ /* Please note that at least one buffer allocator (in particular, the
+ * Next Generation Buffer Allocator) extends this structure with
+ * private data after DATA_PACKET. */
} data_packet_t;
/*****************************************************************************
*****************************************************************************/
typedef struct pes_packet_s
{
+ /* Chained list to the next PES packet (depending on the context) */
+ struct pes_packet_s * p_next;
+
/* PES properties */
boolean_t b_data_alignment; /* used to find the beginning of
* a video or audio unit */
int i_rate; /* current pace of reading
* (see stream_control.h) */
- int i_pes_size; /* size of the current PES packet */
+ unsigned int i_pes_size; /* size of the current PES packet */
- /* Pointers to packets (packets are then linked by the p_prev and
- p_next fields of the data_packet_t struct) */
+ /* Chained list to packets */
data_packet_t * p_first; /* The first packet contained by this
* PES (used by decoders). */
+ data_packet_t * p_last; /* The last packet contained by this
+ PES (used by the buffer allocator) */
+ unsigned int i_nb_data; /* Number of data packets in the chained
+ list */
} pes_packet_t;
/*****************************************************************************
vlc_cond_t data_wait; /* fifo data conditional variable */
/* Data */
- pes_packet_t * buffer[FIFO_SIZE + 1];
- int i_start;
- int i_end;
+ pes_packet_t * p_first;
+ pes_packet_t ** pp_last;
+ int i_depth; /* number of PES packets in the stack */
/* Communication interface between input and decoders */
boolean_t b_die; /* the decoder should return now */
/* function to use when releasing a PES */
} decoder_fifo_t;
-/* Macros to manage a decoder_fifo_t structure. Please remember to take
- * data_lock before using them. */
-#define DECODER_FIFO_ISEMPTY( fifo ) ( (fifo).i_start == (fifo).i_end )
-#define DECODER_FIFO_ISFULL( fifo ) ( ( ((fifo).i_end + 1 - (fifo).i_start)\
- & FIFO_SIZE ) == 0 )
-#define DECODER_FIFO_START( fifo ) ( (fifo).buffer[ (fifo).i_start ] )
-#define DECODER_FIFO_INCSTART( fifo ) ( (fifo).i_start = ((fifo).i_start + 1)\
- & FIFO_SIZE )
-#define DECODER_FIFO_END( fifo ) ( (fifo).buffer[ (fifo).i_end ] )
-#define DECODER_FIFO_INCEND( fifo ) ( (fifo).i_end = ((fifo).i_end + 1) \
- & FIFO_SIZE )
-
/*****************************************************************************
* bit_fifo_t : bit fifo descriptor
*****************************************************************************
* control the pace of reading.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_ext-intf.h,v 1.51 2001/12/07 16:47:47 jobi Exp $
+ * $Id: input_ext-intf.h,v 1.51.2.1 2001/12/31 01:21:44 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
/*
* Communication input -> interface
*/
-#define INPUT_MAX_PLUGINS 1
/* FIXME ! */
#define REQUESTED_MPEG 1
#define REQUESTED_AC3 2
/* PES parser information */
struct pes_packet_s * p_pes; /* Current PES */
- struct data_packet_s * p_last; /* The last packet gathered at present */
int i_pes_real_size; /* as indicated by the header */
/* Decoder information */
#define SPU_ES 0x02
#define NAV_ES 0x03
#define UNKNOWN_ES 0xFF
+
/*****************************************************************************
* pgrm_descriptor_t
*****************************************************************************
/* Read & Demultiplex */
int (* pf_read)( struct input_thread_s *,
- struct data_packet_s * pp_packets[] );
+ struct data_packet_s ** );
void (* pf_demux)( struct input_thread_s *,
struct data_packet_s * );
int i_handle; /* socket or file descriptor */
FILE * p_stream; /* if applicable */
void * p_handle; /* if i_handle isn't suitable */
- int i_read_once; /* number of packet read by
- * pf_read once */
void * p_method_data; /* data of the packet manager */
void * p_plugin_data; /* data of the plugin */
* but exported to plug-ins
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: input_ext-plugins.h,v 1.7 2001/12/07 16:47:47 jobi Exp $
+ * $Id: input_ext-plugins.h,v 1.7.2.1 2001/12/31 01:21:44 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
*/
/* FIXME: you've gotta move this move this, you've gotta move this move this */
-#define INPUT_READ_ONCE 7 /* We live in a world dominated by Ethernet. *
- * Ethernet MTU is 1500 bytes, so in a UDP *
- * packet we can put : 1500/188 = 7 TS *
- * packets. Have a nice day and merry Xmas. */
#define PADDING_PACKET_SIZE 188 /* Size of the NULL packet inserted in case
* of data loss (this should be < 188). */
#define PADDING_PACKET_NUMBER 10 /* Number of padding packets top insert to
return;
}
- memset( p_pad_data->p_buffer, 0, PADDING_PACKET_SIZE );
+ memset( p_pad_data->p_payload_start, 0, PADDING_PACKET_SIZE );
p_pad_data->b_discard_payload = 1;
p_pes = p_es->p_pes;
if( p_pes != NULL )
{
p_pes->b_discontinuity = 1;
- p_es->p_last->p_next = p_pad_data;
- p_es->p_last = p_pad_data;
+ p_pes->p_last->p_next = p_pad_data;
+ p_pes->p_last = p_pad_data;
+ p_pes->i_nb_data++;
}
else
{
}
p_pes->i_rate = p_input->stream.control.i_rate;
- p_pes->p_first = p_pad_data;
+ p_pes->p_first = p_pes->p_last = p_pad_data;
+ p_pes->i_nb_data = 1;
p_pes->b_discontinuity = 1;
input_DecodePES( p_es->p_decoder_fifo, p_pes );
}
/*
- * Optional netlist management
+ * 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_UNIQUE_SIZE 1 /* Only with NB_LIFO == 1 */
+
/*****************************************************************************
- * netlist_t: structure to manage a netlist
+ * _input_buffers_t: defines a LIFO per data type to keep
*****************************************************************************/
-typedef struct netlist_s
+#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 _input_buffers_s \
+{ \
+ vlc_mutex_t lock; \
+ PACKETS_LIFO( pes_packet_t, pes ) \
+ PACKETS_LIFO( _data_packet_t, data ) \
+ BUFFERS_LIFO( _data_buffer_t, buffers[NB_LIFO] ) \
+ size_t i_allocated; \
+} _input_buffers_t;
+
+/* Data buffer, used in case the buffer can be shared between several data
+ * packets */
+typedef struct _data_buffer_s
{
- vlc_mutex_t lock;
+ struct _data_buffer_s * p_next;
- size_t i_buffer_size;
+ /* number of data packets this buffer is referenced from - when it falls
+ * down to 0, the buffer is freed */
+ int i_refcount;
- /* Buffers */
- byte_t * p_buffers; /* Big malloc'ed area */
- data_packet_t * p_data; /* malloc'ed area */
- pes_packet_t * p_pes; /* malloc'ed area */
+ struct /* for compatibility with _data_packet_t */
+ {
+ /* size of the current buffer (starting right thereafter) */
+ unsigned int i_size;
+ } _private;
+} _data_buffer_t;
- /* FIFOs of free packets */
- data_packet_t ** pp_free_data;
- pes_packet_t ** pp_free_pes;
- struct iovec * p_free_iovec;
-
- /* FIFO size */
- unsigned int i_nb_iovec;
- unsigned int i_nb_pes;
- unsigned int i_nb_data;
+/* We overload the data_packet_t type to add private members */
+typedef struct _data_packet_s
+{
+ struct _data_packet_s * p_next;
- /* Index */
- unsigned int i_iovec_start, i_iovec_end;
- unsigned int i_data_start, i_data_end;
- unsigned int i_pes_start, i_pes_end;
+ DATA_PACKET
- /* Reference counters for iovec */
- unsigned int * pi_refcount;
+ union
+ {
+ struct _data_buffer_s * p_buffer; /* in case of shared buffers */
+ /* size of the embedded buffer (starting right thereafter) */
+ unsigned int i_size;
+ } _private;
+} _data_packet_t;
- /* Number of blocs read once by readv */
- unsigned int i_read_once;
-} netlist_t;
/*****************************************************************************
- * Prototypes
+ * input_BuffersInit: initialize the cache structures, return a pointer to it
*****************************************************************************/
-#ifndef PLUGIN
-int input_NetlistInit( struct input_thread_s *,
- int i_nb_iovec,
- int i_nb_data,
- int i_nb_pes,
- size_t i_buffer_size,
- int i_read_once );
-
-struct iovec * input_NetlistGetiovec( void * p_method_data );
-void input_NetlistMviovec( void * , int,
- struct data_packet_s **);
-struct data_packet_s * input_NetlistNewPtr( void * );
-struct data_packet_s * input_NetlistNewPacket( void *, size_t );
-struct pes_packet_s * input_NetlistNewPES( void * );
-void input_NetlistDeletePacket( void *,
- struct data_packet_s * );
-void input_NetlistDeletePES( void *,
- struct pes_packet_s * );
-void input_NetlistEnd( struct input_thread_s * );
-#endif
+#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 BUFFERS_END_STAT_BUFFERS_LOOP( STRUCT ) \
+ for( i = 0; i < NB_LIFO; i++ ) \
+ { \
+ if( FLAGS & BUFFERS_UNIQUE_SIZE ) \
+ { \
+ intf_StatMsg( \
+ "input buffers stats: " #STRUCT "[%d]: %d packets", \
+ i, p_buffers->STRUCT[i].i_depth ); \
+ } \
+ else \
+ { \
+ intf_StatMsg( \
+ "input buffers stats: " #STRUCT "[%d]: %d bytes, %d packets", \
+ i, p_buffers->STRUCT[i].i_average_size, \
+ p_buffers->STRUCT[i].i_depth ); \
+ } \
+ }
+
+#define BUFFERS_END_STAT( FLAGS, NB_LIFO ) \
+ BUFFERS_END_STAT_BUFFERS_LOOP( data );
+
+#define BUFFERS_END_STAT_SHARED( FLAGS, NB_LIFO ) \
+ intf_StatMsg( "input buffers stats: data: %d packets", \
+ p_buffers->data.i_depth ); \
+ BUFFERS_END_STAT_BUFFERS_LOOP( buffers );
+
+
+#define BUFFERS_END_BUFFERS_LOOP \
+ while( p_buf != NULL ) \
+ { \
+ p_next = p_buf->p_next; \
+ p_buffers->i_allocated -= p_buf->_private.i_size; \
+ free( p_buf ); \
+ p_buf = p_next; \
+ }
+
+#define BUFFERS_END_PACKETS_LOOP \
+ while( p_packet != NULL ) \
+ { \
+ p_next = p_packet->p_next; \
+ free( p_packet ); \
+ p_packet = p_next; \
+ }
+
+#define BUFFERS_END_LOOP( FLAGS, NB_LIFO ) \
+ for( i = 0; i < NB_LIFO; i++ ) \
+ { \
+ _data_packet_t * p_next; \
+ _data_packet_t * p_buf = p_buffers->data[i].p_stack; \
+ BUFFERS_END_BUFFERS_LOOP; \
+ } \
+
+#define BUFFERS_END_LOOP_SHARED( FLAGS, NB_LIFO ) \
+ { \
+ /* Free data packets */ \
+ _data_packet_t * p_next; \
+ _data_packet_t * p_packet = p_buffers->data.p_stack; \
+ BUFFERS_END_PACKETS_LOOP; \
+ } \
+ \
+ for( i = 0; i < NB_LIFO; i++ ) \
+ { \
+ _data_buffer_t * p_next; \
+ _data_buffer_t * p_buf = p_buffers->buffers[i].p_stack; \
+ BUFFERS_END_BUFFERS_LOOP; \
+ } \
+
+#define BUFFERS_END( FLAGS, NB_LIFO, STAT_LOOP, LOOP ) \
+static void input_BuffersEnd( void * _p_buffers ) \
+{ \
+ _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
+ \
+ if( _p_buffers != NULL ) \
+ { \
+ int i; \
+ \
+ if( p_main->b_stats ) \
+ { \
+ int i; \
+ intf_StatMsg( "input buffers stats: pes: %d packets", \
+ p_buffers->pes.i_depth ); \
+ STAT_LOOP( FLAGS, NB_LIFO ); \
+ } \
+ \
+ { \
+ /* Free PES */ \
+ pes_packet_t * p_next, * p_packet = p_buffers->pes.p_stack; \
+ BUFFERS_END_PACKETS_LOOP; \
+ } \
+ \
+ LOOP( FLAGS, NB_LIFO ); \
+ \
+ 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 ); \
+ } \
+}
+
+#define DECLARE_BUFFERS_END( FLAGS, NB_LIFO ) \
+ BUFFERS_END( FLAGS, NB_LIFO, BUFFERS_END_STAT, BUFFERS_END_LOOP );
+
+#define DECLARE_BUFFERS_END_SHARED( FLAGS, NB_LIFO ) \
+ BUFFERS_END( FLAGS, NB_LIFO, BUFFERS_END_STAT_SHARED, \
+ BUFFERS_END_LOOP_SHARED );
+
+/*****************************************************************************
+ * input_NewPacket: return a pointer to a data packet of the appropriate size
+ *****************************************************************************/
+#define BUFFERS_NEWPACKET_EXTRA_DECLARATION( FLAGS, NB_LIFO ) \
+ _data_packet_t ** pp_data = &p_buf;
+
+#define BUFFERS_NEWPACKET_EXTRA_DECLARATION_SHARED( FLAGS, NB_LIFO ) \
+ _data_packet_t * p_data; \
+ _data_packet_t ** pp_data = &p_data;
+
+#define BUFFERS_NEWPACKET_EXTRA( FLAGS, NB_LIFO )
+
+#define BUFFERS_NEWPACKET_EXTRA_SHARED( FLAGS, NB_LIFO ) \
+ /* Find a data packet */ \
+ if( p_buffers->data.p_stack != NULL ) \
+ { \
+ p_data = p_buffers->data.p_stack; \
+ p_buffers->data.p_stack = p_data->p_next; \
+ p_buffers->data.i_depth--; \
+ } \
+ else \
+ { \
+ p_data = malloc( sizeof( _data_packet_t ) ); \
+ if( p_data == NULL ) \
+ { \
+ intf_ErrMsg( "Out of memory" ); \
+ vlc_mutex_unlock( &p_buffers->lock ); \
+ return( NULL ); \
+ } \
+ } \
+ \
+ if( i_size == 0 ) \
+ { \
+ /* Warning : in that case, the data packet is left partly \
+ * uninitialized ; theorically only input_ShareBuffer may call \
+ * this. */ \
+ p_data->p_next = NULL; \
+ p_data->b_discard_payload = 0; \
+ return( (data_packet_t *)p_data ); \
+ }
+
+#define BUFFERS_NEWPACKET_END( FLAGS, NB_LIFO, TYPE ) \
+ (*pp_data)->p_demux_start = (byte_t *)*pp_data + sizeof( TYPE );
+
+#define BUFFERS_NEWPACKET_END_SHARED( FLAGS, NB_LIFO, TYPE ) \
+ (*pp_data)->_private.p_buffer = p_buf; \
+ (*pp_data)->p_demux_start = (byte_t *)(*pp_data)->_private.p_buffer \
+ + sizeof( TYPE ); \
+ /* Initialize refcount */ \
+ p_buf->i_refcount = 1;
+
+#define BUFFERS_NEWPACKET( FLAGS, NB_LIFO, TYPE, NAME, EXTRA_DECLARATION, \
+ EXTRA, END ) \
+/* This one doesn't take p_buffers->lock. */ \
+static __inline__ 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; \
+ TYPE * p_buf; \
+ EXTRA_DECLARATION( FLAGS, NB_LIFO ); \
+ \
+ /* Safety check */ \
+ if( p_buffers->i_allocated > INPUT_MAX_ALLOCATION ) \
+ { \
+ intf_ErrMsg( "INPUT_MAX_ALLOCATION reached (%d)", \
+ p_buffers->i_allocated ); \
+ return NULL; \
+ } \
+ \
+ EXTRA( FLAGS, NB_LIFO ); \
+ \
+ for( i_select = 0; i_select < NB_LIFO - 1; i_select++ ) \
+ { \
+ if( i_size <= (2 * p_buffers->NAME[i_select].i_average_size \
+ + p_buffers->NAME[i_select + 1].i_average_size) / 3 ) \
+ { \
+ break; \
+ } \
+ } \
+ \
+ if( p_buffers->NAME[i_select].p_stack != NULL ) \
+ { \
+ /* Take the packet from the cache */ \
+ p_buf = p_buffers->NAME[i_select].p_stack; \
+ p_buffers->NAME[i_select].p_stack = p_buf->p_next; \
+ p_buffers->NAME[i_select].i_depth--; \
+ \
+ /* Reallocate the packet if it is too small or too large */ \
+ if( !(FLAGS & BUFFERS_UNIQUE_SIZE) && \
+ (p_buf->_private.i_size < i_size \
+ || p_buf->_private.i_size > 3 * i_size) ) \
+ { \
+ p_buffers->i_allocated -= p_buf->_private.i_size; \
+ p_buf = realloc( p_buf, sizeof( TYPE ) + i_size ); \
+ if( p_buf == NULL ) \
+ { \
+ intf_ErrMsg( "Out of memory" ); \
+ return NULL; \
+ } \
+ p_buf->_private.i_size = i_size; \
+ p_buffers->i_allocated += i_size; \
+ } \
+ } \
+ else \
+ { \
+ /* Allocate a new packet */ \
+ p_buf = malloc( sizeof( TYPE ) + i_size ); \
+ if( p_buf == NULL ) \
+ { \
+ intf_ErrMsg( "Out of memory" ); \
+ return NULL; \
+ } \
+ p_buf->_private.i_size = i_size; \
+ p_buffers->i_allocated += i_size; \
+ } \
+ \
+ /* Initialize data */ \
+ END( FLAGS, NB_LIFO, TYPE ); \
+ (*pp_data)->p_next = NULL; \
+ (*pp_data)->b_discard_payload = 0; \
+ (*pp_data)->p_payload_start = (*pp_data)->p_demux_start; \
+ (*pp_data)->p_payload_end = (*pp_data)->p_payload_start + i_size; \
+ \
+ return( (data_packet_t *)*pp_data ); \
+} \
+ \
+static data_packet_t * input_NewPacket( void * _p_buffers, size_t i_size ) \
+{ \
+ _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
+ data_packet_t * p_data; \
+ \
+ /* Safety check */ \
+ if( !(FLAGS & BUFFERS_UNIQUE_SIZE) && i_size > INPUT_MAX_PACKET_SIZE ) \
+ { \
+ intf_ErrMsg( "Packet too big (%d)", i_size ); \
+ return NULL; \
+ } \
+ \
+ vlc_mutex_lock( &p_buffers->lock ); \
+ p_data = _input_NewPacket( _p_buffers, i_size ); \
+ vlc_mutex_unlock( &p_buffers->lock ); \
+ return( p_data ); \
+}
+
+#define DECLARE_BUFFERS_NEWPACKET( FLAGS, NB_LIFO ) \
+ BUFFERS_NEWPACKET( FLAGS, NB_LIFO, _data_packet_t, data, \
+ BUFFERS_NEWPACKET_EXTRA_DECLARATION, BUFFERS_NEWPACKET_EXTRA, \
+ BUFFERS_NEWPACKET_END )
+
+#define DECLARE_BUFFERS_NEWPACKET_SHARED( FLAGS, NB_LIFO ) \
+ BUFFERS_NEWPACKET( FLAGS, NB_LIFO, _data_buffer_t, buffers, \
+ BUFFERS_NEWPACKET_EXTRA_DECLARATION_SHARED, \
+ BUFFERS_NEWPACKET_EXTRA_SHARED, BUFFERS_NEWPACKET_END_SHARED )
+
+/*****************************************************************************
+ * input_DeletePacket: put a packet back into the cache
+ *****************************************************************************/
+#define BUFFERS_DELETEPACKET_EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \
+ _data_packet_t * p_buf = p_data;
+
+#define BUFFERS_DELETEPACKET_EXTRA_SHARED( FLAGS, NB_LIFO, DATA_CACHE_SIZE )\
+ _data_buffer_t * p_buf = (_data_buffer_t *)p_data->_private.p_buffer; \
+ \
+ /* Get rid of the data packet */ \
+ if( p_buffers->data.i_depth < DATA_CACHE_SIZE ) \
+ { \
+ /* Cache not full : store the packet in it */ \
+ p_data->p_next = p_buffers->data.p_stack; \
+ p_buffers->data.p_stack = p_data; \
+ p_buffers->data.i_depth++; \
+ } \
+ else \
+ { \
+ free( p_data ); \
+ } \
+ \
+ /* Decrement refcount */ \
+ p_buf->i_refcount--; \
+ if( p_buf->i_refcount > 0 ) \
+ { \
+ return; \
+ }
+
+#define BUFFERS_DELETEPACKETSTACK_EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \
+ _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
+ _data_packet_t * p_first = (_data_packet_t *)_p_first; \
+ _data_packet_t ** pp_last = (_data_packet_t **)_pp_last; \
+ \
+ /* Small hopeless optimization */ \
+ if( (FLAGS & BUFFERS_UNIQUE_SIZE) \
+ && p_buffers->data[0].i_depth < DATA_CACHE_SIZE ) \
+ { \
+ p_buffers->data[0].i_depth += i_nb; \
+ *pp_last = p_buffers->data[0].p_stack; \
+ p_buffers->data[0].p_stack = p_first; \
+ } \
+ else /* No semicolon after this or you will die */
+
+#define BUFFERS_DELETEPACKETSTACK_EXTRA_SHARED( FLAGS, NB_LIFO, \
+ DATA_CACHE_SIZE )
+
+#define BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE, TYPE, \
+ NAME, EXTRA, EXTRA_STACK ) \
+/* This one doesn't take p_buffers->lock. */ \
+static __inline__ void _input_DeletePacket( void * _p_buffers, \
+ data_packet_t * _p_data ) \
+{ \
+ _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
+ _data_packet_t * p_data = (_data_packet_t *)_p_data; \
+ int i_select; \
+ \
+ while( p_data != NULL ) \
+ { \
+ _data_packet_t * p_next = p_data->p_next; \
+ \
+ EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE ); \
+ \
+ for( i_select = 0; i_select < NB_LIFO - 1; i_select++ ) \
+ { \
+ if( p_buf->_private.i_size <= \
+ (2 * p_buffers->NAME[i_select].i_average_size \
+ + p_buffers->NAME[i_select + 1].i_average_size) / 3 ) \
+ { \
+ break; \
+ } \
+ } \
+ \
+ if( p_buffers->NAME[i_select].i_depth < DATA_CACHE_SIZE ) \
+ { \
+ /* Cache not full : store the packet in it */ \
+ p_buf->p_next = p_buffers->NAME[i_select].p_stack; \
+ p_buffers->NAME[i_select].p_stack = p_buf; \
+ p_buffers->NAME[i_select].i_depth++; \
+ \
+ if( !(FLAGS & BUFFERS_UNIQUE_SIZE) ) \
+ { \
+ /* Update Bresenham mean (very approximative) */ \
+ p_buffers->NAME[i_select].i_average_size = \
+ ( p_buf->_private.i_size \
+ + p_buffers->NAME[i_select].i_average_size \
+ * (INPUT_BRESENHAM_NB - 1) ) \
+ / INPUT_BRESENHAM_NB; \
+ } \
+ } \
+ else \
+ { \
+ p_buffers->i_allocated -= p_buf->_private.i_size; \
+ free( p_buf ); \
+ } \
+ \
+ p_data = p_next; \
+ } \
+} \
+ \
+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 ); \
+} \
+ \
+/* Delete a chained list of i_nb data packets. -- needed by DeletePES */ \
+static __inline__ void _input_DeletePacketStack( void * _p_buffers, \
+ data_packet_t * _p_first, \
+ data_packet_t ** _pp_last, \
+ unsigned int i_nb ) \
+{ \
+ /* Do not add code before, EXTRA_STACK makes its own declarations. */ \
+ EXTRA_STACK( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \
+ /* No semicolon - PLEASE */ \
+ { \
+ _input_DeletePacket( _p_buffers, _p_first ); \
+ } \
+}
+
+#define DECLARE_BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \
+ BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE, _data_packet_t, \
+ data, BUFFERS_DELETEPACKET_EXTRA, \
+ BUFFERS_DELETEPACKETSTACK_EXTRA )
+
+#define DECLARE_BUFFERS_DELETEPACKET_SHARED( FLAGS, NB_LIFO, \
+ DATA_CACHE_SIZE ) \
+ BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE, _data_buffer_t, \
+ buffers, BUFFERS_DELETEPACKET_EXTRA_SHARED, \
+ BUFFERS_DELETEPACKETSTACK_EXTRA_SHARED )
+
+/*****************************************************************************
+ * input_DeletePacketStack: optimize deleting of a stack of packets when
+ * knowing much information
+ *****************************************************************************/
+/* AFAIK, this isn't used by anyone - it is here for completion.
+ * _input_DeletePacketStack is declared in DeletePacket because it is needed
+ * by DeletePES. */
+#define DECLARE_BUFFERS_DELETEPACKETSTACK( FLAGS, NB_LIFO ) \
+static void input_DeletePacketStack( void * _p_buffers, \
+ data_packet_t * p_first, \
+ data_packet_t ** pp_last, \
+ unsigned int i_nb ) \
+{ \
+ _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
+ \
+ vlc_mutex_lock( &p_buffers->lock ); \
+ _input_DeletePacketStack( _p_buffers, p_first, pp_last, i_nb ); \
+ 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 = p_pes->p_last = NULL; \
+ p_pes->i_nb_data = 0; \
+ \
+ 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; \
+ \
+ vlc_mutex_lock( &p_buffers->lock ); \
+ \
+ while( p_pes != NULL ) \
+ { \
+ pes_packet_t * p_next = p_pes->p_next; \
+ \
+ /* Delete all data packets */ \
+ if( p_pes->p_first != NULL ) \
+ { \
+ _input_DeletePacketStack( _p_buffers, p_pes->p_first, \
+ &p_pes->p_last->p_next, \
+ p_pes->i_nb_data ); \
+ } \
+ \
+ 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 ); \
+ } \
+ \
+ p_pes = p_next; \
+ } \
+ \
+ vlc_mutex_unlock( &p_buffers->lock ); \
+}
+
+/*****************************************************************************
+ * input_BuffersToIO: return an IO vector (only with BUFFERS_UNIQUE_SIZE)
+ *****************************************************************************/
+#define DECLARE_BUFFERS_TOIO( FLAGS, BUFFER_SIZE ) \
+static data_packet_t * input_BuffersToIO( void * _p_buffers, \
+ struct iovec * p_iovec, int i_nb )\
+{ \
+ _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
+ data_packet_t * p_data = NULL; \
+ int i; \
+ \
+ vlc_mutex_lock( &p_buffers->lock ); \
+ \
+ for( i = i_nb - 1; i >= 0; i-- ) \
+ { \
+ data_packet_t * p_next = _input_NewPacket( _p_buffers, \
+ BUFFER_SIZE /* UNIQUE_SIZE */ ); \
+ if( p_next == NULL ) \
+ { \
+ _input_DeletePacket( _p_buffers, p_data ); \
+ return( NULL ); \
+ } \
+ \
+ p_iovec[i].iov_base = p_next->p_demux_start; \
+ p_iovec[i].iov_len = BUFFER_SIZE; \
+ p_next->p_next = p_data; \
+ p_data = p_next; \
+ } \
+ \
+ vlc_mutex_unlock( &p_buffers->lock ); \
+ \
+ return( p_data ); \
+}
+
+/*****************************************************************************
+ * input_ShareBuffer: return a new data_packet to the same buffer
+ *****************************************************************************/
+#define DECLARE_BUFFERS_SHAREBUFFER( FLAGS ) \
+static data_packet_t * input_ShareBuffer( void * _p_buffers, \
+ data_packet_t * _p_shared_data ) \
+{ \
+ _input_buffers_t * p_buffers = (_input_buffers_t *)_p_buffers; \
+ _data_packet_t * p_shared_data = (_data_packet_t *)_p_shared_data; \
+ _data_packet_t * p_data; \
+ _data_buffer_t * p_buf = p_shared_data->_private.p_buffer; \
+ \
+ vlc_mutex_lock( &p_buffers->lock ); \
+ \
+ /* Get new data_packet_t, without a buffer through a special backdoor \
+ * in _input_NewPacket. */ \
+ p_data = (_data_packet_t *)_input_NewPacket( _p_buffers, 0 ); \
+ \
+ /* Finish initialization of p_data */ \
+ p_data->_private.p_buffer = p_shared_data->_private.p_buffer; \
+ p_data->p_demux_start = p_data->p_payload_start \
+ = (byte_t *)p_shared_data->_private.p_buffer \
+ + sizeof( _data_buffer_t ); \
+ p_data->p_payload_end = p_data->p_demux_start + p_buf->_private.i_size; \
+ \
+ /* Update refcount */ \
+ p_buf->i_refcount++; \
+ \
+ vlc_mutex_unlock( &p_buffers->lock ); \
+ \
+ return( (data_packet_t *)p_data ); \
+}
/*
(p_symbols)->input_DemuxTS = input_DemuxTS; \
(p_symbols)->input_DemuxPSI = input_DemuxPSI; \
(p_symbols)->input_ClockManageControl = input_ClockManageControl; \
- (p_symbols)->input_NetlistInit = input_NetlistInit; \
- (p_symbols)->input_NetlistGetiovec = input_NetlistGetiovec; \
- (p_symbols)->input_NetlistMviovec = input_NetlistMviovec; \
- (p_symbols)->input_NetlistNewPacket = input_NetlistNewPacket; \
- (p_symbols)->input_NetlistNewPtr = input_NetlistNewPtr; \
- (p_symbols)->input_NetlistNewPES = input_NetlistNewPES; \
- (p_symbols)->input_NetlistDeletePacket = input_NetlistDeletePacket; \
- (p_symbols)->input_NetlistDeletePES = input_NetlistDeletePES; \
- (p_symbols)->input_NetlistEnd = input_NetlistEnd; \
(p_symbols)->aout_CreateFifo = aout_CreateFifo; \
(p_symbols)->aout_DestroyFifo = aout_DestroyFifo; \
(p_symbols)->vout_CreateThread = vout_CreateThread; \
* ac3_adec.c: ac3 decoder module main file
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: ac3_adec.c,v 1.5.2.1 2001/12/30 06:06:00 sam Exp $
+ * $Id: ac3_adec.c,v 1.5.2.2 2001/12/31 01:21:44 massiot Exp $
*
* Authors: Michel Lespinasse <walken@zoy.org>
*
sync = 1;
}
- if (DECODER_FIFO_START(*p_ac3thread->p_fifo)->i_pts)
+ if (p_ac3thread->p_fifo->p_first->i_pts)
{
p_ac3thread->p_aout_fifo->date[
p_ac3thread->p_aout_fifo->l_end_frame] =
- DECODER_FIFO_START(*p_ac3thread->p_fifo)->i_pts;
- DECODER_FIFO_START(*p_ac3thread->p_fifo)->i_pts = 0;
+ p_ac3thread->p_fifo->p_first->i_pts;
+ p_ac3thread->p_fifo->p_first->i_pts = 0;
} else {
p_ac3thread->p_aout_fifo->date[
p_ac3thread->p_aout_fifo->l_end_frame] =
* ac3_spdif.c: ac3 pass-through to external decoder with enabled soundcard
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: ac3_spdif.c,v 1.5.2.1 2001/12/30 06:06:00 sam Exp $
+ * $Id: ac3_spdif.c,v 1.5.2.2 2001/12/31 01:21:44 massiot Exp $
*
* Authors: Stéphane Borel <stef@via.ecp.fr>
* Juha Yrjola <jyrjola@cc.hut.fi>
p_bit_stream->p_byte += 3;
p_spdif->i_pts =
- DECODER_FIFO_START( *p_bit_stream->p_decoder_fifo )->i_pts;
- DECODER_FIFO_START( *p_bit_stream->p_decoder_fifo )->i_pts = 0;
+ p_bit_stream->p_decoder_fifo->p_first->i_pts;
+ p_bit_stream->p_decoder_fifo->p_first->i_pts = 0;
}
}
* -dvd_udf to find files
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: input_dvd.c,v 1.105.2.1 2001/12/29 23:35:10 sam Exp $
+ * $Id: input_dvd.c,v 1.105.2.2 2001/12/31 01:21:44 massiot Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
/* how many blocks DVDRead will read in each loop */
#define DVD_BLOCK_READ_ONCE 64
-#define DVD_DATA_READ_ONCE (4 * DVD_BLOCK_READ_ONCE)
-
-/* Size of netlist */
-#define DVD_NETLIST_SIZE 256
/*****************************************************************************
* Local prototypes
static int DVDFindSector( thread_dvd_data_t * );
static int DVDChapterSelect( thread_dvd_data_t *, int );
+/*****************************************************************************
+ * Declare a buffer manager
+ *****************************************************************************/
+#define FLAGS BUFFERS_UNIQUE_SIZE
+#define NB_LIFO 1
+DECLARE_BUFFERS_SHARED( FLAGS, NB_LIFO );
+DECLARE_BUFFERS_INIT( FLAGS, NB_LIFO );
+DECLARE_BUFFERS_END_SHARED( FLAGS, NB_LIFO );
+DECLARE_BUFFERS_NEWPACKET_SHARED( FLAGS, NB_LIFO );
+DECLARE_BUFFERS_DELETEPACKET_SHARED( FLAGS, NB_LIFO, 1000 );
+DECLARE_BUFFERS_NEWPES( FLAGS, NB_LIFO );
+DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, 1000 );
+DECLARE_BUFFERS_TOIO( FLAGS, DVD_LB_SIZE );
+DECLARE_BUFFERS_SHAREBUFFER( FLAGS );
+
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
input.pf_set_area = DVDSetArea;
input.pf_set_program = DVDSetProgram;
input.pf_demux = input_DemuxPS;
- input.pf_new_packet = input_NetlistNewPacket;
- input.pf_new_pes = input_NetlistNewPES;
- input.pf_delete_packet = input_NetlistDeletePacket;
- input.pf_delete_pes = input_NetlistDeletePES;
+ 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 = DVDRewind;
input.pf_seek = DVDSeek;
#undef input
}
p_input->p_plugin_data = (void *)p_dvd;
- p_input->p_method_data = NULL;
+ if( (p_input->p_method_data = input_BuffersInit()) == NULL )
+ {
+ p_input->b_error = 1;
+ return;
+ }
p_dvd->dvdhandle = (dvdcss_handle) p_input->p_handle;
if( dvdcss_seek( p_dvd->dvdhandle, 0, DVDCSS_NOFLAGS ) < 0 )
{
intf_ErrMsg( "dvd error: %s", dvdcss_error( p_dvd->dvdhandle ) );
+ input_BuffersEnd( p_input->p_method_data );
p_input->b_error = 1;
return;
}
- /* We read DVD_BLOCK_READ_ONCE in each loop, so the input will receive
- * DVD_DATA_READ_ONCE at most */
+ /* We read DVD_BLOCK_READ_ONCE in each loop */
p_dvd->i_block_once = DVD_BLOCK_READ_ONCE;
- /* this value mustn't be modifed */
- p_input->i_read_once = DVD_DATA_READ_ONCE;
-
- /* Reading structures initialisation */
- input_NetlistInit( p_input, DVD_NETLIST_SIZE, 2 * DVD_NETLIST_SIZE,
- DVD_NETLIST_SIZE, DVD_LB_SIZE, p_dvd->i_block_once );
- intf_WarnMsg( 2, "dvd info: netlist initialized" );
/* Ifo allocation & initialisation */
if( IfoCreate( p_dvd ) < 0 )
{
intf_ErrMsg( "dvd error: allcation error in ifo" );
free( p_dvd );
+ input_BuffersEnd( p_input->p_method_data );
p_input->b_error = 1;
return;
}
intf_ErrMsg( "dvd error: fatal failure in ifo" );
IfoDestroy( p_dvd->p_ifo );
free( p_dvd );
+ input_BuffersEnd( p_input->p_method_data );
p_input->b_error = 1;
return;
}
i_chapter = 1;
}
- p_input->stream.pp_areas[i_title]->i_part = i_chapter;
-
p_area = p_input->stream.pp_areas[i_title];
+ p_area->i_part = i_chapter;
/* set title, chapter, audio and subpic */
DVDSetArea( p_input, p_area );
vlc_mutex_unlock( &p_input->stream.stream_lock );
- /* Parse input string : dvd:device[:rawdevice] */
+ /* Parse input string : dvd:device[@rawdevice] */
if( strlen( p_input->p_source ) > 4
&& !strncasecmp( p_input->p_source, "dvd:", 4 ) )
{
free( p_dvd );
- input_NetlistEnd( p_input );
+ input_BuffersEnd( p_input->p_method_data );
}
/*****************************************************************************
return 0;
}
-
/*****************************************************************************
- * DVDRead: reads data packets into the netlist.
+ * DVDRead: reads data packets.
*****************************************************************************
- * Returns -1 in case of error, 0 if everything went well, and 1 in case of
- * EOF.
+ * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
+ * packets.
*****************************************************************************/
static int DVDRead( input_thread_t * p_input,
- data_packet_t ** pp_packets )
+ data_packet_t ** pp_data )
{
thread_dvd_data_t * p_dvd;
- netlist_t * p_netlist;
- struct iovec * p_vec;
- struct data_packet_s * pp_data[DVD_DATA_READ_ONCE];
+ struct iovec p_vec[DVD_BLOCK_READ_ONCE];
u8 * pi_cur;
int i_block_once;
int i_packet_size;
int i_pos;
int i_read_blocks;
int i_sector;
- boolean_t b_eof;
- boolean_t b_eot;
boolean_t b_eoc;
+ data_packet_t * p_data;
p_dvd = (thread_dvd_data_t *)p_input->p_plugin_data;
- p_netlist = (netlist_t *)p_input->p_method_data;
+
+ *pp_data = NULL;
b_eoc = 0;
i_sector = p_dvd->i_title_start + p_dvd->i_sector;
/* Find cell index in adress map */
if( DVDFindSector( p_dvd ) < 0 )
{
- pp_packets[0] = NULL;
intf_ErrMsg( "dvd error: can't find next cell" );
return 1;
}
/*
intf_WarnMsg( 2, "Sector: 0x%x Read: %d Chapter: %d", p_dvd->i_sector, i_block_once, p_dvd->i_chapter );
*/
- p_netlist->i_read_once = i_block_once;
- /* Get an iovec pointer */
- if( ( p_vec = input_NetlistGetiovec( p_netlist ) ) == NULL )
+ /* Get iovecs */
+ *pp_data = p_data = input_BuffersToIO( p_input->p_method_data, p_vec,
+ DVD_BLOCK_READ_ONCE );
+
+ if ( p_data == NULL )
{
- intf_ErrMsg( "dvd error: can't get iovec" );
- return -1;
+ return( -1 );
}
/* Reads from DVD */
i_read_blocks = dvdcss_readv( p_dvd->dvdhandle, p_vec,
i_block_once, DVDCSS_READ_DECRYPT );
- /* Update netlist indexes: we don't do it in DVDGetiovec since we
- * need know the real number of blocks read */
- input_NetlistMviovec( p_netlist, i_read_blocks, pp_data );
-
/* Update global position */
p_dvd->i_sector += i_read_blocks;
/* Read headers to compute payload length */
for( i_iovec = 0 ; i_iovec < i_read_blocks ; i_iovec++ )
{
+ data_packet_t * p_current = p_data;
i_pos = 0;
- while( i_pos < p_netlist->i_buffer_size )
+ while( i_pos < DVD_LB_SIZE )
{
pi_cur = (u8*)p_vec[i_iovec].iov_base + i_pos;
- /*default header */
+ /* Default header */
if( U32_AT( pi_cur ) != 0x1BA )
{
/* That's the case for all packets, except pack header. */
i_packet_size = U16_AT( pi_cur + 4 );
- pp_packets[i_packet] = input_NetlistNewPtr( p_netlist );
- (*pp_data[i_iovec]->pi_refcount)++;
- pp_packets[i_packet]->pi_refcount =
- pp_data[i_iovec]->pi_refcount;
- pp_packets[i_packet]->p_buffer = pp_data[i_iovec]->p_buffer;
}
else
{
/* MPEG-2 Pack header. */
i_packet_size = 8;
- pp_packets[i_packet] = pp_data[i_iovec];
}
- pp_packets[i_packet]->p_payload_start =
- pp_packets[i_packet]->p_buffer + i_pos;
+ if( i_pos != 0 )
+ {
+ *pp_data = input_ShareBuffer( p_input->p_method_data,
+ p_current );
+ }
+ else
+ {
+ *pp_data = p_data;
+ p_data = p_data->p_next;
+ }
+
+ (*pp_data)->p_payload_start = (*pp_data)->p_demux_start =
+ (*pp_data)->p_demux_start + i_pos;
- pp_packets[i_packet]->p_payload_end =
- pp_packets[i_packet]->p_payload_start + i_packet_size + 6;
+ (*pp_data)->p_payload_end =
+ (*pp_data)->p_payload_start + i_packet_size + 6;
i_packet++;
i_pos += i_packet_size + 6;
+ pp_data = &(*pp_data)->p_next;
}
}
- pp_packets[i_packet] = NULL;
+ p_input->pf_delete_packet( p_input->p_method_data, p_data );
+ *pp_data = NULL;
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.p_selected_area->i_part = p_dvd->i_chapter;
}
- b_eot = !( p_input->stream.p_selected_area->i_tell
- < p_input->stream.p_selected_area->i_size );
- b_eof = b_eot && ( ( p_dvd->i_title + 1 ) >= p_input->stream.i_area_nb );
-
- if( b_eof )
+ if( p_input->stream.p_selected_area->i_tell
+ >= p_input->stream.p_selected_area->i_size )
{
- vlc_mutex_unlock( &p_input->stream.stream_lock );
- return 1;
- }
+ if( ( p_dvd->i_title + 1 ) >= p_input->stream.i_area_nb )
+ {
+ /* EOF */
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ return 0;
+ }
- if( b_eot )
- {
+ /* EOT */
intf_WarnMsg( 4, "dvd info: new title" );
p_dvd->i_title++;
DVDSetArea( p_input, p_input->stream.pp_areas[p_dvd->i_title] );
vlc_mutex_unlock( &p_input->stream.stream_lock );
- return 0;
+ return( i_packet );
}
vlc_mutex_unlock( &p_input->stream.stream_lock );
- if( i_read_blocks == i_block_once )
+ if( i_read_blocks != i_block_once )
{
- return 0;
+ return -1;
}
- return -1;
+ return( i_packet );
}
/*****************************************************************************
* It depends on: libdvdread for ifo files and block reading.
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: input_dvdread.c,v 1.3 2001/12/07 18:33:07 sam Exp $
+ * $Id: input_dvdread.c,v 1.3.2.1 2001/12/31 01:21:44 massiot Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
/* how many blocks DVDRead will read in each loop */
#define DVD_BLOCK_READ_ONCE 64
-#define DVD_DATA_READ_ONCE (4 * DVD_BLOCK_READ_ONCE)
-
-/* Size of netlist */
-#define DVD_NETLIST_SIZE 512
/*****************************************************************************
* Local prototypes
static void DvdReadOpen ( struct input_thread_s * );
static void DvdReadClose ( struct input_thread_s * );
static int DvdReadSetArea ( struct input_thread_s *, struct input_area_s * );
+static int DvdReadSetProgram( struct input_thread_s *, pgrm_descriptor_t * );
static int DvdReadRead ( struct input_thread_s *, data_packet_t ** );
static void DvdReadSeek ( struct input_thread_s *, off_t );
static int DvdReadRewind ( struct input_thread_s * );
static void DvdReadHandleDSI( thread_dvd_data_t * p_dvd, u8 * p_data );
static void DvdReadFindCell ( thread_dvd_data_t * p_dvd );
+/*****************************************************************************
+ * Declare a buffer manager
+ *****************************************************************************/
+#define FLAGS BUFFERS_UNIQUE_SIZE
+#define NB_LIFO 1
+DECLARE_BUFFERS_SHARED( FLAGS, NB_LIFO );
+DECLARE_BUFFERS_INIT( FLAGS, NB_LIFO );
+DECLARE_BUFFERS_END_SHARED( FLAGS, NB_LIFO );
+DECLARE_BUFFERS_NEWPACKET_SHARED( FLAGS, NB_LIFO );
+DECLARE_BUFFERS_DELETEPACKET_SHARED( FLAGS, NB_LIFO, 1000 );
+DECLARE_BUFFERS_NEWPES( FLAGS, NB_LIFO );
+DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, 1000 );
+DECLARE_BUFFERS_TOIO( FLAGS, DVD_VIDEO_LB_LEN );
+DECLARE_BUFFERS_SHAREBUFFER( FLAGS );
+
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
input.pf_init_bit_stream = InitBitstream;
input.pf_read = DvdReadRead;
input.pf_set_area = DvdReadSetArea;
+ input.pf_set_program = DvdReadSetProgram;
input.pf_demux = input_DemuxPS;
- input.pf_new_packet = input_NetlistNewPacket;
- input.pf_new_pes = input_NetlistNewPES;
- input.pf_delete_packet = input_NetlistDeletePacket;
- input.pf_delete_pes = input_NetlistDeletePES;
+ 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 = DvdReadRewind;
input.pf_seek = DvdReadSeek;
#undef input
/* If the user specified "dvdread:" then he probably wants
* to use libdvdread */
i_score = 100;
- psz_name += 4;
+ psz_name += 8;
}
return( i_score );
p_dvd->p_vts_file = NULL;
p_input->p_plugin_data = (void *)p_dvd;
- p_input->p_method_data = NULL;
- /* We read DVD_BLOCK_READ_ONCE in each loop, so the input will receive
- * DVD_DATA_READ_ONCE at most */
- p_dvd->i_block_once = DVD_BLOCK_READ_ONCE;
- /* this value mustn't be modifed */
- p_input->i_read_once = DVD_DATA_READ_ONCE;
+ if( (p_input->p_method_data = input_BuffersInit()) == NULL )
+ {
+ free( p_dvd );
+ p_input->b_error = 1;
+ return;
+ }
- /* Reading structures initialisation */
- input_NetlistInit( p_input, DVD_NETLIST_SIZE, 2 * DVD_NETLIST_SIZE,
- DVD_NETLIST_SIZE, DVD_VIDEO_LB_LEN, p_dvd->i_block_once );
- intf_WarnMsg( 2, "dvdread info: netlist initialized" );
+ /* We read DVD_BLOCK_READ_ONCE in each loop */
+ p_dvd->i_block_once = DVD_BLOCK_READ_ONCE;
/* Ifo allocation & initialisation */
if( ! ( p_dvd->p_vmg_file = ifoOpen( p_dvd->p_dvdread, 0 ) ) )
{
intf_ErrMsg( "dvdread error: can't open VMG info" );
- DVDClose( p_dvd->p_dvdread );
+ input_BuffersEnd( p_input->p_method_data );
free( p_dvd );
p_input->b_error = 1;
return;
ifoClose( p_dvd->p_vts_file );
ifoClose( p_dvd->p_vmg_file );
- /* Close netlist */
- input_NetlistEnd( p_input );
- p_input->p_method_data = NULL;
+ input_BuffersEnd( p_input->p_method_data );
+}
+
+/*****************************************************************************
+ * DvdReadSetProgram: Does nothing, a DVD is mono-program
+ *****************************************************************************/
+static int DvdReadSetProgram( input_thread_t * p_input,
+ pgrm_descriptor_t * p_program )
+{
+ return 0;
}
#define p_pgc p_dvd->p_cur_pgc
}
free( p_input->stream.pp_selected_es );
- input_DelProgram( p_input, p_input->stream.pp_programs[0] );
+ input_DelProgram( p_input, p_input->stream.p_selected_program );
p_input->stream.pp_selected_es = NULL;
p_input->stream.i_selected_es_number = 0;
}
input_AddProgram( p_input, 0, sizeof( stream_ps_data_t ) );
+ p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
/* No PSM to read in DVD mode, we already have all information */
- p_input->stream.pp_programs[0]->b_is_ok = 1;
+ p_input->stream.p_selected_program->b_is_ok = 1;
p_es = NULL;
/* ES 0 -> video MPEG2 */
// IfoPrintVideo( p_dvd );
- p_es = input_AddES( p_input, p_input->stream.pp_programs[0], 0xe0, 0 );
+ p_es = input_AddES( p_input, p_input->stream.p_selected_program, 0xe0, 0 );
p_es->i_stream_id = 0xe0;
p_es->i_type = MPEG2_VIDEO_ES;
p_es->i_cat = VIDEO_ES;
case 0x00: /* AC3 */
i_id = ( ( 0x80 + i_position ) << 8 ) | 0xbd;
p_es = input_AddES( p_input,
- p_input->stream.pp_programs[0], i_id, 0 );
+ p_input->stream.p_selected_program, i_id, 0 );
p_es->i_stream_id = 0xbd;
p_es->i_type = AC3_AUDIO_ES;
p_es->b_audio = 1;
case 0x03: /* MPEG audio */
i_id = 0xc0 + i_position;
p_es = input_AddES( p_input,
- p_input->stream.pp_programs[0], i_id, 0 );
+ p_input->stream.p_selected_program, i_id, 0 );
p_es->i_stream_id = i_id;
p_es->i_type = MPEG2_AUDIO_ES;
p_es->b_audio = 1;
i_id = ( ( 0xa0 + i_position ) << 8 ) | 0xbd;
p_es = input_AddES( p_input,
- p_input->stream.pp_programs[0], i_id, 0 );
+ p_input->stream.p_selected_program, i_id, 0 );
p_es->i_stream_id = i_id;
p_es->i_type = LPCM_AUDIO_ES;
p_es->b_audio = 1;
i_id = ( ( 0x20 + i_position ) << 8 ) | 0xbd;
p_es = input_AddES( p_input,
- p_input->stream.pp_programs[0], i_id, 0 );
+ p_input->stream.p_selected_program, i_id, 0 );
p_es->i_stream_id = 0xbd;
p_es->i_type = DVD_SPU_ES;
p_es->i_cat = SPU_ES;
* EOF.
*****************************************************************************/
static int DvdReadRead( input_thread_t * p_input,
- data_packet_t ** pp_packets )
+ data_packet_t ** pp_data )
{
thread_dvd_data_t * p_dvd;
- netlist_t * p_netlist;
u8 p_data[DVD_VIDEO_LB_LEN];
- struct iovec * p_vec;
- struct data_packet_s * pp_data[DVD_DATA_READ_ONCE];
+ struct iovec p_vec[DVD_BLOCK_READ_ONCE];
u8 * pi_cur;
int i_blocks;
int i_read;
int i_packet_size;
int i_packet;
int i_pos;
+ data_packet_t * p_data_p;
+ boolean_t b_eot = 0;
p_dvd = (thread_dvd_data_t *)p_input->p_plugin_data;
- p_netlist = (netlist_t *)p_input->p_method_data;
+
+ *pp_data = NULL;
/*
* Playback by cell in this pgc, starting at the cell for our chapter.
return -1;
}
+ /* basic check to be sure we don't have a empty title
+ * go to next title if so */
assert( p_data[41] == 0xbf && p_data[1027] == 0xbf );
+ if( p_data[41] == 0xbf && p_data[1027] == 0xbf )
+ {
+ /*
+ * Parse the contained dsi packet.
+ */
- /*
- * Parse the contained dsi packet.
- */
+ DvdReadHandleDSI( p_dvd, p_data );
- DvdReadHandleDSI( p_dvd, p_data );
+ /* End of File */
+ if( p_dvd->i_next_vobu >= p_dvd->i_end_block + 1 )
+ {
+ return 1;
+ }
- /* End of File */
- if( p_dvd->i_next_vobu >= p_dvd->i_end_block + 1 )
+ assert( p_dvd->i_pack_len < 1024 );
+ /* FIXME: Ugly kludge: we send the pack block to the input for it
+ * sometimes has a zero scr and restart the sync */
+ //p_dvd->i_cur_block ++;
+ p_dvd->i_pack_len++;
+ }
+ else
{
- return 1;
+ b_eot = 1;
+ p_dvd->i_pack_len = 0;
+ return 1;
}
-
- assert( p_dvd->i_pack_len < 1024 );
- /* Ugly kludge: we send the pack block to the input for it
- * sometimes has a zero scr and restart the sync */
-// p_dvd->i_cur_block ++;
- p_dvd->i_pack_len++;
-
}
/*
i_blocks = p_dvd->i_pack_len >= DVD_BLOCK_READ_ONCE
? DVD_BLOCK_READ_ONCE : p_dvd->i_pack_len;
p_dvd->i_pack_len -= i_blocks;
- p_netlist->i_read_once = i_blocks;
- /* Get an iovec pointer */
- if( ( p_vec = input_NetlistGetiovec( p_netlist ) ) == NULL )
+ /* Get iovecs */
+ *pp_data = p_data_p = input_BuffersToIO( p_input->p_method_data, p_vec,
+ DVD_BLOCK_READ_ONCE );
+
+ if ( p_data_p == NULL )
{
- intf_ErrMsg( "dvdread error: can't get iovec" );
- return -1;
+ return( -1 );
}
/* Reads from DVD */
/*
intf_WarnMsg( 12, "dvdread i_blocks: %d len: %d current: 0x%02x", i_read, p_dvd->i_pack_len, p_dvd->i_cur_block );
*/
- /* Update netlist indexes: we don't do it in DVDGetiovec since we
- * need know the real number of blocks read */
- input_NetlistMviovec( p_netlist, i_read, pp_data );
-
i_packet = 0;
/* Read headers to compute payload length */
for( i_iovec = 0 ; i_iovec < i_read ; i_iovec++ )
{
+ data_packet_t * p_current = p_data_p;
i_pos = 0;
- while( i_pos < p_netlist->i_buffer_size )
+ while( i_pos < DVD_VIDEO_LB_LEN )
{
pi_cur = (u8*)p_vec[i_iovec].iov_base + i_pos;
{
/* That's the case for all packets, except pack header. */
i_packet_size = U16_AT( pi_cur + 4 );
- pp_packets[i_packet] = input_NetlistNewPtr( p_netlist );
- (*pp_data[i_iovec]->pi_refcount)++;
- pp_packets[i_packet]->pi_refcount =
- pp_data[i_iovec]->pi_refcount;
- pp_packets[i_packet]->p_buffer = pp_data[i_iovec]->p_buffer;
}
else
{
/* MPEG-2 Pack header. */
i_packet_size = 8;
- pp_packets[i_packet] = pp_data[i_iovec];
-
+ }
+ if( i_pos != 0 )
+ {
+ *pp_data = input_ShareBuffer( p_input->p_method_data,
+ p_current );
+ }
+ else
+ {
+ *pp_data = p_data_p;
+ p_data_p = p_data_p->p_next;
}
- pp_packets[i_packet]->p_payload_start =
- pp_packets[i_packet]->p_buffer + i_pos;
+ (*pp_data)->p_payload_start = (*pp_data)->p_demux_start =
+ (*pp_data)->p_demux_start + i_pos;
+
- pp_packets[i_packet]->p_payload_end =
- pp_packets[i_packet]->p_payload_start + i_packet_size + 6;
+ (*pp_data)->p_payload_end =
+ (*pp_data)->p_payload_start + i_packet_size + 6;
- pp_packets[i_packet]->p_next = NULL;
- pp_packets[i_packet]->b_discard_payload = 0;
+// pp_packets[i_packet]->p_next = NULL;
+// pp_packets[i_packet]->b_discard_payload = 0;
i_packet++;
i_pos += i_packet_size + 6;
+ pp_data = &(*pp_data)->p_next;
}
}
- pp_packets[i_packet] = NULL;
+ p_input->pf_delete_packet( p_input->p_method_data, p_data_p );
+ *pp_data = NULL;
+
+ while( p_data_p != NULL )
+ {
+ data_packet_t * p_next = p_data_p->p_next;
+ p_input->pf_delete_packet( p_input->p_method_data, p_data_p );
+ p_data_p = p_next;
+ }
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.p_selected_area->i_part = p_dvd->i_chapter;
p_dvd->b_eoc = 0;
}
+
+ if( p_input->stream.p_selected_area->i_tell
+ >= p_input->stream.p_selected_area->i_size || b_eot )
+ {
+ if( ( p_input->stream.p_selected_area->i_id + 1 ) >=
+ p_input->stream.i_area_nb )
+ {
+ /* EOF */
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ return 1;
+ }
+ /* EOT */
+ intf_WarnMsg( 4, "dvd info: new title" );
+ DvdReadSetArea( p_input, p_input->stream.pp_areas[
+ p_input->stream.p_selected_area->i_id+1] );
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ return 0;
+ }
vlc_mutex_unlock( &p_input->stream.stream_lock );
* lpcm_decoder_thread.c: lpcm decoder thread
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: lpcm_adec.c,v 1.3.2.1 2001/12/30 06:06:00 sam Exp $
+ * $Id: lpcm_adec.c,v 1.3.2.2 2001/12/31 01:21:44 massiot Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Henri Fallon <henri@videolan.org>
int i_loop;
byte_t byte1, byte2;
- if( DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts )
+ if( p_lpcmdec->p_fifo->p_first->i_pts )
{
p_lpcmdec->p_aout_fifo->date[p_lpcmdec->p_aout_fifo->l_end_frame] =
- DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts;
- DECODER_FIFO_START(*p_lpcmdec->p_fifo)->i_pts = 0;
+ p_lpcmdec->p_fifo->p_first->i_pts;
+ p_lpcmdec->p_fifo->p_first->i_pts = 0;
}
else
{
byte_t buffer[ADEC_FRAME_SIZE];
/* Store time stamp of current frame */
- if ( DECODER_FIFO_START(*p_mad_adec->p_fifo)->i_pts ) {
- p_mad_adec->i_pts_save = DECODER_FIFO_START(*p_mad_adec->p_fifo)->i_pts;
- DECODER_FIFO_START(*p_mad_adec->p_fifo)->i_pts = 0;
+ if ( p_mad_adec->p_fifo->p_first->i_pts ) {
+ p_mad_adec->i_pts_save = p_mad_adec->p_fifo->p_first->i_pts;
+ p_mad_adec->p_fifo->p_first->i_pts = 0;
}
else {
p_mad_adec->i_pts_save = LAST_MDATE;
* input_es.c: Elementary Stream demux and packet management
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: input_es.c,v 1.16.2.1 2001/12/10 15:56:57 massiot Exp $
+ * $Id: input_es.c,v 1.16.2.2 2001/12/31 01:21:45 massiot Exp $
*
* Author: Christophe Massiot <massiot@via.ecp.fr>
*
*****************************************************************************/
static int ESProbe ( probedata_t * );
static int ESRead ( struct input_thread_s *,
- data_packet_t * p_packets[INPUT_READ_ONCE] );
+ data_packet_t ** );
static void ESInit ( struct input_thread_s * );
static void ESEnd ( struct input_thread_s * );
static void ESSeek ( struct input_thread_s *, off_t );
void * );
+/*****************************************************************************
+ * Declare a buffer manager
+ *****************************************************************************/
+#define FLAGS BUFFERS_UNIQUE_SIZE
+#define NB_LIFO 1
+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 );
+DECLARE_BUFFERS_TOIO( FLAGS, ES_PACKET_SIZE );
+
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
* we don't pollute the namespace too much.
input.pf_set_program = ESSetProgram;
input.pf_read = ESRead;
input.pf_demux = ESDemux;
- input.pf_new_packet = input_NetlistNewPacket;
- input.pf_new_pes = input_NetlistNewPES;
- input.pf_delete_packet = input_NetlistDeletePacket;
- input.pf_delete_pes = input_NetlistDeletePES;
+ 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 = ESSeek;
#undef input
{
es_descriptor_t * p_es;
- p_input->p_method_data = NULL;
-
- /* Initialize netlist */
- if( input_NetlistInit( p_input, NB_DATA, NB_DATA, NB_PES, ES_PACKET_SIZE,
- INPUT_READ_ONCE ) )
+ if( (p_input->p_method_data = input_BuffersInit()) == NULL )
{
- intf_ErrMsg( "ES input : Could not initialize netlist" );
+ p_input->b_error = 1;
return;
}
/* FIXME : detect if InitStream failed */
input_InitStream( p_input, 0 );
input_AddProgram( p_input, 0, 0 );
+ p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
vlc_mutex_lock( &p_input->stream.stream_lock );
- p_es = input_AddES( p_input, p_input->stream.pp_programs[0], 0xE0, 0 );
+ p_es = input_AddES( p_input, p_input->stream.p_selected_program, 0xE0, 0 );
p_es->i_stream_id = 0xE0;
p_es->i_type = MPEG1_VIDEO_ES;
p_es->i_cat = VIDEO_ES;
input_SelectES( p_input, p_es );
p_input->stream.p_selected_area->i_tell = 0;
- p_input->stream.pp_programs[0]->b_is_ok = 1;
+ p_input->stream.p_selected_program->b_is_ok = 1;
vlc_mutex_unlock( &p_input->stream.stream_lock );
}
*****************************************************************************/
static void ESEnd( input_thread_t * p_input )
{
+ input_BuffersEnd( p_input->p_method_data );
}
/*****************************************************************************
* ESRead: reads data packets
*****************************************************************************
- * Returns -1 in case of error, 0 if everything went well, and 1 in case of
- * EOF.
+ * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
+ * packets.
*****************************************************************************/
static int ESRead( input_thread_t * p_input,
- data_packet_t * pp_packets[INPUT_READ_ONCE] )
+ data_packet_t ** pp_data )
{
int i_read;
- struct iovec * p_iovec;
+ struct iovec p_iovec[ES_READ_ONCE];
+ data_packet_t * p_data;
/* Get iovecs */
- p_iovec = input_NetlistGetiovec( p_input->p_method_data );
+ *pp_data = p_data = input_BuffersToIO( p_input->p_method_data, p_iovec,
+ ES_READ_ONCE );
- if ( p_iovec == NULL )
+ if ( p_data == NULL )
{
- return( -1 ); /* empty netlist */
+ return( -1 );
}
- memset( pp_packets, 0, INPUT_READ_ONCE * sizeof(data_packet_t *) );
-
- i_read = readv( p_input->i_handle, p_iovec, INPUT_READ_ONCE );
+ i_read = readv( p_input->i_handle, p_iovec, ES_READ_ONCE );
if( i_read == -1 )
{
intf_ErrMsg( "input error: ES readv error" );
+ p_input->pf_delete_packet( p_input->p_method_data, p_data );
return( -1 );
}
+ p_input->stream.p_selected_area->i_tell += i_read;
+ i_read /= ES_PACKET_SIZE;
- /* EOF */
- if( i_read == 0 && p_input->stream.b_seekable )
+ if( i_read != ES_READ_ONCE )
{
- return( 1 );
- }
+ /* We got fewer packets than wanted. Give remaining packets
+ * back to the buffer allocator. */
+ int i_loop;
- input_NetlistMviovec( p_input->p_method_data,
- (int)(i_read/ES_PACKET_SIZE), pp_packets );
+ for( i_loop = 0; i_loop < i_read; i_loop++ )
+ {
+ pp_data = &(*pp_data)->p_next;
+ }
- p_input->stream.p_selected_area->i_tell += i_read;
+ p_input->pf_delete_packet( p_input->p_method_data, *pp_data );
+ *pp_data = NULL;
+ }
- return( 0 );
+ return( i_read );
}
/*****************************************************************************
{
pes_packet_t * p_pes = p_input->pf_new_pes( p_input->p_method_data );
decoder_fifo_t * p_fifo =
- p_input->stream.pp_programs[0]->pp_es[0]->p_decoder_fifo;
+ p_input->stream.p_selected_program->pp_es[0]->p_decoder_fifo;
if( p_pes == NULL )
{
}
p_pes->i_rate = p_input->stream.control.i_rate;
- p_pes->p_first = p_data;
+ p_pes->p_first = p_pes->p_last = p_data;
+ p_pes->i_nb_data = 1;
- if( (p_input->stream.pp_programs[0]->i_synchro_state == SYNCHRO_REINIT)
- | (input_ClockManageControl( p_input, p_input->stream.pp_programs[0],
- (mtime_t)0 ) == PAUSE_S) )
+ if( (p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT)
+ | (input_ClockManageControl( p_input,
+ p_input->stream.p_selected_program,
+ (mtime_t)0 ) == PAUSE_S) )
{
intf_WarnMsg( 2, "synchro reinit" );
p_pes->i_pts = mdate() + DEFAULT_PTS_DELAY;
- p_input->stream.pp_programs[0]->i_synchro_state = SYNCHRO_OK;
+ p_input->stream.p_selected_program->i_synchro_state = SYNCHRO_OK;
}
input_DecodePES( p_fifo, p_pes );
vlc_mutex_lock( &p_fifo->data_lock );
- if( ( (DECODER_FIFO_END( *p_fifo ) - DECODER_FIFO_START( *p_fifo ))
- & FIFO_SIZE ) >= MAX_PACKETS_IN_FIFO )
+ if( p_fifo->i_depth >= MAX_PACKETS_IN_FIFO )
{
vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
}
* time to jump to the next PES packet */
if( p_bit_stream->p_data->p_next == NULL )
{
- /* We are going to read/write the start and end indexes of the
- * decoder fifo and to use the fifo's conditional variable,
- * that's why we need to take the lock before. */
+ pes_packet_t * p_next;
+
vlc_mutex_lock( &p_fifo->data_lock );
/* Free the previous PES packet. */
+ p_next = p_fifo->p_first->p_next;
+ p_fifo->p_first->p_next = NULL;
p_fifo->pf_delete_pes( p_fifo->p_packets_mgt,
- DECODER_FIFO_START( *p_fifo ) );
- DECODER_FIFO_INCSTART( *p_fifo );
+ p_fifo->p_first );
+ p_fifo->p_first = p_next;
+ p_fifo->i_depth--;
- if( DECODER_FIFO_ISEMPTY( *p_fifo ) )
+ if( p_fifo->p_first == NULL )
{
+ /* No PES in the FIFO. p_last is no longer valid. */
+ p_fifo->pp_last = &p_fifo->p_first;
+
/* Signal the input thread we're waiting. */
vlc_cond_signal( &p_fifo->data_wait );
}
/* The next byte could be found in the next PES packet */
- p_bit_stream->p_data = DECODER_FIFO_START( *p_fifo )->p_first;
+ p_bit_stream->p_data = p_fifo->p_first->p_first;
vlc_mutex_unlock( &p_fifo->data_lock );
* input_es.h: thread structure of the ES plugin
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: input_es.h,v 1.2 2001/06/27 09:53:56 massiot Exp $
+ * $Id: input_es.h,v 1.2.2.1 2001/12/31 01:21:45 massiot Exp $
*
* Authors:
*
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
-
-#define NB_DATA 8192
-#define NB_PES 4096
#define ES_PACKET_SIZE 2048
-#define MAX_PACKETS_IN_FIFO 14
+#define ES_READ_ONCE 50
+#define MAX_PACKETS_IN_FIFO 50
* input_ps.c: PS demux and packet management
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: input_ps.c,v 1.44 2001/12/07 18:33:07 sam Exp $
+ * $Id: input_ps.c,v 1.44.2.1 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Cyril Deguet <asmax@via.ecp.fr>
*****************************************************************************/
static int PSProbe ( probedata_t * );
static int PSRead ( struct input_thread_s *,
- data_packet_t * p_packets[INPUT_READ_ONCE] );
+ data_packet_t ** );
static void PSInit ( struct input_thread_s * );
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, 300 );
+DECLARE_BUFFERS_NEWPES( FLAGS, NB_LIFO );
+DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, 300 );
+
/*****************************************************************************
* 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 */
if( p_input->p_stream == NULL )
{
intf_ErrMsg( "Cannot open file (%s)", strerror(errno) );
+ input_BuffersEnd( p_input->p_method_data );
p_input->b_error = 1;
return;
}
while( !p_input->b_die && !p_input->b_error
&& !p_demux_data->b_has_PSM )
{
- int i_result, i;
- data_packet_t * pp_packets[INPUT_READ_ONCE];
+ int i_result;
+ data_packet_t * p_data;
+ data_packet_t * p_saved_data;
- i_result = PSRead( p_input, pp_packets );
- if( i_result == 1 )
+ i_result = PSRead( p_input, &p_data );
+ p_saved_data = p_data;
+
+ while( p_data != NULL )
+ {
+ input_ParsePS( p_input, p_data );
+ p_data = p_data->p_next;
+ }
+
+ p_input->pf_delete_packet( p_input->p_method_data, p_saved_data );
+
+ if( i_result == 0 )
{
/* EOF */
vlc_mutex_lock( &p_input->stream.stream_lock );
vlc_mutex_unlock( &p_input->stream.stream_lock );
break;
}
- if( i_result == -1 )
+ else if( i_result == -1 )
{
p_input->b_error = 1;
break;
}
- for( i = 0; i < INPUT_READ_ONCE && pp_packets[i] != NULL; i++ )
- {
- /* FIXME: use i_p_config_t */
- input_ParsePS( p_input, pp_packets[i] );
- DeletePacket( p_input->p_method_data, pp_packets[i] );
- }
-
/* File too big. */
if( p_input->stream.p_selected_area->i_tell >
INPUT_PREPARSE_LENGTH )
*****************************************************************************/
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 );
}
/*****************************************************************************
{
if( feof( p_input->p_stream ) )
{
- return( 1 );
+ return( 0 );
}
if( (i_error = ferror( p_input->p_stream )) )
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.p_selected_area->i_tell += i_len;
vlc_mutex_unlock( &p_input->stream.stream_lock );
- return( 0 );
+ return( i_len );
}
/*****************************************************************************
* PSRead: reads data packets
*****************************************************************************
- * Returns -1 in case of error, 0 if everything went well, and 1 in case of
- * EOF.
+ * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
+ * packets.
*****************************************************************************/
static int PSRead( input_thread_t * p_input,
- data_packet_t * pp_packets[INPUT_READ_ONCE] )
+ data_packet_t ** pp_data )
{
byte_t p_header[6];
data_packet_t * p_data;
size_t i_packet_size;
int i_packet, i_error;
- memset( pp_packets, 0, INPUT_READ_ONCE * sizeof(data_packet_t *) );
- for( i_packet = 0; i_packet < INPUT_READ_ONCE; i_packet++ )
+ *pp_data = NULL;
+
+ for( i_packet = 0; i_packet < PS_READ_ONCE; i_packet++ )
{
/* Read what we believe to be a packet header. */
- if( (i_error = SafeRead( p_input, p_header, 4 )) )
+ if( (i_error = SafeRead( p_input, p_header, 4 )) <= 0 )
{
return( i_error );
}
}
else
{
- return( 1 );
+ return( 0 );
}
}
/* Packet found. */
if( U32_AT(p_header) != 0x1B9 )
{
/* The packet is at least 6 bytes long. */
- if( (i_error = SafeRead( p_input, p_header + 4, 2 )) )
+ if( (i_error = SafeRead( p_input, p_header + 4, 2 )) <= 0 )
{
return( i_error );
}
}
/* 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" );
if( U32_AT(p_header) != 0x1B9 )
{
/* Copy the header we already read. */
- memcpy( p_data->p_buffer, p_header, 6 );
+ memcpy( p_data->p_demux_start, p_header, 6 );
/* Read the remaining of the packet. */
if( i_packet_size && (i_error =
- SafeRead( p_input, p_data->p_buffer + 6, i_packet_size )) )
+ SafeRead( p_input, p_data->p_demux_start + 6,
+ i_packet_size )) <= 0 )
{
+ p_input->pf_delete_packet( p_input->p_method_data, p_data );
return( i_error );
}
/* In MPEG-2 pack headers we still have to read stuffing bytes. */
if( U32_AT(p_header) == 0x1BA )
{
- if( i_packet_size == 8 && (p_data->p_buffer[13] & 0x7) != 0 )
+ if( i_packet_size == 8 && (p_data->p_demux_start[13] & 0x7) != 0 )
{
/* MPEG-2 stuffing bytes */
byte_t p_garbage[8];
if( (i_error = SafeRead( p_input, p_garbage,
- p_data->p_buffer[13] & 0x7)) )
+ p_data->p_demux_start[13] & 0x7)) <= 0 )
{
+ p_input->pf_delete_packet( p_input->p_method_data,
+ p_data );
return( i_error );
}
}
else
{
/* Copy the small header. */
- memcpy( p_data->p_buffer, p_header, 4 );
+ memcpy( p_data->p_demux_start, p_header, 4 );
}
/* Give the packet to the other input stages. */
- pp_packets[i_packet] = p_data;
+ *pp_data = p_data;
+ pp_data = &p_data->p_next;
}
- return( 0 );
+ return( i_packet + 1 );
}
/*****************************************************************************
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 );
-}
-
* input_ps.h: thread structure of the PS plugin
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_ps.h,v 1.9 2001/10/02 16:46:59 massiot Exp $
+ * $Id: input_ps.h,v 1.9.2.1 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Cyril Deguet <asmax@via.ecp.fr>
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
-#define DATA_CACHE_SIZE 150
-#define PES_CACHE_SIZE 150
-#define SMALL_CACHE_SIZE 150
-#define LARGE_CACHE_SIZE 150
-#define MAX_SMALL_SIZE 50 // frontier between small and large packets
-
-typedef struct
-{
- data_packet_t ** p_stack;
- long l_index;
-} data_packet_cache_t;
-
-
-typedef struct
-{
- pes_packet_t ** p_stack;
- long l_index;
-} pes_packet_cache_t;
-
-
-typedef struct
-{
- byte_t * p_data;
- long l_size;
-} packet_buffer_t;
-
-
-typedef struct
-{
- packet_buffer_t * p_stack;
- long l_index;
-} small_buffer_cache_t;
-
-
-typedef struct
-{
- packet_buffer_t * p_stack;
- long l_index;
-} large_buffer_cache_t;
-
-
-typedef struct
-{
- vlc_mutex_t lock;
- data_packet_cache_t data;
- pes_packet_cache_t pes;
- small_buffer_cache_t smallbuffer;
- large_buffer_cache_t largebuffer;
-} packet_cache_t;
-
+#define PS_READ_ONCE 50
* input_ts.c: TS demux and netlist management
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: input_ts.c,v 1.42 2001/12/07 18:33:07 sam Exp $
+ * $Id: input_ts.c,v 1.42.2.1 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Henri Fallon <henri@videolan.org>
*
static void TSInit ( struct input_thread_s * );
static void TSEnd ( struct input_thread_s * );
static int TSRead ( struct input_thread_s *,
- data_packet_t * p_packets[INPUT_READ_ONCE] );
+ data_packet_t ** );
+
+/*****************************************************************************
+ * Declare a buffer manager
+ *****************************************************************************/
+#define FLAGS BUFFERS_UNIQUE_SIZE
+#define NB_LIFO 1
+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, 1000 );
+DECLARE_BUFFERS_NEWPES( FLAGS, NB_LIFO );
+DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, 150 );
+DECLARE_BUFFERS_TOIO( FLAGS, TS_PACKET_SIZE );
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
input.pf_set_program = input_SetProgram;
input.pf_read = TSRead;
input.pf_demux = input_DemuxTS;
- input.pf_new_packet = input_NetlistNewPacket;
- input.pf_new_pes = input_NetlistNewPES;
- input.pf_delete_packet = input_NetlistDeletePacket;
- input.pf_delete_pes = input_NetlistDeletePES;
+ 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 = NULL;
#undef input
*****************************************************************************/
static void TSInit( input_thread_t * p_input )
{
- /* Initialize netlist and TS structures */
thread_ts_data_t * p_method;
es_descriptor_t * p_pat_es;
es_ts_data_t * p_demux_data;
p_input->p_method_data = NULL;
- /* Initialize netlist */
- if( input_NetlistInit( p_input, NB_DATA, NB_DATA, NB_PES, TS_PACKET_SIZE,
- INPUT_READ_ONCE ) )
+ if( (p_input->p_method_data = input_BuffersInit()) == NULL )
{
- intf_ErrMsg( "TS input : Could not initialize netlist" );
+ p_input->b_error = 1;
return;
}
input_DelES( p_input, p_pat_es );
free(p_input->p_plugin_data);
- input_NetlistEnd( p_input );
+ input_BuffersEnd( p_input->p_method_data );
}
/*****************************************************************************
* TSRead: reads data packets
*****************************************************************************
- * Returns -1 in case of error, 0 if everything went well, and 1 in case of
- * EOF.
+ * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
+ * packets.
*****************************************************************************/
static int TSRead( input_thread_t * p_input,
- data_packet_t * pp_packets[INPUT_READ_ONCE] )
+ data_packet_t ** pp_data )
{
thread_ts_data_t * p_method;
- unsigned int i_loop;
- int i_read;
+ int i_read = 0, i_loop;
int i_data = 1;
- struct iovec * p_iovec;
+ struct iovec p_iovec[TS_READ_ONCE];
+ data_packet_t * p_data;
struct timeval timeout;
/* Init */
timeout.tv_sec = 0;
timeout.tv_usec = 500000;
- /* Reset pointer table */
- memset( pp_packets, 0, INPUT_READ_ONCE * sizeof(data_packet_t *) );
-
/* Fill if some data is available */
#if defined( WIN32 )
if ( ! p_input->stream.b_pace_control )
if( i_data )
{
/* Get iovecs */
- p_iovec = input_NetlistGetiovec( p_input->p_method_data );
+ *pp_data = p_data = input_BuffersToIO( p_input->p_method_data, p_iovec,
+ TS_READ_ONCE );
- if ( p_iovec == NULL )
+ if ( p_data == NULL )
{
- return( -1 ); /* empty netlist */
+ return( -1 );
}
#if defined( WIN32 )
if( p_input->stream.b_pace_control )
{
- i_read = readv( p_input->i_handle, p_iovec, INPUT_READ_ONCE );
+ i_read = readv( p_input->i_handle, p_iovec, TS_READ_ONCE );
}
else
{
i_read = readv_network( p_input->i_handle, p_iovec,
- INPUT_READ_ONCE, p_method );
+ TS_READ_ONCE, p_method );
}
#else
- i_read = readv( p_input->i_handle, p_iovec, INPUT_READ_ONCE );
+ i_read = readv( p_input->i_handle, p_iovec, TS_READ_ONCE );
/* Shouldn't happen, but it does - at least under Linux */
if( (i_read == -1) && ( (errno == EAGAIN) || (errno = EWOULDBLOCK) ) )
i_read = 0;
}
#endif
+ /* Error */
if( i_read == -1 )
{
intf_ErrMsg( "input error: TS readv error" );
+ p_input->pf_delete_packet( p_input->p_method_data, p_data );
return( -1 );
}
+ p_input->stream.p_selected_area->i_tell += i_read;
+ i_read /= TS_PACKET_SIZE;
- /* EOF */
- if( i_read == 0 && p_input->stream.b_seekable )
- {
- return( 1 );
- }
-
- input_NetlistMviovec( p_input->p_method_data,
- (int)(((i_read-1)/TS_PACKET_SIZE)+1) , pp_packets );
-
- /* check correct TS header */
- for( i_loop=0; i_loop * TS_PACKET_SIZE < i_read; i_loop++ )
+ /* Check correct TS header */
+ for( i_loop = 0; i_loop < i_read; i_loop++ )
{
- if( pp_packets[i_loop]->p_buffer[0] != 0x47 )
+ if( (*pp_data)->p_demux_start[0] != 0x47 )
+ {
intf_ErrMsg( "input error: bad TS packet (starts with "
"0x%.2x, should be 0x47)",
- pp_packets[i_loop]->p_buffer[0] );
+ p_data->p_demux_start[0] );
+ }
+ pp_data = &(*pp_data)->p_next;
}
- for( ; i_loop < INPUT_READ_ONCE ; i_loop++ )
+
+ if( i_read != TS_READ_ONCE )
{
- pp_packets[i_loop] = NULL;
+ /* Delete remaining packets */
+ p_input->pf_delete_packet( p_input->p_method_data, *pp_data );
+ *pp_data = NULL;
}
-
- p_input->stream.p_selected_area->i_tell += i_read;
}
- return 0;
+ return( i_read );
}
* input_ts.h: structures of the input not exported to other modules
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_ts.h,v 1.12.2.1 2001/12/09 21:14:19 sam Exp $
+ * $Id: input_ts.h,v 1.12.2.2 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Henri Fallon <henri@via.ecp.fr>
* Boris Dorès <babal@via.ecp.fr>
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
-#define NB_DATA 16384
-#define NB_PES 8192
+/* UDP packets contain 1500 bytes, that is 7 TS packets */
+#define TS_READ_ONCE 7
-#define BUFFER_SIZE (7 * TS_PACKET_SIZE)
+#ifdef WIN32
+# define BUFFER_SIZE (7 * TS_PACKET_SIZE)
+#endif
/*****************************************************************************
* thread_ts_data_t: private input data
* mpeg_adec.c: MPEG audio decoder thread
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: mpeg_adec.c,v 1.5.2.1 2001/12/30 06:06:00 sam Exp $
+ * $Id: mpeg_adec.c,v 1.5.2.2 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr>
buffer = ((s16 *)p_adec->p_aout_fifo->buffer)
+ (p_adec->p_aout_fifo->l_end_frame * ADEC_FRAME_SIZE);
- if( DECODER_FIFO_START( *p_adec->p_fifo)->i_pts )
+ if( p_adec->p_fifo->p_first->i_pts )
{
p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] =
- DECODER_FIFO_START( *p_adec->p_fifo )->i_pts;
- DECODER_FIFO_START(*p_adec->p_fifo)->i_pts = 0;
+ p_adec->p_fifo->p_first->i_pts;
+ p_adec->p_fifo->p_first->i_pts = 0;
}
else
{
* video_parser.c : video parser thread
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: video_parser.c,v 1.6.2.1 2001/12/30 06:06:00 sam Exp $
+ * $Id: video_parser.c,v 1.6.2.2 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Samuel Hocevar <sam@via.ecp.fr>
return( 0 );
}
-/*****************************************************************************
- * mpeg_vdec_ErrorThread: RunThread() error loop
- *****************************************************************************
- * This function is called when an error occured during thread main's loop. The
- * thread can still receive feed, but must be ready to terminate as soon as
- * possible.
- *****************************************************************************/
-static void mpeg_vdec_ErrorThread( vpar_thread_t *p_vpar )
-{
- /* We take the lock, because we are going to read/write the start/end
- * indexes of the decoder fifo */
- vlc_mutex_lock( &p_vpar->p_fifo->data_lock );
-
- /* Wait until a `die' order is sent */
- while( !p_vpar->p_fifo->b_die )
- {
- /* Trash all received PES packets */
- while( !DECODER_FIFO_ISEMPTY(*p_vpar->p_fifo) )
- {
- p_vpar->p_fifo->pf_delete_pes( p_vpar->p_fifo->p_packets_mgt,
- DECODER_FIFO_START(*p_vpar->p_fifo) );
- DECODER_FIFO_INCSTART( *p_vpar->p_fifo );
- }
-
- /* Waiting for the input thread to put new PES packets in the fifo */
- vlc_cond_wait( &p_vpar->p_fifo->data_wait, &p_vpar->p_fifo->data_lock );
- }
-
- /* We can release the lock before leaving */
- vlc_mutex_unlock( &p_vpar->p_fifo->data_lock );
-}
-
/*****************************************************************************
* EndThread: thread destruction
*****************************************************************************
if( b_new_pes )
{
p_vpar->sequence.next_pts =
- DECODER_FIFO_START( *p_bit_stream->p_decoder_fifo )->i_pts;
+ p_bit_stream->p_decoder_fifo->p_first->i_pts;
p_vpar->sequence.next_dts =
- DECODER_FIFO_START( *p_bit_stream->p_decoder_fifo )->i_dts;
+ p_bit_stream->p_decoder_fifo->p_first->i_dts;
p_vpar->sequence.i_current_rate =
- DECODER_FIFO_START( *p_bit_stream->p_decoder_fifo )->i_rate;
+ p_bit_stream->p_decoder_fifo->p_first->i_rate;
- if( DECODER_FIFO_START( *p_bit_stream->p_decoder_fifo )->b_discontinuity )
+ if( p_bit_stream->p_decoder_fifo->p_first->b_discontinuity )
{
#ifdef TRACE_VPAR
intf_DbgMsg( "Discontinuity in BitstreamCallback" );
* spu_decoder.c : spu decoder thread
*****************************************************************************
* Copyright (C) 2000-2001 VideoLAN
- * $Id: spu_decoder.c,v 1.5.2.2 2001/12/30 06:06:00 sam Exp $
+ * $Id: spu_decoder.c,v 1.5.2.3 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
p_spudec->i_spu_size );
/* We cannot display a subpicture with no date */
- if( DECODER_FIFO_START(*p_spudec->p_fifo)->i_pts == 0 )
+ if( p_spudec->p_fifo->p_first->i_pts == 0 )
{
intf_WarnMsg( 3, "spudec error: subtitle without a date" );
return;
}
/* Get display time now. If we do it later, we may miss the PTS. */
- p_spudec->i_pts = DECODER_FIFO_START(*p_spudec->p_fifo)->i_pts;
+ p_spudec->i_pts = p_spudec->p_fifo->p_first->i_pts;
/* Allocate the temporary buffer we will parse */
p_src = malloc( p_spudec->i_rle_size );
#include "modules.h"
#include "modules_export.h"
-#include "../mpeg/input_ps.h"
#include "input_vcd.h"
#include "linux_cdrom_tools.h"
/* how many blocks VCDRead will read in each loop */
-#define VCD_BLOCKS_ONCE 64
-#define VCD_DATA_ONCE (2 * VCD_BLOCKS_ONCE)
+#define VCD_BLOCKS_ONCE 4
+#define VCD_DATA_ONCE (2 * VCD_BLOCKS_ONCE)
#define BUFFER_SIZE VCD_DATA_SIZE
-
-
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static void VCDEnd ( struct input_thread_s *);
static void VCDSeek ( struct input_thread_s *, off_t );
static int VCDRewind ( struct input_thread_s * );
-static struct data_packet_s * NewPacket( void *, size_t );
-static pes_packet_t * NewPES ( void * );
-static void DeletePacket ( void *, data_packet_t * );
-static void DeletePES ( void *, pes_packet_t *);
+/*****************************************************************************
+ * 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, 1000 );
+DECLARE_BUFFERS_NEWPES( FLAGS, NB_LIFO );
+DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, 1000 );
/*****************************************************************************
input.pf_set_area = VCDSetArea;
input.pf_set_program = VCDSetProgram;
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 = VCDRewind;
input.pf_seek = VCDSeek;
#undef input
*****************************************************************************/
static void VCDOpen( struct input_thread_s *p_input )
{
- int vcdhandle;
-
vlc_mutex_lock( &p_input->stream.stream_lock );
/* If we are here we can control the pace... */
p_input->stream.b_seekable = 1;
p_input->stream.p_selected_area->i_size = 0;
-
p_input->stream.p_selected_area->i_tell = 0;
vlc_mutex_unlock( &p_input->stream.stream_lock );
if( strlen( p_input->p_source ) > 4
&& !strncasecmp( p_input->p_source, "vcd:", 4 ) )
{
- vcdhandle = open( p_input->p_source + 4, O_RDONLY | O_NONBLOCK );
+ p_input->i_handle = open( p_input->p_source + 4, O_RDONLY | O_NONBLOCK );
}
else
{
- vcdhandle = open( p_input->p_source + 4, O_RDONLY | O_NONBLOCK );
+ p_input->i_handle = open( p_input->p_source + 4, O_RDONLY | O_NONBLOCK );
}
- if( vcdhandle == -1 )
+ if( p_input->i_handle == -1 )
{
p_input->b_error = 1;
- return;
}
-
- p_input->i_handle = (int) vcdhandle;
}
/*****************************************************************************
int i;
input_area_t * p_area;
es_descriptor_t * p_es;
- packet_cache_t * p_packet_cache;
-
+
p_vcd = malloc( sizeof(thread_vcd_data_t) );
-
+
if( p_vcd == NULL )
{
intf_ErrMsg( "vcd error: out of memory" );
return;
}
-
-
p_input->p_plugin_data = (void *)p_vcd;
- p_input->p_method_data = NULL;
- p_vcd->vcdhandle = p_input->i_handle;
- p_vcd->b_end_of_track = 0;
-
- /* we read the Table Of Content information */
- if ( read_toc(p_vcd) == -1 )
- {
- intf_ErrMsg("An error occured when reading vcd's TOC");
- }
-
- p_input->i_read_once = VCD_DATA_ONCE;
-
- p_packet_cache = malloc( sizeof(packet_cache_t) );
-
- if ( p_packet_cache == NULL )
+ if( (p_input->p_method_data = input_BuffersInit()) == NULL )
{
- intf_ErrMsg( "vcd error: 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" );
+ free( p_vcd );
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 )
+
+ p_vcd->i_handle = p_input->i_handle;
+
+ /* We read the Table Of Content information */
+ p_vcd->nb_tracks = ioctl_GetTrackCount( p_input->i_handle );
+ if( p_vcd->nb_tracks < 0 )
{
- intf_ErrMsg( "Out of memory" );
+ input_BuffersEnd( p_input->p_method_data );
+ free( p_vcd );
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 )
+
+ p_vcd->p_sectors = ioctl_GetSectors( p_input->i_handle );
+ if ( p_vcd->p_sectors == NULL )
{
- intf_ErrMsg( "Out of memory" );
+ input_BuffersEnd( p_input->p_method_data );
+ free( p_vcd );
p_input->b_error = 1;
return;
}
- p_packet_cache->largebuffer.l_index = 0;
/* Set stream and area data */
vlc_mutex_lock( &p_input->stream.stream_lock );
/* disc input method */
p_input->stream.i_method = INPUT_METHOD_VCD;
-
#define area p_input->stream.pp_areas
for( i = 1 ; i <= p_vcd->nb_tracks - 1 ; i++ )
{
area[i]->i_id = i;
/* Absolute start offset and size */
- area[i]->i_start = p_vcd->tracks_sector[i];
- area[i]->i_size = p_vcd->tracks_sector[i+1] - p_vcd->tracks_sector[i];
+ area[i]->i_start = (off_t)p_vcd->p_sectors[i] * (off_t)VCD_DATA_SIZE;
+ area[i]->i_size = (off_t)(p_vcd->p_sectors[i+1] - p_vcd->p_sectors[i])
+ * (off_t)VCD_DATA_SIZE;
/* Number of chapters */
area[i]->i_part_nb = 0; // will be the entry points
area[i]->i_angle_nb = 1; // no angle support in VCDs
area[i]->i_angle = 1;
- area[i]->i_plugin_data = p_vcd->tracks_sector[i];
- }
+ area[i]->i_plugin_data = p_vcd->p_sectors[i];
+ }
#undef area
/* Get requested title - if none try the first title */
i_title = main_GetIntVariable( INPUT_TITLE_VAR, 1 );
- if( i_title <= 0)
+ if( i_title <= 0 )
{
i_title = 1;
}
-
- // p_vcd->current_track = i_title-1 ;
-
+
+ // p_vcd->i_track = i_title-1;
+
/* Get requested chapter - if none defaults to first one */
i_chapter = main_GetIntVariable( INPUT_CHAPTER_VAR, 1 );
if( i_chapter <= 0 )
i_chapter = 1;
}
-
p_input->stream.pp_areas[i_title]->i_part = i_chapter;
p_area = p_input->stream.pp_areas[i_title];
input_AddProgram( p_input, 0, sizeof( stream_ps_data_t ) );
p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
- /* No PSM to read in disc mode, we already have all information */
+ /* No PSM to read in disc mode, we already have all the information */
p_input->stream.p_selected_program->b_is_ok = 1;
p_es = input_AddES( p_input, p_input->stream.p_selected_program, 0xe0, 0 );
p_es->i_stream_id = 0xe0;
p_es->i_type = MPEG1_VIDEO_ES;
p_es->i_cat = VIDEO_ES;
-
+
if( p_main->b_video )
{
input_SelectES( p_input, p_es );
}
-
- p_es = input_AddES( p_input,
- p_input->stream.p_selected_program, 0xc0, 0 );
+
+ p_es = input_AddES( p_input, p_input->stream.p_selected_program, 0xc0, 0 );
p_es->i_stream_id = 0xc0;
p_es->i_type = MPEG1_AUDIO_ES;
p_es->b_audio = 1;
p_es->i_cat = AUDIO_ES;
-
+
if( p_main->b_audio )
{
input_SelectES( p_input, p_es );
}
-
- vlc_mutex_unlock( &p_input->stream.stream_lock );
-
- return;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
}
-
/*****************************************************************************
* VCDEnd: frees unused data
*****************************************************************************/
{
thread_vcd_data_t * p_vcd;
+ input_BuffersEnd( p_input->p_method_data );
+
p_vcd = (thread_vcd_data_t*)p_input->p_plugin_data;
free( p_vcd );
-
}
/*****************************************************************************
* VCDSetProgram: Does nothing since a VCD is mono_program
*****************************************************************************/
-static int VCDSetProgram( input_thread_t * p_input,
- pgrm_descriptor_t * p_program)
+static int VCDSetProgram( input_thread_t * p_input,
+ pgrm_descriptor_t * p_program)
{
return 0;
}
static int VCDSetArea( input_thread_t * p_input, input_area_t * p_area )
{
thread_vcd_data_t * p_vcd;
-
+
p_vcd = (thread_vcd_data_t*)p_input->p_plugin_data;
-
+
/* we can't use the interface slider until initilization is complete */
p_input->stream.b_seekable = 0;
-
- if ( p_area != p_input->stream.p_selected_area )
+
+ if( p_area != p_input->stream.p_selected_area )
{
- /* Reset the Chapter position of the old title */
- p_input->stream.p_selected_area->i_part = 0;
+ /* Reset the Chapter position of the current title */
+ p_input->stream.p_selected_area->i_part = 1;
p_input->stream.p_selected_area->i_tell = 0;
-
+
/* Change the default area */
p_input->stream.p_selected_area = p_area;
/* Change the current track */
/* The first track is not a valid one */
- p_vcd->current_track = p_area->i_id ;
- p_vcd->current_sector = p_vcd->tracks_sector[p_vcd->current_track] ;
+ p_vcd->i_track = p_area->i_id;
+ p_vcd->i_sector = p_vcd->p_sectors[p_vcd->i_track];
}
+
/* warn interface that something has changed */
p_input->stream.b_seekable = 1;
p_input->stream.b_changed = 1;
- return 0 ;
-
-}
-
+ return 0;
+}
/*****************************************************************************
* VCDRead: reads from the VCD into PES packets.
*****************************************************************************
- * Returns -1 in case of error, 0 if everything went well, and 1 in case of
- * EOF.
+ * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
+ * packets.
*****************************************************************************/
-static int VCDRead( input_thread_t * p_input,
- data_packet_t ** pp_packets )
+static int VCDRead( input_thread_t * p_input, data_packet_t ** pp_data )
{
thread_vcd_data_t * p_vcd;
data_packet_t * p_data;
int i_packet_size;
int i_index;
- int i_packet;
- boolean_t b_eof;
- byte_t * p_buffer;
- boolean_t b_no_packet;
+ int i_packet;
+ u32 i_header;
+ byte_t p_buffer[ VCD_DATA_SIZE ];
+ boolean_t b_eot = 0; /* end of track */
/* boolean_t b_eoc; No chapters yet */
-
+
p_vcd = (thread_vcd_data_t *)p_input->p_plugin_data;
-
- p_buffer = malloc ( VCD_DATA_SIZE );
+ i_packet = 0;
+ *pp_data = NULL;
- if ( p_buffer == NULL )
+ while( i_packet < VCD_DATA_ONCE )
{
- intf_ErrMsg("Could not malloc the read buffer");
- return -1;
- }
+ if( ioctl_ReadSector( p_vcd->i_handle, p_vcd->i_sector, p_buffer ) )
+ {
+ /* Read error, but assume we reached the end of the track */
+ b_eot = 1;
+ break;
+ }
-
- i_packet = 0;
- b_no_packet = 0;
+ p_vcd->i_sector++;
- while( i_packet < VCD_DATA_ONCE )
- {
- i_index = 0;
-
- if ( VCD_sector_read( p_vcd, p_buffer ) == -1 )
+ if( p_vcd->i_sector >= p_vcd->p_sectors[p_vcd->i_track + 1] )
{
- return -1;
+ b_eot = 1;
+ break;
}
-
- while (i_index < BUFFER_SIZE - 6)
+
+ i_index = 0;
+
+ while( i_index < BUFFER_SIZE-6 && i_packet < VCD_DATA_ONCE )
{
-
- if( (U32_AT(p_buffer + i_index) & 0xFFFFFF00) != 0x100L )
+ i_header = U32_AT(p_buffer + i_index);
+
+ /* It is common for MPEG-1 streams to pad with zeros
+ * (although it is forbidden by the recommendation), so
+ * don't bother everybody in this case. */
+ while( !i_header && (++i_index < BUFFER_SIZE - 4) )
{
- /* This is not the startcode of a packet. Read the stream
- * until we find one. */
-
- if( !U32_AT( p_buffer + i_index ) )
- {
- /* It is common for MPEG-1 streams to pad with zeros
- * (although it is forbidden by the recommendation), so
- * don't bother everybody in this case. */
- intf_WarnMsg( 3, "Garbage at input" );
- }
-
- while( ( (U32_AT(p_buffer + i_index) & 0xFFFFFF00) != 0x100L )
- && ( i_index < BUFFER_SIZE - 4 ) )
- {
- i_index ++;
- }
-
- if ( i_index == BUFFER_SIZE - 4 )
- {
- b_no_packet = 1;
- }
- /* Packet found. */
+ i_header = U32_AT(p_buffer + i_index);
+ }
+
+ if( !i_header )
+ {
+ intf_WarnMsg( 12, "vcd warning: zero-padded packet" );
+ break;
}
-
- if (b_no_packet)
+
+ /* Read the stream until we find a startcode. */
+ while( (i_header & 0xFFFFFF00) != 0x100L
+ && (++i_index < BUFFER_SIZE - 4) )
+ {
+ i_header = U32_AT(p_buffer + i_index);
+ }
+
+ if( (i_header & 0xFFFFFF00) != 0x100L )
{
- b_no_packet = 0;
- intf_WarnMsg(3, "No packet found on sector %d\n",
- p_vcd->current_sector -1 );
+ intf_WarnMsg( 3, "vcd warning: no packet at sector %d",
+ p_vcd->i_sector - 1 );
break; /* go to the next sector */
}
-
-#ifdef DEBUG
- intf_DbgMsg("packet start code : %X\n",
- U32_AT(p_buffer + i_index));
-#endif
- /* 0x1B9 == SYSTEM_END_CODE, it is only 4 bytes long. */
- if( U32_AT(p_buffer + i_index) != 0x1B9 )
+
+ intf_DbgMsg( "packet start code : %X", i_header );
+
+ switch( i_header )
{
- /* The packet is at least 6 bytes long. */
-
- if( U32_AT(p_buffer + i_index) != 0x1BA )
- {
- /* That's the case for all packets, except pack header. */
- i_packet_size = U16_AT((p_buffer + ( i_index + 4 )));
- }
- else
- {
- /* Pack header. */
+ /* 0x1b9 == SYSTEM_END_CODE, it is only 4 bytes long. */
+ case 0x1b9:
+ i_packet_size = -2;
+ break;
+
+ /* Pack header */
+ case 0x1ba:
if( ( *( p_buffer + ( i_index + 4 ) ) & 0xC0) == 0x40 )
{
/* MPEG-2 */
}
else
{
- intf_ErrMsg( "Unable to determine stream type" );
+ intf_ErrMsg( "vcd error: unable to determine "
+ "stream type" );
return( -1 );
}
- }
- }
- else
- {
- /* System End Code */
- i_packet_size = -2;
+ break;
+
+ /* The packet is at least 6 bytes long. */
+ default:
+ /* That's the case for all packets, except pack header. */
+ i_packet_size = U16_AT((p_buffer + ( i_index + 4 )));
+ break;
}
-#ifdef DEBUG
- intf_DbgMsg("i_index : %d\n", i_index);
- intf_DbgMsg("i_packet_size : %d\n", i_packet_size);
-#endif
+
+ intf_DbgMsg( "i_index : %d", i_index );
+ intf_DbgMsg( "i_packet_size : %d", i_packet_size );
+
if ( i_index + i_packet_size > BUFFER_SIZE )
{
- intf_ErrMsg( "Too long packet");
+ intf_ErrMsg( "vcd error: packet too long (%i)",
+ i_index + i_packet_size );
continue;
}
-
+
/* 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" );
+ intf_ErrMsg( "vcd error: out of memory" );
return( -1 );
}
-
+
if( U32_AT(p_buffer) != 0x1B9 )
{
- p_main->fast_memcpy( p_data->p_buffer, p_buffer + i_index,
- 6 + i_packet_size );
+ p_main->fast_memcpy( p_data->p_demux_start, p_buffer + i_index,
+ 6 + i_packet_size );
i_index += ( 6 + i_packet_size );
-
}
else
{
/* Copy the small header. */
- memcpy( p_data->p_buffer, p_buffer + i_index, 4 );
+ memcpy( p_data->p_demux_start, p_buffer + i_index, 4 );
i_index += 4;
}
-
+
/* Give the packet to the other input stages. */
- pp_packets[i_packet] = p_data;
- i_packet ++;
+ *pp_data = p_data;
+ pp_data = &p_data->p_next;
+
+ i_packet++;
}
-
- if ( p_vcd->b_end_of_track )
- break;
}
- pp_packets[i_packet] = NULL;
-
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.p_selected_area->i_tell =
- p_vcd->current_sector -
- p_input->stream.p_selected_area->i_start ;
-
+ (off_t)p_vcd->i_sector * (off_t)VCD_DATA_SIZE
+ - p_input->stream.p_selected_area->i_start;
+
/* no chapter for the moment*/
- /*if( b_eoc )
+#if 0
+ if( b_eoc )
{
- * We modify i_part only at end of chapter not to erase
- * some modification from the interface *
+ /* We modify i_part only at end of chapter not to erase
+ * some modification from the interface */
p_input->stream.p_selected_area->i_part = p_vcd->i_chapter;
- }*/
-
-
- b_eof = p_vcd->b_end_of_track
- && ( ( p_vcd->current_track ) >= p_vcd->nb_tracks - 1);
-
- if( b_eof )
- {
- vlc_mutex_unlock( &p_input->stream.stream_lock );
- return 1;
}
+#endif
- if( p_vcd->b_end_of_track )
+ if( b_eot )
{
+ input_area_t *p_area;
+
+ /* EOF ? */
+ if( p_vcd->i_track >= p_vcd->nb_tracks - 1 )
+ {
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ return 0;
+ }
+
intf_WarnMsg( 4, "vcd info: new title" );
- p_vcd->b_end_of_track = 0;
- VCDSetArea( p_input, p_input->stream.pp_areas[
- p_input->stream.p_selected_area->i_id + 1] );
- vlc_mutex_unlock( &p_input->stream.stream_lock );
- return 0;
+
+ p_area = p_input->stream.pp_areas[
+ p_input->stream.p_selected_area->i_id + 1 ];
+
+ p_area->i_part = 1;
+ VCDSetArea( p_input, p_area );
}
-
- vlc_mutex_unlock( &p_input->stream.stream_lock );
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
- return 0;
+ return( i_packet + 1 );
}
/*****************************************************************************
return( -1 );
}
-
/****************************************************************************
* VCDSeek
****************************************************************************/
p_vcd = (thread_vcd_data_t *) p_input->p_plugin_data;
- p_vcd->current_sector = p_vcd->tracks_sector[p_vcd->current_track]
- + i_off;
+ p_vcd->i_sector = p_vcd->p_sectors[p_vcd->i_track]
+ + i_off / (off_t)VCD_DATA_SIZE;
- p_input->stream.p_selected_area->i_tell = p_vcd->current_sector
- - p_input->stream.p_selected_area->i_start;
-
- return ;
+ p_input->stream.p_selected_area->i_tell =
+ (off_t)p_vcd->i_sector * (off_t)VCD_DATA_SIZE
+ - p_input->stream.p_selected_area->i_start;
}
-
-
-/*
- * 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 );
-}
* input_vcd.h: thread structure of the VCD plugin
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: input_vcd.h,v 1.1 2001/10/23 03:17:49 jobi Exp $
+ * $Id: input_vcd.h,v 1.1.2.1 2001/12/31 01:21:45 massiot Exp $
*
* Author: Johan Bilien <jobi@via.ecp.fr>
*
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-
-
-
-
/*****************************************************************************
* thread_vcd_data_t: VCD information
*****************************************************************************/
typedef struct thread_vcd_data_s
{
- int vcdhandle; // File descriptor
- int nb_tracks; // Nb of tracks (titles)
- int current_track; // Current track
- int current_sector; // Current Sector
- int * tracks_sector; // index of tracks
- boolean_t b_end_of_track; // if the end of track is
- // reached
-} thread_vcd_data_t ;
+ int i_handle; /* File descriptor */
+ int nb_tracks; /* Nb of tracks (titles) */
+ int i_track; /* Current track */
+ int i_sector; /* Current Sector */
+ int * p_sectors; /* Track sectors */
+ boolean_t b_end_of_track; /* If the end of track was reached */
+} thread_vcd_data_t;
#include "modules.h"
#include "modules_export.h"
-
-#include "input_vcd.h"
#include "linux_cdrom_tools.h"
+
/*****************************************************************************
-* read_toc : Reads the Table of Content of a CD-ROM and fills p_vcd with *
-* the read information *
-*****************************************************************************/
-int read_toc ( thread_vcd_data_t * p_vcd )
-{
- int i ;
- struct cdrom_tochdr tochdr ;
- struct cdrom_tocentry tocent ;
- int fd = p_vcd->vcdhandle ;
-
- /* first we read the TOC header */
- if (ioctl(fd, CDROMREADTOCHDR, &tochdr) == -1)
+ * ioctl_ReadTocHeader: Read the TOC header and return the track number.
+ *****************************************************************************/
+int ioctl_GetTrackCount( int i_fd )
+{
+ struct cdrom_tochdr tochdr;
+
+ /* First we read the TOC header */
+ if( ioctl( i_fd, CDROMREADTOCHDR, &tochdr ) == -1 )
{
- intf_ErrMsg("problem occured when reading CD's TOCHDR\n") ;
- return -1 ;
+ intf_ErrMsg( "vcd error: could not read TOCHDR" );
+ return -1;
}
-
- p_vcd->nb_tracks = tochdr.cdth_trk1;
- /* nb_tracks + 1 because we put the lead_out tracks for computing last
- track's size */
- p_vcd->tracks_sector = malloc( ( p_vcd->nb_tracks + 1 )
- * sizeof( int ) );
- if ( p_vcd->tracks_sector == NULL )
+
+ return tochdr.cdth_trk1 - tochdr.cdth_trk0 + 1;
+}
+
+/*****************************************************************************
+ * ioctl_GetSectors: Read the Table of Contents and fill p_vcd.
+ *****************************************************************************/
+int * ioctl_GetSectors( int i_fd )
+{
+ int i, i_tracks;
+ int *p_sectors;
+ struct cdrom_tochdr tochdr;
+ struct cdrom_tocentry tocent;
+
+ /* First we read the TOC header */
+ if( ioctl( i_fd, CDROMREADTOCHDR, &tochdr ) == -1 )
{
- intf_ErrMsg("could not malloc tracks_sector");
- return -1;
+ intf_ErrMsg( "vcd error: could not read TOCHDR" );
+ return NULL;
}
- /* then for each track we read its TOC entry */
+ i_tracks = tochdr.cdth_trk1 - tochdr.cdth_trk0 + 1;
- for( i=tochdr.cdth_trk0 ; i <= tochdr.cdth_trk1 ; i++ )
+ p_sectors = malloc( (i_tracks + 1) * sizeof(int) );
+ if( p_sectors == NULL )
+ {
+ intf_ErrMsg( "vcd error: could not allocate p_sectors" );
+ return NULL;
+ }
+
+ /* Fill the p_sectors structure with the track/sector matches */
+ for( i = 0 ; i <= i_tracks ; i++ )
{
- tocent.cdte_track = i;
tocent.cdte_format = CDROM_LBA;
- if (ioctl( fd, CDROMREADTOCENTRY, &tocent) == -1 )
+ tocent.cdte_track =
+ ( i == i_tracks ) ? CDROM_LEADOUT : tochdr.cdth_trk0 + i;
+
+ if( ioctl( i_fd, CDROMREADTOCENTRY, &tocent ) == -1 )
{
- intf_ErrMsg( "problem occured when reading CD's TOCENTRY\n" );
- free ( p_vcd->tracks_sector );
- return -1;
+ intf_ErrMsg( "vcd error: could not read TOCENTRY" );
+ free( p_sectors );
+ return NULL;
}
-
- p_vcd->tracks_sector[i-1] = tocent.cdte_addr.lba ;
+ p_sectors[ i ] = tocent.cdte_addr.lba;
}
-
- /* finally we read the lead-out track toc entry */
-
- tocent.cdte_track = CDROM_LEADOUT ;
- tocent.cdte_format = CDROM_LBA ;
- if (ioctl(fd, CDROMREADTOCENTRY, &tocent) == -1)
- {
- intf_ErrMsg("problem occured when readind CD's
- lead-out track TOC entry") ;
- free (p_vcd->tracks_sector) ;
- return -1 ;
- }
-
- p_vcd->tracks_sector[p_vcd->nb_tracks] = tocent.cdte_addr.lba ;
-
- return 1 ;
+ return p_sectors;
}
-
+
/****************************************************************************
- * VCD_sector_read : Function that reads a sector (2324 bytes) from VCD
+ * ioctl_ReadSector: Read a sector (2324 bytes)
****************************************************************************/
-int VCD_sector_read ( struct thread_vcd_data_s * p_vcd, byte_t * p_buffer )
+int ioctl_ReadSector( int i_fd, int i_sector, byte_t * p_buffer )
{
- byte_t p_read_block[VCD_SECTOR_SIZE] ;
- struct cdrom_msf0 msf_cursor ;
-
- msf_cursor = lba2msf( p_vcd->current_sector ) ;
-
-#ifdef DEBUG
- intf_DbgMsg("Playing frame %d:%d-%d\n", msf_cursor.minute,
- msf_cursor.second, msf_cursor.frame) ;
-#endif
-
- memcpy(p_read_block, &msf_cursor, sizeof(struct cdrom_msf0)) ;
-
- if (ioctl(p_vcd->vcdhandle, CDROMREADRAW, p_read_block) == -1)
- {
- intf_ErrMsg("problem occured when reading CD") ;
- free (p_read_block) ;
- return -1 ;
- }
-
- /* we don't want to keep the header of the read sector */
- memcpy( p_buffer, &p_read_block[VCD_DATA_START],
- VCD_DATA_SIZE );
-
-
- p_vcd->current_sector ++;
-
- if ( p_vcd->current_sector ==
- p_vcd->tracks_sector[p_vcd->current_track + 1] )
+ byte_t p_block[ VCD_SECTOR_SIZE ];
+ int i_dummy = i_sector + 2 * CD_FRAMES;
+
+#define p_msf ((struct cdrom_msf0 *)p_block)
+ p_msf->minute = i_dummy / (CD_FRAMES * CD_SECS);
+ p_msf->second = ( i_dummy % (CD_FRAMES * CD_SECS) ) / CD_FRAMES;
+ p_msf->frame = ( i_dummy % (CD_FRAMES * CD_SECS) ) % CD_FRAMES;
+
+ intf_DbgMsg( "vcd debug: playing frame %d:%d-%d",
+ p_msf->minute, p_msf->second, p_msf->frame);
+#undef p_msf
+
+ if( ioctl(i_fd, CDROMREADRAW, p_block) == -1 )
{
- p_vcd->b_end_of_track = 1;
+ intf_ErrMsg( "vcd error: could not read block %i from disc",
+ i_sector );
+ return -1;
}
-
- return 1;
-}
+ /* We don't want to keep the header of the read sector */
+ p_main->fast_memcpy( p_buffer, p_block + VCD_DATA_START, VCD_DATA_SIZE );
-/*****************************************************************************
- * lba2msf : converts a logical block address into a minute/second/frame
- * address.
- *****************************************************************************/
-
-struct cdrom_msf0 lba2msf( int lba)
-{
- struct cdrom_msf0 msf_result ;
-
- /* we add 2*CD_FRAMES since the 2 first seconds are not played*/
-
- msf_result.minute = (lba+2*CD_FRAMES) / ( CD_FRAMES * CD_SECS ) ;
- msf_result.second = ( (lba+2*CD_FRAMES) % ( CD_FRAMES * CD_SECS ) )
- / CD_FRAMES ;
- msf_result.frame = ( (lba+2*CD_FRAMES) % ( CD_FRAMES * CD_SECS ) )
- % CD_FRAMES ;
- return msf_result ;
+ return 0;
}
/******************************************************************************
* Prototypes *
******************************************************************************/
-
-int read_toc ( struct thread_vcd_data_s *);
-int VCD_sector_read ( struct thread_vcd_data_s *, byte_t *) ;
-struct cdrom_msf0 lba2msf ( int ) ;
+int ioctl_GetTrackCount ( int );
+int * ioctl_GetSectors ( int );
+int ioctl_ReadSector ( int, int, byte_t * );
* decoders.
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: input.c,v 1.163.2.2 2001/12/12 02:13:20 sam Exp $
+ * $Id: input.c,v 1.163.2.3 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
return( NULL );
}
- /* Packets read once */
- p_input->i_read_once = INPUT_READ_ONCE;
-
/* Initialize thread properties */
p_input->b_die = 0;
p_input->b_error = 0;
/* Request thread destruction */
p_input->b_die = 1;
- /* Make the thread exit of an eventual vlc_cond_wait() */
+ /* Make the thread exit from an eventual vlc_cond_wait() */
vlc_mutex_lock( &p_input->stream.stream_lock );
vlc_cond_signal( &p_input->stream.stream_wait );
vlc_mutex_unlock( &p_input->stream.stream_lock );
*****************************************************************************/
static void RunThread( input_thread_t *p_input )
{
- int i_error, i;
- data_packet_t ** pp_packets;
-
if( InitThread( p_input ) )
{
/* If we failed, wait before we are killed, and exit */
return;
}
- /* initialization is completed */
+ /* initialization is complete */
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.b_changed = 1;
vlc_mutex_unlock( &p_input->stream.stream_lock );
- pp_packets = (data_packet_t **) malloc( p_input->i_read_once *
- sizeof( data_packet_t * ) );
- if( pp_packets == NULL )
- {
- intf_ErrMsg( "input error: out of memory" );
- free( pp_packets );
- p_input->b_error = 1;
- }
-
while( !p_input->b_die && !p_input->b_error && !p_input->b_eof )
{
+ data_packet_t * p_data;
+ int i_count, i;
+
p_input->c_loops++;
vlc_mutex_lock( &p_input->stream.stream_lock );
vlc_mutex_unlock( &p_input->stream.stream_lock );
- i_error = p_input->pf_read( p_input, pp_packets );
+ i_count = p_input->pf_read( p_input, &p_data );
/* Demultiplex read packets. */
- for( i = 0; i < p_input->i_read_once && pp_packets[i] != NULL; i++ )
+ while( p_data != NULL )
{
+ data_packet_t * p_next = p_data->p_next;
+ p_data->p_next = NULL;
+
p_input->stream.c_packets_read++;
- p_input->pf_demux( p_input, pp_packets[i] );
+ p_input->pf_demux( p_input, p_data );
+
+ p_data = p_next;
}
- if( i_error )
+ if( i_count == 0 && p_input->stream.b_seekable )
{
- if( i_error == 1 )
- {
- /* End of file - we do not set b_die because only the
- * interface is allowed to do so. */
- intf_WarnMsg( 3, "input: EOF reached" );
- p_input->b_eof = 1;
- }
- else
- {
- p_input->b_error = 1;
- }
+ /* End of file - we do not set b_die because only the
+ * interface is allowed to do so. */
+ intf_WarnMsg( 3, "input: EOF reached" );
+ p_input->b_eof = 1;
+ }
+ else if( i_count < 0 )
+ {
+ p_input->b_error = 1;
}
}
- free( pp_packets );
-
if( p_input->b_error || p_input->b_eof )
{
ErrorThread( p_input );
*****************************************************************************/
static int InitThread( input_thread_t * p_input )
{
-
/* Initialize statistics */
p_input->c_loops = 0;
p_input->stream.c_packets_read = 0;
* input_dec.c: Functions for the management of decoders
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: input_dec.c,v 1.19 2001/12/03 16:18:37 sam Exp $
+ * $Id: input_dec.c,v 1.19.2.1 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
{
vlc_mutex_lock( &p_decoder_fifo->data_lock );
- if( !DECODER_FIFO_ISFULL( *p_decoder_fifo ) )
- {
- p_decoder_fifo->buffer[p_decoder_fifo->i_end] = p_pes;
- DECODER_FIFO_INCEND( *p_decoder_fifo );
+ p_pes->p_next = NULL;
+ *p_decoder_fifo->pp_last = p_pes;
+ p_decoder_fifo->pp_last = &p_pes->p_next;
+ p_decoder_fifo->i_depth++;
- /* Warn the decoder that it's got work to do. */
- vlc_cond_signal( &p_decoder_fifo->data_wait );
- }
- else
- {
- /* The FIFO is full !!! This should not happen. */
- p_decoder_fifo->pf_delete_pes( p_decoder_fifo->p_packets_mgt,
- p_pes );
- intf_ErrMsg( "PES trashed - decoder fifo full !" );
- }
+ /* Warn the decoder that it's got work to do. */
+ vlc_cond_signal( &p_decoder_fifo->data_wait );
vlc_mutex_unlock( &p_decoder_fifo->data_lock );
}
p_config->i_type = p_es->i_type;
p_config->p_stream_ctrl = &p_input->stream.control;
- p_config->p_decoder_fifo->i_start = p_config->p_decoder_fifo->i_end = 0;
+ p_config->p_decoder_fifo->p_first = NULL;
+ p_config->p_decoder_fifo->pp_last = &p_config->p_decoder_fifo->p_first;
+ p_config->p_decoder_fifo->i_depth = 0;
p_config->p_decoder_fifo->b_die = p_config->p_decoder_fifo->b_error = 0;
p_config->p_decoder_fifo->p_packets_mgt = p_input->p_method_data;
p_config->p_decoder_fifo->pf_delete_pes = p_input->pf_delete_pes;
*****************************************************************************/
static void DeleteDecoderConfig( decoder_config_t * p_config )
{
+ intf_StatMsg( "input stats: killing decoder for 0x%x, type 0x%x, %d PES in FIFO",
+ p_config->i_id, p_config->i_type,
+ p_config->p_decoder_fifo->i_depth );
/* Free all packets still in the decoder fifo. */
- while( !DECODER_FIFO_ISEMPTY( *p_config->p_decoder_fifo ) )
- {
- p_config->p_decoder_fifo->pf_delete_pes(
- p_config->p_decoder_fifo->p_packets_mgt,
- DECODER_FIFO_START( *p_config->p_decoder_fifo ) );
- DECODER_FIFO_INCSTART( *p_config->p_decoder_fifo );
- }
+ p_config->p_decoder_fifo->pf_delete_pes(
+ p_config->p_decoder_fifo->p_packets_mgt,
+ p_config->p_decoder_fifo->p_first );
/* Destroy the lock and cond */
vlc_cond_destroy( &p_config->p_decoder_fifo->data_wait );
* input_ext-dec.c: services to the decoders
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: input_ext-dec.c,v 1.21.2.1 2001/12/30 06:06:00 sam Exp $
+ * $Id: input_ext-dec.c,v 1.21.2.2 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
/* Get the first data packet. */
vlc_mutex_lock( &p_fifo->data_lock );
- while ( DECODER_FIFO_ISEMPTY( *p_fifo ) )
+ while ( p_fifo->p_first == NULL )
{
if ( p_fifo->b_die )
{
}
vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
}
- p_bit_stream->p_data = DECODER_FIFO_START( *p_fifo )->p_first;
+ p_bit_stream->p_data = p_fifo->p_first->p_first;
p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
p_bit_stream->fifo.buffer = 0;
while( !p_fifo->b_die )
{
/* Trash all received PES packets */
- while( !DECODER_FIFO_ISEMPTY(*p_fifo) )
- {
- p_fifo->pf_delete_pes( p_fifo->p_packets_mgt,
- DECODER_FIFO_START(*p_fifo) );
- DECODER_FIFO_INCSTART( *p_fifo );
- }
+ p_fifo->pf_delete_pes( p_fifo->p_packets_mgt, p_fifo->p_first );
/* Waiting for the input thread to put new PES packets in the fifo */
vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
* time to jump to the next PES packet */
if( p_bit_stream->p_data->p_next == NULL )
{
- /* We are going to read/write the start and end indexes of the
- * decoder fifo and to use the fifo's conditional variable,
- * that's why we need to take the lock before. */
+ pes_packet_t * p_next;
+
vlc_mutex_lock( &p_fifo->data_lock );
/* Free the previous PES packet. */
+ p_next = p_fifo->p_first->p_next;
+ p_fifo->p_first->p_next = NULL;
p_fifo->pf_delete_pes( p_fifo->p_packets_mgt,
- DECODER_FIFO_START( *p_fifo ) );
- DECODER_FIFO_INCSTART( *p_fifo );
+ p_fifo->p_first );
+ p_fifo->p_first = p_next;
+ p_fifo->i_depth--;
- if( DECODER_FIFO_ISEMPTY( *p_fifo ) )
+ if( p_fifo->p_first == NULL )
{
+ /* No PES in the FIFO. p_last is no longer valid. */
+ p_fifo->pp_last = &p_fifo->p_first;
+
/* Wait for the input to tell us when we receive a packet. */
vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
}
/* The next byte could be found in the next PES packet */
- p_bit_stream->p_data = DECODER_FIFO_START( *p_fifo )->p_first;
+ p_bit_stream->p_data = p_fifo->p_first->p_first;
vlc_mutex_unlock( &p_fifo->data_lock );
+++ /dev/null
-/*****************************************************************************
- * dvd_netlist.c: netlist management v2
- *****************************************************************************
- * There is only one major change from input_netlist.c (1) : data is now a
- * pointer to an offset in iovec ; and iovec has a reference counter. It
- * will only be given back to netlist when refcount is zero.
- *****************************************************************************
- * Copyright (C) 1998-2001 VideoLAN
- * $Id: input_netlist.c,v 1.47 2001/12/03 17:34:08 stef Exp $
- *
- * Authors: Henri Fallon <henri@videolan.org>
- * Stéphane Borel <stef@videolan.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#include "defs.h"
-
-#include <stdlib.h>
-#include <string.h> /* memcpy(), memset() */
-#include <sys/types.h>
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#if defined( WIN32 )
-# include <io.h> /* read() */
-#else
-# include <sys/uio.h> /* struct iovec */
-#endif
-
-#include "config.h"
-#include "common.h"
-#include "intf_msg.h" /* intf_*Msg */
-#include "threads.h" /* mutex */
-#include "mtime.h"
-
-#if defined( WIN32 )
-# include "input_iovec.h"
-#endif
-
-#include "stream_control.h"
-#include "input_ext-intf.h"
-#include "input_ext-dec.h"
-#include "input_ext-plugins.h"
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-
-/*****************************************************************************
- * input_NetlistInit: allocates netlist buffers and init indexes
- * ---
- * Changes from input_NetList: we have to give the length of the buffer which
- * is different from i_nb_data now, since we may have several data pointers
- * in one iovec. Thus we can only delete an iovec when its refcount is 0.
- * We only received a buffer with a GetIovec whereas NewPacket gives a pointer.
- *****************************************************************************/
-int input_NetlistInit( input_thread_t * p_input,
- int i_nb_iovec, int i_nb_data, int i_nb_pes,
- size_t i_buffer_size, int i_read_once )
-{
- unsigned int i_loop;
- netlist_t * p_netlist;
-
- /* First we allocate and initialise our netlist struct */
- p_input->p_method_data = malloc(sizeof(netlist_t));
- if ( p_input->p_method_data == NULL )
- {
- intf_ErrMsg("Unable to malloc the netlist struct");
- return (-1);
- }
-
- p_netlist = (netlist_t *) p_input->p_method_data;
-
- /* Nb of packets read once by input */
- p_netlist->i_read_once = i_read_once;
-
- /* In order to optimize netlist, we are taking i_nb_data a 2^i
- * so that modulo is an "&".
- * This is not changing i_nb data outside this function except in
- * the netlist_t struct */
- /* As i_loop is unsigned int, and i_ns_data int, this shouldn't be a
- * problem */
- for( i_loop = 1; i_loop < i_nb_data; i_loop *= 2 )
- {
- ;
- }
-
- intf_DbgMsg( "Netlist : Required %i byte, got %u",i_nb_data,i_loop );
- i_nb_data = i_loop;
-
- /* Same thing for i_nb_pes */
- for( i_loop = 1; i_loop < i_nb_pes; i_loop *= 2 )
- {
- ;
- }
-
- intf_DbgMsg( "Netlist : Required %i byte, got %u",i_nb_pes,i_loop );
- i_nb_pes = i_loop;
-
- /* Same thing for i_nb_iovec */
- for( i_loop = 1; i_loop < i_nb_iovec; i_loop *= 2 )
- {
- ;
- }
-
- intf_DbgMsg( "Netlist : Required %i byte, got %u",i_nb_iovec,i_loop );
- i_nb_iovec = i_loop;
-
- /* allocate the buffers */
- p_netlist->p_buffers = malloc( i_nb_iovec *i_buffer_size );
- if ( p_netlist->p_buffers == NULL )
- {
- intf_ErrMsg ("Unable to malloc in netlist initialization (1)");
- free( p_netlist );
- return -1;
- }
-
- /* table of pointers to data packets */
- p_netlist->p_data = malloc( i_nb_data *sizeof(data_packet_t) );
- if ( p_netlist->p_data == NULL )
- {
- intf_ErrMsg ("Unable to malloc in netlist initialization (2)");
- free( p_netlist->p_buffers );
- free( p_netlist );
- return -1;
- }
-
- /* table of pointer to PES packets */
- p_netlist->p_pes = malloc( i_nb_pes *sizeof(pes_packet_t) );
- if ( p_netlist->p_pes == NULL )
- {
- intf_ErrMsg ("Unable to malloc in netlist initialization (3)");
- free( p_netlist->p_buffers );
- free( p_netlist->p_data );
- free( p_netlist );
- return -1;
- }
-
- /* allocate the FIFOs : tables of free pointers */
- p_netlist->pp_free_data =
- malloc( i_nb_data *sizeof(data_packet_t *) );
- if ( p_netlist->pp_free_data == NULL )
- {
- intf_ErrMsg ("Unable to malloc in netlist initialization (4)");
- free( p_netlist->p_buffers );
- free( p_netlist->p_data );
- free( p_netlist->p_pes );
- free( p_netlist );
- return -1;
- }
- p_netlist->pp_free_pes =
- malloc( i_nb_pes *sizeof(pes_packet_t *) );
- if ( p_netlist->pp_free_pes == NULL )
- {
- intf_ErrMsg ("Unable to malloc in netlist initialization (5)");
- free( p_netlist->p_buffers );
- free( p_netlist->p_data );
- free( p_netlist->p_pes );
- free( p_netlist->pp_free_data );
- free( p_netlist );
- return -1;
- }
-
- p_netlist->p_free_iovec =
- malloc( (i_nb_iovec + p_netlist->i_read_once) * sizeof(struct iovec) );
- if ( p_netlist->p_free_iovec == NULL )
- {
- intf_ErrMsg ("Unable to malloc in DVD netlist initialization (6)");
- free( p_netlist->p_buffers );
- free( p_netlist->p_data );
- free( p_netlist->p_pes );
- free( p_netlist->pp_free_data );
- free( p_netlist->pp_free_pes );
- free( p_netlist );
- return -1;
- }
-
- /* table for reference counter of iovecs */
- p_netlist->pi_refcount = malloc( i_nb_iovec *sizeof(int) );
- if ( p_netlist->pi_refcount == NULL )
- {
- intf_ErrMsg ("Unable to malloc in DVD netlist initialization (7)");
- free( p_netlist->p_buffers );
- free( p_netlist->p_data );
- free( p_netlist->p_pes );
- free( p_netlist->pp_free_data );
- free( p_netlist->pp_free_pes );
- free( p_netlist->p_free_iovec );
- free( p_netlist );
- return -1;
- }
-
- /* Fill the data FIFO */
- for ( i_loop = 0; i_loop < i_nb_data; i_loop++ )
- {
- p_netlist->pp_free_data[i_loop] =
- p_netlist->p_data + i_loop;
-
- /* by default, one data packet for one buffer */
- if( i_nb_data == i_nb_iovec )
- {
- p_netlist->pp_free_data[i_loop]->p_buffer =
- p_netlist->p_buffers + i_loop * i_buffer_size;
-
- p_netlist->pp_free_data[i_loop]->p_payload_start =
- p_netlist->pp_free_data[i_loop]->p_buffer;
-
- p_netlist->pp_free_data[i_loop]->p_payload_end =
- p_netlist->pp_free_data[i_loop]->p_buffer + i_buffer_size;
- }
- }
-
- /* Fill the PES FIFO */
- for ( i_loop = 0; i_loop < i_nb_pes ; i_loop++ )
- {
- p_netlist->pp_free_pes[i_loop] =
- p_netlist->p_pes + i_loop;
- }
-
- /* Deal with the iovec */
- for ( i_loop = 0; i_loop < i_nb_iovec; i_loop++ )
- {
- p_netlist->p_free_iovec[i_loop].iov_base =
- p_netlist->p_buffers + i_loop * i_buffer_size;
-
- p_netlist->p_free_iovec[i_loop].iov_len = i_buffer_size;
- }
-
- /* initialize reference counters */
- memset( p_netlist->pi_refcount, 0, i_nb_iovec *sizeof(int) );
-
- /* vlc_mutex_init */
- vlc_mutex_init (&p_netlist->lock);
-
- /* initialize indexes */
- p_netlist->i_iovec_start = 0;
- p_netlist->i_iovec_end = i_nb_iovec - 1;
-
- p_netlist->i_data_start = 0;
- p_netlist->i_data_end = i_nb_data - 1;
-
- p_netlist->i_pes_start = 0;
- p_netlist->i_pes_end = i_nb_pes - 1;
-
- /* we give (nb - 1) to use & instead of %
- * if you really need nb you have to add 1 */
- p_netlist->i_nb_iovec = i_nb_iovec - 1;
- p_netlist->i_nb_data = i_nb_data - 1;
- p_netlist->i_nb_pes = i_nb_pes - 1;
- p_netlist->i_buffer_size = i_buffer_size;
-
- return 0; /* Everything went all right */
-}
-
-/*****************************************************************************
- * input_NetlistGetiovec: returns an iovec pointer for a readv() operation
- *****************************************************************************
- * We return an iovec vector, so that readv can read many packets at a time.
- * pp_data will be set to direct to the fifo pointer in DVDMviovec, which
- * will allow us to get the corresponding data_packet.
- *****************************************************************************/
-struct iovec * input_NetlistGetiovec( void * p_method_data )
-{
- netlist_t * p_netlist;
-
- /* cast */
- p_netlist = (netlist_t *)p_method_data;
-
- /* check that we have enough free iovec */
- if( (
- (p_netlist->i_iovec_end - p_netlist->i_iovec_start)
- & p_netlist->i_nb_iovec ) < p_netlist->i_read_once )
- {
- intf_WarnMsg( 4, "input info: waiting for free iovec" );
- msleep( INPUT_IDLE_SLEEP );
-
- while( (
- (p_netlist->i_iovec_end - p_netlist->i_iovec_start)
- & p_netlist->i_nb_iovec ) < p_netlist->i_read_once )
- {
- msleep( INPUT_IDLE_SLEEP );
- }
-
- intf_WarnMsg( 4, "input info: found free iovec" );
- }
-
- if( (
- (p_netlist->i_data_end - p_netlist->i_data_start)
- & p_netlist->i_nb_data ) < p_netlist->i_read_once )
- {
- intf_WarnMsg( 4, "input info: waiting for free data packet" );
- msleep( INPUT_IDLE_SLEEP );
-
- while( (
- (p_netlist->i_data_end - p_netlist->i_data_start)
- & p_netlist->i_nb_data ) < p_netlist->i_read_once )
- {
- msleep( INPUT_IDLE_SLEEP );
- }
-
- intf_WarnMsg( 4, "input info: found free data packet" );
- }
-
- /* readv only takes contiguous buffers
- * so, as a solution, we chose to have a FIFO a bit longer
- * than i_nb_data, and copy the begining of the FIFO to its end
- * if the readv needs to go after the end */
- if( p_netlist->i_nb_iovec - p_netlist->i_iovec_start + 1 <
- p_netlist->i_read_once )
- {
- memcpy( &p_netlist->p_free_iovec[p_netlist->i_nb_iovec + 1],
- p_netlist->p_free_iovec,
- (p_netlist->i_read_once -
- (p_netlist->i_nb_iovec + 1 - p_netlist->i_iovec_start))
- * sizeof(struct iovec)
- );
-
- }
-
- return p_netlist->p_free_iovec + p_netlist->i_iovec_start;
-
-}
-
-/*****************************************************************************
- * input_NetlistMviovec: move the iovec pointer by one after a readv()
- * operation and gives a data_packet corresponding to iovec in p_data
- *****************************************************************************/
-void input_NetlistMviovec( void * p_method_data, int i_nb_iovec,
- struct data_packet_s ** pp_data )
-{
- netlist_t * p_netlist;
- unsigned int i_loop = 0;
-
- /* cast */
- p_netlist = (netlist_t *)p_method_data;
-
- /* lock */
- vlc_mutex_lock( &p_netlist->lock );
-
- /* Fills a table of pointers to packets associated with the io_vec's */
- while( i_loop < i_nb_iovec )
- {
- pp_data[i_loop] = p_netlist->pp_free_data[p_netlist->i_data_start];
-
- pp_data[i_loop]->p_buffer =
- p_netlist->p_free_iovec[p_netlist->i_iovec_start].iov_base;
-
- pp_data[i_loop]->p_payload_start = pp_data[i_loop]->p_buffer;
-
- pp_data[i_loop]->p_payload_end =
- pp_data[i_loop]->p_buffer + p_netlist->i_buffer_size;
-
- pp_data[i_loop]->p_next = NULL;
- pp_data[i_loop]->b_discard_payload = 0;
-
- pp_data[i_loop]->pi_refcount = p_netlist->pi_refcount +
- p_netlist->i_iovec_start;
- if( (*pp_data[i_loop]->pi_refcount) != 0)
- {
- intf_ErrMsg( "netlist error: refcount should be 0 (%d)",
- (*pp_data[i_loop]->pi_refcount) );
- }
- (*pp_data[i_loop]->pi_refcount) = 1;
-
- p_netlist->i_iovec_start ++;
- p_netlist->i_iovec_start &= p_netlist->i_nb_iovec;
-
- p_netlist->i_data_start ++;
- p_netlist->i_data_start &= p_netlist->i_nb_data;
-
- i_loop ++;
- }
-
- /* unlock */
- vlc_mutex_unlock( &p_netlist->lock );
-
-}
-
-/*****************************************************************************
- * input_NetlistNewPtr: returns a free data_packet_t
- * Gives a pointer ; its fields need to be initialized
- *****************************************************************************/
-struct data_packet_s * input_NetlistNewPtr( void * p_method_data )
-{
- netlist_t * p_netlist;
- struct data_packet_s * p_return;
-
- /* cast */
- p_netlist = (netlist_t *)p_method_data;
-
- /* lock */
- vlc_mutex_lock ( &p_netlist->lock );
-
- /* check */
- if ( p_netlist->i_data_start == p_netlist->i_data_end )
- {
- intf_ErrMsg("Empty Data FIFO in netlist. Unable to allocate memory");
- return ( NULL );
- }
-
- p_return = (p_netlist->pp_free_data[p_netlist->i_data_start]);
-
- p_netlist->i_data_start++;
- p_netlist->i_data_start &= p_netlist->i_nb_data;
-
- p_return->p_payload_start = p_return->p_buffer;
-
- p_return->p_payload_end =
- p_return->p_buffer + p_netlist->i_buffer_size;
-
- p_return->p_next = NULL;
- p_return->b_discard_payload = 0;
-
- /* unlock */
- vlc_mutex_unlock (&p_netlist->lock);
-
- return ( p_return );
-}
-
-/*****************************************************************************
- * input_NetlistNewPacket: returns a free data_packet_t, and takes
- * a corresponding storage iovec.
- *****************************************************************************/
-struct data_packet_s * input_NetlistNewPacket( void * p_method_data,
- size_t i_buffer_size )
-{
- netlist_t * p_netlist;
- struct data_packet_s * p_packet;
-
- /* cast */
- p_netlist = (netlist_t *)p_method_data;
-
-#ifdef DEBUG
- if( i_buffer_size > p_netlist->i_buffer_size )
- {
- /* This should not happen */
- intf_ErrMsg( "Netlist packet too small !" );
- return NULL;
- }
-#endif
-
- /* lock */
- vlc_mutex_lock( &p_netlist->lock );
-
- /* check */
- if ( p_netlist->i_iovec_start == p_netlist->i_iovec_end )
- {
- intf_ErrMsg("Empty io_vec FIFO in netlist. Unable to allocate memory");
- return ( NULL );
- }
-
- if ( p_netlist->i_data_start == p_netlist->i_data_end )
- {
- intf_ErrMsg("Empty Data FIFO in netlist. Unable to allocate memory");
- return ( NULL );
- }
-
-
- /* Gives an io_vec and associated data */
- p_packet = p_netlist->pp_free_data[p_netlist->i_data_start];
-
- p_packet->p_buffer =
- p_netlist->p_free_iovec[p_netlist->i_iovec_start].iov_base;
-
- p_packet->p_payload_start = p_packet->p_buffer;
-
- p_packet->p_payload_end =
- p_packet->p_buffer + i_buffer_size;
-
- p_packet->p_next = NULL;
- p_packet->b_discard_payload = 0;
-
- p_packet->pi_refcount = p_netlist->pi_refcount + p_netlist->i_iovec_start;
- if( (*p_packet->pi_refcount) != 0)
- {
- intf_ErrMsg( "netlist error: refcount should be 0 (%d)",
- (*p_packet->pi_refcount) );
- }
- (*p_packet->pi_refcount) = 1;
-
- p_netlist->i_iovec_start ++;
- p_netlist->i_iovec_start &= p_netlist->i_nb_iovec;
-
- p_netlist->i_data_start ++;
- p_netlist->i_data_start &= p_netlist->i_nb_data;
-
- /* unlock */
- vlc_mutex_unlock( &p_netlist->lock );
-
- return p_packet;
-}
-
-/*****************************************************************************
- * input_NetlistNewPES: returns a free pes_packet_t
- *****************************************************************************/
-struct pes_packet_s * input_NetlistNewPES( void * p_method_data )
-{
- netlist_t * p_netlist;
- pes_packet_t * p_return;
-
- /* cast */
- p_netlist = (netlist_t *)p_method_data;
-
- /* lock */
- vlc_mutex_lock ( &p_netlist->lock );
-
- /* check */
- if ( p_netlist->i_pes_start == p_netlist->i_pes_end )
- {
- intf_ErrMsg("Empty PES FIFO in netlist - Unable to allocate memory");
- return ( NULL );
- }
-
- /* allocate */
- p_return = p_netlist->pp_free_pes[p_netlist->i_pes_start];
- p_netlist->i_pes_start++;
- p_netlist->i_pes_start &= p_netlist->i_nb_pes;
-
- /* unlock */
- vlc_mutex_unlock (&p_netlist->lock);
-
- /* initialize PES */
- p_return->b_data_alignment = 0;
- p_return->b_discontinuity = 0;
- p_return->i_pts = 0;
- p_return->i_dts = 0;
- p_return->i_pes_size = 0;
- p_return->p_first = NULL;
-
- return ( p_return );
-}
-
-/*****************************************************************************
- * input_NetlistDeletePacket: puts a data_packet_t back into the netlist
- *****************************************************************************/
-void input_NetlistDeletePacket( void * p_method_data, data_packet_t * p_data )
-{
- netlist_t * p_netlist;
-
- /* cast */
- p_netlist = (netlist_t *) p_method_data;
-
- /* lock */
- vlc_mutex_lock ( &p_netlist->lock );
-
- /* Delete data_packet */
- p_netlist->i_data_end ++;
- p_netlist->i_data_end &= p_netlist->i_nb_data;
-
- p_data->p_payload_start = p_data->p_buffer;
- p_data->p_payload_end = p_data->p_buffer + p_netlist->i_buffer_size;
-
- p_netlist->pp_free_data[p_netlist->i_data_end] = p_data;
-
- p_data->p_next = NULL;
- p_data->b_discard_payload = 0;
-
- /* Update reference counter */
- (*p_data->pi_refcount)--;
-
- if( (*p_data->pi_refcount) == 0 )
- {
- (*p_data->pi_refcount) = 0;
- p_netlist->i_iovec_end++;
- p_netlist->i_iovec_end &= p_netlist->i_nb_iovec;
- p_netlist->p_free_iovec[p_netlist->i_iovec_end].iov_base =
- p_data->p_buffer;
- }
- else if( (*p_data->pi_refcount) < 0 )
- {
- intf_ErrMsg( "netlist error: refcount can't be negative (%d)",
- (*p_data->pi_refcount) );
- }
-
- /* unlock */
- vlc_mutex_unlock (&p_netlist->lock);
-}
-
-/*****************************************************************************
- * input_NetlistDeletePES: puts a pes_packet_t back into the netlist
- *****************************************************************************/
-void input_NetlistDeletePES( void * p_method_data, pes_packet_t * p_pes )
-{
- netlist_t * p_netlist;
- data_packet_t * p_current_packet;
- data_packet_t * p_next_packet;
-
- /* cast */
- p_netlist = (netlist_t *)p_method_data;
-
- /* lock */
- vlc_mutex_lock ( &p_netlist->lock );
-
- /* delete free p_pes->p_first, p_next ... */
- p_current_packet = p_pes->p_first;
- while ( p_current_packet != NULL )
- {
- /* copy of NetListDeletePacket, duplicate code avoid many locks */
-
- p_netlist->i_data_end ++;
- p_netlist->i_data_end &= p_netlist->i_nb_data;
-
- /* re initialize */
- p_current_packet->p_payload_start = p_current_packet->p_buffer;
- p_current_packet->p_payload_end = p_current_packet->p_buffer
- + p_netlist->i_buffer_size;
-
- p_netlist->pp_free_data[p_netlist->i_data_end] = p_current_packet;
-
- /* Update reference counter */
- (*p_current_packet->pi_refcount)--;
-
- if( (*p_current_packet->pi_refcount) == 0 )
- {
- (*p_current_packet->pi_refcount) = 0;
- p_netlist->i_iovec_end++;
- p_netlist->i_iovec_end &= p_netlist->i_nb_iovec;
- p_netlist->p_free_iovec[p_netlist->i_iovec_end].iov_base =
- p_current_packet->p_buffer;
- }
- else if( (*p_current_packet->pi_refcount) < 0 )
- {
- intf_ErrMsg( "netlist error: refcount can't be negative (%d)",
- (*p_current_packet->pi_refcount) );
- }
-
- p_next_packet = p_current_packet->p_next;
- p_current_packet->p_next = NULL;
- p_current_packet->b_discard_payload = 0;
- p_current_packet = p_next_packet;
- }
-
- /* delete our current PES packet */
- p_netlist->i_pes_end ++;
- p_netlist->i_pes_end &= p_netlist->i_nb_pes;
- p_netlist->pp_free_pes[p_netlist->i_pes_end] = p_pes;
-
- /* unlock */
- vlc_mutex_unlock (&p_netlist->lock);
-
-}
-
-/*****************************************************************************
- * input_NetlistEnd: frees all allocated structures
- *****************************************************************************/
-void input_NetlistEnd( input_thread_t * p_input )
-{
- netlist_t * p_netlist;
-
- /* cast */
- p_netlist = ( netlist_t * ) p_input->p_method_data;
-
- /* destroy the mutex lock */
- vlc_mutex_destroy( &p_netlist->lock );
-
- /* free the FIFO, the buffer, and the netlist structure */
- free( p_netlist->pi_refcount );
- free( p_netlist->p_free_iovec );
- free( p_netlist->pp_free_pes );
- free( p_netlist->pp_free_data );
- free( p_netlist->p_pes );
- free( p_netlist->p_data );
- free( p_netlist->p_buffers );
-
- /* free the netlist */
- free( p_netlist );
-}
* mpeg_system.c: TS, PS and PES management
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: mpeg_system.c,v 1.69.2.4 2001/12/17 16:37:25 sam Exp $
+ * $Id: mpeg_system.c,v 1.69.2.5 2001/12/31 01:21:45 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr>
if( MoveChunk( p_header, &p_data, &p_byte, PES_HEADER_SIZE )
!= PES_HEADER_SIZE )
{
- intf_WarnMsg( 1, "PES packet too short to have a header" );
+ intf_WarnMsg( 1, "input: PES packet too short to have a header" );
p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
if( (p_header[0] || p_header[1] || (p_header[2] != 1)) )
{
/* packet_start_code_prefix != 0x000001 */
- intf_ErrMsg( "PES packet doesn't start with 0x000001 : data loss" );
+ intf_ErrMsg( "input error: data loss, "
+ "PES packet doesn't start with 0x000001" );
p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
}
{
/* PES_packet_length is set and != total received payload */
/* Warn the decoder that the data may be corrupt. */
- intf_WarnMsg( 1, "PES sizes do not match : packet corrupted" );
+ intf_WarnMsg( 1, "input: packet corrupted, "
+ "PES sizes do not match" );
}
switch( p_es->i_stream_id )
}
if( i_pes_header_size == 23 )
{
- intf_ErrMsg( "Too much MPEG-1 stuffing" );
+ intf_ErrMsg( "input error: too much MPEG-1 stuffing" );
p_input->pf_delete_pes( p_input->p_method_data, p_pes );
p_pes = NULL;
return;
else
{
/* Update the relations between the data packets */
- p_es->p_last->p_next = p_data;
+ p_pes->p_last->p_next = p_data;
}
- p_es->p_last = p_data;
+ p_pes->p_last = p_data;
+ p_pes->i_nb_data++;
/* Size of the payload carried in the data packet */
p_pes->i_pes_size += (p_data->p_payload_end
{
u16 i_id;
- i_id = p_data->p_payload_start[3]; /* stream_id */
+ i_id = p_data->p_demux_start[3]; /* stream_id */
if( i_id == 0xBD )
{
/* FIXME : this is not valid if the header is split in multiple
* packets */
/* stream_private_id */
- i_id |= p_data->p_payload_start[ 9 + p_data->p_payload_start[8] ] << 8;
+ i_id |= p_data->p_demux_start[ 9 + p_data->p_demux_start[8] ] << 8;
}
return( i_id );
}
int i;
int i_new_es_number = 0;
- if( p_data->p_payload_start + 10 > p_data->p_payload_end )
+ if( p_data->p_demux_start + 10 > p_data->p_payload_end )
{
intf_ErrMsg( "PSM too short : packet corrupt" );
return;
}
if( p_demux->b_has_PSM
- && p_demux->i_PSM_version == (p_data->p_payload_start[6] & 0x1F) )
+ && p_demux->i_PSM_version == (p_data->p_demux_start[6] & 0x1F) )
{
/* Already got that one. */
return;
intf_DbgMsg( "Building PSM" );
p_demux->b_has_PSM = 1;
- p_demux->i_PSM_version = p_data->p_payload_start[6] & 0x1F;
+ p_demux->i_PSM_version = p_data->p_demux_start[6] & 0x1F;
/* Go to elementary_stream_map_length, jumping over
* program_stream_info. */
- p_byte = p_data->p_payload_start + 10
- + U16_AT(&p_data->p_payload_start[8]);
+ p_byte = p_data->p_demux_start + 10
+ + U16_AT(&p_data->p_demux_start[8]);
if( p_byte > p_data->p_payload_end )
{
intf_ErrMsg( "PSM too short : packet corrupt" );
u32 i_code;
es_descriptor_t * p_es = NULL;
- i_code = p_data->p_payload_start[3];
+ i_code = p_data->p_demux_start[3];
if( i_code > 0xBC ) /* ES start code */
{
i_id, 0 );
if( p_es != NULL )
{
- p_es->i_stream_id = p_data->p_payload_start[3];
+ p_es->i_stream_id = p_data->p_demux_start[3];
/* Set stream type and auto-spawn. */
if( (i_id & 0xF0) == 0xE0 )
boolean_t b_trash = 0;
es_descriptor_t * p_es = NULL;
- i_code = U32_AT( p_data->p_payload_start );
+ i_code = ((u32)p_data->p_demux_start[0] << 24)
+ | ((u32)p_data->p_demux_start[1] << 16)
+ | ((u32)p_data->p_demux_start[2] << 8)
+ | p_data->p_demux_start[3];
if( i_code <= 0x1BC )
{
switch( i_code )
mtime_t scr_time;
u32 i_mux_rate;
- if( (p_data->p_payload_start[4] & 0xC0) == 0x40 )
+ if( (p_data->p_demux_start[4] & 0xC0) == 0x40 )
{
/* MPEG-2 */
byte_t p_header[14];
byte_t * p_byte;
- p_byte = p_data->p_payload_start;
+ p_byte = p_data->p_demux_start;
if( MoveChunk( p_header, &p_data, &p_byte, 14 ) != 14 )
{
/* MPEG-1 SCR is like PTS. */
byte_t p_header[12];
byte_t * p_byte;
- p_byte = p_data->p_payload_start;
+ p_byte = p_data->p_demux_start;
if( MoveChunk( p_header, &p_data, &p_byte, 12 ) != 12 )
{
es_ts_data_t * p_es_demux = NULL;
pgrm_ts_data_t * p_pgrm_demux = NULL;
-#define p (p_data->p_buffer)
+#define p (p_data->p_demux_start)
/* Extract flags values from TS common header. */
i_pid = ((p[1] & 0x1F) << 8) | p[2];
b_unit_start = (p[1] & 0x40);