* ./modules/demux/mpeg/system.c: added a helper plugin for MPEG-related
authorSam Hocevar <sam@videolan.org>
Wed, 7 Aug 2002 00:29:37 +0000 (00:29 +0000)
committerSam Hocevar <sam@videolan.org>
Wed, 7 Aug 2002 00:29:37 +0000 (00:29 +0000)
    demux plugins (ps, ts, but also dvd*).
  * ./src/input/mpeg_system.c: removed MPEG-related stuff from the vlc core.
  * ./src/misc/modules.c: max recursion level is now 5.
  * ./modules/access/dvdplay/es.c: fixed a buffer overflow.

42 files changed:
Makefile
Makefile.opts.in
bootstrap.sh
configure
configure.in
include/input_ext-dec.h
include/input_ext-intf.h
include/input_ext-plugins.h
include/vlc_common.h
include/vlc_symbols.h
modules/access/dvd/access.c
modules/access/dvd/demux.c
modules/access/dvd/dvd.c
modules/access/dvdplay/access.c
modules/access/dvdplay/demux.c
modules/access/dvdplay/es.c
modules/access/dvdread/dvdread.c
modules/access/dvdread/input.c
modules/access/http.c
modules/access/satellite/access.c
modules/access/udp.c
modules/access/vcd/vcd.c
modules/codec/a52old/downmix.h
modules/codec/a52old/imdct.h
modules/codec/mpeg_video/decoder.h
modules/codec/mpeg_video/parser.h
modules/codec/mpeg_video/plugins.h
modules/codec/mpeg_video/pool.h
modules/demux/avi/avi.c
modules/demux/avi/avi.h
modules/demux/mp4/mp4.c
modules/demux/mp4/mp4.h
modules/demux/mpeg/Makefile
modules/demux/mpeg/audio.c
modules/demux/mpeg/ps.c
modules/demux/mpeg/system.c [new file with mode: 0644]
modules/demux/mpeg/system.h [new file with mode: 0644]
modules/demux/mpeg/ts.c
src/input/mpeg_system.c [deleted file]
src/misc/configuration.c
src/misc/modules.c
src/misc/modules_plugin.h

index aca16eb..3be52d1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -20,7 +20,7 @@ VLC := vlc
 LIBVLC := libvlc
 INTERFACE := interface intf_eject
 PLAYLIST := playlist
-INPUT := input input_ext-plugins input_ext-dec input_ext-intf input_dec input_programs input_clock mpeg_system input_info
+INPUT := input input_ext-plugins input_ext-dec input_ext-intf input_dec input_programs input_clock input_info
 VIDEO_OUTPUT := video_output video_text vout_pictures vout_subpictures
 AUDIO_OUTPUT := audio_output aout_ext-dec aout_pcm aout_spdif
 MISC := mtime modules threads cpu configuration netutils iso_lang messages objects extras
index 84ef92a..520186c 100644 (file)
@@ -32,7 +32,7 @@ RELEASE = @RELEASE@
 # Build environment
 # 
 CC = @CC@
-CFLAGS = @CFLAGS@
+CFLAGS += @CFLAGS@
 SHELL = @SHELL@
 RANLIB = @RANLIB@
 STRIP = @STRIP@
index 9be521a..e80cdbb 100755 (executable)
@@ -1,7 +1,7 @@
 #! /bin/sh
 
 ##  bootstrap.sh file for vlc, the VideoLAN Client
-##  $Id: bootstrap.sh,v 1.8 2002/07/21 15:27:09 sam Exp $
+##  $Id: bootstrap.sh,v 1.9 2002/08/07 00:29:36 sam Exp $
 ##
 ##  Authors: Samuel Hocevar <sam@zoy.org>
 
@@ -73,7 +73,7 @@ echo "$file."
 echo -n " + fixing glade bugs: "
 for file in gnome_interface.c gtk_interface.c
 do
-if grep -q "DO NOT EDIT THIS FILE" plugins/gtk/$file
+if grep -q "DO NOT EDIT THIS FILE" modules/gui/gtk/$file
 then
     rm -f /tmp/$$.$file.bak
     cat > /tmp/$$.$file.bak << EOF
@@ -81,7 +81,7 @@ then
 
 #include <vlc/vlc.h>
 EOF
-    tail +8 plugins/gtk/$file \
+    tail +8 modules/gui/gtk/$file \
         | sed 's#DISABLED!!!_("/dev/dvd")#config_GetPsz( "dvd" )#' \
         | sed 's#DISABLED!!!11954#config_GetInt( "frequency" )#' \
         | sed 's#DISABLED!!!27500#config_GetInt( "symbol-rate" )#' \
@@ -91,17 +91,17 @@ EOF
         | sed 's#_("/dev/dvd")#"/dev/dvd"#' \
         | sed 's#_(\("./."\))#\1#' \
         >> /tmp/$$.$file.bak
-    mv -f /tmp/$$.$file.bak plugins/gtk/$file
+    mv -f /tmp/$$.$file.bak modules/gui/gtk/$file
 fi
 echo -n "$file "
 done
 
 file=gtk_support.h
-if grep -q "DO NOT EDIT THIS FILE" plugins/gtk/$file
+if grep -q "DO NOT EDIT THIS FILE" modules/gui/gtk/$file
 then
     rm -f /tmp/$$.$file.bak
-    sed 's/DO NOT EDIT THIS FILE.*/This file was created automatically by glade and fixed by bootstrap.sh/ ; s/#if.*ENABLE_NLS.*/#if defined( ENABLE_NLS ) \&\& defined ( HAVE_GETTEXT )/' < plugins/gtk/$file > /tmp/$$.$file.bak
-    mv -f /tmp/$$.$file.bak plugins/gtk/$file
+    sed 's/DO NOT EDIT THIS FILE.*/This file was created automatically by glade and fixed by bootstrap.sh/ ; s/#if.*ENABLE_NLS.*/#if defined( ENABLE_NLS ) \&\& defined ( HAVE_GETTEXT )/' < modules/gui/gtk/$file > /tmp/$$.$file.bak
+    mv -f /tmp/$$.$file.bak modules/gui/gtk/$file
 fi
 echo "$file."
 
index e042027..c5bc523 100755 (executable)
--- a/configure
+++ b/configure
@@ -5538,7 +5538,7 @@ esac
 BUILTINS="${BUILTINS}"
 PLUGINS="${PLUGINS} misc/dummy/dummy misc/null/null"
 PLUGINS="${PLUGINS} control/rc/rc misc/logger/logger access/file access/udp access/http misc/network/ipv4 misc/memcpy/memcpy"
-PLUGINS="${PLUGINS} demux/mpeg/es demux/mpeg/audio demux/mpeg/ps demux/mpeg/ts"
+PLUGINS="${PLUGINS} demux/mpeg/es demux/mpeg/audio demux/mpeg/mpeg_system demux/mpeg/ps demux/mpeg/ts"
 PLUGINS="${PLUGINS} codec/mpeg_video/idct/idct codec/mpeg_video/idct/idctclassic codec/mpeg_video/motion/motion codec/a52old/imdct/imdct codec/a52old/downmix/downmix codec/mpeg_audio/mpeg_audio codec/a52old/a52old codec/mpeg_video/mpeg_video codec/lpcm/lpcm codec/spdif/spdif codec/spudec/spudec"
 PLUGINS="${PLUGINS} video_filter/deinterlace/deinterlace video_filter/invert video_filter/wall video_filter/transform video_filter/distort video_filter/clone video_filter/crop"
 PLUGINS="${PLUGINS} visualization/scope/scope"
index 88b8198..eb4c651 100644 (file)
@@ -436,7 +436,7 @@ dnl
 BUILTINS="${BUILTINS}"
 PLUGINS="${PLUGINS} misc/dummy/dummy misc/null/null"
 PLUGINS="${PLUGINS} control/rc/rc misc/logger/logger access/file access/udp access/http misc/network/ipv4 misc/memcpy/memcpy"
-PLUGINS="${PLUGINS} demux/mpeg/es demux/mpeg/audio demux/mpeg/ps demux/mpeg/ts"
+PLUGINS="${PLUGINS} demux/mpeg/es demux/mpeg/audio demux/mpeg/mpeg_system demux/mpeg/ps demux/mpeg/ts"
 PLUGINS="${PLUGINS} codec/mpeg_video/idct/idct codec/mpeg_video/idct/idctclassic codec/mpeg_video/motion/motion codec/a52old/imdct/imdct codec/a52old/downmix/downmix codec/mpeg_audio/mpeg_audio codec/a52old/a52old codec/mpeg_video/mpeg_video codec/lpcm/lpcm codec/spdif/spdif codec/spudec/spudec"
 PLUGINS="${PLUGINS} video_filter/deinterlace/deinterlace video_filter/invert video_filter/wall video_filter/transform video_filter/distort video_filter/clone video_filter/crop"
 PLUGINS="${PLUGINS} visualization/scope/scope"
index ff32291..7c916bc 100644 (file)
@@ -2,7 +2,7 @@
  * input_ext-dec.h: structures exported to the VideoLAN decoders
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: input_ext-dec.h,v 1.66 2002/08/04 17:23:41 sam Exp $
+ * $Id: input_ext-dec.h,v 1.67 2002/08/07 00:29:36 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Michel Kaempf <maxx@via.ecp.fr>
@@ -116,7 +116,7 @@ struct decoder_fifo_t
     /* Standard pointers given to the decoders as a toolbox. */
     u16                 i_id;
     vlc_fourcc_t        i_fourcc;
-    void *              p_demux_data;
+    es_sys_t *          p_demux_data;
     stream_ctrl_t *     p_stream_ctrl;
 
     /* Module properties */
index 4b107b8..063dc3b 100644 (file)
@@ -4,7 +4,7 @@
  * control the pace of reading. 
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_ext-intf.h,v 1.74 2002/08/04 17:23:41 sam Exp $
+ * $Id: input_ext-intf.h,v 1.75 2002/08/07 00:29:36 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -56,7 +56,7 @@ struct es_descriptor_t
                                            *  available */
 
     /* Demultiplexer information */
-    void *                  p_demux_data;
+    es_sys_t *              p_demux_data;
     pgrm_descriptor_t *     p_pgrm;  /* very convenient in the demultiplexer */
 
     /* PES parser information */
@@ -112,7 +112,7 @@ struct pgrm_descriptor_t
     int                     i_synchro_state;
 
     /* Demultiplexer data */
-    void *                  p_demux_data;
+    pgrm_sys_t *            p_demux_data;
 
     int                     i_es_number;      /* size of the following array */
     es_descriptor_t **      pp_es;                /* array of pointers to ES */
@@ -213,7 +213,7 @@ struct stream_descriptor_t
                                           * status change request            */
 
     /* Demultiplexer data */
-    void *                  p_demux_data;
+    stream_sys_t *          p_demux_data;
 
     /* Programs descriptions */
     int                     i_pgrm_number;    /* size of the following array */
@@ -275,7 +275,7 @@ struct input_thread_t
     int           (* pf_set_program )( input_thread_t *, pgrm_descriptor_t * );
     int           (* pf_set_area )( input_thread_t *, input_area_t * );
     void          (* pf_seek ) ( input_thread_t *, off_t );
-    void *           p_access_data;
+    access_sys_t *   p_access_data;
     size_t           i_mtu;
 
     /* Demux module */
@@ -284,7 +284,7 @@ struct input_thread_t
     int           (* pf_rewind ) ( input_thread_t * );
                                            /* NULL if we don't support going *
                                             * backwards (it's gonna be fun)  */
-    void *           p_demux_data;                      /* data of the demux */
+    demux_sys_t *    p_demux_data;                      /* data of the demux */
 
     /* Buffer manager */
     input_buffers_t *p_method_data;     /* data of the packet manager */
index 3bf087b..d8d5293 100644 (file)
@@ -3,7 +3,7 @@
  *                      but exported to plug-ins
  *****************************************************************************
  * Copyright (C) 1999-2002 VideoLAN
- * $Id: input_ext-plugins.h,v 1.33 2002/07/31 20:56:50 sam Exp $
+ * $Id: input_ext-plugins.h,v 1.34 2002/08/07 00:29:36 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -142,130 +142,6 @@ static inline void input_NullPacket( input_thread_t * p_input,
     }
 }
 
-
-/*
- * Optional MPEG demultiplexing
- */
-
-/*****************************************************************************
- * Constants
- *****************************************************************************/
-#define TS_PACKET_SIZE      188                       /* Size of a TS packet */
-#define TS_SYNC_CODE        0x47                /* First byte of a TS packet */
-#define PSI_SECTION_SIZE    4096            /* Maximum size of a PSI section */
-
-#define PAT_UNINITIALIZED    (1 << 6)
-#define PMT_UNINITIALIZED    (1 << 6)
-
-#define PSI_IS_PAT          0x00
-#define PSI_IS_PMT          0x01
-#define UNKNOWN_PSI         0xff
-
-/****************************************************************************
- * psi_callback_t
- ****************************************************************************
- * Used by TS demux to handle a PSI, either with the builtin decoder, either
- * with a library such as libdvbpsi
- ****************************************************************************/
-typedef void( * psi_callback_t )( 
-        input_thread_t  * p_input,
-        data_packet_t   * p_data,
-        es_descriptor_t * p_es,
-        vlc_bool_t        b_unit_start );
-
-
-/*****************************************************************************
- * psi_section_t
- *****************************************************************************
- * Describes a PSI section. Beware, it doesn't contain pointers to the TS
- * packets that contain it as for a PES, but the data themselves
- *****************************************************************************/
-typedef struct psi_section_t
-{
-    byte_t                  buffer[PSI_SECTION_SIZE];
-
-    u8                      i_section_number;
-    u8                      i_last_section_number;
-    u8                      i_version_number;
-    u16                     i_section_length;
-    u16                     i_read_in_section;
-    
-    /* the PSI is complete */
-    vlc_bool_t              b_is_complete;
-    
-    /* packet missed up ? */
-    vlc_bool_t              b_trash;
-
-    /*about sections  */ 
-    vlc_bool_t              b_section_complete;
-
-    /* where are we currently ? */
-    byte_t                * p_current;
-
-} psi_section_t;
-
-/*****************************************************************************
- * es_ts_data_t: extension of es_descriptor_t
- *****************************************************************************/
-typedef struct es_ts_data_t
-{
-    vlc_bool_t              b_psi;   /* Does the stream have to be handled by
-                                      *                    the PSI decoder ? */
-
-    int                     i_psi_type;  /* There are different types of PSI */
-    
-    psi_section_t *         p_psi_section;                    /* PSI packets */
-
-    /* Markers */
-    int                     i_continuity_counter;
-} es_ts_data_t;
-
-/*****************************************************************************
- * pgrm_ts_data_t: extension of pgrm_descriptor_t
- *****************************************************************************/
-typedef struct pgrm_ts_data_t
-{
-    u16                     i_pcr_pid;             /* PCR ES, for TS streams */
-    int                     i_pmt_version;
-    /* libdvbpsi pmt decoder handle */
-    void *                  p_pmt_handle;
-} pgrm_ts_data_t;
-
-/*****************************************************************************
- * stream_ts_data_t: extension of stream_descriptor_t
- *****************************************************************************/
-typedef struct stream_ts_data_t
-{
-    int i_pat_version;          /* Current version of the PAT */
-    /* libdvbpsi pmt decoder handle */
-    void *                  p_pat_handle;
-} stream_ts_data_t;
-
-/*****************************************************************************
- * stream_ps_data_t: extension of stream_descriptor_t
- *****************************************************************************/
-typedef struct stream_ps_data_t
-{
-    vlc_bool_t              b_has_PSM;                 /* very rare, in fact */
-
-    u8                      i_PSM_version;
-} stream_ps_data_t;
-
-/* PSM version is 5 bits, so -1 is not a valid value */
-#define EMPTY_PSM_VERSION   -1
-
-
-/*****************************************************************************
- * Prototypes
- *****************************************************************************/
-VLC_EXPORT( void, input_ParsePES,  ( input_thread_t *, es_descriptor_t * ) );
-VLC_EXPORT( void, input_GatherPES, ( input_thread_t *, data_packet_t *, es_descriptor_t *, vlc_bool_t, vlc_bool_t ) );
-VLC_EXPORT( ssize_t, input_ReadPS, ( input_thread_t *, data_packet_t ** ) );
-VLC_EXPORT( es_descriptor_t *, input_ParsePS, ( input_thread_t *, data_packet_t * ) );
-VLC_EXPORT( ssize_t, input_ReadTS, ( input_thread_t *, data_packet_t ** ) );
-VLC_EXPORT( void, input_DemuxPS,   ( input_thread_t *, data_packet_t * ) );
-VLC_EXPORT( void, input_DemuxTS,   ( input_thread_t *, data_packet_t *, void(*) ( input_thread_t *, data_packet_t *, es_descriptor_t *, vlc_bool_t ) ) );
-
 /*
  * Optional standard file descriptor operations (input_ext-plugins.h)
  */
index a9be580..f4f1f1d 100644 (file)
@@ -3,7 +3,7 @@
  * Collection of useful common types and macros definitions
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: vlc_common.h,v 1.13 2002/07/31 20:56:50 sam Exp $
+ * $Id: vlc_common.h,v 1.14 2002/08/07 00:29:36 sam Exp $
  *
  * Authors: Samuel Hocevar <sam@via.ecp.fr>
  *          Vincent Seguin <seguin@via.ecp.fr>
@@ -147,7 +147,6 @@ VLC_DECLARE_STRUCT(module_bank_t)
 VLC_DECLARE_STRUCT(module_t)
 VLC_DECLARE_STRUCT(module_config_t)
 VLC_DECLARE_STRUCT(module_symbols_t)
-VLC_DECLARE_STRUCT(module_functions_t)
 
 /* Interface */
 VLC_DECLARE_STRUCT(intf_thread_t)
@@ -159,10 +158,19 @@ VLC_DECLARE_STRUCT(intf_channel_t)
 /* Input */
 VLC_DECLARE_STRUCT(input_thread_t)
 VLC_DECLARE_STRUCT(input_channel_t)
-VLC_DECLARE_STRUCT(input_cfg_t)
 VLC_DECLARE_STRUCT(input_area_t)
 VLC_DECLARE_STRUCT(input_buffers_t)
 VLC_DECLARE_STRUCT(input_socket_t)
+VLC_DECLARE_STRUCT(input_info_t)
+VLC_DECLARE_STRUCT(input_info_category_t)
+VLC_DECLARE_STRUCT(access_sys_t)
+VLC_DECLARE_STRUCT(demux_sys_t)
+VLC_DECLARE_STRUCT(es_descriptor_t)
+VLC_DECLARE_STRUCT(es_sys_t)
+VLC_DECLARE_STRUCT(pgrm_descriptor_t)
+VLC_DECLARE_STRUCT(pgrm_sys_t)
+VLC_DECLARE_STRUCT(stream_descriptor_t)
+VLC_DECLARE_STRUCT(stream_sys_t)
 
 /* Audio */
 VLC_DECLARE_STRUCT(aout_thread_t)
@@ -184,24 +192,14 @@ VLC_DECLARE_STRUCT(subpicture_sys_t)
 VLC_DECLARE_STRUCT(decoder_fifo_t)
 
 /* Misc */
-VLC_DECLARE_STRUCT(macroblock_t)
 VLC_DECLARE_STRUCT(data_packet_t)
 VLC_DECLARE_STRUCT(data_buffer_t)
-VLC_DECLARE_STRUCT(downmix_t)
-VLC_DECLARE_STRUCT(imdct_t)
-VLC_DECLARE_STRUCT(complex_t)
-VLC_DECLARE_STRUCT(dm_par_t)
-VLC_DECLARE_STRUCT(es_descriptor_t)
-VLC_DECLARE_STRUCT(pgrm_descriptor_t)
-VLC_DECLARE_STRUCT(stream_descriptor_t)
 VLC_DECLARE_STRUCT(stream_position_t)
 VLC_DECLARE_STRUCT(stream_ctrl_t)
 VLC_DECLARE_STRUCT(pes_packet_t)
 VLC_DECLARE_STRUCT(bit_stream_t)
 VLC_DECLARE_STRUCT(network_socket_t)
 VLC_DECLARE_STRUCT(iso639_lang_t)
-VLC_DECLARE_STRUCT(input_info_t)
-VLC_DECLARE_STRUCT(input_info_category_t)
 
 /*****************************************************************************
  * Plug-in stuff
index fa2f94b..d677084 100644 (file)
@@ -16,7 +16,6 @@ struct module_symbols_t
     data_packet_t * (* input_ShareBuffer_inner) ( input_buffers_t *, data_buffer_t * ) ;
     es_descriptor_t * (* input_AddES_inner) ( input_thread_t *, pgrm_descriptor_t *, u16, size_t ) ;
     es_descriptor_t * (* input_FindES_inner) ( input_thread_t *, u16 ) ;
-    es_descriptor_t * (* input_ParsePS_inner) ( input_thread_t *, data_packet_t * ) ;
     float (* __config_GetFloat_inner) (vlc_object_t *, const char *) ;
     input_area_t * (* input_AddArea_inner) ( input_thread_t * ) ;
     input_info_category_t * (* input_InfoCategory_inner) ( input_thread_t *, char * ) ;
@@ -61,8 +60,6 @@ struct module_symbols_t
     ssize_t (* input_FDRead_inner) ( input_thread_t *, byte_t *, size_t ) ;
     ssize_t (* input_FillBuffer_inner) ( input_thread_t * ) ;
     ssize_t (* input_Peek_inner) ( input_thread_t *, byte_t **, size_t ) ;
-    ssize_t (* input_ReadPS_inner) ( input_thread_t *, data_packet_t ** ) ;
-    ssize_t (* input_ReadTS_inner) ( input_thread_t *, data_packet_t ** ) ;
     ssize_t (* input_SplitBuffer_inner) ( input_thread_t *, data_packet_t **, size_t ) ;
     subpicture_t * (* vout_CreateSubPicture_inner) ( vout_thread_t *, int, int ) ;
     u32 (* UnalignedGetBits_inner) ( bit_stream_t *, unsigned int ) ;
@@ -112,13 +109,9 @@ struct module_symbols_t
     void (* input_DelProgram_inner) ( input_thread_t *, pgrm_descriptor_t * ) ;
     void (* input_DeletePES_inner) ( input_buffers_t *, pes_packet_t * ) ;
     void (* input_DeletePacket_inner) ( input_buffers_t *, data_packet_t * ) ;
-    void (* input_DemuxPS_inner) ( input_thread_t *, data_packet_t * ) ;
-    void (* input_DemuxTS_inner) ( input_thread_t *, data_packet_t *, void(*) ( input_thread_t *, data_packet_t *, es_descriptor_t *, vlc_bool_t ) ) ;
     void (* input_DumpStream_inner) ( input_thread_t * ) ;
     void (* input_EndStream_inner) ( input_thread_t * ) ;
     void (* input_FDSeek_inner) ( input_thread_t *, off_t ) ;
-    void (* input_GatherPES_inner) ( input_thread_t *, data_packet_t *, es_descriptor_t *, vlc_bool_t, vlc_bool_t ) ;
-    void (* input_ParsePES_inner) ( input_thread_t *, es_descriptor_t * ) ;
     void (* input_ReleaseBuffer_inner) ( input_buffers_t *, data_buffer_t * ) ;
     void (* intf_Destroy_inner) ( intf_thread_t * ) ;
     void (* intf_StopThread_inner) ( intf_thread_t * ) ;
@@ -225,8 +218,6 @@ struct module_symbols_t
 #   define input_DelProgram p_symbols->input_DelProgram_inner
 #   define input_DeletePES p_symbols->input_DeletePES_inner
 #   define input_DeletePacket p_symbols->input_DeletePacket_inner
-#   define input_DemuxPS p_symbols->input_DemuxPS_inner
-#   define input_DemuxTS p_symbols->input_DemuxTS_inner
 #   define input_DumpStream p_symbols->input_DumpStream_inner
 #   define input_EndStream p_symbols->input_EndStream_inner
 #   define input_FDNetworkRead p_symbols->input_FDNetworkRead_inner
@@ -235,18 +226,13 @@ struct module_symbols_t
 #   define input_FillBuffer p_symbols->input_FillBuffer_inner
 #   define input_FindES p_symbols->input_FindES_inner
 #   define input_FindProgram p_symbols->input_FindProgram_inner
-#   define input_GatherPES p_symbols->input_GatherPES_inner
 #   define input_InfoCategory p_symbols->input_InfoCategory_inner
 #   define input_InitStream p_symbols->input_InitStream_inner
 #   define input_NewBuffer p_symbols->input_NewBuffer_inner
 #   define input_NewPES p_symbols->input_NewPES_inner
 #   define input_NewPacket p_symbols->input_NewPacket_inner
 #   define input_OffsetToTime p_symbols->input_OffsetToTime_inner
-#   define input_ParsePES p_symbols->input_ParsePES_inner
-#   define input_ParsePS p_symbols->input_ParsePS_inner
 #   define input_Peek p_symbols->input_Peek_inner
-#   define input_ReadPS p_symbols->input_ReadPS_inner
-#   define input_ReadTS p_symbols->input_ReadTS_inner
 #   define input_ReleaseBuffer p_symbols->input_ReleaseBuffer_inner
 #   define input_SelectES p_symbols->input_SelectES_inner
 #   define input_SetProgram p_symbols->input_SetProgram_inner
index 267feba..8e84e2f 100644 (file)
@@ -8,7 +8,7 @@
  *  -udf.* to find files
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: access.c,v 1.1 2002/08/04 17:23:41 sam Exp $
+ * $Id: access.c,v 1.2 2002/08/07 00:29:36 sam Exp $
  *
  * Author: Stéphane Borel <stef@via.ecp.fr>
  *
@@ -37,6 +37,8 @@
 #include <vlc/vlc.h>
 #include <vlc/input.h>
 
+#include "../../demux/mpeg/system.h"
+
 #ifdef HAVE_UNISTD_H
 #   include <unistd.h>
 #endif
index b2c7bdc..21ef836 100644 (file)
@@ -1,7 +1,7 @@
 /* demux.c: DVD demux functions.
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: demux.c,v 1.1 2002/08/04 17:23:41 sam Exp $
+ * $Id: demux.c,v 1.2 2002/08/07 00:29:36 sam Exp $
  *
  * Author: Stéphane Borel <stef@via.ecp.fr>
  *
@@ -30,6 +30,8 @@
 #include <vlc/vlc.h>
 #include <vlc/input.h>
 
+#include "../../demux/mpeg/system.h"
+
 #ifdef HAVE_UNISTD_H
 #   include <unistd.h>
 #endif
 /* how many packets DVDDemux will read in each loop */
 #define DVD_READ_ONCE 64
 
