]> git.sesse.net Git - vlc/commitdiff
STABLE/HEAD merge ; backported the Next Generation Buffer Manager.
authorChristophe Massiot <massiot@videolan.org>
Mon, 31 Dec 2001 01:21:45 +0000 (01:21 +0000)
committerChristophe Massiot <massiot@videolan.org>
Mon, 31 Dec 2001 01:21:45 +0000 (01:21 +0000)
31 files changed:
Makefile
include/common.h
include/config.h.in
include/input_ext-dec.h
include/input_ext-intf.h
include/input_ext-plugins.h
include/modules_export.h
plugins/ac3_adec/ac3_adec.c
plugins/ac3_spdif/ac3_spdif.c
plugins/dvd/input_dvd.c
plugins/dvdread/input_dvdread.c
plugins/lpcm_adec/lpcm_adec.c
plugins/mad_adec/mad_libmad.c
plugins/mpeg/input_es.c
plugins/mpeg/input_es.h
plugins/mpeg/input_ps.c
plugins/mpeg/input_ps.h
plugins/mpeg/input_ts.c
plugins/mpeg/input_ts.h
plugins/mpeg_adec/mpeg_adec.c
plugins/mpeg_vdec/video_parser.c
plugins/spu_dec/spu_decoder.c
plugins/vcd/input_vcd.c
plugins/vcd/input_vcd.h
plugins/vcd/linux_cdrom_tools.c
plugins/vcd/linux_cdrom_tools.h
src/input/input.c
src/input/input_dec.c
src/input/input_ext-dec.c
src/input/input_netlist.c [deleted file]
src/input/mpeg_system.c

index b5282ac7b20a9afa709492d97d0d5ef4e6e79499..69a996cfe2ca84a19639a13bbf29d63afd04ee00 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -110,7 +110,7 @@ PLUGINS_TARGETS := ac3_adec/ac3_adec \
 # 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
index d6087dfbecc59267fe656b2cb03907de9822df15..ae54e4abfa7159a7dd63acffa1f023f0c07b72a0 100644 (file)
@@ -3,7 +3,7 @@
  * 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>
@@ -347,18 +347,6 @@ typedef struct module_symbols_s
                                            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 * );
index b2ba24b0d2437d73788f71932d56d53a724ea89f..5c9ffe56a93c30f13ef9995ec95a34d16b786a3c 100644 (file)
 /* 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"
index b3fdc0f03001306589463657a9227ebe29451a29..a5f585ceb342eed57bf9ad2e0e2f3a8dba961521 100644 (file)
@@ -2,7 +2,7 @@
  * 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;
 
 /*****************************************************************************
@@ -66,6 +69,9 @@ typedef struct data_packet_s
  *****************************************************************************/
 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      */
@@ -77,12 +83,15 @@ typedef struct pes_packet_s
     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;
 
 /*****************************************************************************
@@ -97,9 +106,9 @@ typedef struct decoder_fifo_s
     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 */
@@ -110,18 +119,6 @@ typedef struct decoder_fifo_s
                                      /* 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
  *****************************************************************************
index 24692eddbd9e9e07597e3a757cfee618008a5da9..03d79a5927b7b3a9d4c231303e00bef277601e99 100644 (file)
@@ -4,7 +4,7 @@
  * 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>
  *
@@ -26,7 +26,6 @@
 /*
  * Communication input -> interface
  */
-#define INPUT_MAX_PLUGINS   1
 /* FIXME ! */
 #define REQUESTED_MPEG         1
 #define REQUESTED_AC3          2
@@ -66,7 +65,6 @@ typedef struct es_descriptor_s
 
     /* 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 */
@@ -95,6 +93,7 @@ typedef struct es_descriptor_s
 #define SPU_ES          0x02
 #define NAV_ES          0x03
 #define UNKNOWN_ES      0xFF
+
 /*****************************************************************************
  * pgrm_descriptor_t
  *****************************************************************************
@@ -263,7 +262,7 @@ typedef struct input_thread_s
 
     /* 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 * );
 
@@ -289,8 +288,6 @@ typedef struct input_thread_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 */
 
