* Collection of useful common types and macros definitions
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: common.h,v 1.27 2001/02/08 04:43:27 sam Exp $
+ * $Id: common.h,v 1.28 2001/02/08 07:24:25 sam Exp $
*
* Authors: Samuel Hocevar <sam@via.ecp.fr>
* Vincent Seguin <seguin@via.ecp.fr>
typedef struct plugin_bank_s * p_plugin_bank_t;
typedef struct plugin_info_s * p_plugin_info_t;
-/* Playlist */
+/* Plugins */
struct playlist_s;
+struct playlist_item_s;
typedef struct playlist_s * p_playlist_t;
+typedef struct playlist_item_s * p_playlist_item_t;
/* Interface */
struct intf_thread_s;
* control the pace of reading.
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: input_ext-intf.h,v 1.14 2001/02/08 04:43:27 sam Exp $
+ * $Id: input_ext-intf.h,v 1.15 2001/02/08 07:24:25 sam Exp $
*
* Authors:
*
/*****************************************************************************
* Prototypes
*****************************************************************************/
-struct input_thread_s * input_CreateThread( int *pi_status );
+struct input_thread_s * input_CreateThread ( struct playlist_item_s *,
+ int *pi_status );
void input_DestroyThread( struct input_thread_s *,
int *pi_status );
-void input_Play( struct input_thread_s * );
+void input_Play ( struct input_thread_s * );
void input_Forward( struct input_thread_s *, int );
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
- * Authors:
+ * Authors: Samuel Hocevar <sam@zoy.org>
*
* 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
/* Input plugin */
struct
{
- int ( * pf_init ) ( struct input_thread_s * );
- void ( * pf_open ) ( struct input_thread_s * );
- void ( * pf_close ) ( struct input_thread_s * );
+ void ( * pf_init ) ( struct input_thread_s * );
+ void ( * pf_open ) ( struct input_thread_s * );
+ void ( * pf_close )( struct input_thread_s * );
void ( * pf_end ) ( struct input_thread_s * );
- void ( * pf_read ) ( struct input_thread_s *,
+ int ( * pf_read ) ( struct input_thread_s *,
struct data_packet_s *
pp_packets[] );
void ( * pf_demux )( struct input_thread_s *,
struct data_packet_s * ( * pf_new_packet ) ( void *, size_t );
struct pes_packet_s * ( * pf_new_pes ) ( void * );
- void ( * pf_delete_packet ) ( struct data_packet_s * );
- void ( * pf_delete_pes ) ( struct pes_packet_s * );
+ void ( * pf_delete_packet ) ( void *, struct data_packet_s * );
+ void ( * pf_delete_pes ) ( void *, struct pes_packet_s * );
int ( * pf_rewind ) ( struct input_thread_s * );
int ( * pf_seek ) ( struct input_thread_s *, off_t );
* input_ps.c: PS demux and packet management
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: input_ps.c,v 1.1 2001/02/08 04:43:27 sam Exp $
+ * $Id: input_ps.c,v 1.2 2001/02/08 07:24:25 sam Exp $
*
* Authors:
*
case MPEG1_AUDIO_ES:
case MPEG2_AUDIO_ES:
- if( main_GetIntVariable( INPUT_DVD_AUDIO_VAR, 0 )
- == REQUESTED_MPEG
- && main_GetIntVariable( INPUT_DVD_CHANNEL_VAR, 0 )
+ if( main_GetIntVariable( INPUT_DVD_CHANNEL_VAR, 0 )
== (p_es->i_id & 0x1F) )
+ switch( main_GetIntVariable( INPUT_DVD_AUDIO_VAR, 0 ) )
{
+ case 0:
+ main_PutIntVariable( INPUT_DVD_CHANNEL_VAR,
+ REQUESTED_MPEG );
+ case REQUESTED_MPEG:
input_SelectES( p_input, p_es );
}
break;
case AC3_AUDIO_ES:
- if( main_GetIntVariable( INPUT_DVD_AUDIO_VAR, 0 )
- == REQUESTED_AC3
- && main_GetIntVariable( INPUT_DVD_CHANNEL_VAR, 0 )
+ if( main_GetIntVariable( INPUT_DVD_CHANNEL_VAR, 0 )
== ((p_es->i_id & 0xF00) >> 8) )
+ switch( main_GetIntVariable( INPUT_DVD_AUDIO_VAR, 0 ) )
{
+ case 0:
+ main_PutIntVariable( INPUT_DVD_CHANNEL_VAR,
+ REQUESTED_AC3 );
+ case REQUESTED_AC3:
input_SelectES( p_input, p_es );
}
break;
* decoders.
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: input.c,v 1.75 2001/02/08 04:43:27 sam Exp $
+ * $Id: input.c,v 1.76 2001/02/08 07:24:25 sam Exp $
*
* Authors:
*
* Local prototypes
*****************************************************************************/
static void RunThread ( input_thread_t *p_input );
-static void InitLoop ( input_thread_t *p_input );
-static void StopLoop ( 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 );
* 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 ( 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 */
/* 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;
{
msleep( THREAD_SLEEP );
} while( (i_status != THREAD_READY) && (i_status != THREAD_ERROR)
- && (i_status != THREAD_FATAL) && (i_status != THREAD_OVER) );
+ && (i_status != THREAD_FATAL) );
if( i_status != THREAD_READY )
{
return( NULL );
data_packet_t * pp_packets[INPUT_READ_ONCE];
int i_error, i;
- *p_input->pi_status = THREAD_READY;
+ 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 )
{
- InitLoop( p_input );
-
- if( p_input->b_die || p_input->b_error )
- {
- break;
- }
-
- while( !p_input->b_die && !p_input->b_error && !p_input->b_eof )
- {
#ifdef STATS
- p_input->c_loops++;
+ 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->pf_rewind != NULL )
- {
- p_input->pf_rewind( p_input );
- /* FIXME: probably don't do it every loop, but when ? */
- }
- vlc_mutex_unlock( &p_input->stream.control.control_lock );
+ vlc_mutex_lock( &p_input->stream.control.control_lock );
+ if( p_input->stream.control.i_status == BACKWARD_S
+ && p_input->pf_rewind != NULL )
+ {
+ p_input->pf_rewind( p_input );
+ /* FIXME: probably don't do it every loop, but when ? */
+ }
+ vlc_mutex_unlock( &p_input->stream.control.control_lock );
+
+ i_error = p_input->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->pf_demux( p_input, pp_packets[i] );
+ }
- /* Demultiplex read packets. */
- for( i = 0; i < INPUT_READ_ONCE && pp_packets[i] != NULL; i++ )
+ if( i_error )
+ {
+ if( i_error == 1 )
{
- p_input->pf_demux( p_input, pp_packets[i] );
+ /* 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" );
+ p_input->b_eof = 1;
}
-
- if( i_error )
+ else
{
- if( i_error == 1 )
- {
- /* End of file */
- 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;
}
}
-
- /* Free all ES and destroy all decoder threads */
- input_EndStream( p_input );
-
- StopLoop( p_input );
}
- if( p_input->b_error )
+ if( p_input->b_error || p_input->b_eof )
{
ErrorThread( p_input );
}
}
/*****************************************************************************
- * InitLoop: init the input loop
+ * InitThread: init the input Thread
*****************************************************************************/
-static void InitLoop( input_thread_t * p_input )
+static void InitThread( input_thread_t * p_input )
{
- playlist_Next( p_main->p_playlist );
-
- if( p_main->p_playlist->i_index == -1 )
- {
- /* FIXME: wait for user to add stuff to playlist ? */
- /* FIXME II: we shouldn't set b_error but rather b_die */
- intf_Msg( "playlist: end" );
- p_input->b_error = 1;
- return;
- }
-
- p_input->p_source = p_main->p_playlist->current.psz_name;
#ifdef STATS
/* Initialize statistics */
p_input->pf_seek = f.pf_seek;
#undef f
- p_input->b_eof = 0;
p_input->pf_open( p_input );
if( p_input->b_error )
{
module_Unneed( p_main->p_module_bank, p_input->p_input_module );
- return;
}
-
- p_input->pf_init( p_input );
-
- return;
-}
-
-/*****************************************************************************
- * StopLoop: stop the input loop
- *****************************************************************************/
-static void StopLoop( input_thread_t * p_input )
-{
-#ifdef STATS
+ else
{
- struct tms cpu_usage;
- times( &cpu_usage );
-
- intf_Msg("input stats: cpu usage (user: %d, system: %d)",
- cpu_usage.tms_utime, cpu_usage.tms_stime);
+ p_input->pf_init( p_input );
}
-#endif
- /* Free demultiplexer's data */
- p_input->pf_end( p_input );
-
- /* Release modules */
- module_Unneed( p_main->p_module_bank, p_input->p_input_module );
+ *p_input->pi_status = THREAD_READY;
}
/*****************************************************************************
pi_status = p_input->pi_status;
*pi_status = THREAD_END;
+#ifdef STATS
+ {
+ struct tms cpu_usage;
+ times( &cpu_usage );
+
+ intf_Msg("input stats: cpu usage (user: %d, system: %d)",
+ cpu_usage.tms_utime, cpu_usage.tms_stime);
+ }
+#endif
+
+ /* 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->pf_end( p_input );
+
+ /* Release modules */
+ module_Unneed( p_main->p_module_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 );
*****************************************************************************/
void input_Play( input_thread_t * p_input )
{
- intf_Msg( "Playing normally" );
+ intf_Msg( "input: playing at normal rate" );
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.i_new_status = PLAYING_S;
vlc_mutex_unlock( &p_input->stream.stream_lock );
*****************************************************************************/
void input_Forward( input_thread_t * p_input, int i_rate )
{
- if ( i_rate > 1000 )
- intf_Msg( "Forward enabled at 1/%d",i_rate/1000 );
+ if ( i_rate > DEFAULT_RATE )
+ {
+ intf_Msg( "input: playing at 1:%i slow motion", i_rate / 1000 );
+ }
+ else if( i_rate < DEFAULT_RATE )
+ {
+ intf_Msg( "input: playing at %i:1 fast forward", 1000 / i_rate );
+ }
else
- intf_Msg( "Forward enabled at %d/1",1000/i_rate );
+ {
+ /* Not very joli, but this is going to disappear soon anyway */
+ input_Play( p_input );
+ return;
+ }
+
vlc_mutex_lock( &p_input->stream.stream_lock );
p_input->stream.i_new_status = FORWARD_S;
p_input->stream.i_new_rate = i_rate;
vlc_mutex_unlock( &p_input->stream.stream_lock );
}
+
/* Flush messages before spawning input */
intf_FlushMsg();
- p_intf->p_input = input_CreateThread( NULL );
-
/* Main loop */
- while(!p_intf->b_die && (p_intf->p_input != NULL) )
+ while( !p_intf->b_die )
{
- /* Flush waiting messages */
- intf_FlushMsg();
-
- /* Manage specific interface */
- p_intf->p_sys_manage( p_intf );
+ /* Select the next playlist item */
+ playlist_Next( p_main->p_playlist );
- /* Manage module bank */
- module_ManageBank( p_main->p_module_bank );
-
- /* Check attached threads status */
- if( (p_intf->p_vout != NULL) && p_intf->p_vout->b_error )
+ if( p_main->p_playlist->i_index == -1 )
{
- /* FIXME: add aout error detection ?? */
+ /* FIXME: wait for user to add stuff to playlist ? */
p_intf->b_die = 1;
+ return;
}
- if( (p_intf->p_input != NULL) && p_intf->p_input->b_error )
+
+ p_intf->p_input =
+ input_CreateThread( &p_main->p_playlist->current, NULL );
+
+ /* Main loop */
+ while( !p_intf->b_die && (p_intf->p_input != NULL) )
{
- input_DestroyThread( p_intf->p_input, NULL );
- p_intf->p_input = NULL;
- intf_DbgMsg("Input thread destroyed");
- }
+ /* Flush waiting messages */
+ intf_FlushMsg();
+
+ /* Manage specific interface */
+ p_intf->p_sys_manage( p_intf );
+
+ /* Manage module bank */
+ module_ManageBank( p_main->p_module_bank );
- /* Sleep to avoid using all CPU - since some interfaces needs to access
- * keyboard events, a 100ms delay is a good compromise */
- msleep( INTF_IDLE_SLEEP );
+ /* Check attached threads status */
+ if( (p_intf->p_vout != NULL) && p_intf->p_vout->b_error )
+ {
+ /* FIXME: add aout error detection ?? */
+ p_intf->b_die = 1;
+ }
+
+ if( ( p_intf->p_input != NULL ) &&
+ ( p_intf->p_input->b_error || p_intf->p_input->b_eof ) )
+ {
+ input_DestroyThread( p_intf->p_input, NULL );
+ p_intf->p_input = NULL;
+ intf_DbgMsg("Input thread destroyed");
+ }
+
+ /* Sleep to avoid using all CPU - since some interfaces needs
+ * to access keyboard events, a 100ms delay is a good compromise */
+ msleep( INTF_IDLE_SLEEP );
+ }
}
}
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
*
- * Authors:
+ * Authors: Samuel Hocevar <sam@zoy.org>
*
* 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
p_playlist = malloc( sizeof( playlist_t ) );
if( !p_playlist )
{
- intf_ErrMsg("playlist error: %s", strerror( ENOMEM ) );
+ intf_ErrMsg( "intf error: couldn't create playlist (%s)",
+ strerror( ENOMEM ) );
return( NULL );
}
/* The playlist is empty */
p_playlist->p_item = NULL;
- intf_Msg("playlist: playlist created");
+ intf_Msg("intf: playlist initialized");
}
int playlist_Add( playlist_t * p_playlist, int i_pos, char * psz_item )
}
else if( i_pos > p_playlist->i_size )
{
- intf_ErrMsg( "playlist error: inserting item beyond playlist size" );
+ intf_ErrMsg( "intf error: inserting item beyond playlist size" );
vlc_mutex_unlock( &p_playlist->change_lock );
return( -1 );
}
p_item->i_status = 0;
p_item->psz_name = strdup( psz_item );
- intf_Msg( "playlist: added %s", psz_item );
+ intf_WarnMsg( 1, "intf: added %s to playlist", psz_item );
vlc_mutex_unlock( &p_playlist->change_lock );
if( !p_playlist->i_size || i_pos >= p_playlist->i_size )
{
- intf_ErrMsg( "playlist error: deleting item beyond playlist size" );
+ intf_ErrMsg( "intf error: deleting item beyond playlist size" );
vlc_mutex_unlock( &p_playlist->change_lock );
return( -1 );
}
p_playlist->p_item = realloc( p_playlist->p_item,
p_playlist->i_size * sizeof( playlist_item_t ) );
- intf_Msg( "playlist: removed %s", psz_name );
+ intf_WarnMsg( 1, "intf: removed %s from playlist", psz_name );
/* Delete the item */
free( psz_name );
free( p_playlist );
- intf_Msg("playlist: playlist destroyed");
+ intf_Msg("intf: playlist destroyed");
}
static void NextItem( playlist_t * p_playlist )
}
p_bank->i_plugin_count = MAX_PLUGIN_COUNT;
- intf_Msg("plugin: bank initialized");
return( p_bank );
}
/* Dummy plugin */
SEEK_PLUGIN( "dummy" );
-
#undef SEEK_PLUGIN
+
+ intf_Msg("plugin: plugin bank initialized \e[41;9;1m[OBSOLETE]\e[m");
}
void bank_Destroy( plugin_bank_t * p_bank )