* Minor optimizations in the Next Generation Buffer Manager.
# C Objects
#
INTERFACE := main interface intf_msg intf_playlist
-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 vout_pictures vout_subpictures
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.60 2001/12/19 03:50:22 sam Exp $
+ * $Id: common.h,v 1.61 2001/12/27 01:49:34 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 * );
/*****************************************************************************
* input_ext-dec.h: structures exported to the VideoLAN decoders
*****************************************************************************
- * Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_ext-dec.h,v 1.45 2001/12/19 10:00:00 massiot Exp $
+ * Copyright (C) 1999-2000 VideoLAN
+ * $Id: input_ext-dec.h,v 1.46 2001/12/27 01:49:34 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Kaempf <maxx@via.ecp.fr>
*****************************************************************************/
typedef struct data_packet_s
{
- /* Nothing before this line, the code relies on that */
- byte_t * p_buffer; /* raw data packet */
-
/* Decoders information */
byte_t * p_demux_start; /* start of the PS or TS packet */
byte_t * p_payload_start;
byte_t * p_payload_end; /* guess ? :-) */
boolean_t b_discard_payload; /* is the packet messed up ? */
- int * pi_refcount;
- unsigned int i_size; /* buffer size */
- long l_size; /* buffer size */
-
/* Used to chain the TS packets that carry data for a same PES or PSI */
struct data_packet_s * p_next;
+
+ /* Buffer manager information */
+ byte_t * p_buffer; /* raw data packet */
+ unsigned int i_size; /* buffer size */
} data_packet_t;
/*****************************************************************************
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) */
- int i_nb_data;
+ int i_nb_data; /* Number of data packets in the chained
+ list */
/* Chained list used by the input buffers manager */
struct pes_packet_s * p_next;
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
*****************************************************************************
* input_ext-plugins.h: structures of the input not exported to other modules,
* but exported to plug-ins
*****************************************************************************
- * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: input_ext-plugins.h,v 1.11 2001/12/19 10:00:00 massiot Exp $
+ * Copyright (C) 1999-2001 VideoLAN
+ * $Id: input_ext-plugins.h,v 1.12 2001/12/27 01:49:34 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
}
-/*
- * Optional netlist management
- */
-
-/*****************************************************************************
- * netlist_t: structure to manage a netlist
- *****************************************************************************/
-typedef struct netlist_s
-{
- vlc_mutex_t lock;
-
- size_t i_buffer_size;
-
- /* 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 */
-
- /* 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;
-
- /* 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;
-
- /* Reference counters for iovec */
- unsigned int * pi_refcount;
-
- /* Number of blocs read once by readv */
- unsigned int i_read_once;
-} netlist_t;
-
-/*****************************************************************************
- * Prototypes
- *****************************************************************************/
-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 * );
-
-
/*
* Optional Next Generation buffer manager
*
/* Flags */
#define BUFFERS_NOFLAGS 0
-#define BUFFERS_SHARED 1
-#define BUFFERS_UNIQUE_SIZE 2 /* Only with NB_LIFO == 1 */
+#define BUFFERS_UNIQUE_SIZE 1 /* Only with NB_LIFO == 1 */
/*****************************************************************************
* input_buffers_t: defines a LIFO per data type to keep
input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
int i_select; \
\
- EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE ); \
- \
- for( i_select = 0; i_select < NB_LIFO - 1; i_select++ ) \
+ while( p_data != NULL ) \
{ \
- if( p_buf->i_size <= (2 * p_buffers->NAME[i_select].i_average_size \
- + p_buffers->NAME[i_select + 1].i_average_size) / 3 ) \
+ 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++ ) \
{ \
- break; \
+ if( p_buf->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( 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) ) \
+ if( !(FLAGS & BUFFERS_UNIQUE_SIZE) ) \
+ { \
+ /* Update Bresenham mean (very approximative) */ \
+ p_buffers->NAME[i_select].i_average_size = ( p_buf->i_size \
+ + p_buffers->NAME[i_select].i_average_size \
+ * (INPUT_BRESENHAM_NB - 1) ) \
+ / INPUT_BRESENHAM_NB; \
+ } \
+ } \
+ else \
{ \
- /* Update Bresenham mean (very approximative) */ \
- p_buffers->NAME[i_select].i_average_size = ( p_buf->i_size \
- + p_buffers->NAME[i_select].i_average_size \
- * (INPUT_BRESENHAM_NB - 1) ) \
- / INPUT_BRESENHAM_NB; \
+ p_buffers->i_allocated -= p_buf->i_size; \
+ free( p_buf ); \
} \
- } \
- else \
- { \
- p_buffers->i_allocated -= p_buf->i_size; \
- free( p_buf ); \
+ \
+ p_data = p_next; \
} \
} \
\
/*****************************************************************************
* input_DeletePES: put a pes and all data packets back into the cache
*****************************************************************************/
-#define DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, PES_CACHE_SIZE ) \
+#define BUFFERS_DELETEPES_EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \
+ /* Small hopeless optimization */ \
+ if( (FLAGS & BUFFERS_UNIQUE_SIZE) \
+ && p_buffers->data[0].i_depth < DATA_CACHE_SIZE ) \
+ { \
+ p_buffers->data[0].i_depth += p_pes->i_nb_data; \
+ p_pes->p_last->p_next = p_buffers->data[0].p_stack; \
+ p_buffers->data[0].p_stack = p_pes->p_first; \
+ } \
+ else /* No semicolon after this or you will die */
+
+#define BUFFERS_DELETEPES_EXTRA_SHARED( FLAGS, NB_LIFO, DATA_CACHE_SIZE )
+
+#define BUFFERS_DELETEPES( FLAGS, NB_LIFO, DATA_CACHE_SIZE, PES_CACHE_SIZE, \
+ EXTRA ) \
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 ) \
{ \
- data_packet_t * p_data = p_pes->p_first; \
- while( p_data != NULL ) \
+ pes_packet_t * p_next = p_pes->p_next; \
+ \
+ /* Delete all data packets - no semicolon, PLEASE */ \
+ EXTRA( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \
{ \
- data_packet_t * p_next = p_data->p_next; \
- _input_DeletePacket( _p_buffers, p_data ); \
- p_data = p_next; \
+ _input_DeletePacket( _p_buffers, p_pes->p_first ); \
} \
- } \
\
- 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 ); \
+ 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 ); \
}
+#define DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, DATA_CACHE_SIZE, \
+ PES_CACHE_SIZE ) \
+ BUFFERS_DELETEPES( FLAGS, NB_LIFO, DATA_CACHE_SIZE, PES_CACHE_SIZE, \
+ BUFFERS_DELETEPES_EXTRA )
+
+#define DECLARE_BUFFERS_DELETEPES_SHARED( FLAGS, NB_LIFO, DATA_CACHE_SIZE, \
+ PES_CACHE_SIZE ) \
+ BUFFERS_DELETEPES( FLAGS, NB_LIFO, DATA_CACHE_SIZE, PES_CACHE_SIZE, \
+ BUFFERS_DELETEPES_EXTRA_SHARED )
+
/*****************************************************************************
* input_BuffersToIO: return an io vector (only with BUFFERS_UNIQUE_SIZE)
*****************************************************************************/
(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; \
# define input_ClockManageControl p_symbols->input_ClockManageControl
-# define input_NetlistInit p_symbols->input_NetlistInit
-# define input_NetlistGetiovec p_symbols->input_NetlistGetiovec
-# define input_NetlistMviovec p_symbols->input_NetlistMviovec
-# define input_NetlistNewPacket p_symbols->input_NetlistNewPacket
-# define input_NetlistNewPtr p_symbols->input_NetlistNewPtr
-# define input_NetlistNewPES p_symbols->input_NetlistNewPES
-# define input_NetlistDeletePacket p_symbols->input_NetlistDeletePacket
-# define input_NetlistDeletePES p_symbols->input_NetlistDeletePES
-# define input_NetlistEnd p_symbols->input_NetlistEnd
-
# define aout_CreateFifo p_symbols->aout_CreateFifo
# define aout_DestroyFifo p_symbols->aout_DestroyFifo
* ac3_adec.c: ac3 decoder module main file
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: ac3_adec.c,v 1.8 2001/12/16 16:18:36 sam Exp $
+ * $Id: ac3_adec.c,v 1.9 2001/12/27 01:49:34 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] =
while (!p_ac3thread->p_fifo->b_die)
{
/* Trash all received PES packets */
- while (!DECODER_FIFO_ISEMPTY(*p_ac3thread->p_fifo))
- {
- p_ac3thread->p_fifo->pf_delete_pes(
- p_ac3thread->p_fifo->p_packets_mgt,
- DECODER_FIFO_START(*p_ac3thread->p_fifo));
- DECODER_FIFO_INCSTART (*p_ac3thread->p_fifo);
- }
+ p_ac3thread->p_fifo->pf_delete_pes(
+ p_ac3thread->p_fifo->p_packets_mgt,
+ p_ac3thread->p_fifo->p_first );
/* Waiting for the input thread to put new PES packets in the fifo */
vlc_cond_wait (&p_ac3thread->p_fifo->data_wait,
* ac3_spdif.c: ac3 pass-through to external decoder with enabled soundcard
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: ac3_spdif.c,v 1.7 2001/12/10 04:53:10 sam Exp $
+ * $Id: ac3_spdif.c,v 1.8 2001/12/27 01:49:34 massiot Exp $
*
* Authors: Stéphane Borel <stef@via.ecp.fr>
* Juha Yrjola <jyrjola@cc.hut.fi>
while( !p_spdif->p_fifo->b_die )
{
/* Trash all received PES packets */
- while( !DECODER_FIFO_ISEMPTY( *p_spdif->p_fifo ) )
- {
- p_spdif->p_fifo->pf_delete_pes(p_spdif->p_fifo->p_packets_mgt,
- DECODER_FIFO_START( *p_spdif->p_fifo ) );
- DECODER_FIFO_INCSTART( *p_spdif->p_fifo );
- }
+ p_spdif->p_fifo->pf_delete_pes(
+ p_spdif->p_fifo->p_packets_mgt,
+ p_spdif->p_fifo->p_first );
/* Waiting for the input thread to put new PES packets in the fifo */
vlc_cond_wait( &p_spdif->p_fifo->data_wait,
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.109 2001/12/19 23:19:20 sam Exp $
+ * $Id: input_dvd.c,v 1.110 2001/12/27 01:49:34 massiot Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
DECLARE_BUFFERS_NEWPACKET_SHARED( FLAGS, NB_LIFO );
DECLARE_BUFFERS_DELETEPACKET_SHARED( FLAGS, NB_LIFO, 150 );
DECLARE_BUFFERS_NEWPES( FLAGS, NB_LIFO );
-DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, 150 );
+DECLARE_BUFFERS_DELETEPES_SHARED( FLAGS, NB_LIFO, 150, 150 );
DECLARE_BUFFERS_TOIO( FLAGS, DVD_LB_SIZE );
DECLARE_BUFFERS_SHAREBUFFER( FLAGS );
pp_packets[i_packet] = NULL;
- while( p_data != NULL )
- {
- data_packet_t * p_next = p_data->p_next;
- p_input->pf_delete_packet( p_input->p_method_data, p_data );
- p_data = p_next;
- }
+ p_input->pf_delete_packet( p_input->p_method_data, p_data );
vlc_mutex_lock( &p_input->stream.stream_lock );
* It depends on: libdvdread for ifo files and block reading.
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: input_dvdread.c,v 1.5 2001/12/20 23:53:49 massiot Exp $
+ * $Id: input_dvdread.c,v 1.6 2001/12/27 01:49:34 massiot Exp $
*
* Author: Stéphane Borel <stef@via.ecp.fr>
*
DECLARE_BUFFERS_NEWPACKET_SHARED( FLAGS, NB_LIFO );
DECLARE_BUFFERS_DELETEPACKET_SHARED( FLAGS, NB_LIFO, 150 );
DECLARE_BUFFERS_NEWPES( FLAGS, NB_LIFO );
-DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, 150 );
+DECLARE_BUFFERS_DELETEPES_SHARED( FLAGS, NB_LIFO, 150, 150 );
DECLARE_BUFFERS_TOIO( FLAGS, DVD_LB_SIZE );
DECLARE_BUFFERS_SHAREBUFFER( FLAGS );
pp_packets[i_packet] = 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;
- }
+ p_input->pf_delete_packet( p_input->p_method_data, p_data_p );
vlc_mutex_lock( &p_input->stream.stream_lock );
* lpcm_decoder_thread.c: lpcm decoder thread
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: lpcm_adec.c,v 1.5 2001/12/10 04:53:11 sam Exp $
+ * $Id: lpcm_adec.c,v 1.6 2001/12/27 01:49:34 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
{
while( !p_lpcmdec->p_fifo->b_die )
{
/* Trash all received PES packets */
- while( !DECODER_FIFO_ISEMPTY(*p_lpcmdec->p_fifo) )
- {
- p_lpcmdec->p_fifo->pf_delete_pes( p_lpcmdec->p_fifo->p_packets_mgt,
- DECODER_FIFO_START(*p_lpcmdec->p_fifo ));
- DECODER_FIFO_INCSTART( *p_lpcmdec->p_fifo );
- }
+ p_lpcmdec->p_fifo->pf_delete_pes(
+ p_lpcmdec->p_fifo->p_packets_mgt,
+ p_lpcmdec->p_fifo->p_first );
/* Waiting for the input thread to put new PES packets in the fifo */
vlc_cond_wait ( &p_lpcmdec->p_fifo->data_wait,
while (!p_mad_adec->p_fifo->b_die)
{
/* Trash all received PES packets */
- while (!DECODER_FIFO_ISEMPTY(*p_mad_adec->p_fifo))
- {
- p_mad_adec->p_fifo->pf_delete_pes(
- p_mad_adec->p_fifo->p_packets_mgt,
- DECODER_FIFO_START(*p_mad_adec->p_fifo));
- DECODER_FIFO_INCSTART (*p_mad_adec->p_fifo);
- }
+ p_mad_adec->p_fifo->pf_delete_pes(
+ p_mad_adec->p_fifo->p_packets_mgt,
+ p_mad_adec->p_fifo->p_first );
/* Waiting for the input thread to put new PES packets in the fifo */
vlc_cond_wait (&p_mad_adec->p_fifo->data_wait,
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;
* mpeg_adec.c: MPEG audio decoder thread
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: mpeg_adec.c,v 1.7 2001/12/10 04:53:11 sam Exp $
+ * $Id: mpeg_adec.c,v 1.8 2001/12/27 01:49:34 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
{
while ( !p_adec->p_fifo->b_die )
{
/* Trash all received PES packets */
- while ( !DECODER_FIFO_ISEMPTY(*p_adec->p_fifo) )
- {
- p_adec->p_fifo->pf_delete_pes ( p_adec->p_fifo->p_packets_mgt,
- DECODER_FIFO_START(*p_adec->p_fifo) );
- DECODER_FIFO_INCSTART ( *p_adec->p_fifo );
- }
+ p_adec->p_fifo->pf_delete_pes(
+ p_adec->p_fifo->p_packets_mgt,
+ p_adec->p_fifo->p_first );
/* Waiting for the input thread to put new PES packets in the fifo */
vlc_cond_wait ( &p_adec->p_fifo->data_wait, &p_adec->p_fifo->data_lock );
* input_es.c: Elementary Stream demux and packet management
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: input_es.c,v 1.6 2001/12/19 10:00:00 massiot Exp $
+ * $Id: input_es.c,v 1.7 2001/12/27 01:49:34 massiot Exp $
*
* Author: Christophe Massiot <massiot@via.ecp.fr>
*
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_DELETEPES( FLAGS, NB_LIFO, 150, 150 );
DECLARE_BUFFERS_TOIO( FLAGS, ES_PACKET_SIZE );
/*****************************************************************************
p_data = p_data->p_next;
pp_packets[i_loop]->p_next = NULL;
}
+ /* Delete remaining packets */
+ input_DeletePacket( p_input->p_method_data, p_data );
for( ; i_loop < INPUT_READ_ONCE ; i_loop++ )
{
- data_packet_t * p_next = p_data->p_next;
- input_DeletePacket( p_input->p_method_data, p_data );
- p_data = p_next;
pp_packets[i_loop] = NULL;
}
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_ps.c: PS demux and packet management
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: input_ps.c,v 1.6 2001/12/19 10:00:00 massiot Exp $
+ * $Id: input_ps.c,v 1.7 2001/12/27 01:49:34 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Cyril Deguet <asmax@via.ecp.fr>
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_DELETEPES( FLAGS, NB_LIFO, 150, 150 );
/*****************************************************************************
* input_ts.c: TS demux and netlist management
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
- * $Id: input_ts.c,v 1.5 2001/12/19 10:00:00 massiot Exp $
+ * $Id: input_ts.c,v 1.6 2001/12/27 01:49:34 massiot Exp $
*
* Authors: Henri Fallon <henri@videolan.org>
*
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_DELETEPES( FLAGS, NB_LIFO, 1000, 150 );
DECLARE_BUFFERS_TOIO( FLAGS, TS_PACKET_SIZE );
/*****************************************************************************
"0x%.2x, should be 0x47)",
pp_packets[i_loop]->p_demux_start[0] );
}
+ /* Delete remaining packets */
+ input_DeletePacket( p_input->p_method_data, p_data );
for( ; i_loop < INPUT_READ_ONCE ; i_loop++ )
{
- data_packet_t * p_next = p_data->p_next;
- input_DeletePacket( p_input->p_method_data, p_data );
- p_data = p_next;
pp_packets[i_loop] = NULL;
}
* video_parser.c : video parser thread
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: video_parser.c,v 1.7 2001/12/10 04:53:11 sam Exp $
+ * $Id: video_parser.c,v 1.8 2001/12/27 01:49:34 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Samuel Hocevar <sam@via.ecp.fr>
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 );
- }
+ p_vpar->p_fifo->pf_delete_pes(
+ p_vpar->p_fifo->p_packets_mgt,
+ p_vpar->p_fifo->p_first );
/* 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 );
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.3 2001/12/16 16:18:36 sam Exp $
+ * $Id: spu_decoder.c,v 1.4 2001/12/27 01:49:34 massiot Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
while( !p_spudec->p_fifo->b_die )
{
/* Trash all received PES packets */
- while( !DECODER_FIFO_ISEMPTY(*p_spudec->p_fifo) )
- {
- p_spudec->p_fifo->pf_delete_pes( p_spudec->p_fifo->p_packets_mgt,
- DECODER_FIFO_START(*p_spudec->p_fifo) );
- DECODER_FIFO_INCSTART( *p_spudec->p_fifo );
- }
+ p_spudec->p_fifo->pf_delete_pes(
+ p_spudec->p_fifo->p_packets_mgt,
+ p_spudec->p_fifo->p_first );
/* Waiting for the input thread to put new PES packets in the fifo */
vlc_cond_wait( &p_spudec->p_fifo->data_wait,
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 );
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_DELETEPES( FLAGS, NB_LIFO, 150, 150 );
/*****************************************************************************
* input_dec.c: Functions for the management of decoders
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: input_dec.c,v 1.20 2001/12/09 17:01:37 sam Exp $
+ * $Id: input_dec.c,v 1.21 2001/12/27 01:49:34 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.22 2001/12/09 17:01:37 sam Exp $
+ * $Id: input_ext-dec.c,v 1.23 2001/12/27 01:49:34 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;
* 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.48 2001/12/09 17:01:37 sam 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 "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 );
-}