index d3abaf98bac3ba11bb994de4629d668aec647fe6..7e0b31fcf2e8a937c4a407fe68487b7d78336e4f 100644 (file)
@@ -3,7 +3,7 @@
  *                      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
@@ -115,15 +111,16 @@ static __inline__ void input_NullPacket( input_thread_t * p_input,
         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
     {
@@ -135,7 +132,8 @@ static __inline__ void input_NullPacket( input_thread_t * p_input,
         }
 
         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 );
     }
@@ -143,68 +141,680 @@ static __inline__ void input_NullPacket( input_thread_t * p_input,
 
 
 /*
- * 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 );                                      \
+}
 
 
 /*
index 499fb5dcbc73132f7f8e779018f5d14f4283ba74..67ed823a99d5548fde64f482937d928d93349581 100644 (file)
     (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; \
index b13058d8fe7910ffd9677e963280f418badc4910..aa873edaf7146fb25188f9d3908bb12735efa2f5 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
  *
@@ -171,12 +171,12 @@ static int decoder_Run ( decoder_config_t * p_config )
             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] =
index d125a06156bcbf5742e47849ab808a1f3bafcd65..63cb851863f74ad3d4d9b6ea2900f216a9c9459a 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
@@ -347,7 +347,7 @@ static void BitstreamCallback ( bit_stream_t * p_bit_stream,
         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;
     }
 }
index 796e60222e68d7eecd46cd34a14ff67338227cc7..9fb98fd845ffbecfef49bdf9a0781e32ce4e3a43 100644 (file)
@@ -10,7 +10,7 @@
  *  -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
@@ -119,6 +115,21 @@ static int  DVDFindCell( thread_dvd_data_t * );
 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.
@@ -136,10 +147,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
     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
@@ -194,33 +205,31 @@ static void DVDInit( input_thread_t * p_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;
     }
@@ -230,6 +239,7 @@ static void DVDInit( input_thread_t * p_input )
         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;
     }
@@ -289,9 +299,8 @@ static void DVDInit( input_thread_t * p_input )
         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 );
@@ -322,7 +331,7 @@ static void DVDOpen( struct input_thread_s *p_input )
 
     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 ) )
     {
@@ -383,7 +392,7 @@ static void DVDEnd( input_thread_t * p_input )
 
     free( p_dvd );
 
-    input_NetlistEnd( p_input );
+    input_BuffersEnd( p_input->p_method_data );
 }
 
 /*****************************************************************************
@@ -816,20 +825,17 @@ static int DVDSetArea( input_thread_t * p_input, input_area_t * p_area )
     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;
@@ -838,12 +844,12 @@ static int DVDRead( input_thread_t * p_input,
     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;
@@ -861,7 +867,6 @@ static int DVDRead( input_thread_t * p_input,
         /* 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;
         }
@@ -907,23 +912,20 @@ static int DVDRead( input_thread_t * p_input,
 /*
 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;
 
@@ -932,42 +934,50 @@ intf_WarnMsg( 2, "Sector: 0x%x Read: %d Chapter: %d", p_dvd->i_sector, i_block_o
     /* 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 );
 
@@ -981,33 +991,32 @@ intf_WarnMsg( 2, "Sector: 0x%x Read: %d Chapter: %d", p_dvd->i_sector, i_block_o
         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 );
 }
 
 /*****************************************************************************
index 5f59804fc7e8b8049b80ba8bb7c97cad55be1ba3..2112da7249b34f1cec95d33144728b5df198d769 100644 (file)
@@ -6,7 +6,7 @@
  * 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
@@ -100,6 +96,7 @@ static void DvdReadEnd      ( struct input_thread_s * );
 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 * );
@@ -108,6 +105,21 @@ 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.
@@ -123,11 +135,12 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
     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
@@ -157,7 +170,7 @@ static int DvdReadProbe( probedata_t *p_data )
         /* If the user specified "dvdread:" then he probably wants
          * to use libdvdread */
         i_score = 100;
-        psz_name += 4;
+        psz_name += 8;
     }
 
     return( i_score );
