* Read an MPEG2 stream, demultiplex and parse it before sending it to
* decoders.
*****************************************************************************
- * Copyright (C) 1998-2001 VideoLAN
- * $Id: input.c,v 1.206 2002/07/21 18:57:02 sigmunau Exp $
+ * Copyright (C) 1998-2002 VideoLAN
+ * $Id: input.c,v 1.215 2002/11/11 14:39:12 sam Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
* Preamble
*****************************************************************************/
#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
#include <vlc/vlc.h>
#include <string.h>
-#include <errno.h>
#ifdef HAVE_SYS_TIMES_H
# include <sys/times.h>
#include "input_ext-dec.h"
#include "input_ext-plugins.h"
+#include "stream_output.h"
+
#include "interface.h"
/*****************************************************************************
static int RunThread ( input_thread_t *p_input );
static int InitThread ( input_thread_t *p_input );
static void ErrorThread ( input_thread_t *p_input );
-static void CloseThread ( input_thread_t *p_input );
static void EndThread ( input_thread_t *p_input );
/*****************************************************************************
p_input->psz_source = strdup( p_item->psz_name );
/* Demux */
- p_input->p_demux_module = NULL;
- p_input->pf_init = NULL;
- p_input->pf_end = NULL;
- p_input->pf_demux = NULL;
- p_input->pf_rewind = NULL;
+ p_input->p_demux = NULL;
/* Access */
- p_input->p_access_module = NULL;
- p_input->pf_open = NULL;
- p_input->pf_close = NULL;
- p_input->pf_read = NULL;
- p_input->pf_seek = NULL;
- p_input->pf_set_area = NULL;
- p_input->pf_set_program = NULL;
+ p_input->p_access = NULL;
p_input->i_bufsize = 0;
p_input->i_mtu = 0;
p_input->stream.b_new_mute = MUTE_NO_CHANGE;
p_input->stream.i_mux_rate = 0;
p_input->stream.b_seekable = 0;
+ p_input->stream.p_sout = NULL;
/* no stream, no program, no area, no es */
p_input->stream.p_new_program = NULL;
p_input->stream.control.i_rate = DEFAULT_RATE;
p_input->stream.control.b_mute = 0;
p_input->stream.control.b_grayscale = config_GetInt( p_input, "grayscale" );
- p_input->stream.control.i_smp = config_GetInt( p_input, "vdec-smp" );
/* Initialize input info */
p_input->stream.p_info = malloc( sizeof( input_info_category_t ) );
p_input->stream.p_info->p_info = NULL;
p_input->stream.p_info->p_next = NULL;
- /* test code */
- msg_Dbg( p_input, "finding category \"hepp\"");
- p_info = input_InfoCategory( p_input, "hepp" );
- msg_Dbg( p_input, "adding testkey/testval");
- input_AddInfo( p_info, "testkey", "testval");
- /* end test code */
-
msg_Info( p_input, "playlist item `%s'", p_input->psz_source );
- p_info = input_InfoCategory( p_input, "General");
- input_AddInfo( p_info, "Playlist item", p_input->psz_source );
+ p_info = input_InfoCategory( p_input, "General" );
+ input_AddInfo( p_info, "playlist item", p_input->psz_source );
vlc_object_attach( p_input, p_parent );
/* Create thread and wait for its readiness. */
- if( vlc_thread_create( p_input, "input", RunThread, VLC_TRUE ) )
+ if( vlc_thread_create( p_input, "input", RunThread,
+ VLC_THREAD_PRIORITY_INPUT, VLC_TRUE ) )
{
- msg_Err( p_input, "cannot create input thread (%s)", strerror(errno) );
+ msg_Err( p_input, "cannot create input thread" );
free( p_input );
return NULL;
}
input_AccessReinit( p_input );
p_input->pf_set_program( p_input,
- p_input->stream.p_new_program );
+ p_input->stream.p_new_program );
/* Escape all decoders for the stream discontinuity they
* will encounter. */
if( p_input->stream.p_selected_area->i_seek != NO_SEEK )
{
- if( p_input->stream.b_seekable && p_input->pf_seek != NULL )
+ if( p_input->stream.b_seekable
+ && p_input->pf_seek != NULL )
{
off_t i_new_pos;
if( i_count == 0 && p_input->stream.b_seekable )
{
/* End of file - we do not set b_die because only the
- * interface is allowed to do so. */
+ * playlist is allowed to do so. */
msg_Info( p_input, "EOF reached" );
p_input->b_eof = 1;
}
{
psz_parser++;
}
-#ifdef WIN32
+#if defined( WIN32 ) || defined( UNDER_CE )
if( psz_parser - p_input->psz_source == 1 )
{
msg_Warn( p_input, "drive letter %c: found in source string",
- p_input->psz_source ) ;
+ p_input->psz_source[0] ) ;
psz_parser = "";
}
#endif
}
/* Find and open appropriate access module */
- p_input->p_access_module =
- module_Need( p_input, MODULE_CAPABILITY_ACCESS,
- p_input->psz_access, (void *)p_input );
+ p_input->p_access = module_Need( p_input, "access",
+ p_input->psz_access );
- if( p_input->p_access_module == NULL )
+ if( p_input->p_access == NULL )
{
msg_Err( p_input, "no suitable access module for `%s/%s://%s'",
p_input->psz_access, p_input->psz_demux, p_input->psz_name );
return -1;
}
-#define f p_input->p_access_module->p_functions->access.functions.access
- p_input->pf_open = f.pf_open;
- p_input->pf_close = f.pf_close;
- 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_seek = f.pf_seek;
-#undef f
-
/* Waiting for stream. */
if( p_input->i_mtu )
{
{
if( p_input->b_die || p_input->b_error || p_input->b_eof )
{
- module_Unneed( p_input->p_access_module );
+ module_Unneed( p_input, p_input->p_access );
return -1;
}
}
}
/* Find and open appropriate demux module */
- p_input->p_demux_module =
- module_Need( p_input, MODULE_CAPABILITY_DEMUX,
- p_input->psz_demux, (void *)p_input );
+ p_input->p_demux = module_Need( p_input, "demux",
+ p_input->psz_demux );
- if( p_input->p_demux_module == NULL )
+ if( p_input->p_demux== NULL )
{
msg_Err( p_input, "no suitable demux module for `%s/%s://%s'",
p_input->psz_access, p_input->psz_demux, p_input->psz_name );
- module_Unneed( p_input->p_access_module );
+ module_Unneed( p_input, p_input->p_access );
return -1;
}
-#define f p_input->p_demux_module->p_functions->demux.functions.demux
- p_input->pf_init = f.pf_init;
- p_input->pf_end = f.pf_end;
- p_input->pf_demux = f.pf_demux;
- p_input->pf_rewind = f.pf_rewind;
-#undef f
+ /* Initialize optional stream output. */
+ psz_parser = config_GetPsz( p_input, "sout" );
+ if ( psz_parser != NULL )
+ {
+ if ( *psz_parser &&
+ (p_input->stream.p_sout = sout_NewInstance( p_input, psz_parser ))
+ == NULL )
+ {
+ msg_Err( p_input, "cannot start stream output instance, aborting" );
+ free( psz_parser );
+ module_Unneed( p_input, p_input->p_access );
+ module_Unneed( p_input, p_input->p_demux );
+ return -1;
+ }
+
+ free( psz_parser );
+ }
return 0;
}
input_DumpStream( p_input );
- /* Tell we're dead */
- p_input->b_dead = 1;
-
/* Free all ES and destroy all decoder threads */
input_EndStream( p_input );
+ /* Close optional stream output instance */
+ if ( p_input->stream.p_sout != NULL )
+ {
+ sout_DeleteInstance( p_input->stream.p_sout );
+ }
+
/* Free demultiplexer's data */
- p_input->pf_end( p_input );
- module_Unneed( p_input->p_demux_module );
-
- /* Close the access plug-in */
- CloseThread( p_input );
-}
+ module_Unneed( p_input, p_input->p_demux );
-/*****************************************************************************
- * CloseThread: close the target
- *****************************************************************************/
-static void CloseThread( input_thread_t * p_input )
-{
- p_input->pf_close( p_input );
- module_Unneed( p_input->p_access_module );
+ /* Close the access plug-in */
+ module_Unneed( p_input, p_input->p_access );
input_AccessEnd( p_input );
free( p_input->psz_source );
+
+ /* Tell we're dead */
+ p_input->b_dead = 1;
}