X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Finput%2Finput.c;h=207c598b04670ff48cfc7bad511229036e145089;hb=c7b1c474c6a8687a0645553beb0e5c6f868d8c5c;hp=6bdcc3ba5005dac75628e26496f8c94bc0e60012;hpb=248eb0b5b90523c8929c33dae781ca5b500c906d;p=vlc diff --git a/src/input/input.c b/src/input/input.c index 6bdcc3ba50..207c598b04 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -4,7 +4,7 @@ * decoders. ***************************************************************************** * Copyright (C) 1998-2001 VideoLAN - * $Id: input.c,v 1.161 2001/11/28 15:08:06 massiot Exp $ + * $Id: input.c,v 1.169 2002/01/09 02:01:14 sam Exp $ * * Authors: Christophe Massiot * @@ -26,13 +26,13 @@ /***************************************************************************** * Preamble *****************************************************************************/ -#include "defs.h" - #include #include #include #include +#include + #ifdef HAVE_UNISTD_H # include #elif defined( _MSC_VER ) && defined( _WIN32 ) @@ -62,14 +62,7 @@ # include #endif -#include "config.h" -#include "common.h" -#include "intf_msg.h" -#include "threads.h" -#include "mtime.h" -#include "tests.h" #include "netutils.h" -#include "modules.h" #include "intf_playlist.h" @@ -80,8 +73,6 @@ #include "interface.h" -#include "main.h" - /***************************************************************************** * Local prototypes *****************************************************************************/ @@ -101,6 +92,41 @@ static void HTTPOpen ( input_thread_t *p_input ); static void NetworkClose ( input_thread_t *p_input ); #endif +/***************************************************************************** + * input_InitBank: initialize the input bank. + *****************************************************************************/ +void input_InitBank ( void ) +{ + p_input_bank->i_count = 0; + + /* XXX: Workaround for old interface modules */ + p_input_bank->pp_input[0] = NULL; + + vlc_mutex_init( &p_input_bank->lock ); +} + +/***************************************************************************** + * input_EndBank: empty the input bank. + ***************************************************************************** + * This function ends all unused inputs and empties the bank in + * case of success. + *****************************************************************************/ +void input_EndBank ( void ) +{ + int i_input; + + /* Ask all remaining video outputs to die */ + for( i_input = 0; i_input < p_input_bank->i_count; i_input++ ) + { + input_StopThread( + p_input_bank->pp_input[ i_input ], NULL ); + input_DestroyThread( + p_input_bank->pp_input[ i_input ] ); + } + + vlc_mutex_destroy( &p_input_bank->lock ); +} + /***************************************************************************** * input_CreateThread: creates a new input thread ***************************************************************************** @@ -112,7 +138,6 @@ static void NetworkClose ( input_thread_t *p_input ); input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status ) { input_thread_t * p_input; /* thread descriptor */ - int i_status; /* thread status */ /* Allocate descriptor */ p_input = (input_thread_t *)malloc( sizeof(input_thread_t) ); @@ -123,20 +148,16 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status ) return( NULL ); } - /* Packets read once */ - p_input->i_read_once = INPUT_READ_ONCE; - /* Initialize thread properties */ - p_input->b_die = 0; - p_input->b_error = 0; - p_input->b_eof = 0; + p_input->b_die = 0; + p_input->b_error = 0; + p_input->b_eof = 0; /* Set target */ - p_input->p_source = p_item->psz_name; + p_input->p_source = p_item->psz_name; - /* I have never understood that stuff --Meuuh */ - p_input->pi_status = (pi_status != NULL) ? pi_status : &i_status; - *p_input->pi_status = THREAD_CREATE; + /* Set status */ + p_input->i_status = THREAD_CREATE; /* Initialize stream description */ p_input->stream.i_es_number = 0; @@ -177,6 +198,7 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status ) return( NULL ); } +#if 0 /* If status is NULL, wait until the thread is created */ if( pi_status == NULL ) { @@ -185,36 +207,30 @@ input_thread_t *input_CreateThread ( playlist_item_t *p_item, int *pi_status ) msleep( THREAD_SLEEP ); } while( (i_status != THREAD_READY) && (i_status != THREAD_ERROR) && (i_status != THREAD_FATAL) ); - if( i_status != THREAD_READY ) - { - return( NULL ); - } } +#endif + return( p_input ); } /***************************************************************************** - * input_DestroyThread: mark an input thread as zombie + * input_StopThread: mark an input thread as zombie ***************************************************************************** * This function should not return until the thread is effectively cancelled. *****************************************************************************/ -void input_DestroyThread( input_thread_t *p_input, int *pi_status ) +void input_StopThread( input_thread_t *p_input, int *pi_status ) { - int i_status; /* thread status */ - - /* Set status */ - p_input->pi_status = (pi_status != NULL) ? pi_status : &i_status; - *p_input->pi_status = THREAD_DESTROY; + /* Make the thread exit from a possible vlc_cond_wait() */ + vlc_mutex_lock( &p_input->stream.stream_lock ); /* Request thread destruction */ p_input->b_die = 1; - /* Make the thread exit of an eventual vlc_cond_wait() */ - vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_cond_signal( &p_input->stream.stream_wait ); vlc_mutex_unlock( &p_input->stream.stream_lock ); /* If status is NULL, wait until thread has been destroyed */ +#if 0 if( pi_status == NULL ) { do @@ -223,6 +239,25 @@ void input_DestroyThread( input_thread_t *p_input, int *pi_status ) } while ( (i_status != THREAD_OVER) && (i_status != THREAD_ERROR) && (i_status != THREAD_FATAL) ); } +#endif +} + +/***************************************************************************** + * input_DestroyThread: mark an input thread as zombie + ***************************************************************************** + * This function should not return until the thread is effectively cancelled. + *****************************************************************************/ +void input_DestroyThread( input_thread_t *p_input ) +{ + /* Join the thread */ + vlc_thread_join( p_input->thread_id ); + + /* Destroy Mutex locks */ + vlc_mutex_destroy( &p_input->stream.control.control_lock ); + vlc_mutex_destroy( &p_input->stream.stream_lock ); + + /* Free input structure */ + free( p_input ); } /***************************************************************************** @@ -232,39 +267,55 @@ void input_DestroyThread( input_thread_t *p_input, int *pi_status ) *****************************************************************************/ static void RunThread( input_thread_t *p_input ) { - int i_error, i; - data_packet_t ** pp_packets; - if( InitThread( p_input ) ) { /* If we failed, wait before we are killed, and exit */ - *p_input->pi_status = THREAD_ERROR; + p_input->i_status = THREAD_ERROR; p_input->b_error = 1; ErrorThread( p_input ); DestroyThread( p_input ); return; } - /* initialization is completed */ + p_input->i_status = THREAD_READY; + + /* initialization is complete */ vlc_mutex_lock( &p_input->stream.stream_lock ); p_input->stream.b_changed = 1; vlc_mutex_unlock( &p_input->stream.stream_lock ); - pp_packets = (data_packet_t **) malloc( p_input->i_read_once * - sizeof( data_packet_t * ) ); - if( pp_packets == NULL ) - { - intf_ErrMsg( "input error: out of memory" ); - free( pp_packets ); - p_input->b_error = 1; - } - while( !p_input->b_die && !p_input->b_error && !p_input->b_eof ) { + data_packet_t * p_data; + int i_count, i; + p_input->c_loops++; vlc_mutex_lock( &p_input->stream.stream_lock ); + if( p_input->stream.p_new_program ) + { + if( p_input->pf_set_program != NULL ) + { + + p_input->pf_set_program( p_input, + p_input->stream.p_new_program ); + + for( i = 0; i < p_input->stream.i_pgrm_number; i++ ) + { + pgrm_descriptor_t * p_pgrm + = p_input->stream.pp_programs[i]; + /* Escape all decoders for the stream discontinuity they + * will encounter. */ + input_EscapeDiscontinuity( p_input, p_pgrm ); + + /* Reinitialize synchro. */ + p_pgrm->i_synchro_state = SYNCHRO_REINIT; + } + } + p_input->stream.p_new_program = NULL; + } + if( p_input->stream.p_new_area ) { if( p_input->stream.b_seekable && p_input->pf_set_area != NULL ) @@ -337,33 +388,33 @@ static void RunThread( input_thread_t *p_input ) vlc_mutex_unlock( &p_input->stream.stream_lock ); - i_error = p_input->pf_read( p_input, pp_packets ); + i_count = p_input->pf_read( p_input, &p_data ); /* Demultiplex read packets. */ - for( i = 0; i < p_input->i_read_once && pp_packets[i] != NULL; i++ ) + while( p_data != NULL ) { + data_packet_t * p_next = p_data->p_next; + p_data->p_next = NULL; + p_input->stream.c_packets_read++; - p_input->pf_demux( p_input, pp_packets[i] ); + p_input->pf_demux( p_input, p_data ); + + p_data = p_next; } - if( i_error ) + if( i_count == 0 && p_input->stream.b_seekable ) { - if( i_error == 1 ) - { - /* End of file - we do not set b_die because only the - * interface is allowed to do so. */ - intf_WarnMsg( 3, "input: EOF reached" ); - p_input->b_eof = 1; - } - else - { - p_input->b_error = 1; - } + /* End of file - we do not set b_die because only the + * interface is allowed to do so. */ + intf_WarnMsg( 3, "input: EOF reached" ); + p_input->b_eof = 1; + } + else if( i_count < 0 ) + { + p_input->b_error = 1; } } - free( pp_packets ); - if( p_input->b_error || p_input->b_eof ) { ErrorThread( p_input ); @@ -381,7 +432,6 @@ static void RunThread( input_thread_t *p_input ) *****************************************************************************/ static int InitThread( input_thread_t * p_input ) { - /* Initialize statistics */ p_input->c_loops = 0; p_input->stream.c_packets_read = 0; @@ -395,7 +445,8 @@ static int InitThread( input_thread_t * p_input ) /* Find appropriate module. */ p_input->p_input_module = module_Need( MODULE_CAPABILITY_INPUT, - (probedata_t *)p_input ); + main_GetPszVariable( INPUT_METHOD_VAR, NULL ), + (probedata_t *)p_input ); if( p_input->p_input_module == NULL ) { @@ -410,6 +461,7 @@ static int InitThread( input_thread_t * p_input ) p_input->pf_init_bit_stream= f.pf_init_bit_stream; p_input->pf_read = f.pf_read; p_input->pf_set_area = f.pf_set_area; + p_input->pf_set_program = f.pf_set_program; p_input->pf_demux = f.pf_demux; p_input->pf_new_packet = f.pf_new_packet; p_input->pf_new_pes = f.pf_new_pes; @@ -418,12 +470,17 @@ static int InitThread( input_thread_t * p_input ) p_input->pf_rewind = f.pf_rewind; p_input->pf_seek = f.pf_seek; + if( f.pf_open != NULL ) + { + f.pf_open( p_input ); + p_input->stream.i_method = INPUT_METHOD_DVD; + } #if !defined( SYS_BEOS ) && !defined( SYS_NTO ) /* FIXME : this is waaaay too kludgy */ - if( ( strlen( p_input->p_source ) >= 10 - && !strncasecmp( p_input->p_source, "udpstream:", 10 ) ) - || ( strlen( p_input->p_source ) >= 4 - && !strncasecmp( p_input->p_source, "udp:", 4 ) ) ) + else if( ( strlen( p_input->p_source ) >= 10 + && !strncasecmp( p_input->p_source, "udpstream:", 10 ) ) + || ( strlen( p_input->p_source ) >= 4 + && !strncasecmp( p_input->p_source, "udp:", 4 ) ) ) { /* Network stream */ NetworkOpen( p_input ); @@ -436,30 +493,7 @@ static int InitThread( input_thread_t * p_input ) HTTPOpen( p_input ); p_input->stream.i_method = INPUT_METHOD_NETWORK; } - else #endif - if( ( ( strlen( p_input->p_source ) > 4 ) - && !strncasecmp( p_input->p_source, "dvd:", 4 ) ) - || TestMethod( INPUT_METHOD_VAR, "dvd" ) ) - { - /* DVD - this is THE kludge */ - f.pf_open( p_input ); - p_input->stream.i_method = INPUT_METHOD_DVD; - } - else if( ( ( strlen( p_input->p_source ) > 8 ) - && !strncasecmp( p_input->p_source, "dvdread:", 8 ) ) - || TestMethod( INPUT_METHOD_VAR, "dvdread" ) ) - { - /* DVDRead - this is THE kludge */ - f.pf_open( p_input ); - p_input->stream.i_method = INPUT_METHOD_DVD; - } - else if( ( strlen( p_input->p_source ) > 4 ) - && !strncasecmp( p_input->p_source, "vlc:", 4 ) ) - { - /* Dummy input - very kludgy */ - f.pf_open( p_input ); - } else if( ( strlen( p_input->p_source ) == 1 ) && *p_input->p_source == '-' ) { @@ -491,8 +525,6 @@ static int InitThread( input_thread_t * p_input ) return( -1 ); } - *p_input->pi_status = THREAD_READY; - return( 0 ); } @@ -515,11 +547,8 @@ static void ErrorThread( input_thread_t *p_input ) *****************************************************************************/ static void EndThread( input_thread_t * p_input ) { - int * pi_status; /* thread status */ - /* Store status */ - pi_status = p_input->pi_status; - *pi_status = THREAD_END; + p_input->i_status = THREAD_END; if( p_main->b_stats ) { @@ -558,12 +587,16 @@ static void CloseThread( input_thread_t * p_input ) { #define f p_input->p_input_module->p_functions->input.functions.input + if( f.pf_close != NULL ) + { + f.pf_close( p_input ); + } #if !defined( SYS_BEOS ) && !defined( SYS_NTO ) /* Close stream */ - if( ( strlen( p_input->p_source ) > 10 - && !strncasecmp( p_input->p_source, "udpstream:", 10 ) ) - || ( strlen( p_input->p_source ) > 4 - && !strncasecmp( p_input->p_source, "udp:", 4 ) ) ) + else if( ( strlen( p_input->p_source ) > 10 + && !strncasecmp( p_input->p_source, "udpstream:", 10 ) ) + || ( strlen( p_input->p_source ) > 4 + && !strncasecmp( p_input->p_source, "udp:", 4 ) ) ) { NetworkClose( p_input ); } @@ -572,19 +605,7 @@ static void CloseThread( input_thread_t * p_input ) { NetworkClose( p_input ); } - else #endif - if( ( ( strlen( p_input->p_source ) > 4 ) - && !strncasecmp( p_input->p_source, "dvd:", 4 ) ) - || TestMethod( INPUT_METHOD_VAR, "dvd" ) ) - { - f.pf_close( p_input ); - } - else if( ( strlen( p_input->p_source ) > 4 ) - && !strncasecmp( p_input->p_source, "vlc:", 4 ) ) - { - f.pf_close( p_input ); - } else { FileClose( p_input ); @@ -597,20 +618,8 @@ static void CloseThread( input_thread_t * p_input ) *****************************************************************************/ static void DestroyThread( input_thread_t * p_input ) { - int * pi_status; /* thread status */ - - /* Store status */ - pi_status = p_input->pi_status; - - /* Destroy Mutex locks */ - vlc_mutex_destroy( &p_input->stream.control.control_lock ); - vlc_mutex_destroy( &p_input->stream.stream_lock ); - - /* Free input structure */ - free( p_input ); - /* Update status */ - *pi_status = THREAD_OVER; + p_input->i_status = THREAD_OVER; } /***************************************************************************** @@ -653,7 +662,7 @@ static void FileOpen( input_thread_t * p_input ) psz_name += 8; i_stat = stat( psz_name, &stat_info ); } - else if( ( i_size > 4 ) + else if( ( i_size > 4 ) && !strncasecmp( psz_name, "dvd:", 4 ) ) { /* get rid of the 'dvd:' stuff and try again */