/* Maximum number of selected ES in an input thread */
#define INPUT_MAX_SELECTED_ES 10
+/* Maximum size of a data packet (128 kB) */
+#define INPUT_MAX_PACKET_SIZE 131072
+
/* Maximum number of TS packets in the client at any time
* INPUT_MAX_TS + 1 must be a power of 2, to optimize the %(INPUT_MAX_TS+1)
* operation with a &INPUT_MAX_TS in the case of a fifo netlist.
-/* Structures exported to the interface */
+/*****************************************************************************
+ * input_ext-intf.h: structures of the input exported to the interface
+ * This header provides structures to read the stream descriptors and
+ * control the pace of reading.
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ * $Id: input_ext-intf.h,v 1.4 2000/12/20 16:04:31 massiot Exp $
+ *
+ * Authors:
+ *
+ * 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.
+ *****************************************************************************/
/*
* Communication input -> interface
#define MPEG1_AUDIO_ES 0x03
#define MPEG2_AUDIO_ES 0x04
#define AC3_AUDIO_ES 0x81
-#define DVD_SPU_ES 0x82 /* 0x82 might violate the norm */
+/* These ones might violate the norm : */
+#define DVD_SPU_ES 0x82
#define LPCM_AUDIO_ES 0x83
+#define UNKNOWN_ES 0xFF
/*****************************************************************************
* pgrm_descriptor_t
intf_DbgMsg ("ac3dec debug: initializing ac3 decoder thread %p\n", p_ac3dec);
+ /* Get the first data packet. */
+ vlc_mutex_lock( &p_ac3dec->p_fifo->data_lock );
+ while ( DECODER_FIFO_ISEMPTY( *p_ac3dec->p_fifo ) )
+ {
+ if ( p_ac3dec->p_fifo->b_die )
+ {
+ vlc_mutex_unlock( &p_ac3dec->p_fifo->data_lock );
+ return -1;
+ }
+ vlc_cond_wait( &p_ac3dec->p_fifo->data_wait, &p_ac3dec->p_fifo->data_lock );
+ }
p_ac3dec->p_data = DECODER_FIFO_START(*p_ac3dec->p_fifo)->p_first;
byte_stream = ac3_byte_stream (&p_ac3dec->ac3_decoder);
byte_stream->p_byte = p_ac3dec->p_data->p_payload_start;
* decoders.
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: input.c,v 1.59 2000/12/19 19:08:51 massiot Exp $
+ * $Id: input.c,v 1.60 2000/12/20 16:04:31 massiot Exp $
*
* Authors:
*
*****************************************************************************/
static void RunThread( input_thread_t *p_input )
{
- data_packet_t * pp_packets[INPUT_READ_ONCE];
+ data_packet_t * pp_packets[INPUT_READ_ONCE];
+ int i_error, i;
InitThread( p_input );
}
vlc_mutex_unlock( &p_input->stream.control.control_lock );
- p_input->p_plugin->pf_read( p_input, pp_packets );
- if( !p_input->b_error )
+ i_error = p_input->p_plugin->pf_read( p_input, pp_packets );
+
+ /* Demultiplex read packets. */
+ for( i = 0; i < INPUT_READ_ONCE && pp_packets[i] != NULL; i++ )
{
- int i;
+ p_input->p_plugin->pf_demux( p_input, pp_packets[i] );
+ }
- for( i = 0; i < INPUT_READ_ONCE && pp_packets[i] != NULL; i++ )
+ if( i_error )
+ {
+ if( i_error == 1 )
{
- p_input->p_plugin->pf_demux( p_input, pp_packets[i] );
+ /* End of file */
+ intf_WarnMsg( 1, "End of file reached" );
+ /* FIXME: don't treat that as an error */
}
+ p_input->b_error = 1;
}
}
-/* Communication plugin -> input */
+/*****************************************************************************
+ * input.h: structures of the input not exported to other modules
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ * $Id: input.h,v 1.4 2000/12/20 16:04:31 massiot Exp $
+ *
+ * Authors:
+ *
+ * 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.
+ *****************************************************************************/
+
+/*
+ * Communication plugin -> input
+ */
+/* FIXME: you've gotta move this move this, you've gotta move this move this */
#define INPUT_READ_ONCE 7 /* We live in a world dominated by Ethernet. *
* Ethernet MTU is 1500 bytes, so in a UDP *
* packet we can put : 1500/188 = 7 TS *
void (* pf_end)( struct input_thread_s * );
/* Read & Demultiplex */
- void (* pf_read)( struct input_thread_s *,
+ int (* pf_read)( struct input_thread_s *,
struct data_packet_s * pp_packets[INPUT_READ_ONCE] );
void (* pf_demux)( struct input_thread_s *,
struct data_packet_s * );
struct pgrm_descriptor_s * input_AddProgram( struct input_thread_s *,
u16, size_t );
void input_DelProgram( struct input_thread_s *, u16 );
+void input_DumpStream( struct input_thread_s * );
struct es_descriptor_s * input_AddES( struct input_thread_s *,
struct pgrm_descriptor_s *, u16,
size_t );
* input_programs.c: es_descriptor_t, pgrm_descriptor_t management
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_programs.c,v 1.4 2000/12/19 19:08:51 massiot Exp $
+ * $Id: input_programs.c,v 1.5 2000/12/20 16:04:31 massiot Exp $
*
* Authors:
*
*****************************************************************************/
void input_InitStream( input_thread_t * p_input, size_t i_data_len )
{
+ p_input->stream.i_stream_id = 0;
p_input->stream.i_pgrm_number = 0;
p_input->stream.pp_programs = NULL;
}
}
+#ifdef STATS
+/*****************************************************************************
+ * input_DumpStream: dumps the contents of a stream descriptor
+ *****************************************************************************/
+void input_DumpStream( input_thread_t * p_input )
+{
+ int i, j;
+#define S p_input->stream
+ intf_Msg( "input info: Dumping stream ID 0x%x\n", S.i_stream_id );
+ if( S.b_seekable )
+ intf_Msg( "input info: seekable stream, position: %d/%d\n",
+ S.i_tell, S.i_size );
+ else
+ intf_Msg( "input info: %s\n", S.b_pace_control ? "pace controlled" :
+ "pace un-controlled" );
+#undef S
+ for( i = 0; i < p_input->stream.i_pgrm_number; i++ )
+ {
+#define P p_input->stream.pp_programs[i]
+ intf_Msg( "input info: Dumping program 0x%x, version %d (%s)\n",
+ P->i_number, P->i_version,
+ P->b_is_ok ? "complete" : "partial" );
+ if( P->i_synchro_state == SYNCHRO_OK )
+ intf_Msg( "input info: synchro absolute delta : %lld (jitter : %lld)\n",
+ P->delta_absolute, P->delta_cr );
+#undef P
+ for( j = 0; j < p_input->stream.pp_programs[i]->i_es_number; j++ )
+ {
+#define ES p_input->stream.pp_programs[i]->pp_es[j]
+ intf_Msg( "input info: ES 0x%x, stream 0x%x, type 0x%x, %s\n",
+ ES->i_id, ES->i_stream_id, ES->i_type,
+ ES->p_decoder_fifo != NULL ? "selected" : "not selected");
+#undef ES
+ }
+ }
+}
+#endif
+
/*****************************************************************************
* InitDecConfig: initializes a decoder_config_t
*****************************************************************************/
* input_ps.c: PS demux and packet management
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
+ * $Id: input_ps.c,v 1.7 2000/12/20 16:04:31 massiot Exp $
*
* Authors:
*
* Local prototypes
*****************************************************************************/
static int PSProbe ( struct input_thread_s * );
-static void PSRead ( struct input_thread_s *,
+static int PSRead ( struct input_thread_s *,
data_packet_t * p_packets[INPUT_READ_ONCE] );
static void PSInit ( struct input_thread_s * );
static void PSEnd ( struct input_thread_s * );
}
fseek( p_method->stream, 0, SEEK_SET );
- /* Pre-parse the stream to gather stream_descriptor_t. */
-
input_InitStream( p_input, 0 );
input_AddProgram( p_input, 0, sizeof( stream_ps_data_t ) );
+
+ if( p_input->stream.b_seekable )
+ {
+ /* Pre-parse the stream to gather stream_descriptor_t. */
+ p_input->stream.pp_programs[0]->b_is_ok = 0;
+ /* FIXME: don't read all stream (it can be long !) */
+ while( !p_input->b_die && !p_input->b_error )
+ {
+ int i_result, i;
+ data_packet_t * pp_packets[INPUT_READ_ONCE];
+
+ i_result = PSRead( p_input, pp_packets );
+ if( i_result == 1 ) break;
+ if( i_result == -1 )
+ {
+ p_input->b_error = 1;
+ break;
+ }
+
+ for( i = 0; i < INPUT_READ_ONCE && pp_packets[i] != NULL; i++ )
+ {
+ /* FIXME: use i_p_config_t */
+ input_ParsePS( p_input, pp_packets[i] );
+ }
+ }
+ fseek( p_method->stream, 0, SEEK_SET );
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ p_input->stream.pp_programs[0]->b_is_ok = 1;
+ p_input->stream.i_tell = 0;
+#ifdef STATS
+ input_DumpStream( p_input );
+#endif
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ }
+ else
+ {
+ /* The programs will be added when we read them. */
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ p_input->stream.pp_programs[0]->b_is_ok = 0;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ }
}
/*****************************************************************************
}
/*****************************************************************************
- * PSRead: reads a data packet
+ * SafeRead: reads a chunk of stream and correctly detects errors
*****************************************************************************/
-/* FIXME: read INPUT_READ_ONCE packet at once */
-static void PSRead( input_thread_t * p_input,
- data_packet_t * p_packets[INPUT_READ_ONCE] )
+static __inline__ int SafeRead( input_thread_t * p_input, byte_t * p_buffer,
+ size_t i_len )
{
- byte_t p_header[6];
- data_packet_t * p_data;
- int i_packet_size;
thread_ps_data_t * p_method;
+ int i_error;
p_method = (thread_ps_data_t *)p_input->p_method_data;
-
- while( fread( p_header, 6, 1, p_method->stream ) != 1 )
+ while( fread( p_buffer, i_len, 1, p_method->stream ) != 1 )
{
- int i_error;
- if( (i_error = ferror( p_method->stream )) )
+ if( feof( p_method->stream ) )
{
- intf_ErrMsg( "Read 1 failed (%s)", strerror(i_error) );
- p_input->b_error = 1;
- return;
+ return( 1 );
}
- if( feof( p_method->stream ) )
+ if( (i_error = ferror( p_method->stream )) )
{
- intf_ErrMsg( "EOF reached" );
- p_input->b_error = 1;
- return;
+ intf_ErrMsg( "Read failed (%s)", strerror(i_error) );
+ return( -1 );
}
}
+ vlc_mutex_lock( &p_input->stream.stream_lock );
+ p_input->stream.i_tell += i_len;
+ vlc_mutex_unlock( &p_input->stream.stream_lock );
+ return( 0 );
+}
- if( (U32_AT(p_header) & 0xFFFFFF00) != 0x100L )
+/*****************************************************************************
+ * PSRead: reads a data packet
+ *****************************************************************************
+ * Returns -1 in case of error, 0 if everything went well, and 1 in case of
+ * EOF.
+ *****************************************************************************/
+static int PSRead( input_thread_t * p_input,
+ data_packet_t * pp_packets[INPUT_READ_ONCE] )
+{
+ byte_t p_header[6];
+ data_packet_t * p_data;
+ size_t i_packet_size;
+ int i_packet, i_error;
+ thread_ps_data_t * p_method;
+
+ p_method = (thread_ps_data_t *)p_input->p_method_data;
+
+ memset( pp_packets, 0, INPUT_READ_ONCE * sizeof(data_packet_t *) );
+ for( i_packet = 0; i_packet < INPUT_READ_ONCE; i_packet++ )
{
- u32 i_buffer = U32_AT(p_header);
- intf_WarnMsg( 1, "Garbage at input (%x)\n", i_buffer );
- while( (i_buffer & 0xFFFFFF00) != 0x100L )
+ /* Read what we believe to be a packet header. */
+ if( (i_error = SafeRead( p_input, p_header, 6 )) )
{
- i_buffer <<= 8;
- i_buffer |= getc( p_method->stream );
- if( feof(p_method->stream) || ferror(p_method->stream) )
- {
- p_input->b_error = 1;
- return;
- }
+ return( i_error );
}
- *(u32 *)p_header = U32_AT(&i_buffer);
- fread( p_header + 4, 2, 1, p_method->stream );
- }
- if( U32_AT(p_header) != 0x1BA )
- {
- i_packet_size = U16_AT(&p_header[4]);
- }
- else
- {
- if( (p_header[4] & 0xC0) == 0x40 )
+ if( (U32_AT(p_header) & 0xFFFFFF00) != 0x100L )
{
- /* MPEG-2 */
- i_packet_size = 8;
+ /* This is not the startcode of a packet. Read the stream
+ * until we find one. */
+ u32 i_startcode = U32_AT(p_header);
+ int i_dummy;
+
+ if( i_startcode )
+ {
+ /* It is common for MPEG-1 streams to pad with zeros
+ * (although it is forbidden by the recommendation), so
+ * don't bother everybody in this case. */
+ intf_WarnMsg( 1, "Garbage at input (%x)\n", i_startcode );
+ }
+
+ while( (i_startcode & 0xFFFFFF00) != 0x100L )
+ {
+ i_startcode <<= 8;
+ if( (i_dummy = getc( p_method->stream )) != EOF )
+ {
+ i_startcode |= i_dummy;
+ }
+ else
+ {
+ return( 1 );
+ }
+ }
+ /* Packet found. */
+ *(u32 *)p_header = U32_AT(&i_startcode);
+ if( (i_error = SafeRead( p_input, p_header + 4, 2 )) )
+ {
+ return( i_error );
+ }
}
- else if( (p_header[4] & 0xF0) == 0x20 )
+
+ if( U32_AT(p_header) != 0x1BA )
{
- /* MPEG-1 */
- i_packet_size = 6;
+ /* That's the case for all packets, except pack header. */
+ i_packet_size = U16_AT(&p_header[4]);
}
else
{
- intf_ErrMsg( "Unable to determine stream type" );
- p_input->b_error = 1;
- return;
+ /* Pack header. */
+ if( (p_header[4] & 0xC0) == 0x40 )
+ {
+ /* MPEG-2 */
+ i_packet_size = 8;
+ }
+ else if( (p_header[4] & 0xF0) == 0x20 )
+ {
+ /* MPEG-1 */
+ i_packet_size = 6;
+ }
+ else
+ {
+ intf_ErrMsg( "Unable to determine stream type" );
+ return( -1 );
+ }
}
- }
-
- if( (p_data = NewPacket( p_input, i_packet_size + 6 )) == NULL )
- {
- p_input->b_error = 1;
- intf_ErrMsg( "Out of memory" );
- return;
- }
- memcpy( p_data->p_buffer, p_header, 6 );
-
- /* FIXME: catch EINTR ! */
- while( fread( p_data->p_buffer + 6, i_packet_size,
- 1, p_method->stream ) != 1 )
- {
- int i_error;
- if( (i_error = ferror( p_method->stream)) )
+ /* Fetch a packet of the appropriate size. */
+ if( (p_data = NewPacket( p_input, i_packet_size + 6 )) == NULL )
{
- intf_ErrMsg( "Read 1 failed (%s)", strerror(i_error) );
- p_input->b_error = 1;
- return;
+ intf_ErrMsg( "Out of memory" );
+ return( -1 );
}
- if( feof( p_method->stream ) )
+ /* Copy the header we already read. */
+ memcpy( p_data->p_buffer, p_header, 6 );
+
+ /* Read the remaining of the packet. */
+ if( (i_error =
+ SafeRead( p_input, p_data->p_buffer + 6, i_packet_size )) )
{
- intf_ErrMsg( "EOF reached" );
- p_input->b_error = 1;
- return;
+ return( i_error );
}
- }
- if( U32_AT(p_header) == 0x1BA )
- {
- if( i_packet_size == 8 )
+ /* In MPEG-2 pack headers we still have to read stuffing bytes. */
+ if( U32_AT(p_header) == 0x1BA )
{
- /* MPEG-2 stuffing bytes */
- byte_t p_garbage[8];
- if( (p_data->p_buffer[13] & 0x7) != 0 )
+ if( i_packet_size == 8 && (p_data->p_buffer[13] & 0x7) != 0 )
{
- /* FIXME: catch EINTR ! */
- fread( p_garbage, p_garbage[0] & 0x7, 1,
- p_method->stream );
+ /* MPEG-2 stuffing bytes */
+ byte_t p_garbage[8];
+ if( (i_error = SafeRead( p_input, p_garbage,
+ p_data->p_buffer[13] & 0x7)) )
+ {
+ return( i_error );
+ }
}
}
+
+ /* Give the packet to the other input stages. */
+ pp_packets[i_packet] = p_data;
}
- memset( p_packets, 0, sizeof(p_packets) );
- p_packets[0] = p_data;
+ return( 0 );
}
{
data_packet_t * p_data;
+ /* Safety check */
+ if( i_size > INPUT_MAX_PACKET_SIZE )
+ {
+ intf_ErrMsg( "Packet too big (%d)", i_size );
+ return NULL;
+ }
+
if( (p_data = (data_packet_t *)malloc( sizeof(data_packet_t) )) == NULL )
{
intf_DbgMsg( "Out of memory" );
* mpeg_system.c: TS, PS and PES management
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: mpeg_system.c,v 1.9 2000/12/19 19:08:51 massiot Exp $
+ * $Id: mpeg_system.c,v 1.10 2000/12/20 16:04:31 massiot Exp $
*
* Authors:
*
}
}
+/*****************************************************************************
+ * 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 = U32_AT( p_data->p_buffer );
+ if( i_code > 0x1BC ) /* 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 < INPUT_MAX_SELECTED_ES; i_dummy++ )
+ {
+ if( p_input->pp_selected_es[i_dummy] != NULL
+ && p_input->pp_selected_es[i_dummy]->i_id == i_id )
+ {
+ p_es = p_input->pp_selected_es[i_dummy];
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* Search all ES ; if not found -> AddES */
+ for( i_dummy = 0; i_dummy < INPUT_MAX_ES; i_dummy++ )
+ {
+ if( p_input->p_es[i_dummy].i_id != EMPTY_ID
+ && p_input->p_es[i_dummy].i_id == i_id )
+ {
+ p_es = &p_input->p_es[i_dummy];
+ break;
+ }
+ }
+
+ if( p_es == NULL )
+ {
+ 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_buffer[3];
+
+ /* Set stream type and auto-spawn. */
+ if( (i_id & 0xF0) == 0xE0 )
+ {
+ /* MPEG video */
+ p_es->i_type = MPEG2_VIDEO_ES;
+#ifdef AUTO_SPAWN
+ input_SelectES( p_input, p_es );
+#endif
+ }
+ else if( (i_id & 0xE0) == 0xC0 )
+ {
+ /* MPEG audio */
+ p_es->i_type = MPEG2_AUDIO_ES;
+#ifdef AUTO_SPAWN
+ input_SelectES( p_input, p_es );
+#endif
+ }
+ else if( (i_id & 0xF0FF) == 0x80BD )
+ {
+ /* AC3 audio */
+ p_es->i_type = AC3_AUDIO_ES;
+#ifdef AUTO_SPAWN
+ input_SelectES( p_input, p_es );
+#endif
+ }
+ else if( (i_id & 0xF0FF) == 0x20BD )
+ {
+ /* Subtitles video */
+ p_es->i_type = DVD_SPU_ES;
+#ifdef AUTO_SPAWN
+ input_SelectES( p_input, p_es );
+#endif
+ }
+ else
+ {
+ p_es->i_type = UNKNOWN_ES;
+ }
+ }
+ }
+ } /* 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
*****************************************************************************/
es_descriptor_t * p_es = NULL;
i_code = U32_AT( p_data->p_buffer );
- if( i_code >= 0x1B9 && i_code <= 0x1BC )
+ if( i_code <= 0x1BC )
{
switch( i_code )
{
}
else
{
- 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 1
- for( i_dummy = 0; i_dummy < INPUT_MAX_ES; i_dummy++ )
- {
- if( p_input->p_es[i_dummy].i_id != EMPTY_ID
- && p_input->p_es[i_dummy].i_id == i_id )
- {
- p_es = &p_input->p_es[i_dummy];
- break;
- }
- }
-#else
- for( i_dummy = 0; i_dummy < INPUT_MAX_SELECTED_ES; i_dummy++ )
- {
- if( p_input->pp_selected_es[i_dummy] != NULL
- && p_input->pp_selected_es[i_dummy]->i_id == i_id )
- {
- p_es = p_input->pp_selected_es[i_dummy];
- break;
- }
- }
-#endif
- vlc_mutex_unlock( &p_input->stream.stream_lock );
-
- if( p_es == NULL )
- {
-#if 1
- vlc_mutex_lock( &p_input->stream.stream_lock );
- p_es = input_AddES( p_input, p_input->stream.pp_programs[0],
- i_id, 0 );
-
- if( p_es != NULL )
- {
- if( (i_id & 0xF0) == 0xE0 )
- {
- /* MPEG video */
- p_es->i_stream_id = i_id;
- p_es->i_type = MPEG2_VIDEO_ES;
-
-#ifdef AUTO_SPAWN
- input_SelectES( p_input, p_es );
-#endif
- }
- else if( (i_id & 0xE0) == 0xC0 )
- {
- /* MPEG audio */
- p_es->i_stream_id = i_id;
- p_es->i_type = MPEG2_AUDIO_ES;
-
-#ifdef AUTO_SPAWN
- input_SelectES( p_input, p_es );
-#endif
- }
- else if( (i_id & 0xF0FF) == 0x80BD )
- {
- /* AC3 audio */
- p_es->i_stream_id = 0xBD;
- p_es->i_type = AC3_AUDIO_ES;
-
-#ifdef AUTO_SPAWN
- input_SelectES( p_input, p_es );
-#endif
- }
- else if( (i_id & 0xF0FF) == 0x20BD )
- {
- /* Subtitles video */
- p_es->i_stream_id = 0xBD;
- p_es->i_type = DVD_SPU_ES;
-
-#ifdef AUTO_SPAWN
- input_SelectES( p_input, p_es );
-#endif
- }
- else
- {
- b_trash = 1;
- }
- vlc_mutex_unlock( &p_input->stream.stream_lock );
- }
- else
- b_trash = 1;
-#else
- b_trash = 1;
-#endif
- }
+ p_es = input_ParsePS( p_input, p_data );
- if( p_es->p_decoder_fifo != NULL && !b_trash )
+ if( p_es != NULL && p_es->p_decoder_fifo != NULL && !b_trash )
{
#ifdef STATS
p_es->c_packets++;
+/*****************************************************************************
+ * mpeg_system.h: structures of the input used to parse MPEG-1, MPEG-2 PS
+ * and TS system layers
+ *****************************************************************************
+ * Copyright (C) 1999, 2000 VideoLAN
+ * $Id: mpeg_system.h,v 1.2 2000/12/20 16:04:31 massiot Exp $
+ *
+ * Authors:
+ *
+ * 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.
+ *****************************************************************************/
+
/*****************************************************************************
* Constants
*****************************************************************************/
void input_ParsePES( struct input_thread_s *, struct es_descriptor_s * );
void input_GatherPES( struct input_thread_s *, struct data_packet_s *,
struct es_descriptor_s *, boolean_t, boolean_t );
+es_descriptor_t * input_ParsePS( struct input_thread_s *,
+ struct data_packet_s * );
void input_DemuxPS( struct input_thread_s *, struct data_packet_s * );
void input_DemuxTS( struct input_thread_s *, struct data_packet_s * );