@@ -188,24 +201,22 @@ static void DvdReadInit( input_thread_t * p_input )
     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;
@@ -349,9 +360,16 @@ static void DvdReadEnd( input_thread_t * p_input )
     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
@@ -511,23 +529,24 @@ static int DvdReadSetArea( input_thread_t * p_input, input_area_t * p_area )
             }
 
             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;
@@ -558,7 +577,7 @@ static int DvdReadSetArea( input_thread_t * p_input, input_area_t * p_area )
                 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;
@@ -572,7 +591,7 @@ static int DvdReadSetArea( input_thread_t * p_input, input_area_t * p_area )
                 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;
@@ -586,7 +605,7 @@ static int DvdReadSetArea( input_thread_t * p_input, input_area_t * p_area )
 
                     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;
@@ -651,7 +670,7 @@ static int DvdReadSetArea( input_thread_t * p_input, input_area_t * p_area )
 
                 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;
@@ -772,13 +791,11 @@ static int DvdReadSetArea( input_thread_t * p_input, input_area_t * p_area )
  * 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;
@@ -786,9 +803,12 @@ static int DvdReadRead( input_thread_t * p_input,
     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.
@@ -810,26 +830,35 @@ static int DvdReadRead( input_thread_t * p_input,
             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++;
-
     }
 
     /*
@@ -838,13 +867,14 @@ static int DvdReadRead( input_thread_t * p_input,
     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 */
@@ -861,18 +891,15 @@ static int DvdReadRead( input_thread_t * p_input,
 /*
     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;
 
@@ -881,35 +908,48 @@ static int DvdReadRead( input_thread_t * p_input,
             {
                 /* 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 );
 
@@ -924,7 +964,25 @@ static int DvdReadRead( input_thread_t * p_input,
         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 );
 
index e31041ae5700821548af7b15b450ffcde6214ed2..bbc03e83324a6213cf0b1e4414b0848f4099b812 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
@@ -187,11 +187,11 @@ void DecodeFrame( lpcmdec_thread_t * p_lpcmdec )
     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
     { 
index 30eb99d82571f6ba2a7e3deef4d4106162590cc7..4979d80fa90b4d43e3ba8204d97301b34c3efef2 100644 (file)
@@ -62,9 +62,9 @@ enum mad_flow libmad_input(void *data, struct mad_stream *p_libmad_stream)
     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;
index 49b118f8f74a8be5d515b3d55c04ffbaddf0bcbf..0fd8a1e125b6f6ae6f1e27f5eab851c2ddc5168d 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
  *
@@ -75,7 +75,7 @@
  *****************************************************************************/
 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 );
@@ -89,6 +89,20 @@ static void ESInitBitstream( struct bit_stream_s *, struct decoder_fifo_s *,
                         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.
@@ -106,10 +120,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
     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
@@ -141,27 +155,24 @@ static void ESInit( input_thread_t * p_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 );
 }
 
@@ -170,49 +181,57 @@ static void ESInit( input_thread_t * p_input )
  *****************************************************************************/
 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 );
 }
 
 /*****************************************************************************
@@ -241,7 +260,7 @@ static void ESDemux( input_thread_t * p_input, data_packet_t * p_data )
 {
     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 )
     {
@@ -251,22 +270,23 @@ static void ESDemux( input_thread_t * p_input, data_packet_t * p_data )
     }
 
     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 );
     }
@@ -290,18 +310,23 @@ static void ESNextDataPacket( bit_stream_t * p_bit_stream )
          * 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 );
 
@@ -310,7 +335,7 @@ static void ESNextDataPacket( bit_stream_t * p_bit_stream )
             }
 
             /* 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 );
 
index 484e7bdca600f5639112d8a53953583b7e96393a..654cae03f9587aef9da58eea884753146a3ea174 100644 (file)
@@ -2,7 +2,7 @@
  * 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: 
  *
@@ -20,8 +20,6 @@
  * 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
index 7124580032363db7904bad40569fea1926fe289b..bab057662f8e91332eaa7f6b29fb8072259bc6b9 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
@@ -86,15 +86,25 @@ static __inline__ off_t fseeko( FILE *p_file, off_t i_offset, int i_pos )
  *****************************************************************************/
 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
