From 50118171a93a426f2f553369aa65bbc42101d8b8 Mon Sep 17 00:00:00 2001 From: Christophe Massiot Date: Wed, 20 Dec 2000 16:04:31 +0000 Subject: [PATCH] * Big cleanup of the PS input plugin ; * Fixed a bug in AC3 initialization ; * PS streams are now pre-parsed (this can take a while) if possible ; ./configure is required after this update. --- include/config.h.in | 3 + include/input_ext-intf.h | 29 +++- src/ac3_decoder/ac3_decoder_thread.c | 11 ++ src/input/input.c | 23 ++- src/input/input.h | 31 +++- src/input/input_programs.c | 41 ++++- src/input/input_ps.c | 249 ++++++++++++++++++--------- src/input/mpeg_system.c | 197 +++++++++++---------- src/input/mpeg_system.h | 26 +++ 9 files changed, 419 insertions(+), 191 deletions(-) diff --git a/include/config.h.in b/include/config.h.in index 5ea4e4dfef..caa7d5dc1e 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -183,6 +183,9 @@ /* 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. diff --git a/include/input_ext-intf.h b/include/input_ext-intf.h index e570531410..67eb43c0d5 100644 --- a/include/input_ext-intf.h +++ b/include/input_ext-intf.h @@ -1,4 +1,27 @@ -/* 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 @@ -54,8 +77,10 @@ typedef struct es_descriptor_s #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 diff --git a/src/ac3_decoder/ac3_decoder_thread.c b/src/ac3_decoder/ac3_decoder_thread.c index 98c7e7107d..459b774a91 100644 --- a/src/ac3_decoder/ac3_decoder_thread.c +++ b/src/ac3_decoder/ac3_decoder_thread.c @@ -126,6 +126,17 @@ static int InitThread (ac3dec_thread_t * p_ac3dec) 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; diff --git a/src/input/input.c b/src/input/input.c index 517aaddcba..8a13215e34 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -4,7 +4,7 @@ * 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: * @@ -176,7 +176,8 @@ void input_DestroyThread( input_thread_t *p_input, int *pi_status ) *****************************************************************************/ 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 ); @@ -195,15 +196,23 @@ static void RunThread( input_thread_t *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; } } diff --git a/src/input/input.h b/src/input/input.h index 0c7352552c..848f3f6c14 100644 --- a/src/input/input.h +++ b/src/input/input.h @@ -1,5 +1,31 @@ -/* 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 * @@ -22,7 +48,7 @@ typedef struct input_capabilities_s 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 * ); @@ -54,6 +80,7 @@ void input_InitStream( struct input_thread_s *, size_t ); 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 ); diff --git a/src/input/input_programs.c b/src/input/input_programs.c index 8160472abd..e228ea6c69 100644 --- a/src/input/input_programs.c +++ b/src/input/input_programs.c @@ -2,7 +2,7 @@ * 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: * @@ -51,6 +51,7 @@ *****************************************************************************/ 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; @@ -283,6 +284,44 @@ void input_DelES( input_thread_t * p_input, u16 i_id ) } } +#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 *****************************************************************************/ diff --git a/src/input/input_ps.c b/src/input/input_ps.c index 5647c4a83f..9584334512 100644 --- a/src/input/input_ps.c +++ b/src/input/input_ps.c @@ -2,6 +2,7 @@ * 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: * @@ -52,7 +53,7 @@ * 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 * ); @@ -100,10 +101,49 @@ static void PSInit( input_thread_t * p_input ) } 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 ); + } } /***************************************************************************** @@ -116,125 +156,157 @@ static void PSEnd( input_thread_t * p_input ) } /***************************************************************************** - * 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 ); } @@ -250,6 +322,13 @@ static struct data_packet_s * NewPacket( void * p_garbage, { 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" ); diff --git a/src/input/mpeg_system.c b/src/input/mpeg_system.c index 131fd32cbd..cb05f36d0e 100644 --- a/src/input/mpeg_system.c +++ b/src/input/mpeg_system.c @@ -2,7 +2,7 @@ * 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: * @@ -748,6 +748,105 @@ static void DecodePSM( input_thread_t * p_input, data_packet_t * p_data ) } } +/***************************************************************************** + * 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 *****************************************************************************/ @@ -758,7 +857,7 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data ) 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 ) { @@ -819,99 +918,9 @@ void input_DemuxPS( input_thread_t * p_input, data_packet_t * p_data ) } 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++; diff --git a/src/input/mpeg_system.h b/src/input/mpeg_system.h index f1f18555b9..456af7507e 100644 --- a/src/input/mpeg_system.h +++ b/src/input/mpeg_system.h @@ -1,3 +1,27 @@ +/***************************************************************************** + * 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 *****************************************************************************/ @@ -91,5 +115,7 @@ void input_DecodePES( struct input_thread_s *, struct es_descriptor_s * ); 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 * ); -- 2.39.2