+/*****************************************************************************
+ * Private structure
+ *****************************************************************************/
+struct demux_sys_t
+{
+    module_t *   p_module;
+    mpeg_demux_t mpeg;
+};
+
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
@@ -54,22 +65,33 @@ static int  DVDDemux   ( input_thread_t * );
 
 void DVDLaunchDecoders( input_thread_t * );
 
-/*
- * Data demux functions
- */
-
 /*****************************************************************************
- * DVDInit: initializes DVD structures
+ * DVDInit: initialize DVD structures
  *****************************************************************************/
 int E_(DVDInit) ( vlc_object_t *p_this )
 {
     input_thread_t *p_input = (input_thread_t *)p_this;
+    demux_sys_t *   p_demux;
 
     if( p_input->stream.i_method != INPUT_METHOD_DVD )
     {
         return -1;
     }
 
+    p_demux = p_input->p_demux_data = malloc( sizeof(demux_sys_t ) );
+    if( p_demux == NULL )
+    {
+        return -1;
+    }
+
+    p_input->p_private = (void*)&p_demux->mpeg;
+    p_demux->p_module = module_Need( p_input, "mpeg-system", NULL );
+    if( p_demux->p_module == NULL )
+    {
+        free( p_input->p_demux_data );
+        return -1;
+    }
+
     p_input->pf_demux = DVDDemux;
     p_input->pf_rewind = NULL;
 
@@ -82,6 +104,17 @@ int E_(DVDInit) ( vlc_object_t *p_this )
     return 0;
 }
 
+/*****************************************************************************
+ * DVDEnd: free DVD structures
+ *****************************************************************************/
+void E_(DVDEnd) ( vlc_object_t *p_this )
+{
+    input_thread_t *p_input = (input_thread_t *)p_this;
+
+    module_Unneed( p_input, p_input->p_demux_data->p_module );
+    free( p_input->p_demux_data );
+}
+
 /*****************************************************************************
  * DVDDemux
  *****************************************************************************/
@@ -94,7 +127,7 @@ static int DVDDemux( input_thread_t * p_input )
     /* Read headers to compute payload length */
     for( i = 0 ; i < DVD_READ_ONCE ; i++ )
     {
-        i_result = input_ReadPS( p_input, &p_data );
+        i_result = p_input->p_demux_data->mpeg.pf_read_ps( p_input, &p_data );
 
         if( i_result < 0 )
         {
@@ -105,7 +138,7 @@ static int DVDDemux( input_thread_t * p_input )
             return i;
         }
 
-        input_DemuxPS( p_input, p_data );
+        p_input->p_demux_data->mpeg.pf_demux_ps( p_input, p_data );
     }
     
     return i;
index c229f70..de22837 100644 (file)
@@ -2,7 +2,7 @@
  * dvd.c : DVD input module for vlc
  *****************************************************************************
  * Copyright (C) 2000-2001 VideoLAN
- * $Id: dvd.c,v 1.1 2002/08/04 17:23:41 sam Exp $
+ * $Id: dvd.c,v 1.2 2002/08/07 00:29:36 sam Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -51,6 +51,7 @@ int  E_(DVDOpen)   ( vlc_object_t * );
 void E_(DVDClose)  ( vlc_object_t * );
 
 int  E_(DVDInit)   ( vlc_object_t * );
+void E_(DVDEnd)    ( vlc_object_t * );
 
 #ifdef GOD_DAMN_DMCA
 static void *p_libdvdcss;
@@ -97,7 +98,7 @@ vlc_module_begin();
         set_callbacks( E_(DVDOpen), E_(DVDClose) );
     add_submodule();
         set_capability( "demux", 0 );
-        set_callbacks( E_(DVDInit), NULL );
+        set_callbacks( E_(DVDInit), E_(DVDEnd) );
 #ifdef GOD_DAMN_DMCA
     ProbeLibDVDCSS();
 #endif
index 7161c83..9dcaf75 100644 (file)
@@ -2,7 +2,7 @@
  * access.c: access capabilities for dvdplay plugin.
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: access.c,v 1.1 2002/08/04 17:23:42 sam Exp $
+ * $Id: access.c,v 1.2 2002/08/07 00:29:36 sam Exp $
  *
  * Author: Stéphane Borel <stef@via.ecp.fr>
  *
@@ -30,6 +30,8 @@
 #include <vlc/vlc.h>
 #include <vlc/input.h>
 
+#include "../../demux/mpeg/system.h"
+
 #ifdef HAVE_UNISTD_H
 #   include <unistd.h>
 #endif
index 021f5c7..db491a8 100644 (file)
@@ -2,7 +2,7 @@
  * demux.c: demux functions for dvdplay.
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: demux.c,v 1.1 2002/08/04 17:23:42 sam Exp $
+ * $Id: demux.c,v 1.2 2002/08/07 00:29:36 sam Exp $
  *
  * Author: Stéphane Borel <stef@via.ecp.fr>
  *
@@ -31,6 +31,8 @@
 #include <vlc/vlc.h>
 #include <vlc/input.h>
 
+#include "../../demux/mpeg/system.h"
+
 #ifdef HAVE_UNISTD_H
 #   include <unistd.h>
 #endif
  *****************************************************************************/
 static int  Demux         ( input_thread_t * );
 
+/*****************************************************************************
+ * Private structure
+ *****************************************************************************/
+struct demux_sys_t
+{
+    dvd_data_t * p_dvd;
+
+    module_t *   p_module;
+    mpeg_demux_t mpeg;
+};
+
 /*****************************************************************************
  * InitDVD: initializes dvdplay structures
  *****************************************************************************/
 int E_(InitDVD) ( vlc_object_t *p_this )
 {
     input_thread_t *p_input = (input_thread_t *)p_this;
-    dvd_data_t *    p_dvd;
+    dvd_data_t *    p_dvd = (dvd_data_t *)p_input->p_access_data;
+    demux_sys_t *   p_demux;
     char *          psz_intf = NULL;
 
     if( p_input->stream.i_method != INPUT_METHOD_DVD )
@@ -72,8 +86,21 @@ int E_(InitDVD) ( vlc_object_t *p_this )
         return -1;
     }
 
-    p_input->p_demux_data = (void*)p_input->p_access_data;
-    p_dvd = (dvd_data_t *)p_input->p_demux_data;
+    p_demux = p_input->p_demux_data = malloc( sizeof(demux_sys_t ) );
+    if( p_demux == NULL )
+    {
+        return -1;
+    }
+
+    p_input->p_private = (void*)&p_demux->mpeg;
+    p_demux->p_module = module_Need( p_input, "mpeg-system", NULL );
+    if( p_demux->p_module == NULL )
+    {
+        free( p_input->p_demux_data );
+        return -1;
+    }
+
+    p_input->p_demux_data->p_dvd = p_dvd;
 
     p_input->pf_demux = Demux;
     p_input->pf_rewind = NULL;
@@ -98,7 +125,7 @@ int E_(InitDVD) ( vlc_object_t *p_this )
 void E_(EndDVD) ( vlc_object_t *p_this )
 {
     input_thread_t *p_input = (input_thread_t *)p_this;
-    dvd_data_t *    p_dvd;
+    dvd_data_t *    p_dvd = p_input->p_demux_data->p_dvd;
     intf_thread_t * p_intf = NULL;
 
     p_intf = vlc_object_find( p_input, VLC_OBJECT_INTF, FIND_CHILD );
@@ -110,8 +137,10 @@ void E_(EndDVD) ( vlc_object_t *p_this )
         intf_Destroy( p_intf );
     }
 
-    p_dvd = (dvd_data_t *)p_input->p_demux_data;
     p_dvd->p_intf = NULL;
+
+    module_Unneed( p_input, p_input->p_demux_data->p_module );
+    free( p_input->p_demux_data );
 }
 
 /*****************************************************************************
@@ -125,19 +154,21 @@ static int Demux( input_thread_t * p_input )
     ptrdiff_t               i_remains;
     int                     i_data_nb = 0;
 
-    p_dvd = (dvd_data_t *)p_input->p_demux_data;
+    p_dvd = p_input->p_demux_data->p_dvd;
    
     /* Read headers to compute payload length */
     do
     {
-        if( ( i_result = input_ReadPS( p_input, &p_data ) ) <= 0)
+        i_result = p_input->p_demux_data->mpeg.pf_read_ps( p_input, &p_data );
+
+        if( i_result <= 0 )
         {
             return i_result;
         }
 
         i_remains = p_input->p_last_data - p_input->p_current_data;
 
-        input_DemuxPS( p_input, p_data );
+        p_input->p_demux_data->mpeg.pf_demux_ps( p_input, p_data );
         
 
         ++i_data_nb;
index a09e133..6e565c7 100644 (file)
@@ -2,7 +2,7 @@
  * es.c: functions to handle elementary streams.
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: es.c,v 1.1 2002/08/04 17:23:42 sam Exp $
+ * $Id: es.c,v 1.2 2002/08/07 00:29:36 sam Exp $
  *
  * Author: Stéphane Borel <stef@via.ecp.fr>
  *
@@ -204,7 +204,7 @@ void dvdplay_Subp( input_thread_t * p_input )
             if( pi_palette )
             {
                 ADDES( i_id, VLC_FOURCC('s','p','u',' '), SPU_ES,
-                       p_attr->lang_code, 16*sizeof(u32) );
+                       p_attr->lang_code, sizeof(int) + 16*sizeof(u32) );
                 *(int*)p_es->p_demux_data = 0xBeeF;
                 memcpy( (void*)p_es->p_demux_data + sizeof(int),
                         pi_palette, 16*sizeof(u32) ); 
index 6414f6f..4f7e138 100644 (file)
@@ -2,7 +2,7 @@
  * dvdread.c : DvdRead input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: dvdread.c,v 1.1 2002/08/04 17:23:42 sam Exp $
+ * $Id: dvdread.c,v 1.2 2002/08/07 00:29:36 sam Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -36,6 +36,7 @@ int  E_(OpenDVD)   ( vlc_object_t * );
 void E_(CloseDVD)  ( vlc_object_t * );
 
 int  E_(InitDVD)   ( vlc_object_t * );
+void E_(EndDVD)    ( vlc_object_t * );
 
 /*****************************************************************************
  * Module descriptor
@@ -48,6 +49,6 @@ vlc_module_begin();
         set_callbacks( E_(OpenDVD), E_(CloseDVD) );      
     add_submodule();
         set_capability( "demux", 0 );
-        set_callbacks( E_(InitDVD), NULL );
+        set_callbacks( E_(InitDVD), E_(EndDVD) );
 vlc_module_end();  
 
index 82380ee..3324ea8 100644 (file)
@@ -6,7 +6,7 @@
  * It depends on: libdvdread for ifo files and block reading.
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: input.c,v 1.1 2002/08/04 17:23:42 sam Exp $
+ * $Id: input.c,v 1.2 2002/08/07 00:29:36 sam Exp $
  *
  * Author: Stéphane Borel <stef@via.ecp.fr>
  *
@@ -37,6 +37,8 @@
 #include <vlc/vlc.h>
 #include <vlc/input.h>
 
+#include "../../demux/mpeg/system.h"
+
 #ifdef HAVE_UNISTD_H
 #   include <unistd.h>
 #endif
 /* how many blocks DVDRead will read in each loop */
 #define DVD_BLOCK_READ_ONCE 64
 
+/*****************************************************************************
+ * Private structure
+ *****************************************************************************/
+struct demux_sys_t
+{
+    module_t *   p_module;
+    mpeg_demux_t mpeg;
+};
+
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
@@ -97,17 +108,32 @@ static void DvdReadFindCell ( thread_dvd_data_t * p_dvd );
  */
 
 /*****************************************************************************
- * InitDVD: initializes DVD structures
+ * InitDVD: initialize DVD structures
  *****************************************************************************/
 int E_(InitDVD) ( vlc_object_t *p_this )
 {
     input_thread_t *p_input = (input_thread_t *)p_this;
+    demux_sys_t *   p_demux;
 
     if( p_input->stream.i_method != INPUT_METHOD_DVD )
     {
         return -1;
     }
 
+    p_demux = p_input->p_demux_data = malloc( sizeof(demux_sys_t ) );
+    if( p_demux == NULL )
+    {
+        return -1;
+    }
+
+    p_input->p_private = (void*)&p_demux->mpeg;
+    p_demux->p_module = module_Need( p_input, "mpeg-system", NULL );
+    if( p_demux->p_module == NULL )
+    {
+        free( p_input->p_demux_data );
+        return -1;
+    }
+
     p_input->pf_demux = DvdReadDemux;
     p_input->pf_rewind = NULL;
 
@@ -120,6 +146,17 @@ int E_(InitDVD) ( vlc_object_t *p_this )
     return 0;
 }
 
+/*****************************************************************************
+ * EndDVD: end DVD structures
+ *****************************************************************************/
+void E_(EndDVD) ( vlc_object_t *p_this )
+{
+    input_thread_t *p_input = (input_thread_t *)p_this;
+
+    module_Unneed( p_input, p_input->p_demux_data->p_module );
+    free( p_input->p_demux_data );
+}
+
 /*****************************************************************************
  * DvdReadDemux
  *****************************************************************************/
@@ -180,7 +217,7 @@ static int DvdReadDemux( input_thread_t * p_input )
             p_input->p_current_data += i_stuffing;
         }
 
-        input_DemuxPS( p_input, p_data );
+        p_input->p_demux_data->mpeg.pf_demux_ps( p_input, p_data );
      
     }
 