@@ -113,10 +123,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
     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
@@ -158,65 +168,12 @@ static int PSProbe( probedata_t *p_data )
  *****************************************************************************/
 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 */
@@ -225,6 +182,7 @@ static void PSInit( input_thread_t * p_input )
         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;
         }
@@ -253,11 +211,22 @@ static void PSInit( input_thread_t * p_input )
         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 );
@@ -265,19 +234,12 @@ static void PSInit( input_thread_t * p_input )
                 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 )
@@ -388,22 +350,7 @@ static void PSInit( input_thread_t * p_input )
  *****************************************************************************/
 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 );
 }
 
 /*****************************************************************************
@@ -418,7 +365,7 @@ static __inline__ int SafeRead( input_thread_t * p_input, byte_t * p_buffer,
     {
         if( feof( p_input->p_stream ) )
         {
-            return( 1 );
+            return( 0 );
         }
 
         if( (i_error = ferror( p_input->p_stream )) )
@@ -430,28 +377,29 @@ static __inline__ int SafeRead( input_thread_t * p_input, byte_t * p_buffer,
     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 );
         }
@@ -480,7 +428,7 @@ static int PSRead( input_thread_t * p_input,
                 }
                 else
                 {
-                    return( 1 );
+                    return( 0 );
                 }
             }
             /* Packet found. */
@@ -491,7 +439,7 @@ static int PSRead( input_thread_t * p_input,
         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 );
             }
@@ -528,7 +476,8 @@ static int PSRead( input_thread_t * p_input,
         }
 
         /* 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" );
@@ -538,25 +487,29 @@ static int PSRead( input_thread_t * p_input,
         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 );
                     }
                 }
@@ -565,14 +518,15 @@ static int PSRead( input_thread_t * p_input,
         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 );
 }
 
 /*****************************************************************************
@@ -598,358 +552,3 @@ static void PSSeek( input_thread_t * p_input, off_t i_position )
     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 );
-}
-
index 4d72ade2a88843fe12bd4e2d0e3f1e4dae4f4190..0f7a4154493e6f6c883d1f2fcdfff94ca370d9f6 100644 (file)
@@ -2,7 +2,7 @@
  * 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
 
index 1143818c425ba5f8704cc9e9af5dfabf3398dd06..057aec877ea8a7cc2dfede1ddf965ef158481a4d 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
  *
@@ -89,7 +89,21 @@ static int  TSProbe     ( probedata_t * );
 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
@@ -108,10 +122,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
     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
@@ -160,7 +174,6 @@ static int TSProbe( probedata_t * p_data )
  *****************************************************************************/
 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;
@@ -184,11 +197,9 @@ static void TSInit( input_thread_t * p_input )
     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;
     }
 
@@ -227,23 +238,23 @@ static void TSEnd( input_thread_t * p_input )
         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 */
@@ -257,9 +268,6 @@ static int TSRead( input_thread_t * p_input,
     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 ) 
@@ -278,25 +286,26 @@ static int TSRead( input_thread_t * p_input,
     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) ) )
@@ -306,36 +315,35 @@ static int TSRead( input_thread_t * p_input,
             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 );
 }
 
index f80dc59d74d03bf6974fdc9af9d6932427b1dfc0..d2c0416f2521a35e856df91d5398c9e760ac8f40 100644 (file)
@@ -2,7 +2,7 @@
  * 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
