X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Finput%2Finput.c;h=43bff2eed1ce2ca71071bd105b0e53877f3a9fb0;hb=959674591f4ec45888fcb34321958d080efd73cd;hp=a046ed360fa12918d4392a81d562f59fa316ef74;hpb=a132d75cac753d6da22a2996fd376f42234f9e56;p=vlc diff --git a/src/input/input.c b/src/input/input.c index a046ed360f..43bff2eed1 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -4,9 +4,9 @@ * decoders. ***************************************************************************** * Copyright (C) 1998, 1999, 2000 VideoLAN - * $Id: input.c,v 1.65 2001/01/05 14:45:47 sam Exp $ + * $Id: input.c,v 1.79 2001/02/11 01:15:11 sam Exp $ * - * Authors: + * Authors: Christophe Massiot * * 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 @@ -44,14 +44,19 @@ #include "common.h" #include "threads.h" #include "mtime.h" +#include "modules.h" #include "intf_msg.h" +#include "intf_plst.h" #include "stream_control.h" #include "input_ext-intf.h" #include "input_ext-dec.h" #include "input.h" +#include "interface.h" + +#include "main.h" /***************************************************************************** * Local prototypes @@ -60,8 +65,6 @@ static void RunThread ( input_thread_t *p_input ); static void InitThread ( input_thread_t *p_input ); static void ErrorThread ( input_thread_t *p_input ); static void EndThread ( input_thread_t *p_input ); -static void NetworkOpen ( input_thread_t *p_input ); -static void FileOpen ( input_thread_t *p_input ); /***************************************************************************** * input_CreateThread: creates a new input thread @@ -71,7 +74,7 @@ static void FileOpen ( input_thread_t *p_input ); * If pi_status is NULL, then the function will block until the thread is ready. * If not, it will be updated using one of the THREAD_* constants. *****************************************************************************/ -input_thread_t *input_CreateThread ( input_config_t * p_config, int *pi_status ) +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 */ @@ -82,33 +85,41 @@ input_thread_t *input_CreateThread ( input_config_t * p_config, int *pi_status ) { intf_ErrMsg( "input error: can't allocate input thread (%s)", strerror(errno) ); - free( p_config ); return( NULL ); } /* Initialize thread properties */ 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; + /* I have never understood that stuff --Meuuh */ p_input->pi_status = (pi_status != NULL) ? pi_status : &i_status; *p_input->pi_status = THREAD_CREATE; - p_input->p_config = p_config; /* Initialize stream description */ p_input->stream.i_es_number = 0; p_input->stream.i_selected_es_number = 0; p_input->stream.i_pgrm_number = 0; + p_input->stream.i_new_status = p_input->stream.i_new_rate = 0; + p_input->stream.i_seek = 0; /* Initialize stream control properties. */ p_input->stream.control.i_status = PLAYING_S; p_input->stream.control.i_rate = DEFAULT_RATE; - p_input->stream.control.i_ref_sysdate = 0; - p_input->stream.control.i_ref_clock = 0; p_input->stream.control.b_mute = 0; p_input->stream.control.b_bw = 0; + /* Initialize default settings for spawned decoders */ + p_input->p_default_aout = p_main->p_aout; + p_input->p_default_vout = p_main->p_vout; + /* Create thread and set locks. */ vlc_mutex_init( &p_input->stream.stream_lock ); + vlc_cond_init( &p_input->stream.stream_wait ); vlc_mutex_init( &p_input->stream.control.control_lock ); if( vlc_thread_create( &p_input->thread_id, "input", (void *) RunThread, (void *) p_input ) ) @@ -116,7 +127,6 @@ input_thread_t *input_CreateThread ( input_config_t * p_config, int *pi_status ) intf_ErrMsg( "input error: can't create input thread (%s)", strerror(errno) ); free( p_input ); - free( p_config ); return( NULL ); } @@ -152,6 +162,11 @@ void input_DestroyThread( input_thread_t *p_input, int *pi_status ) /* Request thread destruction */ p_input->b_die = 1; + /* Make the thread exit of an eventual vlc_cond_wait() */ + 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( pi_status == NULL ) { @@ -175,42 +190,61 @@ static void RunThread( input_thread_t *p_input ) InitThread( p_input ); - while( !p_input->b_die && !p_input->b_error ) + while( !p_input->b_die && !p_input->b_error && !p_input->b_eof ) { + #ifdef STATS p_input->c_loops++; #endif - vlc_mutex_lock( &p_input->stream.control.control_lock ); - if( p_input->stream.control.i_status == BACKWARD_S - && p_input->p_plugin->pf_rewind != NULL ) + vlc_mutex_lock( &p_input->stream.stream_lock ); + if( p_input->stream.i_seek ) { - p_input->p_plugin->pf_rewind( p_input ); - /* FIXME: probably don't do it every loop, but when ? */ + if( p_input->stream.b_seekable && p_input->pf_seek != NULL ) + { + p_input->pf_seek( p_input, p_input->stream.i_seek ); + + 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.i_seek = 0; } - vlc_mutex_unlock( &p_input->stream.control.control_lock ); + vlc_mutex_unlock( &p_input->stream.stream_lock ); - i_error = p_input->p_plugin->pf_read( p_input, pp_packets ); + i_error = p_input->pf_read( p_input, pp_packets ); /* Demultiplex read packets. */ for( i = 0; i < INPUT_READ_ONCE && pp_packets[i] != NULL; i++ ) { - p_input->p_plugin->pf_demux( p_input, pp_packets[i] ); + p_input->pf_demux( p_input, pp_packets[i] ); } if( i_error ) { if( i_error == 1 ) { - /* End of file */ + /* End of file - we do not set b_die because only the + * interface is allowed to do so. */ intf_WarnMsg( 1, "End of file reached" ); - /* FIXME: don't treat that as an error */ + p_input->b_eof = 1; + } + else + { + p_input->b_error = 1; } - p_input->b_error = 1; } } - if( p_input->b_error ) + if( p_input->b_error || p_input->b_eof ) { ErrorThread( p_input ); } @@ -220,14 +254,10 @@ static void RunThread( input_thread_t *p_input ) } /***************************************************************************** - * InitThread: init the input thread + * InitThread: init the input Thread *****************************************************************************/ -input_capabilities_t * PSKludge( void ); static void InitThread( input_thread_t * p_input ) { - /* Initialize default settings for spawned decoders */ - p_input->p_default_aout = p_input->p_config->p_default_aout; - p_input->p_default_vout = p_input->p_config->p_default_vout; #ifdef STATS /* Initialize statistics */ @@ -238,40 +268,41 @@ static void InitThread( input_thread_t * p_input ) p_input->c_packets_trashed = 0; #endif - /* Use the appropriate input method */ - switch( p_input->p_config->i_method ) + p_input->p_input_module = module_Need( p_main->p_bank, + MODULE_CAPABILITY_INPUT, NULL ); + + if( p_input->p_input_module == NULL ) { - case INPUT_METHOD_FILE: /* file methods */ - FileOpen( p_input ); - break; - case INPUT_METHOD_VLAN_BCAST: /* vlan network method */ -/* if( !p_main->b_vlans ) - { - intf_ErrMsg("input error: vlans are not activated"); - free( p_input ); - return( NULL ); - } */ /* la-lala */ - /* ... pass through */ - case INPUT_METHOD_UCAST: /* network methods */ - case INPUT_METHOD_MCAST: - case INPUT_METHOD_BCAST: - NetworkOpen( p_input ); - break; -#ifdef DEBUG - default: - intf_ErrMsg( "input error: unknow method 0x%.4x", - p_input->p_config->i_method ); - free( p_input->p_config ); + intf_ErrMsg( "input error: no suitable input module" ); p_input->b_error = 1; - break; -#endif + return; } - free( p_input->p_config ); +#define f p_input->p_input_module->p_functions->input.functions.input + p_input->pf_init = f.pf_init; + p_input->pf_open = f.pf_open; + p_input->pf_close = f.pf_close; + p_input->pf_end = f.pf_end; + p_input->pf_read = f.pf_read; + 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; + p_input->pf_delete_packet = f.pf_delete_packet; + p_input->pf_delete_pes = f.pf_delete_pes; + p_input->pf_rewind = f.pf_rewind; + p_input->pf_seek = f.pf_seek; +#undef f + + p_input->pf_open( p_input ); - /* Probe plugin (FIXME: load plugins before & write this) */ - p_input->p_plugin = PSKludge(); - p_input->p_plugin->pf_init( p_input ); + if( p_input->b_error ) + { + module_Unneed( p_main->p_bank, p_input->p_input_module ); + } + else + { + p_input->pf_init( p_input ); + } *p_input->pi_status = THREAD_READY; } @@ -314,10 +345,19 @@ static void EndThread( input_thread_t * p_input ) /* Free all ES and destroy all decoder threads */ input_EndStream( p_input ); + /* Close stream */ + p_input->pf_close( p_input ); + /* Free demultiplexer's data */ - p_input->p_plugin->pf_end( p_input ); - free( p_input->p_plugin ); + p_input->pf_end( p_input ); + /* Release modules */ + module_Unneed( p_main->p_bank, p_input->p_input_module ); + + /* 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 ); @@ -326,31 +366,16 @@ static void EndThread( input_thread_t * p_input ) } /***************************************************************************** - * NetworkOpen : open a network socket descriptor + * input_FileOpen : open a file descriptor *****************************************************************************/ -static void NetworkOpen( input_thread_t * p_input ) -{ - /* straight copy & paste of input_network.c of input-I */ - - /* We cannot rewind nor lseek() */ - p_input->stream.b_seekable = 0; - /* We cannot control the pace */ - p_input->stream.b_pace_control = 0; -} - -/***************************************************************************** - * FileOpen : open a file descriptor - *****************************************************************************/ -static void FileOpen( input_thread_t * p_input ) +void input_FileOpen( input_thread_t * p_input ) { struct stat stat_info; -#define p_config p_input->p_config - - if( stat( p_config->p_source, &stat_info ) == (-1) ) + if( stat( p_input->p_source, &stat_info ) == (-1) ) { - intf_ErrMsg( "input error: cannot stat() file %s (%s)", - p_config->p_source, strerror(errno)); + intf_ErrMsg( "input error: cannot stat() file `%s' (%s)", + p_input->p_source, strerror(errno)); p_input->b_error = 1; return; } @@ -374,8 +399,8 @@ static void FileOpen( input_thread_t * p_input ) else { vlc_mutex_unlock( &p_input->stream.stream_lock ); - intf_ErrMsg( "input error: unknown file type for %s", - p_config->p_source ); + intf_ErrMsg( "input error: unknown file type for `%s'", + p_input->p_source ); p_input->b_error = 1; return; } @@ -383,14 +408,24 @@ static void FileOpen( input_thread_t * p_input ) p_input->stream.i_tell = 0; vlc_mutex_unlock( &p_input->stream.stream_lock ); - intf_Msg( "Opening file %s", p_config->p_source ); - if( (p_input->i_handle = open( p_config->p_source, + intf_Msg( "input: opening file %s", p_input->p_source ); + if( (p_input->i_handle = open( p_input->p_source, /*O_NONBLOCK | O_LARGEFILE*/0 )) == (-1) ) { - intf_ErrMsg( "input error: cannot open file %s", strerror(errno) ); + intf_ErrMsg( "input error: cannot open file (%s)", strerror(errno) ); p_input->b_error = 1; return; } -#undef p_config } + +/***************************************************************************** + * input_FileClose : close a file descriptor + *****************************************************************************/ +void input_FileClose( input_thread_t * p_input ) +{ + close( p_input->i_handle ); + + return; +} +