index c7badd1..791fcbb 100644 (file)
@@ -2,7 +2,7 @@
  * http.c: HTTP access plug-in
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: http.c,v 1.1 2002/08/04 17:23:41 sam Exp $
+ * $Id: http.c,v 1.2 2002/08/07 00:29:36 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -91,7 +91,7 @@ typedef struct _input_socket_s
  *****************************************************************************/
 static int HTTPConnect( input_thread_t * p_input, off_t i_tell )
 {
-    _input_socket_t *   p_access_data = p_input->p_access_data;
+    _input_socket_t *   p_access_data;
     module_t *          p_network;
     char                psz_buffer[256];
     byte_t *            psz_parser;
@@ -99,6 +99,7 @@ static int HTTPConnect( input_thread_t * p_input, off_t i_tell )
     char *              psz_return_alpha;
 
     /* Find an appropriate network module */
+    p_access_data = (_input_socket_t *)p_input->p_access_data;
     p_input->p_private = (void*) &p_access_data->socket_desc;
     p_network = module_Need( p_input, "network", p_access_data->psz_network );
     if( p_network == NULL )
@@ -260,7 +261,8 @@ static int Open( vlc_object_t *p_this )
     char *              psz_proxy;
     int                 i_server_port = 0;
 
-    p_access_data = p_input->p_access_data = malloc( sizeof(_input_socket_t) );
+    p_access_data = malloc( sizeof(_input_socket_t) );
+    p_input->p_access_data = (access_sys_t *)p_access_data;
     if( p_access_data == NULL )
     {
         msg_Err( p_input, "out of memory" );
@@ -492,7 +494,7 @@ static int SetProgram( input_thread_t * p_input,
  *****************************************************************************/
 static void Seek( input_thread_t * p_input, off_t i_pos )
 {
-    _input_socket_t *   p_access_data = p_input->p_access_data;
+    _input_socket_t *p_access_data = (_input_socket_t*)p_input->p_access_data;
     close( p_access_data->_socket.i_handle );
     msg_Dbg( p_input, "seeking to position %lld", i_pos );
     HTTPConnect( p_input, i_pos );
index 1e828e0..fc32d93 100644 (file)
@@ -30,6 +30,8 @@
 #include <vlc/vlc.h>
 #include <vlc/input.h>
 
+#include "../../demux/mpeg/system.h"
+
 #ifdef HAVE_UNISTD_H
 #   include <unistd.h>
 #endif
index 3df44d2..04c3c30 100644 (file)
@@ -2,7 +2,7 @@
  * udp.c: raw UDP access plug-in
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: udp.c,v 1.1 2002/08/04 17:23:41 sam Exp $
+ * $Id: udp.c,v 1.2 2002/08/07 00:29:36 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -237,7 +237,9 @@ static int Open( vlc_object_t *p_this )
     }
     module_Unneed( p_input, p_network );
     
-    p_access_data = p_input->p_access_data = malloc( sizeof(input_socket_t) );
+    p_access_data = malloc( sizeof(input_socket_t) );
+    p_input->p_access_data = (access_sys_t *)p_access_data;
+
     if( p_access_data == NULL )
     {
         msg_Err( p_input, "out of memory" );
index 4fa9125..e0136c8 100644 (file)
@@ -2,7 +2,7 @@
  * vcd.c : VCD input module for vlc
  *****************************************************************************
  * Copyright (C) 2000 VideoLAN
- * $Id: vcd.c,v 1.1 2002/08/04 17:23:42 sam Exp $
+ * $Id: vcd.c,v 1.2 2002/08/07 00:29:36 sam Exp $
  *
  * Author: Johan Bilien <jobi@via.ecp.fr>
  *
@@ -30,6 +30,8 @@
 #include <vlc/vlc.h>
 #include <vlc/input.h>
 
+#include "../../demux/mpeg/system.h"
+
 #ifdef HAVE_UNISTD_H
 #   include <unistd.h>
 #endif
index 0da1074..4759b0e 100644 (file)
@@ -2,7 +2,7 @@
  * downmix.h : A52 downmix types
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: downmix.h,v 1.1 2002/08/04 17:23:42 sam Exp $
+ * $Id: downmix.h,v 1.2 2002/08/07 00:29:36 sam Exp $
  *
  * Authors: Michel Kaempf <maxx@via.ecp.fr>
  *          Renaud Dartus <reno@videolan.org>
@@ -22,6 +22,9 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
+VLC_DECLARE_STRUCT(dm_par_t)
+VLC_DECLARE_STRUCT(downmix_t)
+
 struct dm_par_t
 {
     float unit;
index 37d27eb..b12921b 100644 (file)
@@ -2,7 +2,7 @@
  * imdct.h : A52 IMDCT types
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: imdct.h,v 1.1 2002/08/04 17:23:42 sam Exp $
+ * $Id: imdct.h,v 1.2 2002/08/07 00:29:36 sam Exp $
  *
  * Authors: Michel Kaempf <maxx@via.ecp.fr>
  *          Renaud Dartus <reno@videolan.org>
@@ -22,6 +22,9 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
 
+VLC_DECLARE_STRUCT(complex_t)
+VLC_DECLARE_STRUCT(imdct_t)
+
 struct complex_t
 {
     float real;
index deceb75..a3d0d42 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
- * video_decoder.h : video decoder thread
+ * decoder.h : video decoder thread
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: decoder.h,v 1.1 2002/08/04 17:23:42 sam Exp $
+ * $Id: decoder.h,v 1.2 2002/08/07 00:29:36 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  *****************************************************************************/
  
+VLC_DECLARE_STRUCT(vpar_thread_t)
+VLC_DECLARE_STRUCT(vdec_thread_t)
+VLC_DECLARE_STRUCT(vdec_pool_t)
+
 /*****************************************************************************
  * vdec_thread_t: video decoder thread descriptor
  *****************************************************************************/
-typedef struct vdec_thread_s
+struct vdec_thread_t
 {
     VLC_COMMON_MEMBERS
 
     /* IDCT iformations */
-    void *               p_idct_data;
+    void *        p_idct_data;
 
     /* Input properties */
-    struct vdec_pool_s * p_pool;
-
-} vdec_thread_t;
+    vdec_pool_t * p_pool;
+};
 
 /*****************************************************************************
  * Prototypes
@@ -45,6 +48,6 @@ void            vdec_DecodeMacroblockBW ( vdec_thread_t *, macroblock_t * );
 void            vdec_DecodeMacroblock420( vdec_thread_t *, macroblock_t * );
 void            vdec_DecodeMacroblock422( vdec_thread_t *, macroblock_t * );
 void            vdec_DecodeMacroblock444( vdec_thread_t *, macroblock_t * );
-vdec_thread_t * vdec_CreateThread       ( struct vdec_pool_s * );
+vdec_thread_t * vdec_CreateThread       ( vdec_pool_t * );
 void            vdec_DestroyThread      ( vdec_thread_t * );
 
index f91da7e..25fc108 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
- * video_parser.h : video parser thread
+ * parser.h : video parser thread
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: parser.h,v 1.1 2002/08/04 17:23:42 sam Exp $
+ * $Id: parser.h,v 1.2 2002/08/07 00:29:36 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Jean-Marc Dressler <polux@via.ecp.fr>
@@ -60,11 +60,11 @@ extern u8       pi_scan[2][64];
 /*****************************************************************************
  * Prototypes
  *****************************************************************************/
-void vpar_InitScanTable( struct vpar_thread_s * p_vpar );
+void vpar_InitScanTable( vpar_thread_t * p_vpar );
 
-typedef void (*f_picture_data_t)( struct vpar_thread_s * p_vpar );
+typedef void (*f_picture_data_t)( vpar_thread_t * p_vpar );
 #define PROTO_PICD( FUNCNAME )                                              \
-void FUNCNAME( struct vpar_thread_s * p_vpar );
+void FUNCNAME( vpar_thread_t * p_vpar );
 
 PROTO_PICD( vpar_PictureDataGENERIC )
 #if (VPAR_OPTIM_LEVEL > 0)
@@ -232,8 +232,8 @@ typedef struct picture_parsing_s
 /*****************************************************************************
  * Prototypes
  *****************************************************************************/
-int vpar_NextSequenceHeader( struct vpar_thread_s * p_vpar );
-int vpar_ParseHeader( struct vpar_thread_s * p_vpar );
+int vpar_NextSequenceHeader( vpar_thread_t * p_vpar );
+int vpar_ParseHeader( vpar_thread_t * p_vpar );
 
 
 /*
@@ -286,20 +286,13 @@ typedef struct video_synchro_s
 /*****************************************************************************
  * Prototypes
  *****************************************************************************/
-void vpar_SynchroInit           ( struct vpar_thread_s * p_vpar );
-vlc_bool_t vpar_SynchroChoose   ( struct vpar_thread_s * p_vpar,
-                                  int i_coding_type, int i_structure );
-void vpar_SynchroTrash          ( struct vpar_thread_s * p_vpar,
-                                  int i_coding_type, int i_structure );
-void vpar_SynchroDecode         ( struct vpar_thread_s * p_vpar,
-                                  int i_coding_type, int i_structure );
-void vpar_SynchroEnd            ( struct vpar_thread_s * p_vpar,
-                                  int i_coding_type, int i_structure,
-                                  int i_garbage );
-mtime_t vpar_SynchroDate        ( struct vpar_thread_s * p_vpar );
-void vpar_SynchroNewPicture( struct vpar_thread_s * p_vpar, int i_coding_type,
-                             int i_repeat_field );
-
+void vpar_SynchroInit           ( vpar_thread_t * p_vpar );
+vlc_bool_t vpar_SynchroChoose   ( vpar_thread_t * p_vpar, int, int );
+void vpar_SynchroTrash          ( vpar_thread_t * p_vpar, int, int );
+void vpar_SynchroDecode         ( vpar_thread_t * p_vpar, int, int );
+void vpar_SynchroEnd            ( vpar_thread_t * p_vpar, int, int, int );
+mtime_t vpar_SynchroDate        ( vpar_thread_t * p_vpar );
+void vpar_SynchroNewPicture     ( vpar_thread_t * p_vpar, int, int );
 
 /*
  * Video parser structures
@@ -308,7 +301,7 @@ void vpar_SynchroNewPicture( struct vpar_thread_s * p_vpar, int i_coding_type,
 /*****************************************************************************
  * vpar_thread_t: video parser thread descriptor
  *****************************************************************************/
-typedef struct vpar_thread_s
+struct vpar_thread_t
 {
     bit_stream_t            bit_stream;
 
@@ -360,7 +353,7 @@ typedef struct vpar_thread_s
                                                    *        pictures decoded */
     count_t         pc_malformed_pictures[4];  /* number of pictures trashed
                                                 * during parsing             */
-} vpar_thread_t;
+};
 
 /*****************************************************************************
  * NextStartCode : Find the next start code
@@ -382,7 +375,7 @@ static inline void NextStartCode( bit_stream_t * p_bit_stream )
  *****************************************************************************
  * Quantizer scale factor (ISO/IEC 13818-2 7.4.2.2)
  *****************************************************************************/
-static inline void LoadQuantizerScale( struct vpar_thread_s * p_vpar )
+static inline void LoadQuantizerScale( vpar_thread_t * p_vpar )
 {
     /* Quantization coefficient table */
     static u8   pi_non_linear_quantizer_scale[32] =
index 81fe081..088ef7b 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
- * vdec_ext-plugins.h : structures from the video decoder exported to plug-ins
+ * plugins.h : structures from the video decoder exported to plug-ins
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: plugins.h,v 1.1 2002/08/04 18:39:41 sam Exp $
+ * $Id: plugins.h,v 1.2 2002/08/07 00:29:36 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -47,7 +47,7 @@ typedef struct motion_inner_t
     vlc_bool_t              b_second_half;
 } motion_inner_t;
 
-struct macroblock_t
+typedef struct macroblock_t
 {
     int                     i_mb_modes;
 
@@ -64,7 +64,8 @@ struct macroblock_t
     motion_inner_t          p_motions[8];
     int                     i_nb_motions;
     yuv_data_t *            pp_dest[3];
-};
+
+} macroblock_t;
 
 /* Macroblock Modes */
 #define MB_INTRA                        1
index 14347fd..37a7f35 100644 (file)
@@ -2,7 +2,7 @@
  * vpar_pool.h : video parser/video decoders communication
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: pool.h,v 1.1 2002/08/04 17:23:42 sam Exp $
+ * $Id: pool.h,v 1.2 2002/08/07 00:29:36 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -27,9 +27,7 @@
  * This structure is used for the communication between the parser and the
  * decoders.
  *****************************************************************************/
-typedef struct vdec_pool_s vdec_pool_t;
-
-struct vdec_pool_s
+struct vdec_pool_t
 {
     /* Locks */
     vlc_mutex_t         lock;                         /* Structure data lock */
@@ -68,8 +66,7 @@ struct vdec_pool_s
     void             (* pf_decode_mb) ( vdec_pool_t *, macroblock_t * );
 
     /* Pointer to the decoding function - used for B&W switching */
-    void             (* pf_vdec_decode) ( struct vdec_thread_s *,
-                                          macroblock_t * );
+    void             (* pf_vdec_decode) ( vdec_thread_t *, macroblock_t * );
     vlc_bool_t          b_bw;                      /* Current value for B&W */
 
     /* Access to the plug-ins needed by the video decoder thread */
@@ -77,15 +74,15 @@ struct vdec_pool_s
     void ( * ppppf_motion[2][2][4] ) ( yuv_data_t *, yuv_data_t *,
                                        int, int );
 
-    struct vpar_thread_s * p_vpar;
+    vpar_thread_t * p_vpar;
 };
 
 /*****************************************************************************
  * Prototypes
  *****************************************************************************/
-void vpar_InitPool  ( struct vpar_thread_s * );
-void vpar_SpawnPool ( struct vpar_thread_s * );
-void vpar_EndPool   ( struct vpar_thread_s * );
+void vpar_InitPool  ( vpar_thread_t * );
+void vpar_SpawnPool ( vpar_thread_t * );
+void vpar_EndPool   ( vpar_thread_t * );
 
 /*****************************************************************************
  * vpar_GetMacroblock: In a vdec thread, get the next available macroblock
index 6c67e71..b3fbc16 100644 (file)
@@ -2,7 +2,7 @@
  * avi.c : AVI file Stream input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: avi.c,v 1.1 2002/08/04 17:23:42 sam Exp $
+ * $Id: avi.c,v 1.2 2002/08/07 00:29:36 sam Exp $
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  * 
  * This program is free software; you can redistribute it and/or modify
@@ -430,19 +430,18 @@ static void __AVI_GetIndex( input_thread_t *p_input )
     int             i_number;
     int             i_type;
     int             i_totalentry = 0;
-    demux_data_avi_file_t *p_avi_demux =
-                        (demux_data_avi_file_t*)p_input->p_demux_data  ;    
+    demux_sys_t *p_avi = p_input->p_demux_data;
 
     if( RIFF_FindAndGotoDataChunk( p_input,
-                                   p_avi_demux->p_riff, 
+                                   p_avi->p_riff, 
                                    &p_idx1, 
                                    FOURCC_idx1)!=0 )
     {
         msg_Warn( p_input, "cannot find index" );
-        RIFF_GoToChunk( p_input, p_avi_demux->p_hdrl );        
+        RIFF_GoToChunk( p_input, p_avi->p_hdrl );        
         return;
     }
-    p_avi_demux->p_idx1 = p_idx1;
+    p_avi->p_idx1 = p_idx1;
     msg_Dbg( p_input, "loading index" ); 
     for(;;)
     {
@@ -464,11 +463,11 @@ static void __AVI_GetIndex( input_thread_t *p_input )
             index.i_length  = GetDWLE(p_peek+12);
             AVI_ParseStreamHeader( index.i_id, &i_number, &i_type );
             
-            if( ( i_number <  p_avi_demux->i_streams )
-               &&(p_avi_demux->pp_info[i_number]->i_cat == 
+            if( ( i_number <  p_avi->i_streams )
+               &&(p_avi->pp_info[i_number]->i_cat == 
                      AVI_GetESTypeFromTwoCC( i_type ))) 
             {
-                __AVI_AddEntryIndex( p_avi_demux->pp_info[i_number],
+                __AVI_AddEntryIndex( p_avi->pp_info[i_number],
                                      &index );
             }
         }
@@ -482,17 +481,16 @@ static void __AVI_UpdateIndexOffset( input_thread_t *p_input )
 {
     int i_stream;
     int b_start = 1;/* if index pos is based on start of file or not (p_movi) */
-    demux_data_avi_file_t *p_avi_demux =
-                        (demux_data_avi_file_t*)p_input->p_demux_data;
+    demux_sys_t *p_avi = p_input->p_demux_data;
 
 /* FIXME some work to do :
         * test in the file if it's true, if not do a RIFF_Find...
 */
-#define p_info p_avi_demux->pp_info[i_stream]
-    for( i_stream = 0; i_stream < p_avi_demux->i_streams; i_stream++ )
+#define p_info p_avi->pp_info[i_stream]
+    for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
     {
         if( ( p_info->p_index )
-           && ( p_info->p_index[0].i_pos < p_avi_demux->p_movi->i_pos + 8 ))
+           && ( p_info->p_index[0].i_pos < p_avi->p_movi->i_pos + 8 ))
         {
             b_start = 0;
             break;
@@ -500,14 +498,14 @@ static void __AVI_UpdateIndexOffset( input_thread_t *p_input )
     }
     if( !b_start )
     {
-        for( i_stream = 0; i_stream < p_avi_demux->i_streams; i_stream++ )
+        for( i_stream = 0; i_stream < p_avi->i_streams; i_stream++ )
         {
             int i;
             if( p_info->p_index )
             {
                 for( i = 0; i < p_info->i_idxnb; i++ )
                 {
-                    p_info->p_index[i].i_pos += p_avi_demux->p_movi->i_pos + 8;
+                    p_info->p_index[i].i_pos += p_avi->p_movi->i_pos + 8;
                 }
             }
         }
@@ -522,33 +520,32 @@ static void __AVIEnd ( vlc_object_t * p_this )
 {   
     input_thread_t *    p_input = (input_thread_t *)p_this;
     int i;
-    demux_data_avi_file_t *p_avi_demux;
-    p_avi_demux = (demux_data_avi_file_t*)p_input->p_demux_data  ; 
+    demux_sys_t *p_avi = p_input->p_demux_data  ; 
     
-    if( p_avi_demux->p_riff ) 
-            RIFF_DeleteChunk( p_input, p_avi_demux->p_riff );
-    if( p_avi_demux->p_hdrl ) 
-            RIFF_DeleteChunk( p_input, p_avi_demux->p_hdrl );
-    if( p_avi_demux->p_movi ) 
-            RIFF_DeleteChunk( p_input, p_avi_demux->p_movi );
-    if( p_avi_demux->p_idx1 ) 
-            RIFF_DeleteChunk( p_input, p_avi_demux->p_idx1 );
-    if( p_avi_demux->pp_info )
-    {
-        for( i = 0; i < p_avi_demux->i_streams; i++ )
+    if( p_avi->p_riff ) 
+            RIFF_DeleteChunk( p_input, p_avi->p_riff );
+    if( p_avi->p_hdrl ) 
+            RIFF_DeleteChunk( p_input, p_avi->p_hdrl );
+    if( p_avi->p_movi ) 
+            RIFF_DeleteChunk( p_input, p_avi->p_movi );
+    if( p_avi->p_idx1 ) 
+            RIFF_DeleteChunk( p_input, p_avi->p_idx1 );
+    if( p_avi->pp_info )
+    {
+        for( i = 0; i < p_avi->i_streams; i++ )
         {
-            if( p_avi_demux->pp_info[i] ) 
+            if( p_avi->pp_info[i] ) 
             {
-                if( p_avi_demux->pp_info[i]->p_index )
+                if( p_avi->pp_info[i]->p_index )
                 {
-                      free( p_avi_demux->pp_info[i]->p_index );
+                      free( p_avi->pp_info[i]->p_index );
                       AVI_PESBuffer_Flush( p_input->p_method_data, 
-                                           p_avi_demux->pp_info[i] );
+                                           p_avi->pp_info[i] );
                 }
-                free( p_avi_demux->pp_info[i] ); 
+                free( p_avi->pp_info[i] ); 
             }
         }
-         free( p_avi_demux->pp_info );
+         free( p_avi->pp_info );
     }
 }
 
@@ -561,21 +558,21 @@ static int AVIInit( vlc_object_t * p_this )
     riffchunk_t *p_riff,*p_hdrl,*p_movi;
     riffchunk_t *p_avih;
     riffchunk_t *p_strl,*p_strh,*p_strf;
-    demux_data_avi_file_t *p_avi_demux;
+    demux_sys_t *p_avi;
     es_descriptor_t *p_es = NULL; /* for not warning */
     int i;
 
     p_input->pf_demux = AVIDemux;
 
     if( !( p_input->p_demux_data = 
-                    p_avi_demux = malloc( sizeof(demux_data_avi_file_t) ) ) )
+                    p_avi = malloc( sizeof(demux_sys_t) ) ) )
     {
         msg_Err( p_input, "out of memory" );
         return( -1 );
     }
-    memset( p_avi_demux, 0, sizeof( demux_data_avi_file_t ) );
-    p_avi_demux->i_rate = DEFAULT_RATE;
-    p_avi_demux->b_seekable = ( ( p_input->stream.b_seekable )
+    memset( p_avi, 0, sizeof( demux_sys_t ) );
+    p_avi->i_rate = DEFAULT_RATE;
+    p_avi->b_seekable = ( ( p_input->stream.b_seekable )
                         &&( p_input->stream.i_method == INPUT_METHOD_FILE ) );
 
     /* Initialize access plug-in structures. */
@@ -591,7 +588,7 @@ static int AVIInit( vlc_object_t * p_this )
         msg_Warn( p_input, "RIFF-AVI module discarded" );
         return( -1 );
     }
-    p_avi_demux->p_riff = p_riff;
+    p_avi->p_riff = p_riff;
 
     if ( RIFF_DescendChunk(p_input) != 0 )
     {
@@ -607,7 +604,7 @@ static int AVIInit( vlc_object_t * p_this )
         msg_Err( p_input, "cannot find \"LIST-hdrl\"" );
         return( -1 );
     }
-    p_avi_demux->p_hdrl = p_hdrl;
+    p_avi->p_hdrl = p_hdrl;
 
     if( RIFF_DescendChunk(p_input) != 0 )
     {
@@ -623,10 +620,10 @@ static int AVIInit( vlc_object_t * p_this )
         msg_Err( p_input, "cannot find \"avih\" chunk" );
         return( -1 );
     }
-    AVI_Parse_avih( &p_avi_demux->avih, p_avih->p_data->p_payload_start );
+    AVI_Parse_avih( &p_avi->avih, p_avih->p_data->p_payload_start );
     RIFF_DeleteChunk( p_input, p_avih );
     
-    if( p_avi_demux->avih.i_streams == 0 )  
+    if( p_avi->avih.i_streams == 0 )  
     /* no stream found, perhaps it would be cool to find it */
     {
         AVIEnd( p_input );
@@ -651,21 +648,21 @@ static int AVIInit( vlc_object_t * p_this )
         return( -1 );
     }
     p_input->stream.p_selected_program = p_input->stream.pp_programs[0];
-    p_input->stream.i_mux_rate = p_avi_demux->avih.i_maxbytespersec / 50;
+    p_input->stream.i_mux_rate = p_avi->avih.i_maxbytespersec / 50;
     vlc_mutex_unlock( &p_input->stream.stream_lock ); 
 
     /* now read info on each stream and create ES */
-    p_avi_demux->i_streams = p_avi_demux->avih.i_streams;
+    p_avi->i_streams = p_avi->avih.i_streams;
     
-    p_avi_demux->pp_info = calloc( p_avi_demux->i_streams, 
+    p_avi->pp_info = calloc( p_avi->i_streams, 
                                     sizeof( AVIStreamInfo_t* ) );
-    memset( p_avi_demux->pp_info, 
+    memset( p_avi->pp_info, 
             0, 
-            sizeof( AVIStreamInfo_t* ) * p_avi_demux->i_streams );
+            sizeof( AVIStreamInfo_t* ) * p_avi->i_streams );
 
-    for( i = 0 ; i < p_avi_demux->i_streams; i++ )
+    for( i = 0 ; i < p_avi->i_streams; i++ )
     {
-#define p_info  p_avi_demux->pp_info[i]
+#define p_info  p_avi->pp_info[i]
         p_info = malloc( sizeof(AVIStreamInfo_t ) );
         memset( p_info, 0, sizeof( AVIStreamInfo_t ) );        
 
@@ -771,17 +768,17 @@ static int AVIInit( vlc_object_t * p_this )
         AVIEnd( p_input );
         return( -1 );
     }
-    p_avi_demux->p_movi = p_movi;
+    p_avi->p_movi = p_movi;
     
     /* get index  XXX need to have p_movi */
-    if( p_avi_demux->b_seekable )
+    if( p_avi->b_seekable )
     {
         /* get index */
         __AVI_GetIndex( p_input ); 
         /* try to get i_idxoffset for each stream  */
         __AVI_UpdateIndexOffset( p_input );
         /* to make sure to go the begining unless demux will see a seek */
-        RIFF_GoToChunk( p_input, p_avi_demux->p_movi );
+        RIFF_GoToChunk( p_input, p_avi->p_movi );
 
     }
     else
@@ -798,15 +795,15 @@ static int AVIInit( vlc_object_t * p_this )
 
     /* print informations on streams */
     msg_Dbg( p_input, "AVIH: %d stream, flags %s%s%s%s ", 
-             p_avi_demux->i_streams,
-             p_avi_demux->avih.i_flags&AVIF_HASINDEX?" HAS_INDEX":"",
-             p_avi_demux->avih.i_flags&AVIF_MUSTUSEINDEX?" MUST_USE_INDEX":"",
-             p_avi_demux->avih.i_flags&AVIF_ISINTERLEAVED?" IS_INTERLEAVED":"",
-             p_avi_demux->avih.i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"" );
+             p_avi->i_streams,
+             p_avi->avih.i_flags&AVIF_HASINDEX?" HAS_INDEX":"",
+             p_avi->avih.i_flags&AVIF_MUSTUSEINDEX?" MUST_USE_INDEX":"",
+             p_avi->avih.i_flags&AVIF_ISINTERLEAVED?" IS_INTERLEAVED":"",
+             p_avi->avih.i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"" );
 
-    for( i = 0; i < p_avi_demux->i_streams; i++ )
+    for( i = 0; i < p_avi->i_streams; i++ )
     {
-#define p_info  p_avi_demux->pp_info[i]
+#define p_info  p_avi->pp_info[i]
         switch( p_info->p_es->i_cat )
         {
             case( VIDEO_ES ):
@@ -818,9 +815,9 @@ static int AVIInit( vlc_object_t * p_this )
                          p_info->video_format.i_bitcount,
                          (float)p_info->header.i_rate /
                              (float)p_info->header.i_scale );
-                if( (p_avi_demux->p_info_video == NULL) ) 
+                if( (p_avi->p_info_video == NULL) ) 
                 {
-                    p_avi_demux->p_info_video = p_info;
+                    p_avi->p_info_video = p_info;
                     /* TODO add test to see if a decoder has been found */
                     vlc_mutex_lock( &p_input->stream.stream_lock );
                     input_SelectES( p_input, p_info->p_es );
@@ -834,9 +831,9 @@ static int AVIInit( vlc_object_t * p_this )
                          p_info->audio_format.i_channels,
                          p_info->audio_format.i_samplespersec,
                          p_info->audio_format.i_bitspersample );
-                if( (p_avi_demux->p_info_audio == NULL) ) 
+                if( (p_avi->p_info_audio == NULL) ) 
                 {
-                    p_avi_demux->p_info_audio = p_info;
+                    p_avi->p_info_audio = p_info;
                     vlc_mutex_lock( &p_input->stream.stream_lock );
                     input_SelectES( p_input, p_info->p_es );
                     vlc_mutex_unlock( &p_input->stream.stream_lock );
@@ -851,11 +848,11 @@ static int AVIInit( vlc_object_t * p_this )
 
     /* we select the first audio and video ES */
     vlc_mutex_lock( &p_input->stream.stream_lock );
-    if( !p_avi_demux->p_info_video ) 
+    if( !p_avi->p_info_video ) 
     {
         msg_Warn( p_input, "no video stream found" );
     }
-    if( !p_avi_demux->p_info_audio )
+    if( !p_avi->p_info_audio )
     {
         msg_Warn( p_input, "no audio stream found!" );
     }
@@ -1173,14 +1170,13 @@ static int __AVI_GetChunk( input_thread_t  *p_input,
                            AVIStreamInfo_t *p_info,
                            int b_load )
 {
-    demux_data_avi_file_t *p_avi_demux =
-                        (demux_data_avi_file_t*)p_input->p_demux_data;
+    demux_sys_t *p_avi = p_input->p_demux_data;
     AVIStreamInfo_t *p_other;
     int i_method;
     off_t i_posmax;
     int i;
    
-#define p_info_i p_avi_demux->pp_info[i]
+#define p_info_i p_avi->pp_info[i]
     while( p_info->p_pes_first )
     {
         if( ( p_info->p_pes_first->i_posc == p_info->i_idxposc ) 
@@ -1197,8 +1193,8 @@ static int __AVI_GetChunk( input_thread_t  *p_input,
         }
     }
     /* up to now we handle only one audio and video streams at the same time */
-    p_other = (p_info == p_avi_demux->p_info_video ) ?
-                     p_avi_demux->p_info_audio : p_avi_demux->p_info_video ;
+    p_other = (p_info == p_avi->p_info_video ) ?
+                     p_avi->p_info_audio : p_avi->p_info_video ;
 
     i_method = __AVI_GetChunkMethod( p_input, p_info, p_other );
 
@@ -1221,7 +1217,7 @@ static int __AVI_GetChunk( input_thread_t  *p_input,
             put in buffer p_other since it could be too far */
         AVIStreamInfo_t *p_info_max = p_info;
         
-        for( i = 0; i < p_avi_demux->i_streams; i++ )
+        for( i = 0; i < p_avi->i_streams; i++ )
         {
             if( p_info_i->i_idxnb )
             {
@@ -1248,7 +1244,7 @@ static int __AVI_GetChunk( input_thread_t  *p_input,
         }
         else
         {
-            i_posmax = p_avi_demux->p_movi->i_pos + 12;
+            i_posmax = p_avi->p_movi->i_pos + 12;
         }
     }
     else
@@ -1287,12 +1283,12 @@ static int __AVI_GetChunk( input_thread_t  *p_input,
         }
         AVI_ParseStreamHeader( p_ck->i_id, &i, &i_type );
         /* littles checks but not too much if you want to read all file */ 
-        if( i >= p_avi_demux->i_streams )
+        if( i >= p_avi->i_streams )
         /* (AVI_GetESTypeFromTwoCC(i_type) != p_info_i->i_cat) perhaps add it*/
             
         {
             RIFF_DeleteChunk( p_input, p_ck );
-            if( RIFF_NextChunk( p_input, p_avi_demux->p_movi ) != 0 )
+            if( RIFF_NextChunk( p_input, p_avi->p_movi ) != 0 )
             {
                 return( 0 );
             }
@@ -1340,7 +1336,7 @@ static int __AVI_GetChunk( input_thread_t  *p_input,
                 }
                 else
                 {
-                    if( RIFF_NextChunk( p_input, p_avi_demux->p_movi ) != 0 )
+                    if( RIFF_NextChunk( p_input, p_avi->p_movi ) != 0 )
                     {
                         RIFF_DeleteChunk( p_input, p_ck );
 
@@ -1372,7 +1368,7 @@ static int __AVI_GetChunk( input_thread_t  *p_input,
             {
                 /* skip it */
                 RIFF_DeleteChunk( p_input, p_ck );
-                if( RIFF_NextChunk( p_input, p_avi_demux->p_movi ) != 0 )
+                if( RIFF_NextChunk( p_input, p_avi->p_movi ) != 0 )
                 {
                     return( 0 );
                 }
@@ -1562,13 +1558,12 @@ static int AVI_ReAlign( input_thread_t *p_input,
     int i;
     off_t   i_pos;
     int     b_after = 0;
-    demux_data_avi_file_t *p_avi_demux =
-                        (demux_data_avi_file_t*)p_input->p_demux_data;
+    demux_sys_t *p_avi = p_input->p_demux_data;
 
 
-    for( i = 0; i < p_avi_demux->i_streams; i++ )
+    for( i = 0; i < p_avi->i_streams; i++ )
     {
-        AVI_PESBuffer_Flush( p_input->p_method_data, p_avi_demux->pp_info[i] );
+        AVI_PESBuffer_Flush( p_input->p_method_data, p_avi->pp_info[i] );
     }
     /* Reinit clock
        TODO use input_ClockInit instead but need to be exported 
@@ -1652,11 +1647,10 @@ static int AVI_ReAlign( input_thread_t *p_input,
 /* make difference between audio and video pts as little as possible */
 static void AVI_SynchroReInit( input_thread_t *p_input )
 {
-    demux_data_avi_file_t *p_avi_demux =
-                        (demux_data_avi_file_t*)p_input->p_demux_data;
+    demux_sys_t *p_avi = p_input->p_demux_data;
     
-#define p_info_video p_avi_demux->p_info_video
-#define p_info_audio p_avi_demux->p_info_audio
+#define p_info_video p_avi->p_info_video
+#define p_info_audio p_avi->p_info_audio
     if( ( !p_info_audio )||( !p_info_video ) )
     {
         return;
@@ -1782,8 +1776,7 @@ static int AVIDemux_Seekable( input_thread_t *p_input,
                               AVIStreamInfo_t *p_info_master,
                               AVIStreamInfo_t *p_info_slave )
 {
-    demux_data_avi_file_t *p_avi_demux = 
-                (demux_data_avi_file_t*)p_input->p_demux_data;
+    demux_sys_t *p_avi = p_input->p_demux_data;
 
     pes_packet_t *p_pes_master;
     pes_packet_t *p_pes_slave;
@@ -1817,17 +1810,17 @@ static int AVIDemux_Seekable( input_thread_t *p_input,
     /* wait for the good time */
     input_ClockManageRef( p_input,
                           p_input->stream.p_selected_program,
-                          p_avi_demux->i_pcr /*- DEFAULT_PTS_DELAY / 2 */); 
+                          p_avi->i_pcr /*- DEFAULT_PTS_DELAY / 2 */); 
     /* calculate pcr, time when we must read the next data */
     /* 9/100 kludge ->need to convert to 1/1000000 clock unit to 1/90000 */
     if( p_info_slave )
     {
-        p_avi_demux->i_pcr =  __MIN( AVI_GetPTS( p_info_master ),
+        p_avi->i_pcr =  __MIN( AVI_GetPTS( p_info_master ),
                                      AVI_GetPTS( p_info_slave ) ) * 9/100;
     }
     else
     {
-        p_avi_demux->i_pcr =  AVI_GetPTS( p_info_master ) * 9/100;
+        p_avi->i_pcr =  AVI_GetPTS( p_info_master ) * 9/100;
     }
 
     /* get video and audio frames */
@@ -1964,8 +1957,7 @@ static int AVIDemux_NotSeekable( input_thread_t *p_input,
                                  AVIStreamInfo_t *p_info_master,
                                  AVIStreamInfo_t *p_info_slave )
 {
-    demux_data_avi_file_t *p_avi_demux = 
-                (demux_data_avi_file_t*)p_input->p_demux_data;
+    demux_sys_t *p_avi = p_input->p_demux_data;
     int i_loop;
     int i_stream;
     int i_type;
@@ -1979,7 +1971,7 @@ static int AVIDemux_NotSeekable( input_thread_t *p_input,
     input_AccessReinit( p_input );
 */
     
-#define p_info p_avi_demux->pp_info[i_stream]
+#define p_info p_avi->pp_info[i_stream]
 
     /* The managment is very basic, we will read packets, caclulate pts 
     and send it to decoder, synchro made on video, and audio is very less
@@ -1988,18 +1980,18 @@ static int AVIDemux_NotSeekable( input_thread_t *p_input,
     /* wait the good time */
     input_ClockManageRef( p_input,
                           p_input->stream.p_selected_program,
-                          p_avi_demux->i_pcr /*- DEFAULT_PTS_DELAY / 2 */); 
+                          p_avi->i_pcr /*- DEFAULT_PTS_DELAY / 2 */); 
     /* TODO be smart, seeing if we can wait for min( audio, video )
         or there is a too big deep */
     if( !p_info_slave )
     {
-        p_avi_demux->i_pcr =  AVI_GetPTS( p_info_master ) * 9/100;
+        p_avi->i_pcr =  AVI_GetPTS( p_info_master ) * 9/100;
     }
     else
     {
-        p_avi_demux->i_pcr =  __MIN( AVI_GetPTS( p_info_master ),
+        p_avi->i_pcr =  __MIN( AVI_GetPTS( p_info_master ),
                                  AVI_GetPTS( p_info_slave ) ) * 9/100;
-        p_avi_demux->i_pcr =  AVI_GetPTS( p_info_master ) * 9/100;
+        p_avi->i_pcr =  AVI_GetPTS( p_info_master ) * 9/100;
     }
     
     for( i_loop = 0; i_loop < 10; i_loop++ )
@@ -2017,14 +2009,14 @@ static int AVIDemux_NotSeekable( input_thread_t *p_input,
             }
             //msg_Err( p_input,"Looking ck: %4.4s %d",&p_ck->i_id, p_ck->i_size );
 
-            switch( __AVIDemux_ChunkAction( p_avi_demux->i_streams, p_ck ) )
+            switch( __AVIDemux_ChunkAction( p_avi->i_streams, p_ck ) )
             {
                 case( 0 ): /* load it if possible */
                     b_load = 1;
                     break;
                 case( 1 ): /* skip it */
                     RIFF_DeleteChunk( p_input, p_ck );
-                    if( RIFF_NextChunk( p_input, p_avi_demux->p_movi ) != 0 )
+                    if( RIFF_NextChunk( p_input, p_avi->p_movi ) != 0 )
                     {
                         return( 0 );
                     }
@@ -2103,7 +2095,7 @@ static int AVIDemux_NotSeekable( input_thread_t *p_input,
         else
         {
 
-            if( RIFF_NextChunk( p_input, p_avi_demux->p_movi ) != 0 )
+            if( RIFF_NextChunk( p_input, p_avi->p_movi ) != 0 )
             {
                 RIFF_DeleteChunk( p_input, p_ck );
                 return( 0 );
@@ -2140,50 +2132,49 @@ static int AVIDemux( input_thread_t *p_input )
     AVIStreamInfo_t *p_info_master;
     AVIStreamInfo_t *p_info_slave;    
 
-    demux_data_avi_file_t *p_avi_demux = 
-                (demux_data_avi_file_t*)p_input->p_demux_data;
+    demux_sys_t *p_avi = p_input->p_demux_data;
 
     /* search new video and audio stream selected 
           if current have been unselected*/
-    if( ( !p_avi_demux->p_info_video )
-            || ( !p_avi_demux->p_info_video->p_es->p_decoder_fifo ) )
+    if( ( !p_avi->p_info_video )
+            || ( !p_avi->p_info_video->p_es->p_decoder_fifo ) )
     {
-        p_avi_demux->p_info_video = NULL;
-        for( i = 0; i < p_avi_demux->i_streams; i++ )
+        p_avi->p_info_video = NULL;
+        for( i = 0; i < p_avi->i_streams; i++ )
         {
-            if( ( p_avi_demux->pp_info[i]->i_cat == VIDEO_ES )
-                  &&( p_avi_demux->pp_info[i]->p_es->p_decoder_fifo ) )
+            if( ( p_avi->pp_info[i]->i_cat == VIDEO_ES )
+                  &&( p_avi->pp_info[i]->p_es->p_decoder_fifo ) )
             {
-                p_avi_demux->p_info_video = p_avi_demux->pp_info[i];
-                p_avi_demux->p_info_video->b_selected = 1;
+                p_avi->p_info_video = p_avi->pp_info[i];
+                p_avi->p_info_video->b_selected = 1;
                 break;
             }
         }
     }
-    if( ( !p_avi_demux->p_info_audio )
-            ||( !p_avi_demux->p_info_audio->p_es->p_decoder_fifo ) )
+    if( ( !p_avi->p_info_audio )
+            ||( !p_avi->p_info_audio->p_es->p_decoder_fifo ) )
     {
-        p_avi_demux->p_info_audio = NULL;
-        for( i = 0; i < p_avi_demux->i_streams; i++ )
+        p_avi->p_info_audio = NULL;
+        for( i = 0; i < p_avi->i_streams; i++ )
         {
-            if( ( p_avi_demux->pp_info[i]->i_cat == AUDIO_ES )
-                  &&( p_avi_demux->pp_info[i]->p_es->p_decoder_fifo ) )
+            if( ( p_avi->pp_info[i]->i_cat == AUDIO_ES )
+                  &&( p_avi->pp_info[i]->p_es->p_decoder_fifo ) )
             {
-                p_avi_demux->p_info_audio = p_avi_demux->pp_info[i];
-                p_avi_demux->p_info_audio->b_selected = 1;
+                p_avi->p_info_audio = p_avi->pp_info[i];
+                p_avi->p_info_audio->b_selected = 1;
                 break;
             }
         }
     }
     /* by default video is master for resync audio (after a seek .. ) */
-    if( p_avi_demux->p_info_video )
+    if( p_avi->p_info_video )
     {
-        p_info_master = p_avi_demux->p_info_video;
-        p_info_slave  = p_avi_demux->p_info_audio;
+        p_info_master = p_avi->p_info_video;
+        p_info_slave  = p_avi->p_info_audio;
     }
     else
     {
-        p_info_master = p_avi_demux->p_info_audio;
+        p_info_master = p_avi->p_info_audio;
         p_info_slave  = NULL;
     }
     
@@ -2195,22 +2186,22 @@ static int AVIDemux( input_thread_t *p_input )
 
     /* manage rate, if not default: skeep audio */
     vlc_mutex_lock( &p_input->stream.stream_lock );
-    if( p_input->stream.control.i_rate != p_avi_demux->i_rate )
+    if( p_input->stream.control.i_rate != p_avi->i_rate )
     {
-        if( p_avi_demux->p_info_audio)
+        if( p_avi->p_info_audio)
         {
-             p_avi_demux->p_info_audio->b_selected = 1;
+             p_avi->p_info_audio->b_selected = 1;
         }
-        p_avi_demux->i_rate = p_input->stream.control.i_rate;
+        p_avi->i_rate = p_input->stream.control.i_rate;
     }
     vlc_mutex_unlock( &p_input->stream.stream_lock );    
-    p_avi_demux->i_rate = DEFAULT_RATE;
-    if( p_avi_demux->i_rate != DEFAULT_RATE )
+    p_avi->i_rate = DEFAULT_RATE;
+    if( p_avi->i_rate != DEFAULT_RATE )
     {
         p_info_slave = NULL;
     }
 
-    if( p_avi_demux->b_seekable )
+    if( p_avi->b_seekable )
     {
         return( AVIDemux_Seekable( p_input,
                                    p_info_master,
index 4f169c0..376e690 100644 (file)
@@ -2,7 +2,7 @@
  * avi.h : AVI file Stream input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: avi.h,v 1.1 2002/08/04 17:23:42 sam Exp $
+ * $Id: avi.h,v 1.2 2002/08/07 00:29:36 sam Exp $
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  * 
  * This program is free software; you can redistribute it and/or modify
@@ -237,7 +237,7 @@ typedef struct AVIStreamInfo_s
     int                 i_pes_totalsize;
 } AVIStreamInfo_t;
 
-typedef struct demux_data_avi_file_s
+struct demux_sys_t
 {
     mtime_t i_pcr; 
     int     i_rate;
@@ -258,6 +258,5 @@ typedef struct demux_data_avi_file_s
     /* current audio and video es */
     AVIStreamInfo_t *p_info_video;
     AVIStreamInfo_t *p_info_audio;
-
-} demux_data_avi_file_t;
+};
 
index b3fecc4..8801986 100644 (file)
@@ -2,7 +2,7 @@
  * mp4.c : MP4 file input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: mp4.c,v 1.1 2002/08/04 17:23:42 sam Exp $
+ * $Id: mp4.c,v 1.2 2002/08/07 00:29:36 sam Exp $
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  * 
  * This program is free software; you can redistribute it and/or modify
@@ -86,7 +86,7 @@ static int MP4Init( vlc_object_t * p_this )
     u8  *p_peek;
     u32 i_type;
     
-    demux_data_mp4_t *p_demux;
+    demux_sys_t *p_demux;
     
     MP4_Box_t *p_moov;    
     MP4_Box_t *p_ftyp;
@@ -138,12 +138,12 @@ static int MP4Init( vlc_object_t * p_this )
 
     /* create our structure that will contains all data */
     if( !( p_input->p_demux_data = 
-                p_demux = malloc( sizeof( demux_data_mp4_t ) ) ) )
+                p_demux = malloc( sizeof( demux_sys_t ) ) ) )
     {
         msg_Err( p_input, "out of memory" );
         return( -1 );
     }
-    memset( p_demux, 0, sizeof( demux_data_mp4_t ) );
+    memset( p_demux, 0, sizeof( demux_sys_t ) );
     p_input->p_demux_data = p_demux;
        
 
@@ -299,7 +299,7 @@ static int MP4Init( vlc_object_t * p_this )
  *****************************************************************************/
 static int MP4Demux( input_thread_t *p_input )
 {
-    demux_data_mp4_t *p_demux = p_input->p_demux_data;
+    demux_sys_t *p_demux = p_input->p_demux_data;
     int i_track;
 
     /* first wait for the good time to read a packet */
@@ -376,7 +376,7 @@ static void __MP4End ( vlc_object_t * p_this )
     if( p ) { free( p ); } 
     int i_track;
     input_thread_t *  p_input = (input_thread_t *)p_this;
-    demux_data_mp4_t *p_demux = p_input->p_demux_data;
+    demux_sys_t *p_demux = p_input->p_demux_data;
     
     msg_Dbg( p_input, "Freeing all memory" );
     MP4_FreeBox( p_input, &p_demux->box_root );
@@ -942,7 +942,7 @@ static void MP4_StartDecoder( input_thread_t *p_input,
             break;
     }
 
-    p_demux_track->p_es->p_demux_data = p_init;
+    p_demux_track->p_es->p_demux_data = (es_sys_t *)p_init;
     vlc_mutex_lock( &p_input->stream.stream_lock );
     input_SelectES( p_input, p_demux_track->p_es );
     vlc_mutex_unlock( &p_input->stream.stream_lock );
index 93cc8d7..98011cd 100644 (file)
@@ -2,7 +2,7 @@
  * mp4.h : MP4 file input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: mp4.h,v 1.1 2002/08/04 17:23:42 sam Exp $
+ * $Id: mp4.h,v 1.2 2002/08/07 00:29:36 sam Exp $
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  * 
  * This program is free software; you can redistribute it and/or modify
@@ -123,7 +123,7 @@ typedef struct track_data_mp4_s
 /*****************************************************************************
  *
  *****************************************************************************/
-typedef struct demux_data_mp4_s
+struct demux_sys_t
 {
 
     MP4_Box_t   box_root;       /* container for the hole file */
@@ -137,7 +137,7 @@ typedef struct demux_data_mp4_s
     track_data_mp4_t *track; /* array of track */
     
   
-} demux_data_mp4_t;
+};
 
 static inline u64 MP4_GetTrackPos( track_data_mp4_t *p_track )
 {
@@ -198,7 +198,7 @@ static inline mtime_t MP4_GetTrackPTS( track_data_mp4_t *p_track )
                 (mtime_t)p_track->i_timescale ) );
 }
 
-static inline mtime_t MP4_GetMoviePTS(demux_data_mp4_t *p_demux )
+static inline mtime_t MP4_GetMoviePTS(demux_sys_t *p_demux )
 {
     return( (mtime_t)(
                 (mtime_t)1000000 *
index 1f968d8..b39a64a 100644 (file)
@@ -1,3 +1,4 @@
+mpeg_system_SOURCES = system.c
 es_SOURCES = es.c
 ps_SOURCES = ps.c
 ts_SOURCES = ts.c
index 444a1e7..4240897 100644 (file)
@@ -2,7 +2,7 @@
  * mpeg_audio.c : mpeg_audio Stream input module for vlc
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: audio.c,v 1.1 2002/08/04 17:23:42 sam Exp $
+ * $Id: audio.c,v 1.2 2002/08/07 00:29:36 sam Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  * 
@@ -94,7 +94,7 @@ typedef struct mpegaudio_xing_header_s
     int i_avgbitrate; /* calculated, XXX: bits/sec not Kb */
 } mpegaudio_xing_header_t;
 
-typedef struct demux_data_mpegaudio_s
+struct demux_sys_t
 {
     mtime_t i_pts;
 
@@ -103,8 +103,7 @@ typedef struct demux_data_mpegaudio_s
     es_descriptor_t         *p_es;
     mpegaudio_format_t      mpeg;
     mpegaudio_xing_header_t xingheader;
-
-} demux_data_mpegaudio_t;
+};
 
 
 static int mpegaudio_bitrate[2][3][16] =
@@ -422,7 +421,7 @@ static void MPEGAudio_ExtractXingHeader( input_thread_t *p_input,
 static int Activate( vlc_object_t * p_this )
 {
     input_thread_t * p_input = (input_thread_t *)p_this;
-    demux_data_mpegaudio_t * p_mpegaudio;
+    demux_sys_t * p_mpegaudio;
     mpegaudio_format_t mpeg;
     es_descriptor_t * p_es;
     int i_pos;
@@ -507,8 +506,7 @@ static int Activate( vlc_object_t * p_this )
     vlc_mutex_unlock( &p_input->stream.stream_lock );
 
     /* create p_mpegaudio and init it */
-    p_input->p_demux_data =
-           p_mpegaudio = malloc( sizeof( demux_data_mpegaudio_t ));
+    p_mpegaudio = p_input->p_demux_data = malloc( sizeof(demux_sys_t) );
 
     if( !p_mpegaudio )
     {
@@ -575,8 +573,8 @@ static int Demux( input_thread_t * p_input )
     int i_toread;
     pes_packet_t    *p_pes;
     mpegaudio_format_t mpeg;
-    demux_data_mpegaudio_t *p_mpegaudio = 
-                        (demux_data_mpegaudio_t*) p_input->p_demux_data;
+    demux_sys_t *p_mpegaudio = p_input->p_demux_data;
+
     /*  look for a frame */
     if( !MPEGAudio_FindFrame( p_input, &i_pos, &mpeg, 4096 ) )
     {
index 9e2d6f6..24908f9 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************
- * mpeg_ps.c : Program Stream input module for vlc
+ * ps.c : Program Stream input module for vlc
  *****************************************************************************
  * Copyright (C) 2000-2001 VideoLAN
- * $Id: ps.c,v 1.1 2002/08/04 17:23:42 sam Exp $
+ * $Id: ps.c,v 1.2 2002/08/07 00:29:36 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
 
 #include <sys/types.h>
 
+#include "system.h"
+
 /*****************************************************************************
  * Constants
  *****************************************************************************/
 #define PS_READ_ONCE 50
 
+/*****************************************************************************
+ * Private structure
+ *****************************************************************************/
+struct demux_sys_t
+{
+    module_t *   p_module;
+    mpeg_demux_t mpeg;
+};
+
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
-static int  Activate ( vlc_object_t * );
-static int  Demux ( input_thread_t * );
+static int  Activate   ( vlc_object_t * );
+static void Deactivate ( vlc_object_t * );
+static int  Demux      ( input_thread_t * );
 
 /*****************************************************************************
  * Module descriptor
@@ -50,16 +62,17 @@ static int  Demux ( input_thread_t * );
 vlc_module_begin();
     set_description( _("ISO 13818-1 MPEG Program Stream input") );
     set_capability( "demux", 100 );
-    set_callbacks( Activate, NULL );
+    set_callbacks( Activate, Deactivate );
     add_shortcut( "ps" );
 vlc_module_end();
 
 /*****************************************************************************
- * Activate: initializes PS structures
+ * Activate: initialize PS structures
  *****************************************************************************/
 static int Activate( vlc_object_t * p_this )
 {
     input_thread_t *    p_input = (input_thread_t *)p_this;
+    demux_sys_t *       p_demux;
     byte_t *            p_peek;
 
     /* Set the demux function */
@@ -77,7 +90,7 @@ static int Activate( vlc_object_t * p_this )
     {
         /* Stream shorter than 4 bytes... */
         msg_Err( p_input, "cannot peek()" );
-        return( -1 );
+        return -1;
     }
 
     if( *p_peek || *(p_peek + 1) || *(p_peek + 2) != 1 )
@@ -106,9 +119,25 @@ static int Activate( vlc_object_t * p_this )
         }
     }
 
+    p_demux = p_input->p_demux_data = malloc( sizeof(demux_sys_t ) );
+    if( p_demux == NULL )
+    {
+        return -1;
+    }
+
+    p_input->p_private = (void*)&p_demux->mpeg;
+    p_demux->p_module = module_Need( p_input, "mpeg-system", NULL );
+    if( p_demux->p_module == NULL )
+    {
+        free( p_input->p_demux_data );
+        return -1;
+    }
+
     if( input_InitStream( p_input, sizeof( stream_ps_data_t ) ) == -1 )
     {
-        return( -1 );
+        module_Unneed( p_input, p_demux->p_module );
+        free( p_input->p_demux_data );
+        return -1;
     }
     input_AddProgram( p_input, 0, sizeof( stream_ps_data_t ) );
     
@@ -130,7 +159,7 @@ static int Activate( vlc_object_t * p_this )
             ssize_t             i_result;
             data_packet_t *     p_data;
 
-            i_result = input_ReadPS( p_input, &p_data );
+            i_result = p_demux->mpeg.pf_read_ps( p_input, &p_data );
 
             if( i_result == 0 )
             {
@@ -146,7 +175,7 @@ static int Activate( vlc_object_t * p_this )
                 break;
             }
 
-            input_ParsePS( p_input, p_data );
+            p_demux->mpeg.pf_parse_ps( p_input, p_data );
             input_DeletePacket( p_input->p_method_data, p_data );
 
             /* File too big. */
@@ -246,7 +275,18 @@ static int Activate( vlc_object_t * p_this )
         vlc_mutex_unlock( &p_input->stream.stream_lock );
     }
 
-    return( 0 );
+    return 0;
+}
+
+/*****************************************************************************
+ * Deactivate: deinitialize PS structures
+ *****************************************************************************/
+static void Deactivate( vlc_object_t * p_this )
+{
+    input_thread_t *    p_input = (input_thread_t *)p_this;
+
+    module_Unneed( p_input, p_input->p_demux_data->p_module );
+    free( p_input->p_demux_data );
 }
 
 /*****************************************************************************
@@ -257,22 +297,22 @@ static int Activate( vlc_object_t * p_this )
  *****************************************************************************/
 static int Demux( input_thread_t * p_input )
 {
-    int                 i;
+    int i;
 
     for( i = 0; i < PS_READ_ONCE; i++ )
     {
         data_packet_t *     p_data;
         ssize_t             i_result;
-        i_result = input_ReadPS( p_input, &p_data );
+        i_result = p_input->p_demux_data->mpeg.pf_read_ps( p_input, &p_data );
 
         if( i_result <= 0 )
         {
-            return( i_result );
+            return i_result;
         }
 
-        input_DemuxPS( p_input, p_data );
+        p_input->p_demux_data->mpeg.pf_demux_ps( p_input, p_data );
     }
 
-    return( i );
+    return i;
 }
 
diff --git a/modules/demux/mpeg/system.c b/modules/demux/mpeg/system.c
new file mode 100644 (file)
index 0000000..c70d951
--- /dev/null
@@ -0,0 +1,1368 @@
+/*****************************************************************************
+ * system.c: helper module for TS, PS and PES management
+ *****************************************************************************
+ * Copyright (C) 1998-2002 VideoLAN
+ * $Id: system.c,v 1.1 2002/08/07 00:29:36 sam Exp $
+ *
+ * Authors: Christophe Massiot <massiot@via.ecp.fr>
+ *          Michel Lespinasse <walken@via.ecp.fr>
+ *          Benoît Steiner <benny@via.ecp.fr>
+ *          Samuel Hocevar <sam@zoy.org>
+ *          Henri Fallon <henri@via.ecp.fr>
+ *
+ * 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 <stdlib.h>
+#include <string.h>                                    /* memcpy(), memset() */
+#include <sys/types.h>                                              /* off_t */
+
+#include <vlc/vlc.h>
+#include <vlc/input.h>
+
+#include "system.h"
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int Activate ( vlc_object_t * );
+
+static ssize_t           ReadPS  ( input_thread_t *, data_packet_t ** );
+static es_descriptor_t * ParsePS ( input_thread_t *, data_packet_t * );
+static void              DemuxPS ( input_thread_t *, data_packet_t * );
+
+static ssize_t           ReadTS  ( input_thread_t *, data_packet_t ** );
+static void              DemuxTS ( input_thread_t *, data_packet_t *,
+                                   psi_callback_t );
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+vlc_module_begin();
+    set_description( _("generic ISO 13818-1 MPEG demultiplexing") );
+    set_capability( "mpeg-system", 100 );
+    set_callbacks( Activate, NULL );
+vlc_module_end();
+
+/*****************************************************************************
+ * Activate: initializes helper functions
+ *****************************************************************************/
+static int Activate ( vlc_object_t *p_this )
+{
+    static mpeg_demux_t mpeg_demux =
+                    { NULL, ReadPS, ParsePS, DemuxPS, ReadTS, DemuxTS };
+
+    memcpy( p_this->p_private, &mpeg_demux, sizeof( mpeg_demux ) );
+
+    return VLC_SUCCESS;
+}
+
+/*
+ * PES Packet management
+ */
+
+/*****************************************************************************
+ * MoveChunk
+ *****************************************************************************
+ * Small utility function used to parse discontinuous headers safely. Copies
+ * i_buf_len bytes of data to a buffer and returns the size copied.
+ * It also solves some alignment problems on non-IA-32, non-PPC processors.
+ * This is a variation on the theme of input_ext-dec.h:GetChunk().
+ *****************************************************************************/
+static inline size_t MoveChunk( byte_t * p_dest, data_packet_t ** pp_data_src,
+                                byte_t ** pp_src, size_t i_buf_len )
+{
+    ptrdiff_t           i_available;
+
+    if( (i_available = (*pp_data_src)->p_payload_end - *pp_src)
+            >= i_buf_len )
+    {
+        if( p_dest != NULL )
+            memcpy( p_dest, *pp_src, i_buf_len );
+        *pp_src += i_buf_len;
+        return( i_buf_len );
+    }
+    else
+    {
+        size_t          i_init_len = i_buf_len;
+
+        do
+        {
+            if( p_dest != NULL )
+                memcpy( p_dest, *pp_src, i_available );
+            *pp_data_src = (*pp_data_src)->p_next;
+            i_buf_len -= i_available;
+            p_dest += i_available;
+            if( *pp_data_src == NULL )
+            {
+                *pp_src = NULL;
+                return( i_init_len - i_buf_len );
+            }
+            *pp_src = (*pp_data_src)->p_payload_start;
+        }
+        while( (i_available = (*pp_data_src)->p_payload_end - *pp_src)
+                <= i_buf_len );
+
+        if( i_buf_len )
+        {
+            if( p_dest != NULL )
+                memcpy( p_dest, *pp_src, i_buf_len );
+            *pp_src += i_buf_len;
+        }
+        return( i_init_len );
+    }
+}
+
+/*****************************************************************************
+ * ParsePES
+ *****************************************************************************
+ * Parse a finished PES packet and analyze its header.
+ *****************************************************************************/
+#define PES_HEADER_SIZE     7
+static void ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
+{
+    data_packet_t * p_data;
+    byte_t *        p_byte;
+    byte_t          p_header[PES_HEADER_SIZE];
+    int             i_done;
+
+#define p_pes (p_es->p_pes)
+
+    /* Parse the header. The header has a variable length, but in order
+     * to improve the algorithm, we will read the 14 bytes we may be
+     * interested in */
+    p_data = p_pes->p_first;
+    p_byte = p_data->p_payload_start;
+    i_done = 0;
+
+    if( MoveChunk( p_header, &p_data, &p_byte, PES_HEADER_SIZE )
+            != PES_HEADER_SIZE )
+    {
+        msg_Warn( p_input, "PES packet too short to have a header" );
+        input_DeletePES( p_input->p_method_data, p_pes );
+        p_pes = NULL;
+        return;
+    }
+
+    /* Get the PES size if defined */
+    p_es->i_pes_real_size = U16_AT(p_header + 4);
+    if( p_es->i_pes_real_size )
+    {
+        p_es->i_pes_real_size += 6;
+    }
+
+    /* First read the 6 header bytes common to all PES packets:
+     * use them to test the PES validity */
+    if( (p_header[0] || p_header[1] || (p_header[2] != 1)) )
+    {
+        /* packet_start_code_prefix != 0x000001 */
+        msg_Err( p_input, "data loss, PES packet does not start with 000001" );
+        input_DeletePES( p_input->p_method_data, p_pes );
+        p_pes = NULL;
+    }
+    else
+    {
+        int i_pes_header_size, i_payload_size;
+
+        if ( p_es->i_pes_real_size &&
+             (p_es->i_pes_real_size != p_pes->i_pes_size) )
+        {
+            /* PES_packet_length is set and != total received payload */
+            /* Warn the decoder that the data may be corrupt. */
+            msg_Warn( p_input, "packet corrupted, PES sizes do not match" );
+        }
+
+        switch( p_es->i_stream_id )
+        {
+        case 0xBC:  /* Program stream map */
+        case 0xBE:  /* Padding */
+        case 0xBF:  /* Private stream 2 */
+        case 0xB0:  /* ECM */
+        case 0xB1:  /* EMM */
+        case 0xFF:  /* Program stream directory */
+        case 0xF2:  /* DSMCC stream */
+        case 0xF8:  /* ITU-T H.222.1 type E stream */
+            /* The payload begins immediately after the 6 bytes header, so
+             * we have finished with the parsing */
+            i_pes_header_size = 6;
+            break;
+
+        default:
+            if( (p_header[6] & 0xC0) == 0x80 )
+            {
+                /* MPEG-2 : the PES header contains at least 3 more bytes. */
+                size_t      i_max_len;
+                vlc_bool_t  b_has_pts, b_has_dts;
+                byte_t      p_full_header[12];
+
+                p_pes->b_data_alignment = p_header[6] & 0x04;
+
+                i_max_len = MoveChunk( p_full_header, &p_data, &p_byte, 12 );
+                if( i_max_len < 2 )
+                {
+                    msg_Warn( p_input, 
+                              "PES packet too short to have a MPEG-2 header" );
+                    input_DeletePES( p_input->p_method_data,
+                                            p_pes );
+                    p_pes = NULL;
+                    return;
+                }
+
+                b_has_pts = p_full_header[0] & 0x80;
+                b_has_dts = p_full_header[0] & 0x40;
+                i_pes_header_size = p_full_header[1] + 9;
+
+                /* Now parse the optional header extensions */
+                if( b_has_pts )
+                {
+                    if( i_max_len < 7 )
+                    {
+                        msg_Warn( p_input,
+                             "PES packet too short to have a MPEG-2 header" );
+                        input_DeletePES( p_input->p_method_data,
+                                                p_pes );
+                        p_pes = NULL;
+                        return;
+                    }
+                    p_pes->i_pts = input_ClockGetTS( p_input, p_es->p_pgrm,
+                    ( ((mtime_t)(p_full_header[2] & 0x0E) << 29) |
+                      ((mtime_t)(p_full_header[3]) << 22) |
+                      ((mtime_t)(p_full_header[4] & 0xFE) << 14) |
+                      ((mtime_t)p_full_header[5] << 7) |
+                      ((mtime_t)p_full_header[6] >> 1) ) );
+
+                    if( b_has_dts )
+                    {
+                        if( i_max_len < 12 )
+                        {
+                            msg_Warn( p_input,
+                              "PES packet too short to have a MPEG-2 header" );
+                            input_DeletePES( p_input->p_method_data,
+                                                    p_pes );
+                            p_pes = NULL;
+                            return;
+                        }
+                        p_pes->i_dts = input_ClockGetTS( p_input, p_es->p_pgrm,
+                        ( ((mtime_t)(p_full_header[7] & 0x0E) << 29) |
+                          (((mtime_t)U16_AT(p_full_header + 8) << 14)
+                                - (1 << 14)) |
+                          ((mtime_t)U16_AT(p_full_header + 10) >> 1) ) );
+                    }
+                }
+            }
+            else
+            {
+                /* Probably MPEG-1 */
+                vlc_bool_t      b_has_pts, b_has_dts;
+
+                i_pes_header_size = 6;
+                p_data = p_pes->p_first;
+                p_byte = p_data->p_payload_start;
+                /* Cannot fail because the previous one succeeded. */
+                MoveChunk( NULL, &p_data, &p_byte, 6 );
+
+                while( *p_byte == 0xFF && i_pes_header_size < 23 )
+                {
+                    i_pes_header_size++;
+                    if( MoveChunk( NULL, &p_data, &p_byte, 1 ) != 1 )
+                    {
+                        msg_Warn( p_input,
+                            "PES packet too short to have a MPEG-1 header" );
+                        input_DeletePES( p_input->p_method_data, p_pes );
+                        p_pes = NULL;
+                        return;
+                    }
+                }
+                if( i_pes_header_size == 23 )
+                {
+                    msg_Err( p_input, "too much MPEG-1 stuffing" );
+                    input_DeletePES( p_input->p_method_data, p_pes );
+                    p_pes = NULL;
+                    return;
+                }
+
+                if( (*p_byte & 0xC0) == 0x40 )
+                {
+                    /* Don't ask why... --Meuuh */
+                    /* Erm... why ? --Sam */
+                    /* Well... According to the recommendation, it is for
+                     * STD_buffer_scale and STD_buffer_size. --Meuuh */
+                    i_pes_header_size += 2;
+                    if( MoveChunk( NULL, &p_data, &p_byte, 2 ) != 2 )
+                    {
+                        msg_Warn( p_input,
+                            "PES packet too short to have a MPEG-1 header" );
+                        input_DeletePES( p_input->p_method_data, p_pes );
+                        p_pes = NULL;
+                        return;
+                    }
+                }
+
+                i_pes_header_size++;
+
+                b_has_pts = *p_byte & 0x20;
+                b_has_dts = *p_byte & 0x10;
+
+                if( b_has_pts )
+                {
+                    byte_t      p_ts[5];
+
+                    i_pes_header_size += 4;
+                    if( MoveChunk( p_ts, &p_data, &p_byte, 5 ) != 5 )
+                    {
+                        msg_Warn( p_input,
+                            "PES packet too short to have a MPEG-1 header" );
+                        input_DeletePES( p_input->p_method_data, p_pes );
+                        p_pes = NULL;
+                        return;
+                    }
+
+                    p_pes->i_pts = input_ClockGetTS( p_input, p_es->p_pgrm,
+                       ( ((mtime_t)(p_ts[0] & 0x0E) << 29) |
+                         (((mtime_t)U32_AT(p_ts) & 0xFFFE00) << 6) |
+                         ((mtime_t)p_ts[3] << 7) |
+                         ((mtime_t)p_ts[4] >> 1) ) );
+
+                    if( b_has_dts )
+                    {
+                        i_pes_header_size += 5;
+                        if( MoveChunk( p_ts, &p_data, &p_byte, 5 ) != 5 )
+                        {
+                            msg_Warn( p_input,
+                              "PES packet too short to have a MPEG-1 header" );
+                            input_DeletePES( p_input->p_method_data, p_pes );
+                            p_pes = NULL;
+                            return;
+                        }
+
+                        p_pes->i_dts = input_ClockGetTS( p_input,
+                                                         p_es->p_pgrm,
+                            ( ((mtime_t)(p_ts[0] & 0x0E) << 29) |
+                              (((mtime_t)U32_AT(p_ts) & 0xFFFE00) << 6) |
+                              ((mtime_t)p_ts[3] << 7) |
+                              ((mtime_t)p_ts[4] >> 1) ) );
+                    }
+                }
+            }
+
+            break;
+        }
+
+        if( p_es->i_stream_id == 0xbd )
+        {
+            /* With private stream 1, the first byte of the payload
+             * is a stream_private_id, so skip it. */
+            i_pes_header_size++;
+        }
+
+        if( p_es->i_fourcc == VLC_FOURCC('a','5','2',' ') )
+        {
+            /* With A52 audio, we need to skip first 3 bytes */
+            i_pes_header_size += 3;
+        }
+
+        /* Now we've parsed the header, we just have to indicate in some
+         * specific data packets where the PES payload begins (renumber
+         * p_payload_start), so that the decoders can find the beginning
+         * of their data right out of the box. */
+        p_data = p_pes->p_first;
+        i_payload_size = p_data->p_payload_end
+                                 - p_data->p_payload_start;
+        while( i_pes_header_size > i_payload_size )
+        {
+            /* These packets are entirely filled by the PES header. */
+            i_pes_header_size -= i_payload_size;
+            p_data->p_payload_start = p_data->p_payload_end;
+            /* Go to the next data packet. */
+            if( (p_data = p_data->p_next) == NULL )
+            {
+                msg_Err( p_input, "PES header bigger than payload" );
+                input_DeletePES( p_input->p_method_data, p_pes );
+                p_pes = NULL;
+                return;
+            }
+            i_payload_size = p_data->p_payload_end
+                                 - p_data->p_payload_start;
+        }
+        /* This last packet is partly header, partly payload. */
+        if( i_payload_size < i_pes_header_size )
+        {
+            msg_Err( p_input, "PES header bigger than payload" );
+            input_DeletePES( p_input->p_method_data, p_pes );
+            p_pes = NULL;
+            return;
+        }
+        p_data->p_payload_start += i_pes_header_size;
+
+
+        /* Now we can eventually put the PES packet in the decoder's
+         * PES fifo */
+        if( p_es->p_decoder_fifo != NULL )
+        {
+            input_DecodePES( p_es->p_decoder_fifo, p_pes );
+        }
+        else
+        {
+            msg_Err( p_input, "no fifo to receive PES %p "
+                              "(who wrote this damn code ?)", p_pes );
+            input_DeletePES( p_input->p_method_data, p_pes );
+        }
+        p_pes = NULL;
+    }
+#undef p_pes
+
+}
+
+/*****************************************************************************
+ * GatherPES:
+ *****************************************************************************
+ * Gather a PES packet.
+ *****************************************************************************/
+static void GatherPES( input_thread_t * p_input, data_packet_t * p_data,
+                       es_descriptor_t * p_es,
+                       vlc_bool_t b_unit_start, vlc_bool_t b_packet_lost )
+{
+#define p_pes (p_es->p_pes)
+
+    /* If we lost data, insert a NULL data packet (philosophy : 0 is quite
+     * often an escape sequence in decoders, so that should make them wait
+     * for the next start code). */
+    if( b_packet_lost )
+    {
+        input_NullPacket( p_input, p_es );
+    }
+
+    if( b_unit_start && p_pes != NULL )
+    {
+        /* If the data packet contains the begining of a new PES packet, and
+         * if we were reassembling a PES packet, then the PES should be
+         * complete now, so parse its header and give it to the decoders. */
+        ParsePES( p_input, p_es );
+    }
+
+    if( !b_unit_start && p_pes == NULL )
+    {
+        /* Random access... */
+        input_DeletePacket( p_input->p_method_data, p_data );
+    }
+    else
+    {
+        if( b_unit_start )
+        {
+            /* If we are at the beginning of a new PES packet, we must fetch
+             * a new PES buffer to begin with the reassembly of this PES
+             * packet. This is also here that we can synchronize with the
+             * stream if we lost packets or if the decoder has just
+             * started. */
+            if( (p_pes = input_NewPES( p_input->p_method_data ) ) == NULL )
+            {
+                msg_Err( p_input, "out of memory" );
+                p_input->b_error = 1;
+                return;
+            }
+            p_pes->i_rate = p_input->stream.control.i_rate;
+            p_pes->p_first = p_data;
+            
+            /* If the PES header fits in the first data packet, we can
+             * already set p_gather->i_pes_real_size. */
+            if( p_data->p_payload_end - p_data->p_payload_start
+                    >= PES_HEADER_SIZE )
+            {
+                p_es->i_pes_real_size = ((u16)p_data->p_payload_start[4] << 8)
+                                         + p_data->p_payload_start[5] + 6;
+            }
+            else
+            { 
+                p_es->i_pes_real_size = 0;
+            } 
+        }
+        else
+        {
+            /* Update the relations between the data packets */
+            p_pes->p_last->p_next = 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
+                                 - p_data->p_payload_start);
+    
+        /* We can check if the packet is finished */
+        if( p_pes->i_pes_size == p_es->i_pes_real_size )
+        {
+            /* The packet is finished, parse it */
+            ParsePES( p_input, p_es );
+        }
+    }
+#undef p_pes
+}
+
+
+/*
+ * PS Demultiplexing
+ */
+
+/*****************************************************************************
+ * GetID: Get the ID of a stream
+ *****************************************************************************/
+static u16 GetID( data_packet_t * p_data )
+{
+    u16         i_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_demux_start[ 9 + p_data->p_demux_start[8] ] << 8;
+    }
+    return( i_id );
+}
+
+/*****************************************************************************
+ * DecodePSM: Decode the Program Stream Map information
+ *****************************************************************************
+ * FIXME : loads are not aligned in this function
+ *****************************************************************************/
+static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data )
+{
+    stream_ps_data_t *  p_demux =
+                 (stream_ps_data_t *)p_input->stream.p_demux_data;
+    byte_t *            p_byte;
+    byte_t *            p_end;
+    int                 i;
+    int                 i_new_es_number = 0;
+
+    if( p_data->p_demux_start + 10 > p_data->p_payload_end )
+    {
+        msg_Err( p_input, "PSM too short, packet corrupt" );
+        return;
+    }
+
+    if( p_demux->b_has_PSM
+        && p_demux->i_PSM_version == (p_data->p_demux_start[6] & 0x1F) )
+    {
+        /* Already got that one. */
+        return;
+    }
+
+    p_demux->b_has_PSM = 1;
+    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_demux_start + 10
+              + U16_AT(&p_data->p_demux_start[8]);
+    if( p_byte > p_data->p_payload_end )
+    {
+        msg_Err( p_input, "PSM too short, packet corrupt" );
+        return;
+    }
+    /* This is the full size of the elementary_stream_map.
+     * 2 == elementary_stream_map_length
+     * Please note that CRC_32 is not included in the length. */
+    p_end = p_byte + 2 + U16_AT(p_byte);
+    p_byte += 2;
+    if( p_end > p_data->p_payload_end )
+    {
+        msg_Err( p_input, "PSM too short, packet corrupt" );
+        return;
+    }
+
+    vlc_mutex_lock( &p_input->stream.stream_lock );
+
+    /* 4 == minimum useful size of a section */
+    while( p_byte + 4 <= p_end )
+    {
+        es_descriptor_t *   p_es = NULL;
+        u8                  i_stream_id = p_byte[1];
+        /* FIXME: there will be a problem with private streams... (same
+         * stream_id) */
+
+        /* Look for the ES in the ES table */
+        for( i = i_new_es_number;
+             i < p_input->stream.pp_programs[0]->i_es_number;
+             i++ )
+        {
+            if( p_input->stream.pp_programs[0]->pp_es[i]->i_stream_id
+                    == i_stream_id )
+            {
+                p_es = p_input->stream.pp_programs[0]->pp_es[i];
+                /* FIXME: do something below */
+#if 0
+                if( p_es->i_type != p_byte[0] )
+                {
+                    input_DelES( p_input, p_es );
+                    p_es = NULL;
+                }
+                else
+#endif
+                {
+                    /* Move the ES to the beginning. */
+                    p_input->stream.pp_programs[0]->pp_es[i]
+                        = p_input->stream.pp_programs[0]->pp_es[ i_new_es_number ];
+                    p_input->stream.pp_programs[0]->pp_es[ i_new_es_number ]
+                        = p_es;
+                    i_new_es_number++;
+                }
+                break;
+            }
+        }
+
+        /* The goal is to have all the ES we have just read in the
+         * beginning of the pp_es table, and all the others at the end,
+         * so that we can close them more easily at the end. */
+        if( p_es == NULL )
+        {
+            p_es = input_AddES( p_input, p_input->stream.pp_programs[0],
+                                i_stream_id, 0 );
+            switch( p_byte[0] )
+            {
+            case MPEG1_VIDEO_ES:
+            case MPEG2_VIDEO_ES:
+                p_es->i_fourcc = VLC_FOURCC('m','p','g','v');
+                p_es->i_cat = VIDEO_ES;
+                break;
+            case DVD_SPU_ES:
+                p_es->i_fourcc = VLC_FOURCC('s','p','u',' ');
+                p_es->i_cat = SPU_ES;
+                break;
+            case MPEG1_AUDIO_ES:
+            case MPEG2_AUDIO_ES:
+                p_es->i_fourcc = VLC_FOURCC('m','p','g','a');
+                p_es->i_cat = AUDIO_ES;
+                break;
+            case A52_AUDIO_ES:
+                p_es->i_fourcc = VLC_FOURCC('a','5','2',' ');
+                p_es->i_cat = AUDIO_ES;
+                break;
+            case LPCM_AUDIO_ES:
+                p_es->i_fourcc = VLC_FOURCC('l','p','c','m');
+                p_es->i_cat = AUDIO_ES;
+                break;
+            default:
+                p_es->i_fourcc = 0;
+                break;
+            }
+
+            /* input_AddES has inserted the new element at the end. */
+            p_input->stream.pp_programs[0]->pp_es[
+                p_input->stream.pp_programs[0]->i_es_number ]
+                = p_input->stream.pp_programs[0]->pp_es[ i_new_es_number ];
+            p_input->stream.pp_programs[0]->pp_es[ i_new_es_number ] = p_es;
+            i_new_es_number++;
+        }
+        p_byte += 4 + U16_AT(&p_byte[2]);
+    }
+
+    /* Un-select the streams that are no longer parts of the program. */
+    while( i_new_es_number < p_input->stream.pp_programs[0]->i_es_number )
+    {
+        /* We remove pp_es[i_new_es_member] and not pp_es[i] because the
+         * list will be emptied starting from the end */
+        input_DelES( p_input,
+                     p_input->stream.pp_programs[0]->pp_es[i_new_es_number] );
+    }
+
+    msg_Dbg( p_input, "the stream map after the PSM is now:" );
+    input_DumpStream( p_input );
+
+    vlc_mutex_unlock( &p_input->stream.stream_lock );
+}
+
+/*****************************************************************************
+ * ReadPS: store a PS packet into a data_buffer_t
+ *****************************************************************************/
+#define PEEK( SIZE )                                                        \
+    i_error = input_Peek( p_input, &p_peek, SIZE );                         \
+    if( i_error == -1 )                                                     \
+    {                                                                       \
+        return( -1 );                                                       \
+    }                                                                       \
+    else if( i_error < SIZE )                                               \
+    {                                                                       \
+        /* EOF */                                                           \
+        return( 0 );                                                        \
+    }
+
+static ssize_t ReadPS( input_thread_t * p_input, data_packet_t ** pp_data )
+{
+    byte_t *            p_peek;
+    size_t              i_packet_size;
+    ssize_t             i_error, i_read;
+
+    /* Read what we believe to be a packet header. */
+    PEEK( 4 );
+
+    if( p_peek[0] || p_peek[1] || p_peek[2] != 1 || p_peek[3] < 0xB9 )
+    {
+        if( p_peek[0] || p_peek[1] || p_peek[2] )
+        {
+            /* 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. */
+            msg_Warn( p_input, "garbage (0x%.2x%.2x%.2x%.2x)",
+                      p_peek[0], p_peek[1], p_peek[2], p_peek[3] );
+        }
+
+        /* This is not the startcode of a packet. Read the stream
+         * until we find one. */
+        while( p_peek[0] || p_peek[1] || p_peek[2] != 1 || p_peek[3] < 0xB9 )
+        {
+            p_input->p_current_data++;
+            PEEK( 4 );
+            if( p_input->b_die ) return( -1 );
+        }
+        /* Packet found. */
+    }
+
+    /* 0x1B9 == SYSTEM_END_CODE, it is only 4 bytes long. */
+    if( p_peek[3] != 0xB9 )
+    {
+        /* The packet is at least 6 bytes long. */
+        PEEK( 6 );
+
+        if( p_peek[3] != 0xBA )
+        {
+            /* That's the case for all packets, except pack header. */
+            i_packet_size = (p_peek[4] << 8) | p_peek[5];
+        }
+        else
+        {
+            /* Pack header. */
+            if( (p_peek[4] & 0xC0) == 0x40 )
+            {
+                /* MPEG-2 */
+                i_packet_size = 8;
+            }
+            else if( (p_peek[4] & 0xF0) == 0x20 )
+            {
+                /* MPEG-1 */
+                i_packet_size = 6;
+            }
+            else
+            {
+                msg_Err( p_input, "unable to determine stream type" );
+                return( -1 );
+            }
+        }
+    }
+    else
+    {
+        /* System End Code */
+        i_packet_size = -2;
+    }
+
+    /* Fetch a packet of the appropriate size. */
+    i_read = input_SplitBuffer( p_input, pp_data, i_packet_size + 6 );
+    if( i_read <= 0 )
+    {
+        return( i_read );
+    }
+
+    /* In MPEG-2 pack headers we still have to read stuffing bytes. */
+    if( ((*pp_data)->p_demux_start[3] == 0xBA) && (i_packet_size == 8) )
+    {
+        size_t i_stuffing = ((*pp_data)->p_demux_start[13] & 0x7);
+        /* Force refill of the input buffer - though we don't care
+         * about p_peek. Please note that this is unoptimized. */
+        PEEK( i_stuffing );
+        p_input->p_current_data += i_stuffing;
+    }
+
+    return( 1 );
+}
+
+#undef PEEK
+
+/*****************************************************************************
+ * ParsePS: read the PS header
+ *****************************************************************************/
+static es_descriptor_t * ParsePS( input_thread_t * p_input,
+                                  data_packet_t * p_data )
+{
+    u32                 i_code;
+    es_descriptor_t *   p_es = NULL;
+
+    i_code = p_data->p_demux_start[3];
+
+    if( i_code > 0xBC ) /* ES start code */
+    {
+        u16                 i_id;
+        int                 i_dummy;
+
+        /* This is a PES packet. Find out if we want it or not. */
+        i_id = GetID( p_data );
+
+        vlc_mutex_lock( &p_input->stream.stream_lock );
+        if( p_input->stream.pp_programs[0]->b_is_ok )
+        {
+            /* Look only at the selected ES. */
+            for( i_dummy = 0; i_dummy < p_input->stream.i_selected_es_number;
+                 i_dummy++ )
+            {
+                if( p_input->stream.pp_selected_es[i_dummy] != NULL
+                    && p_input->stream.pp_selected_es[i_dummy]->i_id == i_id )
+                {
+                    p_es = p_input->stream.pp_selected_es[i_dummy];
+                    break;
+                }
+            }
+        }
+        else
+        {
+            stream_ps_data_t * p_demux =
+              (stream_ps_data_t *)p_input->stream.pp_programs[0]->p_demux_data;
+
+            /* Search all ES ; if not found -> AddES */
+            p_es = input_FindES( p_input, i_id );
+
+            if( p_es == NULL && !p_demux->b_has_PSM )
+            {
+                p_es = input_AddES( p_input, p_input->stream.pp_programs[0],
+                                    i_id, 0 );
+                if( p_es != NULL )
+                {
+                    p_es->i_stream_id = p_data->p_demux_start[3];
+
+                    /* Set stream type and auto-spawn. */
+                    if( (i_id & 0xF0) == 0xE0 )
+                    {
+                        /* MPEG video */
+                        p_es->i_fourcc = VLC_FOURCC('m','p','g','v');
+                        p_es->i_cat = VIDEO_ES;
+#ifdef AUTO_SPAWN
+                        if( !p_input->stream.b_seekable )
+                            input_SelectES( p_input, p_es );
+#endif
+                    }
+                    else if( (i_id & 0xE0) == 0xC0 )
+                    {
+                        /* MPEG audio */
+                        p_es->i_fourcc = VLC_FOURCC('m','p','g','a');
+                        p_es->i_cat = AUDIO_ES;
+#ifdef AUTO_SPAWN
+                        if( !p_input->stream.b_seekable )
+                        if( config_GetInt( p_input, "audio-channel" )
+                                == (p_es->i_id & 0x1F) ||
+                            ( config_GetInt( p_input, "audio-channel" ) < 0
+                              && !(p_es->i_id & 0x1F) ) )
+                        switch( config_GetInt( p_input, "audio-type" ) )
+                        {
+                        case -1:
+                        case REQUESTED_MPEG:
+                            input_SelectES( p_input, p_es );
+                        }
+#endif
+                    }
+                    else if( (i_id & 0xF0FF) == 0x80BD )
+                    {
+                        /* A52 audio (0x80->0x8F) */
+                        p_es->i_fourcc = VLC_FOURCC('a','5','2',' ');
+                        p_es->i_cat = AUDIO_ES;
+#ifdef AUTO_SPAWN
+                        if( !p_input->stream.b_seekable )
+                        if( config_GetInt( p_input, "audio-channel" )
+                                == ((p_es->i_id & 0xF00) >> 8) ||
+                            ( config_GetInt( p_input, "audio-channel" ) < 0
+                              && !((p_es->i_id & 0xF00) >> 8)) )
+                        switch( config_GetInt( p_input, "audio-type" ) )
+                        {
+                        case -1:
+                        case REQUESTED_A52:
+                            input_SelectES( p_input, p_es );
+                        }
+#endif
+                    }
+                    else if( (i_id & 0xE0FF) == 0x20BD )
+                    {
+                        /* Subtitles video (0x20->0x3F) */
+                        p_es->i_fourcc = VLC_FOURCC('s','p','u',' ');
+                        p_es->i_cat = SPU_ES;
+#ifdef AUTO_SPAWN
+                        if( config_GetInt( p_input, "spu-channel" )
+                                == ((p_es->i_id & 0x1F00) >> 8) )
+                        {
+                            if( !p_input->stream.b_seekable )
+                                input_SelectES( p_input, p_es );
+                        }
+#endif
+                    }
+                    else if( (i_id & 0xF0FF) == 0xA0BD )
+                    {
+                        /* LPCM audio (0xA0->0xAF) */
+                        p_es->i_fourcc = VLC_FOURCC('l','p','c','m');
+                        p_es->i_cat = AUDIO_ES;
+                    }
+                    else
+                    {
+                        p_es->i_fourcc = 0;
+                    }
+                }
+
+                /* Tell the interface the stream has changed */
+                p_input->stream.b_changed = 1;
+            }
+        } /* stream.b_is_ok */
+        vlc_mutex_unlock( &p_input->stream.stream_lock );
+    } /* i_code > 0xBC */
+
+    return( p_es );
+}
+
+/*****************************************************************************
+ * DemuxPS: first step of demultiplexing: the PS header
+ *****************************************************************************/
+static void DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
+{
+    u32                 i_code;
+    vlc_bool_t          b_trash = 0;
+    es_descriptor_t *   p_es = NULL;
+
+    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 )
+        {
+        case 0x1BA: /* PACK_START_CODE */
+            {
+                /* Read the SCR. */
+                mtime_t         scr_time;
+                u32             i_mux_rate;
+
+                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_demux_start;
+
+                    if( MoveChunk( p_header, &p_data, &p_byte, 14 ) != 14 )
+                    {
+                        msg_Warn( p_input,
+                                  "packet too short to have a header" );
+                        b_trash = 1;
+                        break;
+                    }
+                    scr_time =
+                         ((mtime_t)(p_header[4] & 0x38) << 27) |
+                         ((mtime_t)(U32_AT(p_header + 4) & 0x03FFF800)
+                                        << 4) |
+                         ((( ((mtime_t)U16_AT(p_header + 6) << 16)
+                            | (mtime_t)U16_AT(p_header + 8) ) & 0x03FFF800)
+                                        >> 11);
+
+                    /* mux_rate */
+                    i_mux_rate = ((u32)U16_AT(p_header + 10) << 6)
+                                   | (p_header[12] >> 2);
+                    /* FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
+                     * This is the biggest kludge ever !
+                     * I don't know what's wrong with mux_rate calculation
+                     * but this heuristic works well : */
+                    i_mux_rate <<= 1;
+                    i_mux_rate /= 3;
+                }
+                else
+                {
+                    /* MPEG-1 SCR is like PTS. */
+                    byte_t      p_header[12];
+                    byte_t *    p_byte;
+                    p_byte = p_data->p_demux_start;
+
+                    if( MoveChunk( p_header, &p_data, &p_byte, 12 ) != 12 )
+                    {
+                        msg_Warn( p_input,
+                                  "packet too short to have a header" );
+                        b_trash = 1;
+                        break;
+                    }
+                    scr_time =
+                         ((mtime_t)(p_header[4] & 0x0E) << 29) |
+                         (((mtime_t)U32_AT(p_header + 4) & 0xFFFE00) << 6) |
+                         ((mtime_t)p_header[7] << 7) |
+                         ((mtime_t)p_header[8] >> 1);
+
+                    /* mux_rate */
+                    i_mux_rate = (U32_AT(p_header + 8) & 0x7FFFFE) >> 1;
+                }
+                /* Call the pace control. */
+                input_ClockManageRef( p_input,
+                                      p_input->stream.p_selected_program,
+                                      scr_time );
+
+                if( i_mux_rate != p_input->stream.i_mux_rate
+                     && p_input->stream.i_mux_rate )
+                {
+                    msg_Warn( p_input,
+                              "mux_rate changed, expect cosmetic errors" );
+                }
+                p_input->stream.i_mux_rate = i_mux_rate;
+
+                b_trash = 1;
+            }
+            break;
+
+        case 0x1BB: /* SYSTEM_START_CODE */
+            b_trash = 1;                              /* Nothing interesting */
+            break;
+
+        case 0x1BC: /* PROGRAM_STREAM_MAP_CODE */
+            DecodePSM( p_input, p_data );
+            b_trash = 1;
+            break;
+    
+        case 0x1B9: /* PROGRAM_END_CODE */
+            b_trash = 1;
+            break;
+   
+        default:
+            /* This should not happen */
+            b_trash = 1;
+            msg_Warn( p_input, "unwanted packet received "
+                               "with startcode 0x%.8x", i_code );
+        }
+    }
+    else
+    {
+        p_es = ParsePS( p_input, p_data );
+
+        vlc_mutex_lock( &p_input->stream.control.control_lock );
+        if( p_es != NULL && p_es->p_decoder_fifo != NULL
+             && (p_es->i_cat != AUDIO_ES || !p_input->stream.control.b_mute) )
+        {
+            vlc_mutex_unlock( &p_input->stream.control.control_lock );
+            p_es->c_packets++;
+            GatherPES( p_input, p_data, p_es, 1, 0 );
+        }
+        else
+        {
+            vlc_mutex_unlock( &p_input->stream.control.control_lock );
+            b_trash = 1;
+        }
+    }
+
+    /* Trash the packet if it has no payload or if it isn't selected */
+    if( b_trash )
+    {
+        input_DeletePacket( p_input->p_method_data, p_data );
+        p_input->stream.c_packets_trashed++;
+    }
+}
+
+/*
+ * TS Demultiplexing
+ */
+
+/*****************************************************************************
+ * ReadTS: store a TS packet into a data_buffer_t
+ *****************************************************************************/
+#define PEEK( SIZE )                                                        \
+    i_error = input_Peek( p_input, &p_peek, SIZE );                         \
+    if( i_error == -1 )                                                     \
+    {                                                                       \
+        return( -1 );                                                       \
+    }                                                                       \
+    else if( i_error < SIZE )                                               \
+    {                                                                       \
+        /* EOF */                                                           \
+        return( 0 );                                                        \
+    }
+
+static ssize_t ReadTS( input_thread_t * p_input, data_packet_t ** pp_data )
+{
+    byte_t *            p_peek;
+    ssize_t             i_error, i_read;
+
+    PEEK( 1 );
+
+    if( *p_peek != TS_SYNC_CODE )
+    {
+        msg_Warn( p_input, "garbage at input (%x)", *p_peek );
+
+        if( p_input->i_mtu )
+        {
+            while( *p_peek != TS_SYNC_CODE )
+            {
+                /* Try to resync on next packet. */
+                PEEK( TS_PACKET_SIZE );
+                p_input->p_current_data += TS_PACKET_SIZE;
+                PEEK( 1 );
+            }
+        }
+        else
+        {
+            /* Move forward until we find 0x47 (and hope it's the good
+             * one... FIXME) */
+            while( *p_peek != TS_SYNC_CODE )
+            {
+                p_input->p_current_data++;
+                PEEK( 1 );
+            }
+        }
+    }
+
+    i_read = input_SplitBuffer( p_input, pp_data, TS_PACKET_SIZE );
+    if( i_read <= 0 )
+    {
+        return( i_read );
+    }
+
+    return( 1 );
+}
+
+/*****************************************************************************
+ * DemuxTS: first step of demultiplexing: the TS header
+ *****************************************************************************/
+static void DemuxTS( input_thread_t * p_input, data_packet_t * p_data,
+                     psi_callback_t pf_psi_callback )
+{
+    u16                 i_pid;
+    int                 i_dummy;
+    vlc_bool_t          b_adaptation;         /* Adaptation field is present */
+    vlc_bool_t          b_payload;                 /* Packet carries payload */
+    vlc_bool_t          b_unit_start;  /* A PSI or a PES start in the packet */
+    vlc_bool_t          b_trash = 0;             /* Is the packet unuseful ? */
+    vlc_bool_t          b_lost = 0;             /* Was there a packet loss ? */
+    vlc_bool_t          b_psi = 0;                        /* Is this a PSI ? */
+    vlc_bool_t          b_pcr = 0;                   /* Does it have a PCR ? */
+    es_descriptor_t *   p_es = NULL;
+    es_ts_data_t *      p_es_demux = NULL;
+    pgrm_ts_data_t *    p_pgrm_demux = NULL;
+
+#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);
+    b_adaptation = (p[3] & 0x20);
+    b_payload = (p[3] & 0x10);
+
+    /* Find out the elementary stream. */
+    vlc_mutex_lock( &p_input->stream.stream_lock );
+    
+    for( i_dummy = 0; i_dummy < p_input->stream.i_pgrm_number; i_dummy ++ )
+    {
+        if( (( pgrm_ts_data_t * ) p_input->stream.pp_programs[i_dummy]->
+                    p_demux_data)->i_pcr_pid == i_pid )
+        {
+            b_pcr = 1;
+            break;
+        }
+    }
+            
+    p_es= input_FindES( p_input, i_pid );
+    
+    if( (p_es != NULL) && (p_es->p_demux_data != NULL) )
+    {
+        p_es_demux = (es_ts_data_t *)p_es->p_demux_data;
+        
+        if( p_es_demux->b_psi )
+        {
+            b_psi = 1;
+        }
+        else
+        {
+            p_pgrm_demux = (pgrm_ts_data_t *)p_es->p_pgrm->p_demux_data; 
+        }
+    }
+
+    vlc_mutex_lock( &p_input->stream.control.control_lock );
+    if( ( p_es == NULL ) || (p_es->i_cat == AUDIO_ES
+                              && p_input->stream.control.b_mute) )
+    {
+        /* Not selected. Just read the adaptation field for a PCR. */
+        b_trash = 1;
+    }
+    else if( p_es->p_decoder_fifo == NULL && !b_psi )
+    {
+        b_trash = 1; 
+    }
+
+    vlc_mutex_unlock( &p_input->stream.control.control_lock );
+    vlc_mutex_unlock( &p_input->stream.stream_lock );
+
+
+    /* Don't change the order of the tests : if b_psi then p_pgrm_demux 
+     * may still be null. Who said it was ugly ?
+     * I have written worse. --Meuuh */
+    if( ( p_es  ) && 
+        ((p_es->p_decoder_fifo != NULL) || b_psi || b_pcr ) )
+    {
+        p_es->c_packets++;
+
+        /* Extract adaptation field information if any */
+
+        if( !b_adaptation )
+        {
+            /* We don't have any adaptation_field, so payload starts
+             * immediately after the 4 byte TS header */
+            p_data->p_payload_start += 4;
+        }
+        else
+        {
+            /* p[4] is adaptation_field_length minus one */
+            p_data->p_payload_start += 5 + p[4];
+    
+            /* The adaptation field can be limited to the
+             * adaptation_field_length byte, so that there is nothing to do:
+             * skip this possibility */
+            if( p[4] )
+            {
+                /* If the packet has both adaptation_field and payload,
+                 * adaptation_field cannot be more than 182 bytes long; if
+                 * there is only an adaptation_field, it must fill the next
+                 * 183 bytes. */
+                if( b_payload ? (p[4] > 182) : (p[4] != 183) )
+                {
+                    msg_Warn( p_input, "invalid TS adaptation field (%p)",
+                              p_data );
+                    p_data->b_discard_payload = 1;
+                    p_es->c_invalid_packets++;
+                }
+    
+                /* Now we are sure that the byte containing flags is present:
+                 * read it */
+                else
+                {
+                    /* discontinuity_indicator */
+                    if( p[5] & 0x80 )
+                    {
+                        msg_Warn( p_input,
+                            "discontinuity_indicator encountered by TS demux "
+                            "(position read: %d, saved: %d)",
+                            p[5] & 0x80, p_es_demux->i_continuity_counter );
+    
+                        /* If the PID carries the PCR, there will be a system
+                         * time-based discontinuity. We let the PCR decoder
+                         * handle that. */
+                        p_es->p_pgrm->i_synchro_state = SYNCHRO_REINIT;
+    
+                        /* There also may be a continuity_counter
+                         * discontinuity: resynchronize our counter with
+                         * the one of the stream. */
+                        p_es_demux->i_continuity_counter = (p[3] & 0x0f) - 1;
+                    }
+    
+                } /* valid TS adaptation field ? */
+            } /* length > 0 */
+        } /* has adaptation field */
+        /* Check the continuity of the stream. */
+        i_dummy = ((p[3] & 0x0f) - p_es_demux->i_continuity_counter) & 0x0f;
+        if( i_dummy == 1 )
+        {
+            /* Everything is ok, just increase our counter */
+            (p_es_demux->i_continuity_counter)++;
+        }
+        else
+        {
+            if( !b_payload && i_dummy == 0 )
+            {
+                /* This is a packet without payload, this is allowed by the
+                 * draft. As there is nothing interesting in this packet
+                 * (except PCR that have already been handled), we can trash
+                 * the packet. */
+                b_trash = 1;
+            }
+            else if( i_dummy <= 0 )
+            {
+                /* Duplicate packet: mark it as being to be trashed. */
+                msg_Warn( p_input,
+                          "duplicate packet received by TS demux" );
+                b_trash = 1;
+            }
+            else if( p_es_demux->i_continuity_counter == 0xFF )
+            {
+                /* This means that the packet is the first one we receive for
+                 * this ES since the continuity counter ranges between 0 and
+                 * 0x0F excepts when it has been initialized by the input:
+                 * init the counter to the correct value. */
+                msg_Warn( p_input, "first packet for PID %d received "
+                                   "by TS demux", p_es->i_id );
+                p_es_demux->i_continuity_counter = (p[3] & 0x0f);
+            }
+            else
+            {
+                /* This can indicate that we missed a packet or that the
+                 * continuity_counter wrapped and we received a dup packet:
+                 * as we don't know, do as if we missed a packet to be sure
+                 * to recover from this situation */
+                msg_Warn( p_input,
+                          "packet lost by TS demux: current %d, packet %d",
+                          p_es_demux->i_continuity_counter & 0x0f,
+                          p[3] & 0x0f );
+                b_lost = 1;
+                p_es_demux->i_continuity_counter = p[3] & 0x0f;
+            } /* not continuous */
+        } /* continuity */
+    } /* if selected or PCR */
+    
+    /* Handle PCR */
+    if( b_pcr && b_adaptation && (p[5] & 0x10) && p[4]>=7 )
+    {
+        /* Read the PCR. */
+        mtime_t     pcr_time;
+        pcr_time = ( (mtime_t)p[6] << 25 ) |
+                   ( (mtime_t)p[7] << 17 ) |
+                   ( (mtime_t)p[8] << 9 ) |
+                   ( (mtime_t)p[9] << 1 ) |
+                   ( (mtime_t)p[10] >> 7 );
+        /* Call the pace control. */
+        for( i_dummy = 0; i_dummy < p_input->stream.i_pgrm_number; 
+                                i_dummy ++ )
+        {
+            if( ( ( pgrm_ts_data_t * ) p_input->stream.pp_programs[i_dummy]->
+                        p_demux_data )->i_pcr_pid == i_pid )
+            {
+                input_ClockManageRef( p_input,
+                    p_input->stream.pp_programs[i_dummy], pcr_time );
+            }
+        }
+
+    }
+    
+    /* Trash the packet if it has no payload or if it isn't selected */
+    if( b_trash )
+    {
+        input_DeletePacket( p_input->p_method_data, p_data );
+        p_input->stream.c_packets_trashed++;
+    }
+    else
+    {
+        if( b_psi )
+        {
+            /* The payload contains PSI tables */
+            (* pf_psi_callback) ( p_input, p_data, p_es, b_unit_start );
+        }
+        else
+        {
+            /* The payload carries a PES stream */
+            GatherPES( p_input, p_data, p_es, b_unit_start, b_lost ); 
+        }
+
+    }
+
+#undef p
+
+}
+
diff --git a/modules/demux/mpeg/system.h b/modules/demux/mpeg/system.h
new file mode 100644 (file)
index 0000000..114441a
--- /dev/null
@@ -0,0 +1,152 @@
+/*****************************************************************************
+ * system.h: MPEG demultiplexing.
+ *****************************************************************************
+ * Copyright (C) 1999-2002 VideoLAN
+ * $Id: system.h,v 1.1 2002/08/07 00:29:36 sam Exp $
+ *
+ * Authors: Christophe Massiot <massiot@via.ecp.fr>
+ *
+ * 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.
+ *****************************************************************************/
+
+/*
+ * Optional MPEG demultiplexing
+ */
+
+/*****************************************************************************
+ * Constants
+ *****************************************************************************/
+#define TS_PACKET_SIZE      188                       /* Size of a TS packet */
+#define TS_SYNC_CODE        0x47                /* First byte of a TS packet */
+#define PSI_SECTION_SIZE    4096            /* Maximum size of a PSI section */
+
+#define PAT_UNINITIALIZED    (1 << 6)
+#define PMT_UNINITIALIZED    (1 << 6)
+
+#define PSI_IS_PAT          0x00
+#define PSI_IS_PMT          0x01
+#define UNKNOWN_PSI         0xff
+
+/****************************************************************************
+ * psi_callback_t
+ ****************************************************************************
+ * Used by TS demux to handle a PSI, either with the builtin decoder, either
+ * with a library such as libdvbpsi
+ ****************************************************************************/
+typedef void( * psi_callback_t )( 
+        input_thread_t  * p_input,
+        data_packet_t   * p_data,
+        es_descriptor_t * p_es,
+        vlc_bool_t        b_unit_start );
+
+
+/****************************************************************************
+ * mpeg_demux_t
+ ****************************************************************************
+ * Demux callbacks exported by the helper plugin
+ ****************************************************************************/
+typedef struct mpeg_demux_t
+{
+    module_t * p_module;
+
+    ssize_t           (*pf_read_ps)  ( input_thread_t *, data_packet_t ** );
+    es_descriptor_t * (*pf_parse_ps) ( input_thread_t *, data_packet_t * );
+    void              (*pf_demux_ps) ( input_thread_t *, data_packet_t * );
+
+    ssize_t           (*pf_read_ts)  ( input_thread_t *, data_packet_t ** );
+    void              (*pf_demux_ts) ( input_thread_t *, data_packet_t *,
+                                       psi_callback_t );
+} mpeg_demux_t;
+
+/*****************************************************************************
+ * psi_section_t
+ *****************************************************************************
+ * Describes a PSI section. Beware, it doesn't contain pointers to the TS
+ * packets that contain it as for a PES, but the data themselves
+ *****************************************************************************/
+typedef struct psi_section_t
+{
+    byte_t                  buffer[PSI_SECTION_SIZE];
+
+    u8                      i_section_number;
+    u8                      i_last_section_number;
+    u8                      i_version_number;
+    u16                     i_section_length;
+    u16                     i_read_in_section;
+    
+    /* the PSI is complete */
+    vlc_bool_t              b_is_complete;
+    
+    /* packet missed up ? */
+    vlc_bool_t              b_trash;
+
+    /*about sections  */ 
+    vlc_bool_t              b_section_complete;
+
+    /* where are we currently ? */
+    byte_t                * p_current;
+
+} psi_section_t;
+
+/*****************************************************************************
+ * es_ts_data_t: extension of es_descriptor_t
+ *****************************************************************************/
+typedef struct es_ts_data_t
+{
+    vlc_bool_t              b_psi;   /* Does the stream have to be handled by
+                                      *                    the PSI decoder ? */
+
+    int                     i_psi_type;  /* There are different types of PSI */
+    
+    psi_section_t *         p_psi_section;                    /* PSI packets */
+
+    /* Markers */
+    int                     i_continuity_counter;
+} es_ts_data_t;
+
+/*****************************************************************************
+ * pgrm_ts_data_t: extension of pgrm_descriptor_t
+ *****************************************************************************/
+typedef struct pgrm_ts_data_t
+{
+    u16                     i_pcr_pid;             /* PCR ES, for TS streams */
+    int                     i_pmt_version;
+    /* libdvbpsi pmt decoder handle */
+    void *                  p_pmt_handle;
+} pgrm_ts_data_t;
+
+/*****************************************************************************
+ * stream_ts_data_t: extension of stream_descriptor_t
+ *****************************************************************************/
+typedef struct stream_ts_data_t
+{
+    int i_pat_version;          /* Current version of the PAT */
+    /* libdvbpsi pmt decoder handle */
+    void *                  p_pat_handle;
+} stream_ts_data_t;
+
+/*****************************************************************************
+ * stream_ps_data_t: extension of stream_descriptor_t
+ *****************************************************************************/
+typedef struct stream_ps_data_t
+{
+    vlc_bool_t              b_has_PSM;                 /* very rare, in fact */
+
+    u8                      i_PSM_version;
+} stream_ps_data_t;
+
+/* PSM version is 5 bits, so -1 is not a valid value */
+#define EMPTY_PSM_VERSION   -1
+
index 2ecf45a..03508fc 100644 (file)
@@ -2,7 +2,7 @@
  * mpeg_ts.c : Transport Stream input module for vlc
  *****************************************************************************
  * Copyright (C) 2000-2001 VideoLAN
- * $Id: ts.c,v 1.1 2002/08/04 17:23:42 sam Exp $
+ * $Id: ts.c,v 1.2 2002/08/07 00:29:36 sam Exp $
  *
  * Authors: Henri Fallon <henri@via.ecp.fr>
  *          Johan Bilien <jobi@via.ecp.fr>
 #   endif
 #endif
 
+#include "system.h"
+
 /*****************************************************************************
  * Constants
  *****************************************************************************/
 #define TS_READ_ONCE 200
 
+/*****************************************************************************
+ * Private structure
+ *****************************************************************************/
+struct demux_sys_t
+{
+    module_t *   p_module;
+    mpeg_demux_t mpeg;
+};
+
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
-static int  Activate ( vlc_object_t * );
-static int  Demux ( input_thread_t * );
+static int  Activate   ( vlc_object_t * );
+static void Deactivate ( vlc_object_t * );
+static int  Demux      ( input_thread_t * );
 
 #if defined MODULE_NAME_IS_ts
 static void TSDemuxPSI ( input_thread_t *, data_packet_t *,
@@ -88,19 +100,20 @@ vlc_module_begin();
     set_capability( "demux", 170 );
     add_shortcut( "ts_dvbpsi" );
 #endif
-    set_callbacks( Activate, NULL );
+    set_callbacks( Activate, Deactivate );
 vlc_module_end();
 
 /*****************************************************************************
- * Activate: initializes TS structures
+ * Activate: initialize TS structures
  *****************************************************************************/
 static int Activate( vlc_object_t * p_this )
 {
     input_thread_t *    p_input = (input_thread_t *)p_this;
-    es_descriptor_t     * p_pat_es;
-    es_ts_data_t        * p_demux_data;
-    stream_ts_data_t    * p_stream_data;
-    byte_t              * p_peek;
+    demux_sys_t *       p_demux;
+    es_descriptor_t *   p_pat_es;
+    es_ts_data_t *      p_demux_data;
+    stream_ts_data_t *  p_stream_data;
+    byte_t *            p_peek;
 
     /* Set the demux function */
     p_input->pf_demux = Demux;
@@ -116,7 +129,7 @@ static int Activate( vlc_object_t * p_this )
     if( input_Peek( p_input, &p_peek, 1 ) < 1 )
     {
         msg_Err( p_input, "cannot peek()" );
-        return( -1 );
+        return -1;
     }
 
     if( *p_peek != TS_SYNC_CODE )
@@ -129,7 +142,7 @@ static int Activate( vlc_object_t * p_this )
         else
         {
             msg_Warn( p_input, "TS module discarded (no sync)" );
-            return( -1 );
+            return -1;
         }
     }
 
@@ -140,13 +153,29 @@ static int Activate( vlc_object_t * p_this )
         p_input->i_bufsize = (p_input->i_mtu / TS_PACKET_SIZE) * TS_PACKET_SIZE;
     }
 
+    p_demux = p_input->p_demux_data = malloc( sizeof(demux_sys_t ) );
+    if( p_demux == NULL )
+    {
+        return -1;
+    }
+
+    p_input->p_private = (void*)&p_demux->mpeg;
+    p_demux->p_module = module_Need( p_input, "mpeg-system", NULL );
+    if( p_demux->p_module == NULL )
+    {
+        free( p_input->p_demux_data );
+        return -1;
+    }
+
     vlc_mutex_lock( &p_input->stream.stream_lock );
 
     if( input_InitStream( p_input, sizeof( stream_ts_data_t ) ) == -1 )
     {
-        return( -1 );
+        module_Unneed( p_input, p_demux->p_module );
+        free( p_input->p_demux_data );
+        return -1;
     }
-    
+
     p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
     p_stream_data->i_pat_version = PAT_UNINITIALIZED ;
 
@@ -157,7 +186,9 @@ static int Activate( vlc_object_t * p_this )
     if( p_stream_data->p_pat_handle == NULL )
     {
         msg_Err( p_input, "could not create PAT decoder" );
-        return( -1 );
+        module_Unneed( p_input, p_demux->p_module );
+        free( p_input->p_demux_data );
+        return -1;
     }
 #endif
     
@@ -174,7 +205,18 @@ static int Activate( vlc_object_t * p_this )
 
     vlc_mutex_unlock( &p_input->stream.stream_lock );
     
-    return( 0 );
+    return 0;
+}
+
+/*****************************************************************************
+ * Deactivate: deinitialize TS structures
+ *****************************************************************************/
+static void Deactivate( vlc_object_t * p_this )
+{
+    input_thread_t *    p_input = (input_thread_t *)p_this;
+
+    module_Unneed( p_input, p_input->p_demux_data->p_module );
+    free( p_input->p_demux_data );
 }
 
 /*****************************************************************************
@@ -185,6 +227,7 @@ static int Activate( vlc_object_t * p_this )
  *****************************************************************************/
 static int Demux( input_thread_t * p_input )
 {
+    demux_sys_t *   p_demux = p_input->p_demux_data;
     int             i_read_once = (p_input->i_mtu ?
                                    p_input->i_bufsize / TS_PACKET_SIZE :
                                    TS_READ_ONCE);
@@ -195,17 +238,18 @@ static int Demux( input_thread_t * p_input )
         data_packet_t *     p_data;
         ssize_t             i_result;
 
-        i_result = input_ReadTS( p_input, &p_data );
+        i_result = p_demux->mpeg.pf_read_ts( p_input, &p_data );
 
         if( i_result <= 0 )
         {
-            return( i_result );
+            return i_result;
         }
 
-        input_DemuxTS( p_input, p_data, (psi_callback_t) &PSI_CALLBACK );
+        p_demux->mpeg.pf_demux_ts( p_input, p_data,
+                                   (psi_callback_t) &PSI_CALLBACK );
     }
 
-    return( i_read_once );
+    return i_read_once;
 }
 
 
diff --git a/src/input/mpeg_system.c b/src/input/mpeg_system.c
deleted file mode 100644 (file)
index 2ac3401..0000000
+++ /dev/null
@@ -1,1334 +0,0 @@
-/*****************************************************************************
- * mpeg_system.c: TS, PS and PES management
- *****************************************************************************
- * Copyright (C) 1998-2001 VideoLAN
- * $Id: mpeg_system.c,v 1.101 2002/08/04 17:23:44 sam Exp $
- *
- * Authors: Christophe Massiot <massiot@via.ecp.fr>
- *          Michel Lespinasse <walken@via.ecp.fr>
- *          Benoît Steiner <benny@via.ecp.fr>
- *          Samuel Hocevar <sam@via.ecp.fr>
- *          Henri Fallon <henri@via.ecp.fr>
- *
- * 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 <stdlib.h>
-#include <string.h>                                    /* memcpy(), memset() */
-#include <sys/types.h>                                              /* off_t */
-
-#include <vlc/vlc.h>
-
-#include "stream_control.h"
-#include "input_ext-intf.h"
-#include "input_ext-dec.h"
-#include "input_ext-plugins.h"
-
-/*
- * PES Packet management
- */
-
-/*****************************************************************************
- * MoveChunk
- *****************************************************************************
- * Small utility function used to parse discontinuous headers safely. Copies
- * i_buf_len bytes of data to a buffer and returns the size copied.
- * It also solves some alignment problems on non-IA-32, non-PPC processors.
- * This is a variation on the theme of input_ext-dec.h:GetChunk().
- *****************************************************************************/
-static inline size_t MoveChunk( byte_t * p_dest, data_packet_t ** pp_data_src,
-                                byte_t ** pp_src, size_t i_buf_len )
-{
-    ptrdiff_t           i_available;
-
-    if( (i_available = (*pp_data_src)->p_payload_end - *pp_src)
-            >= i_buf_len )
-    {
-        if( p_dest != NULL )
-            memcpy( p_dest, *pp_src, i_buf_len );
-        *pp_src += i_buf_len;
-        return( i_buf_len );
-    }
-    else
-    {
-        size_t          i_init_len = i_buf_len;
-
-        do
-        {
-            if( p_dest != NULL )
-                memcpy( p_dest, *pp_src, i_available );
-            *pp_data_src = (*pp_data_src)->p_next;
-            i_buf_len -= i_available;
-            p_dest += i_available;
-            if( *pp_data_src == NULL )
-            {
-                *pp_src = NULL;
-                return( i_init_len - i_buf_len );
-            }
-            *pp_src = (*pp_data_src)->p_payload_start;
-        }
-        while( (i_available = (*pp_data_src)->p_payload_end - *pp_src)
-                <= i_buf_len );
-
-        if( i_buf_len )
-        {
-            if( p_dest != NULL )
-                memcpy( p_dest, *pp_src, i_buf_len );
-            *pp_src += i_buf_len;
-        }
-        return( i_init_len );
-    }
-}
-
-/*****************************************************************************
- * input_ParsePES
- *****************************************************************************
- * Parse a finished PES packet and analyze its header.
- *****************************************************************************/
-#define PES_HEADER_SIZE     7
-void input_ParsePES( input_thread_t * p_input, es_descriptor_t * p_es )
-{
-    data_packet_t * p_data;
-    byte_t *        p_byte;
-    byte_t          p_header[PES_HEADER_SIZE];
-    int             i_done;
-
-#define p_pes (p_es->p_pes)
-
-    /* Parse the header. The header has a variable length, but in order
-     * to improve the algorithm, we will read the 14 bytes we may be
-     * interested in */
-    p_data = p_pes->p_first;
-    p_byte = p_data->p_payload_start;
-    i_done = 0;
-
-    if( MoveChunk( p_header, &p_data, &p_byte, PES_HEADER_SIZE )
-            != PES_HEADER_SIZE )
-    {
-        msg_Warn( p_input, "PES packet too short to have a header" );
-        input_DeletePES( p_input->p_method_data, p_pes );
-        p_pes = NULL;
-        return;
-    }
-
-    /* Get the PES size if defined */
-    p_es->i_pes_real_size = U16_AT(p_header + 4);
-    if( p_es->i_pes_real_size )
-    {
-        p_es->i_pes_real_size += 6;
-    }
-
-    /* First read the 6 header bytes common to all PES packets:
-     * use them to test the PES validity */
-    if( (p_header[0] || p_header[1] || (p_header[2] != 1)) )
-    {
-        /* packet_start_code_prefix != 0x000001 */
-        msg_Err( p_input, "data loss, PES packet does not start with 000001" );
-        input_DeletePES( p_input->p_method_data, p_pes );
-        p_pes = NULL;
-    }
-    else
-    {
-        int i_pes_header_size, i_payload_size;
-
-        if ( p_es->i_pes_real_size &&
-             (p_es->i_pes_real_size != p_pes->i_pes_size) )
-        {
-            /* PES_packet_length is set and != total received payload */
-            /* Warn the decoder that the data may be corrupt. */
-            msg_Warn( p_input, "packet corrupted, PES sizes do not match" );
-        }
-
-        switch( p_es->i_stream_id )
-        {
-        case 0xBC:  /* Program stream map */
-        case 0xBE:  /* Padding */
-        case 0xBF:  /* Private stream 2 */
-        case 0xB0:  /* ECM */
-        case 0xB1:  /* EMM */
-        case 0xFF:  /* Program stream directory */
-        case 0xF2:  /* DSMCC stream */
-        case 0xF8:  /* ITU-T H.222.1 type E stream */
-            /* The payload begins immediately after the 6 bytes header, so
-             * we have finished with the parsing */
-            i_pes_header_size = 6;
-            break;
-
-        default:
-            if( (p_header[6] & 0xC0) == 0x80 )
-            {
-                /* MPEG-2 : the PES header contains at least 3 more bytes. */
-                size_t      i_max_len;
-                vlc_bool_t  b_has_pts, b_has_dts;
-                byte_t      p_full_header[12];
-
-                p_pes->b_data_alignment = p_header[6] & 0x04;
-
-                i_max_len = MoveChunk( p_full_header, &p_data, &p_byte, 12 );
-                if( i_max_len < 2 )
-                {
-                    msg_Warn( p_input, 
-                              "PES packet too short to have a MPEG-2 header" );
-                    input_DeletePES( p_input->p_method_data,
-                                            p_pes );
-                    p_pes = NULL;
-                    return;
-                }
-
-                b_has_pts = p_full_header[0] & 0x80;
-                b_has_dts = p_full_header[0] & 0x40;
-                i_pes_header_size = p_full_header[1] + 9;
-
-                /* Now parse the optional header extensions */
-                if( b_has_pts )
-                {
-                    if( i_max_len < 7 )
-                    {
-                        msg_Warn( p_input,
-                             "PES packet too short to have a MPEG-2 header" );
-                        input_DeletePES( p_input->p_method_data,
-                                                p_pes );
-                        p_pes = NULL;
-                        return;
-                    }
-                    p_pes->i_pts = input_ClockGetTS( p_input, p_es->p_pgrm,
-                    ( ((mtime_t)(p_full_header[2] & 0x0E) << 29) |
-                      ((mtime_t)(p_full_header[3]) << 22) |
-                      ((mtime_t)(p_full_header[4] & 0xFE) << 14) |
-                      ((mtime_t)p_full_header[5] << 7) |
-                      ((mtime_t)p_full_header[6] >> 1) ) );
-
-                    if( b_has_dts )
-                    {
-                        if( i_max_len < 12 )
-                        {
-                            msg_Warn( p_input,
-                              "PES packet too short to have a MPEG-2 header" );
-                            input_DeletePES( p_input->p_method_data,
-                                                    p_pes );
-                            p_pes = NULL;
-                            return;
-                        }
-                        p_pes->i_dts = input_ClockGetTS( p_input, p_es->p_pgrm,
-                        ( ((mtime_t)(p_full_header[7] & 0x0E) << 29) |
-                          (((mtime_t)U16_AT(p_full_header + 8) << 14)
-                                - (1 << 14)) |
-                          ((mtime_t)U16_AT(p_full_header + 10) >> 1) ) );
-                    }
-                }
-            }
-            else
-            {
-                /* Probably MPEG-1 */
-                vlc_bool_t      b_has_pts, b_has_dts;
-
-                i_pes_header_size = 6;
-                p_data = p_pes->p_first;
-                p_byte = p_data->p_payload_start;
-                /* Cannot fail because the previous one succeeded. */
-                MoveChunk( NULL, &p_data, &p_byte, 6 );
-
-                while( *p_byte == 0xFF && i_pes_header_size < 23 )
-                {
-                    i_pes_header_size++;
-                    if( MoveChunk( NULL, &p_data, &p_byte, 1 ) != 1 )
-                    {
-                        msg_Warn( p_input,
-                            "PES packet too short to have a MPEG-1 header" );
-                        input_DeletePES( p_input->p_method_data, p_pes );
-                        p_pes = NULL;
-                        return;
-                    }
-                }
-                if( i_pes_header_size == 23 )
-                {
-                    msg_Err( p_input, "too much MPEG-1 stuffing" );
-                    input_DeletePES( p_input->p_method_data, p_pes );
-                    p_pes = NULL;
-                    return;
-                }
-
-                if( (*p_byte & 0xC0) == 0x40 )
-                {
-                    /* Don't ask why... --Meuuh */
-                    /* Erm... why ? --Sam */
-                    /* Well... According to the recommendation, it is for
-                     * STD_buffer_scale and STD_buffer_size. --Meuuh */
-                    i_pes_header_size += 2;
-                    if( MoveChunk( NULL, &p_data, &p_byte, 2 ) != 2 )
-                    {
-                        msg_Warn( p_input,
-                            "PES packet too short to have a MPEG-1 header" );
-                        input_DeletePES( p_input->p_method_data, p_pes );
-                        p_pes = NULL;
-                        return;
-                    }
-                }
-
-                i_pes_header_size++;
-
-                b_has_pts = *p_byte & 0x20;
-                b_has_dts = *p_byte & 0x10;
-
-                if( b_has_pts )
-                {
-                    byte_t      p_ts[5];
-
-                    i_pes_header_size += 4;
-                    if( MoveChunk( p_ts, &p_data, &p_byte, 5 ) != 5 )
-                    {
-                        msg_Warn( p_input,
-                            "PES packet too short to have a MPEG-1 header" );
-                        input_DeletePES( p_input->p_method_data, p_pes );
-                        p_pes = NULL;
-                        return;
-                    }
-
-                    p_pes->i_pts = input_ClockGetTS( p_input, p_es->p_pgrm,
-                       ( ((mtime_t)(p_ts[0] & 0x0E) << 29) |
-                         (((mtime_t)U32_AT(p_ts) & 0xFFFE00) << 6) |
-                         ((mtime_t)p_ts[3] << 7) |
-                         ((mtime_t)p_ts[4] >> 1) ) );
-
-                    if( b_has_dts )
-                    {
-                        i_pes_header_size += 5;
-                        if( MoveChunk( p_ts, &p_data, &p_byte, 5 ) != 5 )
-                        {
-                            msg_Warn( p_input,
-                              "PES packet too short to have a MPEG-1 header" );
-                            input_DeletePES( p_input->p_method_data, p_pes );
-                            p_pes = NULL;
-                            return;
-                        }
-
-                        p_pes->i_dts = input_ClockGetTS( p_input,
-                                                         p_es->p_pgrm,
-                            ( ((mtime_t)(p_ts[0] & 0x0E) << 29) |
-                              (((mtime_t)U32_AT(p_ts) & 0xFFFE00) << 6) |
-                              ((mtime_t)p_ts[3] << 7) |
-                              ((mtime_t)p_ts[4] >> 1) ) );
-                    }
-                }
-            }
-
-            break;
-        }
-
-        if( p_es->i_stream_id == 0xbd )
-        {
-            /* With private stream 1, the first byte of the payload
-             * is a stream_private_id, so skip it. */
-            i_pes_header_size++;
-        }
-
-        if( p_es->i_fourcc == VLC_FOURCC('a','5','2',' ') )
-        {
-            /* With A52 audio, we need to skip first 3 bytes */
-            i_pes_header_size += 3;
-        }
-
-        /* Now we've parsed the header, we just have to indicate in some
-         * specific data packets where the PES payload begins (renumber
-         * p_payload_start), so that the decoders can find the beginning
-         * of their data right out of the box. */
-        p_data = p_pes->p_first;
-        i_payload_size = p_data->p_payload_end
-                                 - p_data->p_payload_start;
-        while( i_pes_header_size > i_payload_size )
-        {
-            /* These packets are entirely filled by the PES header. */
-            i_pes_header_size -= i_payload_size;
-            p_data->p_payload_start = p_data->p_payload_end;
-            /* Go to the next data packet. */
-            if( (p_data = p_data->p_next) == NULL )
-            {
-                msg_Err( p_input, "PES header bigger than payload" );
-                input_DeletePES( p_input->p_method_data, p_pes );
-                p_pes = NULL;
-                return;
-            }
-            i_payload_size = p_data->p_payload_end
-                                 - p_data->p_payload_start;
-        }
-        /* This last packet is partly header, partly payload. */
-        if( i_payload_size < i_pes_header_size )
-        {
-            msg_Err( p_input, "PES header bigger than payload" );
-            input_DeletePES( p_input->p_method_data, p_pes );
-            p_pes = NULL;
-            return;
-        }
-        p_data->p_payload_start += i_pes_header_size;
-
-
-        /* Now we can eventually put the PES packet in the decoder's
-         * PES fifo */
-        if( p_es->p_decoder_fifo != NULL )
-        {
-            input_DecodePES( p_es->p_decoder_fifo, p_pes );
-        }
-        else
-        {
-            msg_Err( p_input, "no fifo to receive PES %p "
-                              "(who wrote this damn code ?)", p_pes );
-            input_DeletePES( p_input->p_method_data, p_pes );
-        }
-        p_pes = NULL;
-    }
-#undef p_pes
-
-}
-
-/*****************************************************************************
- * input_GatherPES:
- *****************************************************************************
- * Gather a PES packet.
- *****************************************************************************/
-void input_GatherPES( input_thread_t * p_input, data_packet_t * p_data,
-                      es_descriptor_t * p_es,
-                      vlc_bool_t b_unit_start, vlc_bool_t b_packet_lost )
-{
-#define p_pes (p_es->p_pes)
-
-    /* If we lost data, insert a NULL data packet (philosophy : 0 is quite
-     * often an escape sequence in decoders, so that should make them wait
-     * for the next start code). */
-    if( b_packet_lost )
-    {
-        input_NullPacket( p_input, p_es );
-    }
-
-    if( b_unit_start && p_pes != NULL )
-    {
-        /* If the data packet contains the begining of a new PES packet, and
-         * if we were reassembling a PES packet, then the PES should be
-         * complete now, so parse its header and give it to the decoders. */
-        input_ParsePES( p_input, p_es );
-    }
-
-    if( !b_unit_start && p_pes == NULL )
-    {
-        /* Random access... */
-        input_DeletePacket( p_input->p_method_data, p_data );
-    }
-    else
-    {
-        if( b_unit_start )
-        {
-            /* If we are at the beginning of a new PES packet, we must fetch
-             * a new PES buffer to begin with the reassembly of this PES
-             * packet. This is also here that we can synchronize with the
-             * stream if we lost packets or if the decoder has just
-             * started. */
-            if( (p_pes = input_NewPES( p_input->p_method_data ) ) == NULL )
-            {
-                msg_Err( p_input, "out of memory" );
-                p_input->b_error = 1;
-                return;
-            }
-            p_pes->i_rate = p_input->stream.control.i_rate;
-            p_pes->p_first = p_data;
-            
-            /* If the PES header fits in the first data packet, we can
-             * already set p_gather->i_pes_real_size. */
-            if( p_data->p_payload_end - p_data->p_payload_start
-                    >= PES_HEADER_SIZE )
-            {
-                p_es->i_pes_real_size = ((u16)p_data->p_payload_start[4] << 8)
-                                         + p_data->p_payload_start[5] + 6;
-            }
-            else
-            { 
-                p_es->i_pes_real_size = 0;
-            } 
-        }
-        else
-        {
-            /* Update the relations between the data packets */
-            p_pes->p_last->p_next = 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
-                                 - p_data->p_payload_start);
-    
-        /* We can check if the packet is finished */
-        if( p_pes->i_pes_size == p_es->i_pes_real_size )
-        {
-            /* The packet is finished, parse it */
-            input_ParsePES( p_input, p_es );
-        }
-    }
-#undef p_pes
-}
-
-
-/*
- * PS Demultiplexing
- */
-
-/*****************************************************************************
- * GetID: Get the ID of a stream
- *****************************************************************************/
-static u16 GetID( data_packet_t * p_data )
-{
-    u16         i_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_demux_start[ 9 + p_data->p_demux_start[8] ] << 8;
-    }
-    return( i_id );
-}
-
-/*****************************************************************************
- * DecodePSM: Decode the Program Stream Map information
- *****************************************************************************
- * FIXME : loads are not aligned in this function
- *****************************************************************************/
-static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data )
-{
-    stream_ps_data_t *  p_demux =
-                 (stream_ps_data_t *)p_input->stream.p_demux_data;
-    byte_t *            p_byte;
-    byte_t *            p_end;
-    int                 i;
-    int                 i_new_es_number = 0;
-
-    if( p_data->p_demux_start + 10 > p_data->p_payload_end )
-    {
-        msg_Err( p_input, "PSM too short, packet corrupt" );
-        return;
-    }
-
-    if( p_demux->b_has_PSM
-        && p_demux->i_PSM_version == (p_data->p_demux_start[6] & 0x1F) )
-    {
-        /* Already got that one. */
-        return;
-    }
-
-    p_demux->b_has_PSM = 1;
-    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_demux_start + 10
-              + U16_AT(&p_data->p_demux_start[8]);
-    if( p_byte > p_data->p_payload_end )
-    {
-        msg_Err( p_input, "PSM too short, packet corrupt" );
-        return;
-    }
-    /* This is the full size of the elementary_stream_map.
-     * 2 == elementary_stream_map_length
-     * Please note that CRC_32 is not included in the length. */
-    p_end = p_byte + 2 + U16_AT(p_byte);
-    p_byte += 2;
-    if( p_end > p_data->p_payload_end )
-    {
-        msg_Err( p_input, "PSM too short, packet corrupt" );
-        return;
-    }
-
-    vlc_mutex_lock( &p_input->stream.stream_lock );
-
-    /* 4 == minimum useful size of a section */
-    while( p_byte + 4 <= p_end )
-    {
-        es_descriptor_t *   p_es = NULL;
-        u8                  i_stream_id = p_byte[1];
-        /* FIXME: there will be a problem with private streams... (same
-         * stream_id) */
-
-        /* Look for the ES in the ES table */
-        for( i = i_new_es_number;
-             i < p_input->stream.pp_programs[0]->i_es_number;
-             i++ )
-        {
-            if( p_input->stream.pp_programs[0]->pp_es[i]->i_stream_id
-                    == i_stream_id )
-            {
-                p_es = p_input->stream.pp_programs[0]->pp_es[i];
-                /* FIXME: do something below */
-#if 0
-                if( p_es->i_type != p_byte[0] )
-                {
-                    input_DelES( p_input, p_es );
-                    p_es = NULL;
-                }
-                else
-#endif
-                {
-                    /* Move the ES to the beginning. */
-                    p_input->stream.pp_programs[0]->pp_es[i]
-                        = p_input->stream.pp_programs[0]->pp_es[ i_new_es_number ];
-                    p_input->stream.pp_programs[0]->pp_es[ i_new_es_number ]
-                        = p_es;
-                    i_new_es_number++;
-                }
-                break;
-            }
-        }
-
-        /* The goal is to have all the ES we have just read in the
-         * beginning of the pp_es table, and all the others at the end,
-         * so that we can close them more easily at the end. */
-        if( p_es == NULL )
-        {
-            p_es = input_AddES( p_input, p_input->stream.pp_programs[0],
-                                i_stream_id, 0 );
-            switch( p_byte[0] )
-            {
-            case MPEG1_VIDEO_ES:
-            case MPEG2_VIDEO_ES:
-                p_es->i_fourcc = VLC_FOURCC('m','p','g','v');
-                p_es->i_cat = VIDEO_ES;
-                break;
-            case DVD_SPU_ES:
-                p_es->i_fourcc = VLC_FOURCC('s','p','u',' ');
-                p_es->i_cat = SPU_ES;
-                break;
-            case MPEG1_AUDIO_ES:
-            case MPEG2_AUDIO_ES:
-                p_es->i_fourcc = VLC_FOURCC('m','p','g','a');
-                p_es->i_cat = AUDIO_ES;
-                break;
-            case A52_AUDIO_ES:
-                p_es->i_fourcc = VLC_FOURCC('a','5','2',' ');
-                p_es->i_cat = AUDIO_ES;
-                break;
-            case LPCM_AUDIO_ES:
-                p_es->i_fourcc = VLC_FOURCC('l','p','c','m');
-                p_es->i_cat = AUDIO_ES;
-                break;
-            default:
-                p_es->i_fourcc = 0;
-                break;
-            }
-
-            /* input_AddES has inserted the new element at the end. */
-            p_input->stream.pp_programs[0]->pp_es[
-                p_input->stream.pp_programs[0]->i_es_number ]
-                = p_input->stream.pp_programs[0]->pp_es[ i_new_es_number ];
-            p_input->stream.pp_programs[0]->pp_es[ i_new_es_number ] = p_es;
-            i_new_es_number++;
-        }
-        p_byte += 4 + U16_AT(&p_byte[2]);
-    }
-
-    /* Un-select the streams that are no longer parts of the program. */
-    while( i_new_es_number < p_input->stream.pp_programs[0]->i_es_number )
-    {
-        /* We remove pp_es[i_new_es_member] and not pp_es[i] because the
-         * list will be emptied starting from the end */
-        input_DelES( p_input,
-                     p_input->stream.pp_programs[0]->pp_es[i_new_es_number] );
-    }
-
-    msg_Dbg( p_input, "the stream map after the PSM is now:" );
-    input_DumpStream( p_input );
-
-    vlc_mutex_unlock( &p_input->stream.stream_lock );
-}
-
-/*****************************************************************************
- * input_ReadPS: store a PS packet into a data_buffer_t
- *****************************************************************************/
-#define PEEK( SIZE )                                                        \
-    i_error = input_Peek( p_input, &p_peek, SIZE );                         \
-    if( i_error == -1 )                                                     \
-    {                                                                       \
-        return( -1 );                                                       \
-    }                                                                       \
-    else if( i_error < SIZE )                                               \
-    {                                                                       \
-        /* EOF */                                                           \
-        return( 0 );                                                        \
-    }
-
-ssize_t input_ReadPS( input_thread_t * p_input, data_packet_t ** pp_data )
-{
-    byte_t *            p_peek;
-    size_t              i_packet_size;
-    ssize_t             i_error, i_read;
-
-    /* Read what we believe to be a packet header. */
-    PEEK( 4 );
-
-    if( p_peek[0] || p_peek[1] || p_peek[2] != 1 || p_peek[3] < 0xB9 )
-    {
-        if( p_peek[0] || p_peek[1] || p_peek[2] )
-        {
-            /* 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. */
-            msg_Warn( p_input, "garbage (0x%.2x%.2x%.2x%.2x)",
-                      p_peek[0], p_peek[1], p_peek[2], p_peek[3] );
-        }
-
-        /* This is not the startcode of a packet. Read the stream
-         * until we find one. */
-        while( p_peek[0] || p_peek[1] || p_peek[2] != 1 || p_peek[3] < 0xB9 )
-        {
-            p_input->p_current_data++;
-            PEEK( 4 );
-            if( p_input->b_die ) return( -1 );
-        }
-        /* Packet found. */
-    }
-
-    /* 0x1B9 == SYSTEM_END_CODE, it is only 4 bytes long. */
-    if( p_peek[3] != 0xB9 )
-    {
-        /* The packet is at least 6 bytes long. */
-        PEEK( 6 );
-
-        if( p_peek[3] != 0xBA )
-        {
-            /* That's the case for all packets, except pack header. */
-            i_packet_size = (p_peek[4] << 8) | p_peek[5];
-        }
-        else
-        {
-            /* Pack header. */
-            if( (p_peek[4] & 0xC0) == 0x40 )
-            {
-                /* MPEG-2 */
-                i_packet_size = 8;
-            }
-            else if( (p_peek[4] & 0xF0) == 0x20 )
-            {
-                /* MPEG-1 */
-                i_packet_size = 6;
-            }
-            else
-            {
-                msg_Err( p_input, "unable to determine stream type" );
-                return( -1 );
-            }
-        }
-    }
-    else
-    {
-        /* System End Code */
-        i_packet_size = -2;
-    }
-
-    /* Fetch a packet of the appropriate size. */
-    i_read = input_SplitBuffer( p_input, pp_data, i_packet_size + 6 );
-    if( i_read <= 0 )
-    {
-        return( i_read );
-    }
-
-    /* In MPEG-2 pack headers we still have to read stuffing bytes. */
-    if( ((*pp_data)->p_demux_start[3] == 0xBA) && (i_packet_size == 8) )
-    {
-        size_t i_stuffing = ((*pp_data)->p_demux_start[13] & 0x7);
-        /* Force refill of the input buffer - though we don't care
-         * about p_peek. Please note that this is unoptimized. */
-        PEEK( i_stuffing );
-        p_input->p_current_data += i_stuffing;
-    }
-
-    return( 1 );
-}
-
-#undef PEEK
-
-/*****************************************************************************
- * input_ParsePS: read the PS header
- *****************************************************************************/
-es_descriptor_t * input_ParsePS( input_thread_t * p_input,
-                                 data_packet_t * p_data )
-{
-    u32                 i_code;
-    es_descriptor_t *   p_es = NULL;
-
-    i_code = p_data->p_demux_start[3];
-
-    if( i_code > 0xBC ) /* ES start code */
-    {
-        u16                 i_id;
-        int                 i_dummy;
-
-        /* This is a PES packet. Find out if we want it or not. */
-        i_id = GetID( p_data );
-
-        vlc_mutex_lock( &p_input->stream.stream_lock );
-        if( p_input->stream.pp_programs[0]->b_is_ok )
-        {
-            /* Look only at the selected ES. */
-            for( i_dummy = 0; i_dummy < p_input->stream.i_selected_es_number;
-                 i_dummy++ )
-            {
-                if( p_input->stream.pp_selected_es[i_dummy] != NULL
-                    && p_input->stream.pp_selected_es[i_dummy]->i_id == i_id )
-                {
-                    p_es = p_input->stream.pp_selected_es[i_dummy];
-                    break;
-                }
-            }
-        }
-        else
-        {
-            stream_ps_data_t * p_demux =
-              (stream_ps_data_t *)p_input->stream.pp_programs[0]->p_demux_data;
-
-            /* Search all ES ; if not found -> AddES */
-            p_es = input_FindES( p_input, i_id );
-
-            if( p_es == NULL && !p_demux->b_has_PSM )
-            {
-                p_es = input_AddES( p_input, p_input->stream.pp_programs[0],
-                                    i_id, 0 );
-                if( p_es != NULL )
-                {
-                    p_es->i_stream_id = p_data->p_demux_start[3];
-
-                    /* Set stream type and auto-spawn. */
-                    if( (i_id & 0xF0) == 0xE0 )
-                    {
-                        /* MPEG video */
-                        p_es->i_fourcc = VLC_FOURCC('m','p','g','v');
-                        p_es->i_cat = VIDEO_ES;
-#ifdef AUTO_SPAWN
-                        if( !p_input->stream.b_seekable )
-                            input_SelectES( p_input, p_es );
-#endif
-                    }
-                    else if( (i_id & 0xE0) == 0xC0 )
-                    {
-                        /* MPEG audio */
-                        p_es->i_fourcc = VLC_FOURCC('m','p','g','a');
-                        p_es->i_cat = AUDIO_ES;
-#ifdef AUTO_SPAWN
-                        if( !p_input->stream.b_seekable )
-                        if( config_GetInt( p_input, "audio-channel" )
-                                == (p_es->i_id & 0x1F) ||
-                            ( config_GetInt( p_input, "audio-channel" ) < 0
-                              && !(p_es->i_id & 0x1F) ) )
-                        switch( config_GetInt( p_input, "audio-type" ) )
-                        {
-                        case -1:
-                        case REQUESTED_MPEG:
-                            input_SelectES( p_input, p_es );
-                        }
-#endif
-                    }
-                    else if( (i_id & 0xF0FF) == 0x80BD )
-                    {
-                        /* A52 audio (0x80->0x8F) */
-                        p_es->i_fourcc = VLC_FOURCC('a','5','2',' ');
-                        p_es->i_cat = AUDIO_ES;
-#ifdef AUTO_SPAWN
-                        if( !p_input->stream.b_seekable )
-                        if( config_GetInt( p_input, "audio-channel" )
-                                == ((p_es->i_id & 0xF00) >> 8) ||
-                            ( config_GetInt( p_input, "audio-channel" ) < 0
-                              && !((p_es->i_id & 0xF00) >> 8)) )
-                        switch( config_GetInt( p_input, "audio-type" ) )
-                        {
-                        case -1:
-                        case REQUESTED_A52:
-                            input_SelectES( p_input, p_es );
-                        }
-#endif
-                    }
-                    else if( (i_id & 0xE0FF) == 0x20BD )
-                    {
-                        /* Subtitles video (0x20->0x3F) */
-                        p_es->i_fourcc = VLC_FOURCC('s','p','u',' ');
-                        p_es->i_cat = SPU_ES;
-#ifdef AUTO_SPAWN
-                        if( config_GetInt( p_input, "spu-channel" )
-                                == ((p_es->i_id & 0x1F00) >> 8) )
-                        {
-                            if( !p_input->stream.b_seekable )
-                                input_SelectES( p_input, p_es );
-                        }
-#endif
-                    }
-                    else if( (i_id & 0xF0FF) == 0xA0BD )
-                    {
-                        /* LPCM audio (0xA0->0xAF) */
-                        p_es->i_fourcc = VLC_FOURCC('l','p','c','m');
-                        p_es->i_cat = AUDIO_ES;
-                    }
-                    else
-                    {
-                        p_es->i_fourcc = 0;
-                    }
-                }
-
-                /* Tell the interface the stream has changed */
-                p_input->stream.b_changed = 1;
-            }
-        } /* stream.b_is_ok */
-        vlc_mutex_unlock( &p_input->stream.stream_lock );
-    } /* i_code > 0xBC */
-
-    return( p_es );
-}
-
-/*****************************************************************************
- * input_DemuxPS: first step of demultiplexing: the PS header
- *****************************************************************************/
-void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
-{
-    u32                 i_code;
-    vlc_bool_t          b_trash = 0;
-    es_descriptor_t *   p_es = NULL;
-
-    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 )
-        {
-        case 0x1BA: /* PACK_START_CODE */
-            {
-                /* Read the SCR. */
-                mtime_t         scr_time;
-                u32             i_mux_rate;
-
-                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_demux_start;
-
-                    if( MoveChunk( p_header, &p_data, &p_byte, 14 ) != 14 )
-                    {
-                        msg_Warn( p_input,
-                                  "packet too short to have a header" );
-                        b_trash = 1;
-                        break;
-                    }
-                    scr_time =
-                         ((mtime_t)(p_header[4] & 0x38) << 27) |
-                         ((mtime_t)(U32_AT(p_header + 4) & 0x03FFF800)
-                                        << 4) |
-                         ((( ((mtime_t)U16_AT(p_header + 6) << 16)
-                            | (mtime_t)U16_AT(p_header + 8) ) & 0x03FFF800)
-                                        >> 11);
-
-                    /* mux_rate */
-                    i_mux_rate = ((u32)U16_AT(p_header + 10) << 6)
-                                   | (p_header[12] >> 2);
-                    /* FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
-                     * This is the biggest kludge ever !
-                     * I don't know what's wrong with mux_rate calculation
-                     * but this heuristic works well : */
-                    i_mux_rate <<= 1;
-                    i_mux_rate /= 3;
-                }
-                else
-                {
-                    /* MPEG-1 SCR is like PTS. */
-                    byte_t      p_header[12];
-                    byte_t *    p_byte;
-                    p_byte = p_data->p_demux_start;
-
-                    if( MoveChunk( p_header, &p_data, &p_byte, 12 ) != 12 )
-                    {
-                        msg_Warn( p_input,
-                                  "packet too short to have a header" );
-                        b_trash = 1;
-                        break;
-                    }
-                    scr_time =
-                         ((mtime_t)(p_header[4] & 0x0E) << 29) |
-                         (((mtime_t)U32_AT(p_header + 4) & 0xFFFE00) << 6) |
-                         ((mtime_t)p_header[7] << 7) |
-                         ((mtime_t)p_header[8] >> 1);
-
-                    /* mux_rate */
-                    i_mux_rate = (U32_AT(p_header + 8) & 0x7FFFFE) >> 1;
-                }
-                /* Call the pace control. */
-                input_ClockManageRef( p_input,
-                                      p_input->stream.p_selected_program,
-                                      scr_time );
-
-                if( i_mux_rate != p_input->stream.i_mux_rate
-                     && p_input->stream.i_mux_rate )
-                {
-                    msg_Warn( p_input,
-                              "mux_rate changed, expect cosmetic errors" );
-                }
-                p_input->stream.i_mux_rate = i_mux_rate;
-
-                b_trash = 1;
-            }
-            break;
-
-        case 0x1BB: /* SYSTEM_START_CODE */
-            b_trash = 1;                              /* Nothing interesting */
-            break;
-
-        case 0x1BC: /* PROGRAM_STREAM_MAP_CODE */
-            DecodePSM( p_input, p_data );
-            b_trash = 1;
-            break;
-    
-        case 0x1B9: /* PROGRAM_END_CODE */
-            b_trash = 1;
-            break;
-   
-        default:
-            /* This should not happen */
-            b_trash = 1;
-            msg_Warn( p_input, "unwanted packet received "
-                               "with startcode 0x%.8x", i_code );
-        }
-    }
-    else
-    {
-        p_es = input_ParsePS( p_input, p_data );
-
-        vlc_mutex_lock( &p_input->stream.control.control_lock );
-        if( p_es != NULL && p_es->p_decoder_fifo != NULL
-             && (p_es->i_cat != AUDIO_ES || !p_input->stream.control.b_mute) )
-        {
-            vlc_mutex_unlock( &p_input->stream.control.control_lock );
-            p_es->c_packets++;
-            input_GatherPES( p_input, p_data, p_es, 1, 0 );
-        }
-        else
-        {
-            vlc_mutex_unlock( &p_input->stream.control.control_lock );
-            b_trash = 1;
-        }
-    }
-
-    /* Trash the packet if it has no payload or if it isn't selected */
-    if( b_trash )
-    {
-        input_DeletePacket( p_input->p_method_data, p_data );
-        p_input->stream.c_packets_trashed++;
-    }
-}
-
-/*
- * TS Demultiplexing
- */
-
-/*****************************************************************************
- * input_ReadTS: store a TS packet into a data_buffer_t
- *****************************************************************************/
-#define PEEK( SIZE )                                                        \
-    i_error = input_Peek( p_input, &p_peek, SIZE );                         \
-    if( i_error == -1 )                                                     \
-    {                                                                       \
-        return( -1 );                                                       \
-    }                                                                       \
-    else if( i_error < SIZE )                                               \
-    {                                                                       \
-        /* EOF */                                                           \
-        return( 0 );                                                        \
-    }
-
-ssize_t input_ReadTS( input_thread_t * p_input, data_packet_t ** pp_data )
-{
-    byte_t *            p_peek;
-    ssize_t             i_error, i_read;
-
-    PEEK( 1 );
-
-    if( *p_peek != TS_SYNC_CODE )
-    {
-        msg_Warn( p_input, "garbage at input (%x)", *p_peek );
-
-        if( p_input->i_mtu )
-        {
-            while( *p_peek != TS_SYNC_CODE )
-            {
-                /* Try to resync on next packet. */
-                PEEK( TS_PACKET_SIZE );
-                p_input->p_current_data += TS_PACKET_SIZE;
-                PEEK( 1 );
-            }
-        }
-        else
-        {
-            /* Move forward until we find 0x47 (and hope it's the good
-             * one... FIXME) */
-            while( *p_peek != TS_SYNC_CODE )
-            {
-                p_input->p_current_data++;
-                PEEK( 1 );
-            }
-        }
-    }
-
-    i_read = input_SplitBuffer( p_input, pp_data, TS_PACKET_SIZE );
-    if( i_read <= 0 )
-    {
-        return( i_read );
-    }
-
-    return( 1 );
-}
-
-/*****************************************************************************
- * input_DemuxTS: first step of demultiplexing: the TS header
- *****************************************************************************/
-void input_DemuxTS( input_thread_t * p_input, data_packet_t * p_data,
-                        psi_callback_t pf_psi_callback )
-{
-    u16                 i_pid;
-    int                 i_dummy;
-    vlc_bool_t          b_adaptation;         /* Adaptation field is present */
-    vlc_bool_t          b_payload;                 /* Packet carries payload */
-    vlc_bool_t          b_unit_start;  /* A PSI or a PES start in the packet */
-    vlc_bool_t          b_trash = 0;             /* Is the packet unuseful ? */
-    vlc_bool_t          b_lost = 0;             /* Was there a packet loss ? */
-    vlc_bool_t          b_psi = 0;                        /* Is this a PSI ? */
-    vlc_bool_t          b_pcr = 0;                   /* Does it have a PCR ? */
-    es_descriptor_t *   p_es = NULL;
-    es_ts_data_t *      p_es_demux = NULL;
-    pgrm_ts_data_t *    p_pgrm_demux = NULL;
-
-#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);
-    b_adaptation = (p[3] & 0x20);
-    b_payload = (p[3] & 0x10);
-
-    /* Find out the elementary stream. */
-    vlc_mutex_lock( &p_input->stream.stream_lock );
-    
-    for( i_dummy = 0; i_dummy < p_input->stream.i_pgrm_number; i_dummy ++ )
-    {
-        if( (( pgrm_ts_data_t * ) p_input->stream.pp_programs[i_dummy]->
-                    p_demux_data)->i_pcr_pid == i_pid )
-        {
-            b_pcr = 1;
-            break;
-        }
-    }
-            
-    p_es= input_FindES( p_input, i_pid );
-    
-    if( (p_es != NULL) && (p_es->p_demux_data != NULL) )
-    {
-        p_es_demux = (es_ts_data_t *)p_es->p_demux_data;
-        
-        if( p_es_demux->b_psi )
-        {
-            b_psi = 1;
-        }
-        else
-        {
-            p_pgrm_demux = (pgrm_ts_data_t *)p_es->p_pgrm->p_demux_data; 
-        }
-    }
-
-    vlc_mutex_lock( &p_input->stream.control.control_lock );
-    if( ( p_es == NULL ) || (p_es->i_cat == AUDIO_ES
-                              && p_input->stream.control.b_mute) )
-    {
-        /* Not selected. Just read the adaptation field for a PCR. */
-        b_trash = 1;
-    }
-    else if( p_es->p_decoder_fifo == NULL && !b_psi )
-    {
-        b_trash = 1; 
-    }
-
-    vlc_mutex_unlock( &p_input->stream.control.control_lock );
-    vlc_mutex_unlock( &p_input->stream.stream_lock );
-
-
-    /* Don't change the order of the tests : if b_psi then p_pgrm_demux 
-     * may still be null. Who said it was ugly ?
-     * I have written worse. --Meuuh */
-    if( ( p_es  ) && 
-        ((p_es->p_decoder_fifo != NULL) || b_psi || b_pcr ) )
-    {
-        p_es->c_packets++;
-
-        /* Extract adaptation field information if any */
-
-        if( !b_adaptation )
-        {
-            /* We don't have any adaptation_field, so payload starts
-             * immediately after the 4 byte TS header */
-            p_data->p_payload_start += 4;
-        }
-        else
-        {
-            /* p[4] is adaptation_field_length minus one */
-            p_data->p_payload_start += 5 + p[4];
-    
-            /* The adaptation field can be limited to the
-             * adaptation_field_length byte, so that there is nothing to do:
-             * skip this possibility */
-            if( p[4] )
-            {
-                /* If the packet has both adaptation_field and payload,
-                 * adaptation_field cannot be more than 182 bytes long; if
-                 * there is only an adaptation_field, it must fill the next
-                 * 183 bytes. */
-                if( b_payload ? (p[4] > 182) : (p[4] != 183) )
-                {
-                    msg_Warn( p_input, "invalid TS adaptation field (%p)",
-                              p_data );
-                    p_data->b_discard_payload = 1;
-                    p_es->c_invalid_packets++;
-                }
-    
-                /* Now we are sure that the byte containing flags is present:
-                 * read it */
-                else
-                {
-                    /* discontinuity_indicator */
-                    if( p[5] & 0x80 )
-                    {
-                        msg_Warn( p_input,
-                            "discontinuity_indicator encountered by TS demux "
-                            "(position read: %d, saved: %d)",
-                            p[5] & 0x80, p_es_demux->i_continuity_counter );
-    
-                        /* If the PID carries the PCR, there will be a system
-                         * time-based discontinuity. We let the PCR decoder
-                         * handle that. */
-                        p_es->p_pgrm->i_synchro_state = SYNCHRO_REINIT;
-    
-                        /* There also may be a continuity_counter
-                         * discontinuity: resynchronize our counter with
-                         * the one of the stream. */
-                        p_es_demux->i_continuity_counter = (p[3] & 0x0f) - 1;
-                    }
-    
-                } /* valid TS adaptation field ? */
-            } /* length > 0 */
-        } /* has adaptation field */
-        /* Check the continuity of the stream. */
-        i_dummy = ((p[3] & 0x0f) - p_es_demux->i_continuity_counter) & 0x0f;
-        if( i_dummy == 1 )
-        {
-            /* Everything is ok, just increase our counter */
-            (p_es_demux->i_continuity_counter)++;
-        }
-        else
-        {
-            if( !b_payload && i_dummy == 0 )
-            {
-                /* This is a packet without payload, this is allowed by the
-                 * draft. As there is nothing interesting in this packet
-                 * (except PCR that have already been handled), we can trash
-                 * the packet. */
-                b_trash = 1;
-            }
-            else if( i_dummy <= 0 )
-            {
-                /* Duplicate packet: mark it as being to be trashed. */
-                msg_Warn( p_input,
-                          "duplicate packet received by TS demux" );
-                b_trash = 1;
-            }
-            else if( p_es_demux->i_continuity_counter == 0xFF )
-            {
-                /* This means that the packet is the first one we receive for
-                 * this ES since the continuity counter ranges between 0 and
-                 * 0x0F excepts when it has been initialized by the input:
-                 * init the counter to the correct value. */
-                msg_Warn( p_input, "first packet for PID %d received "
-                                   "by TS demux", p_es->i_id );
-                p_es_demux->i_continuity_counter = (p[3] & 0x0f);
-            }
-            else
-            {
-                /* This can indicate that we missed a packet or that the
-                 * continuity_counter wrapped and we received a dup packet:
-                 * as we don't know, do as if we missed a packet to be sure
-                 * to recover from this situation */
-                msg_Warn( p_input,
-                          "packet lost by TS demux: current %d, packet %d",
-                          p_es_demux->i_continuity_counter & 0x0f,
-                          p[3] & 0x0f );
-                b_lost = 1;
-                p_es_demux->i_continuity_counter = p[3] & 0x0f;
-            } /* not continuous */
-        } /* continuity */
-    } /* if selected or PCR */
-    
-    /* Handle PCR */
-    if( b_pcr && b_adaptation && (p[5] & 0x10) && p[4]>=7 )
-    {
-        /* Read the PCR. */
-        mtime_t     pcr_time;
-        pcr_time = ( (mtime_t)p[6] << 25 ) |
-                   ( (mtime_t)p[7] << 17 ) |
-                   ( (mtime_t)p[8] << 9 ) |
-                   ( (mtime_t)p[9] << 1 ) |
-                   ( (mtime_t)p[10] >> 7 );
-        /* Call the pace control. */
-        for( i_dummy = 0; i_dummy < p_input->stream.i_pgrm_number; 
-                                i_dummy ++ )
-        {
-            if( ( ( pgrm_ts_data_t * ) p_input->stream.pp_programs[i_dummy]->
-                        p_demux_data )->i_pcr_pid == i_pid )
-            {
-                input_ClockManageRef( p_input,
-                    p_input->stream.pp_programs[i_dummy], pcr_time );
-            }
-        }
-
-    }
-    
-    /* Trash the packet if it has no payload or if it isn't selected */
-    if( b_trash )
-    {
-        input_DeletePacket( p_input->p_method_data, p_data );
-        p_input->stream.c_packets_trashed++;
-    }
-    else
-    {
-        if( b_psi )
-        {
-            /* The payload contains PSI tables */
-            (* pf_psi_callback) ( p_input, p_data, p_es, b_unit_start );
-        }
-        else
-        {
-            /* The payload carries a PES stream */
-            input_GatherPES( p_input, p_data, p_es, b_unit_start, b_lost ); 
-        }
-
-    }
-
-#undef p
-
-}
index 81db0c1..160550e 100644 (file)
@@ -2,7 +2,7 @@
  * configuration.c management of the modules configuration
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: configuration.c,v 1.33 2002/07/31 20:56:53 sam Exp $
+ * $Id: configuration.c,v 1.34 2002/08/07 00:29:37 sam Exp $
  *
  * Authors: Gildas Bazin <gbazin@netcourrier.com>
  *
@@ -511,8 +511,8 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
                 !memcmp( &line[1], p_module->psz_object_name,
                          strlen(p_module->psz_object_name) ) )
             {
-                msg_Dbg( p_this, "loading config for module \"%s\"",
-                                 p_module->psz_object_name );
+                //msg_Dbg( p_this, "loading config for module \"%s\"",
+                //                 p_module->psz_object_name );
 
                 break;
             }
@@ -560,16 +560,16 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
                         if( !*psz_option_value )
                             break;                    /* ignore empty option */
                         p_item->i_value = atoi( psz_option_value);
-                        msg_Dbg( p_this, "option \"%s\", value %i",
-                                 p_item->psz_name, p_item->i_value );
+                        //msg_Dbg( p_this, "option \"%s\", value %i",
+                        //         p_item->psz_name, p_item->i_value );
                         break;
 
                     case CONFIG_ITEM_FLOAT:
                         if( !*psz_option_value )
                             break;                    /* ignore empty option */
                         p_item->f_value = (float)atof( psz_option_value);
-                        msg_Dbg( p_this, "option \"%s\", value %f",
-                                 p_item->psz_name, (double)p_item->f_value );
+                        //msg_Dbg( p_this, "option \"%s\", value %f",
+                        //         p_item->psz_name, (double)p_item->f_value );
                         break;
 
                     default:
@@ -584,9 +584,9 @@ int __config_LoadConfigFile( vlc_object_t *p_this, const char *psz_module_name )
 
                         vlc_mutex_unlock( p_item->p_lock );
 
-                        msg_Dbg( p_this, "option \"%s\", value \"%s\"",
-                                 p_item->psz_name,
-                                 p_item->psz_value ? p_item->psz_value : "" );
+                        //msg_Dbg( p_this, "option \"%s\", value \"%s\"",
+                        //         p_item->psz_name,
+                        //         p_item->psz_value ? p_item->psz_value : "" );
                         break;
                     }
                 }
index 138719c..3795cb5 100644 (file)
@@ -2,7 +2,7 @@
  * modules.c : Builtin and plugin modules management functions
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: modules.c,v 1.80 2002/08/06 00:26:48 sam Exp $
+ * $Id: modules.c,v 1.81 2002/08/07 00:29:37 sam Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *          Ethan C. Baldridge <BaldridgeE@cadmus.com>
@@ -88,7 +88,7 @@
  *****************************************************************************/
 #ifdef HAVE_DYNAMIC_PLUGINS
 static void AllocateAllPlugins   ( vlc_object_t * );
-static void AllocatePluginDir    ( vlc_object_t *, const char * );
+static void AllocatePluginDir    ( vlc_object_t *, const char *, int );
 static int  AllocatePluginFile   ( vlc_object_t *, char * );
 #endif
 static int  AllocateBuiltinModule( vlc_object_t *, int ( * ) ( module_t * ) );
@@ -630,7 +630,8 @@ static void AllocateAllPlugins( vlc_object_t *p_this )
 
         msg_Dbg( p_this, "recursively browsing `%s'", psz_fullpath );
 
-        AllocatePluginDir( p_this, psz_fullpath );
+        /* Don't go deeper than 5 subdirectories */
+        AllocatePluginDir( p_this, psz_fullpath, 5 );
 
 #if defined( SYS_BEOS ) || defined( SYS_DARWIN )
         if( b_notinroot )
@@ -644,7 +645,8 @@ static void AllocateAllPlugins( vlc_object_t *p_this )
 /*****************************************************************************
  * AllocatePluginDir: recursively parse a directory to look for plugins
  *****************************************************************************/
-static void AllocatePluginDir( vlc_object_t *p_this, const char *psz_dir )
+static void AllocatePluginDir( vlc_object_t *p_this, const char *psz_dir,
+                               int i_maxdepth )
 {
 #define PLUGIN_EXT ".so"
     int    i_dirlen;
@@ -653,6 +655,11 @@ static void AllocatePluginDir( vlc_object_t *p_this, const char *psz_dir )
 
     struct dirent * file;
 
+    if( i_maxdepth < 0 )
+    {
+        return;
+    }
+
     dir = opendir( psz_dir );
 
     if( !dir )
@@ -679,7 +686,7 @@ static void AllocatePluginDir( vlc_object_t *p_this, const char *psz_dir )
 
         if( !stat( psz_file, &statbuf ) && statbuf.st_mode & S_IFDIR )
         {
-            AllocatePluginDir( p_this, psz_file );
+            AllocatePluginDir( p_this, psz_file, i_maxdepth - 1 );
         }
         else if( i_len > strlen( PLUGIN_EXT )
                   /* We only load files ending with ".so" */
@@ -763,8 +770,8 @@ static int AllocatePluginFile( vlc_object_t * p_this, char * psz_file )
     p_this->p_vlc->p_module_bank->first = p_module;
     p_this->p_vlc->p_module_bank->i_count++;
 
-    msg_Dbg( p_this, "plugin \"%s\", %s",
-             p_module->psz_object_name, p_module->psz_longname );
+    //msg_Dbg( p_this, "plugin \"%s\", %s",
+    //         p_module->psz_object_name, p_module->psz_longname );
 
     vlc_object_attach( p_module, p_this->p_vlc->p_module_bank );
 
@@ -881,8 +888,8 @@ static int AllocateBuiltinModule( vlc_object_t * p_this,
     p_this->p_vlc->p_module_bank->first = p_module;
     p_this->p_vlc->p_module_bank->i_count++;
 
-    msg_Dbg( p_this, "builtin \"%s\", %s",
-             p_module->psz_object_name, p_module->psz_longname );
+    //msg_Dbg( p_this, "builtin \"%s\", %s",
+    //         p_module->psz_object_name, p_module->psz_longname );
 
     vlc_object_attach( p_module, p_this->p_vlc->p_module_bank );
 
index 8e68ecf..b518f1f 100644 (file)
@@ -245,13 +245,6 @@ static inline const char * module_error( char *psz_buffer )
     (p_symbols)->input_AccessInit_inner = input_AccessInit; \
     (p_symbols)->input_AccessReinit_inner = input_AccessReinit; \
     (p_symbols)->input_AccessEnd_inner = input_AccessEnd; \
-    (p_symbols)->input_ParsePES_inner = input_ParsePES; \
-    (p_symbols)->input_GatherPES_inner = input_GatherPES; \
-    (p_symbols)->input_ReadPS_inner = input_ReadPS; \
-    (p_symbols)->input_ParsePS_inner = input_ParsePS; \
-    (p_symbols)->input_ReadTS_inner = input_ReadTS; \
-    (p_symbols)->input_DemuxPS_inner = input_DemuxPS; \
-    (p_symbols)->input_DemuxTS_inner = input_DemuxTS; \
     (p_symbols)->__input_FDClose_inner = __input_FDClose; \
     (p_symbols)->__input_FDNetworkClose_inner = __input_FDNetworkClose; \
     (p_symbols)->input_FDRead_inner = input_FDRead; \