index 6cfd653d671a4877985b12447f4bc5efb83ce510..b2d96f761b9b9950d8a804b30c5928ed9ba77070 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
@@ -203,11 +203,11 @@ static void DecodeThread( adec_thread_t * p_adec )
         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
         {
index b94569d62cd76d9d0e20198e28c4b5eb02c7556c..ff13a44721c90a25359dc6d5b939762198df45cc 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
@@ -281,38 +281,6 @@ static int InitThread( vpar_thread_t *p_vpar )
     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
  *****************************************************************************
@@ -428,13 +396,13 @@ static void BitstreamCallback ( bit_stream_t * p_bit_stream,
     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" );
index 09e531604464efe551145ac53386d32807fa75cb..0f69b5b11450918d8d6b42cbf1c10c68fc62dc44 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
  *
@@ -275,7 +275,7 @@ static void ParsePacket( spudec_thread_t *p_spudec )
                   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;
@@ -295,7 +295,7 @@ static void ParsePacket( spudec_thread_t *p_spudec )
     }
 
     /* 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 );
index 2443b8e2a12003e7a1b2bf341d233cd1cdf61914..5077ff39a97ae2df13c8ce9a754f96c6220953b3 100644 (file)
 #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
  *****************************************************************************/
@@ -95,11 +92,19 @@ static void VCDClose         ( struct input_thread_s *);
 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 );
 
 
 /*****************************************************************************
@@ -119,10 +124,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
     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
@@ -162,8 +167,6 @@ static int VCDProbe( probedata_t *p_data )
  *****************************************************************************/
 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... */
@@ -171,7 +174,6 @@ static void VCDOpen( struct input_thread_s *p_input )
 
     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 );
@@ -181,20 +183,17 @@ static void VCDOpen( struct input_thread_s *p_input )
     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;
 }
 
 /*****************************************************************************
@@ -216,10 +215,9 @@ static void VCDInit( input_thread_t * p_input )
     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" );
@@ -227,78 +225,35 @@ static void VCDInit( input_thread_t * p_input )
         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 );
@@ -309,7 +264,6 @@ static void VCDInit( input_thread_t * p_input )
     /* 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++ )
     {
@@ -319,8 +273,9 @@ static void VCDInit( input_thread_t * p_input )
         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
@@ -330,19 +285,19 @@ static void VCDInit( input_thread_t * p_input )
         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 )
@@ -350,7 +305,6 @@ static void VCDInit( input_thread_t * p_input )
         i_chapter = 1;
     }
 
-    
     p_input->stream.pp_areas[i_title]->i_part = i_chapter;
 
     p_area = p_input->stream.pp_areas[i_title];
@@ -362,38 +316,33 @@ static void VCDInit( input_thread_t * p_input )
     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
  *****************************************************************************/
@@ -401,17 +350,18 @@ static void VCDEnd( input_thread_t * p_input )
 {
     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;
 }
@@ -424,132 +374,119 @@ static int VCDSetProgram( input_thread_t * p_input,
 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 */
@@ -562,99 +499,99 @@ static int VCDRead( input_thread_t * p_input,
                     }
                     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 );
 }
 
 /*****************************************************************************
@@ -665,7 +602,6 @@ static int VCDRewind( input_thread_t * p_input )
     return( -1 );
 }
 
-
 /****************************************************************************
  * VCDSeek
  ****************************************************************************/
@@ -675,368 +611,11 @@ static void VCDSeek( input_thread_t * p_input, off_t i_off )
 
     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 );
-}
index d75dcda4532f05ad2c25581b55a5c369c6964e53..b8f7c483571412ac167e15bd09ee3cb27ba7e1a2 100644 (file)
@@ -2,7 +2,7 @@
  * 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;
 
index e70c1325cce326ac0ece8c352815f24215ad8e22..e6b160edecc0863ca54f4b7929bf994cc6ebace3 100644 (file)
 #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;
 }
index f68706041d6638e2b9453d7b04e668d2c1112c82..fa69e887b42baf5a0884766093792625bbb02edb 100644 (file)
@@ -36,7 +36,6 @@
 /******************************************************************************
 * 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 * );
index 6cbb1ea8d3963c499857057f7456d5993f1fe2f5..4b395f19ff7b84d1ed20525dc6bda5b9cb9d3d04 100644 (file)
@@ -4,7 +4,7 @@
  * 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>
  *
@@ -120,9 +120,6 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status )
         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;
@@ -206,7 +203,7 @@ void input_DestroyThread( input_thread_t *p_input, int *pi_status )
     /* 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 );
@@ -229,9 +226,6 @@ void input_DestroyThread( input_thread_t *p_input, int *pi_status )
  *****************************************************************************/
 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 */
@@ -242,22 +236,16 @@ static void RunThread( input_thread_t *p_input )
         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 );
@@ -357,33 +345,33 @@ static void RunThread( input_thread_t *p_input )
 
         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 );
@@ -401,7 +389,6 @@ static void RunThread( input_thread_t *p_input )
  *****************************************************************************/
 static int InitThread( input_thread_t * p_input )
 {
-
     /* Initialize statistics */
     p_input->c_loops                    = 0;
     p_input->stream.c_packets_read      = 0;
index c8307c98f1ee83d7fa8e6afdc2277f724a95adc5..f8dc0b239687d399581adb58bd94477999e7a9cd 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
  *
@@ -144,21 +144,13 @@ void input_DecodePES( decoder_fifo_t * p_decoder_fifo, pes_packet_t * p_pes )
 {
     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 );
 }
 
@@ -261,7 +253,9 @@ static decoder_config_t * CreateDecoderConfig( input_thread_t * p_input,
     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;
@@ -274,14 +268,13 @@ static decoder_config_t * CreateDecoderConfig( input_thread_t * p_input,
  *****************************************************************************/
 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 );
index b38a144cd52a005eb22ca7ac6a1235e4c896d3a0..8db4270fa381538ead666db767a6998a091f616b 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
  *
@@ -55,7 +55,7 @@ void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo,
 
     /* 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 )
         {
@@ -64,7 +64,7 @@ void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo,
         }
         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;
@@ -100,12 +100,7 @@ void DecoderError( decoder_fifo_t * p_fifo )
     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 );
@@ -131,24 +126,29 @@ void NextDataPacket( bit_stream_t * p_bit_stream )
          * 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 );
 
diff --git a/src/input/input_netlist.c b/src/input/input_netlist.c
deleted file mode 100644 (file)
index 4437675..0000000
+++ /dev/null
@@ -1,685 +0,0 @@
-/*****************************************************************************
- * 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 );
-}
index aa9444baa074cc23d4c03ebd2ceef508fb86d921..487cd2f0aa6f8c38bf8c3bbe1fd6868b6c3926b5 100644 (file)
@@ -2,7 +2,7 @@
  * 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>
@@ -136,7 +136,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
     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;
@@ -154,7 +154,8 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
     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;
     }
@@ -167,7 +168,8 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
         {
             /* 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 )
@@ -273,7 +275,7 @@ void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
                 }
                 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;
@@ -474,10 +476,11 @@ void input_GatherPES( input_thread_t * p_input, data_packet_t * p_data,
         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
@@ -505,13 +508,13 @@ static u16 GetID( data_packet_t * p_data )
 {
     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 );
 }
@@ -530,14 +533,14 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data )
     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;
@@ -545,12 +548,12 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data )
 
     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" );
@@ -655,7 +658,7 @@ es_descriptor_t * input_ParsePS( input_thread_t * p_input,
     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 */
     {
@@ -694,7 +697,7 @@ es_descriptor_t * input_ParsePS( input_thread_t * p_input,
                                     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 )
@@ -794,7 +797,10 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
     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 )
@@ -805,12 +811,12 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
                 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 )
                     {
@@ -841,7 +847,7 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
                     /* 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 )
                     {
@@ -943,7 +949,7 @@ void input_DemuxTS( input_thread_t * p_input, data_packet_t * p_data )
     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);