1 /*****************************************************************************
2 * main.c: main vlc source
3 * Includes the main() function for vlc. Parses command line, start interface
5 *****************************************************************************
6 * Copyright (C) 1998-2001 VideoLAN
7 * $Id: main.c,v 1.160 2002/03/04 23:56:38 massiot Exp $
9 * Authors: Vincent Seguin <seguin@via.ecp.fr>
10 * Samuel Hocevar <sam@zoy.org>
11 * Gildas Bazin <gbazin@netcourrier.com>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
26 *****************************************************************************/
28 /*****************************************************************************
30 *****************************************************************************/
31 #include <signal.h> /* SIGHUP, SIGINT, SIGKILL */
32 #include <stdio.h> /* sprintf() */
33 #include <setjmp.h> /* longjmp, setjmp */
35 #include <videolan/vlc.h>
37 #ifdef HAVE_GETOPT_LONG
39 # include <getopt.h> /* getopt() */
42 # include "GNUgetopt/getopt.h"
46 # include <mach/mach.h> /* Altivec detection */
47 # include <mach/mach_error.h> /* some day the header files||compiler *
48 will define it for us */
49 # include <mach/bootstrap.h>
53 # include <netinet/in.h> /* BSD: struct in_addr */
58 #elif defined( _MSC_VER ) && defined( _WIN32 )
66 #include <errno.h> /* ENOMEM */
67 #include <stdlib.h> /* getenv(), strtol(), */
68 #include <string.h> /* strerror() */
69 #include <fcntl.h> /* open(), O_WRONLY */
70 #include <sys/stat.h> /* S_IREAD */
72 #include "netutils.h" /* network_ChannelJoin */
74 #include "stream_control.h"
75 #include "input_ext-intf.h"
77 #include "intf_playlist.h"
78 #include "interface.h"
80 #include "audio_output.h"
83 #include "video_output.h"
87 /*****************************************************************************
88 * Configuration options for the main program. Each plugin will also separatly
89 * define its own configuration options.
90 * Look into configuration.h if you need to know more about the following
93 *****************************************************************************/
95 #define MODULE_NAME main
96 #include "modules_inner.h" /* for configuration stuff */
101 ADD_CATEGORY_HINT( text, longtext )
102 ADD_SUBCATEGORY_HINT( text, longtext )
103 ADD_STRING( option_name, value, p_callback, text, longtext )
104 ADD_FILE( option_name, psz_value, p_callback, text, longtext )
105 ADD_PLUGIN( option_name, psz_value, i_capability, p_callback, text, longtext )
106 ADD_INTEGER( option_name, i_value, p_callback, text, longtext )
107 ADD_BOOL( option_name, p_callback, text, longtext )
113 ADD_CATEGORY_HINT( "Help Options", NULL )
114 ADD_BOOL ( "help", NULL,"print help and exit (or use -h)", NULL )
115 ADD_BOOL ( "longhelp", NULL, "print long help version and exit (or use -H)",
117 ADD_BOOL ( "list", NULL, "list available plugins (or use -l)", NULL )
118 ADD_STRING ( "pluginhelp", NULL, NULL,"print help on a plugin and exit",NULL )
119 ADD_BOOL ( "version", NULL, "output version information and exit", NULL )
121 /* Interface options */
122 ADD_CATEGORY_HINT( "Interface Options", NULL)
123 ADD_PLUGIN ( INTF_METHOD_VAR, MODULE_CAPABILITY_INTF, NULL, NULL,
124 "interface method", NULL )
125 ADD_INTEGER ( INTF_WARNING_VAR, 0, NULL, "warning level (or use -v)", NULL )
126 ADD_BOOL ( INTF_STATS_VAR, NULL, "output statistics", NULL )
127 ADD_STRING ( INTF_PATH_VAR, NULL, NULL, "interface default search path", NULL)
130 ADD_CATEGORY_HINT( "Audio Options", NULL)
131 ADD_BOOL ( AOUT_NOAUDIO_VAR, NULL, "disable audio", NULL )
132 ADD_PLUGIN ( AOUT_METHOD_VAR, MODULE_CAPABILITY_AOUT, NULL, NULL,
133 "audio output method", NULL )
134 ADD_BOOL ( AOUT_MONO_VAR, NULL, "mono audio", NULL )
135 ADD_INTEGER ( AOUT_VOLUME_VAR, VOLUME_DEFAULT, NULL, "VLC output volume", NULL)
136 ADD_INTEGER ( AOUT_RATE_VAR, 44100, NULL, "VLC output frequency", NULL )
137 ADD_INTEGER ( AOUT_DESYNC_VAR, 0, NULL, "Compensate desynchronization of the "
138 "audio (in ms)", NULL )
141 ADD_CATEGORY_HINT( "Video Options", NULL )
142 ADD_BOOL ( VOUT_NOVIDEO_VAR, NULL, "disable video", NULL )
143 ADD_PLUGIN ( VOUT_METHOD_VAR, MODULE_CAPABILITY_VOUT, NULL, NULL,
144 "video output method", NULL )
145 ADD_STRING ( VOUT_DISPLAY_VAR, NULL, NULL, "display string", NULL )
146 ADD_INTEGER ( VOUT_WIDTH_VAR, 720, NULL, "display width", NULL )
147 ADD_INTEGER ( VOUT_HEIGHT_VAR, 576, NULL, "display height", NULL )
148 ADD_BOOL ( VOUT_GRAYSCALE_VAR, NULL, "grayscale output", NULL )
149 ADD_BOOL ( VOUT_FULLSCREEN_VAR, NULL, "fullscreen output", NULL )
150 ADD_BOOL ( VOUT_NOOVERLAY_VAR, NULL, "disable accelerated display", NULL )
151 ADD_PLUGIN ( VOUT_FILTER_VAR, MODULE_CAPABILITY_VOUT, NULL, NULL,
152 "video filter module", NULL )
153 ADD_INTEGER ( VOUT_SPUMARGIN_VAR, -1, NULL, "force SPU position", NULL )
156 ADD_CATEGORY_HINT( "Input Options", NULL )
157 ADD_STRING ( INPUT_METHOD_VAR, NULL, NULL, "input method", NULL )
158 ADD_INTEGER ( INPUT_PORT_VAR, 1234, NULL, "server port", NULL )
159 ADD_BOOL ( INPUT_NETWORK_CHANNEL_VAR, NULL, "enable network channel mode",
161 ADD_STRING ( INPUT_CHANNEL_SERVER_VAR, "localhost", NULL,
162 "channel server address", NULL )
163 ADD_INTEGER ( INPUT_CHANNEL_PORT_VAR, 6010, NULL, "channel server port", NULL )
164 ADD_STRING ( INPUT_IFACE_VAR, "eth0", NULL, "network interface", NULL )
166 ADD_INTEGER ( INPUT_AUDIO_VAR, -1, NULL, "choose audio", NULL )
167 ADD_INTEGER ( INPUT_CHANNEL_VAR, -1, NULL, "choose channel", NULL )
168 ADD_INTEGER ( INPUT_SUBTITLE_VAR, -1, NULL, "choose subtitles", NULL )
170 ADD_STRING ( INPUT_DVD_DEVICE_VAR, "/dev/dvd", NULL, "DVD device", NULL )
171 ADD_STRING ( INPUT_VCD_DEVICE_VAR, "/dev/cdrom", NULL, "VCD device", NULL )
172 ADD_BOOL ( INPUT_IPV6_VAR, NULL, "force IPv6", NULL )
173 ADD_BOOL ( INPUT_IPV4_VAR, NULL, "force IPv4", NULL )
175 /* Decoder options */
176 ADD_CATEGORY_HINT( "Decoders Options", NULL )
177 ADD_PLUGIN ( ADEC_MPEG_VAR, MODULE_CAPABILITY_DECODER, NULL, NULL,
178 "choose MPEG audio decoder", NULL )
179 ADD_PLUGIN ( ADEC_AC3_VAR, MODULE_CAPABILITY_DECODER, NULL, NULL,
180 "choose AC3 audio decoder", NULL )
181 ADD_INTEGER ( VDEC_SMP_VAR, 0, NULL, "use additional processors", NULL )
182 ADD_STRING ( VPAR_SYNCHRO_VAR, NULL, NULL, "force synchro algorithm "
183 "{I|I+|IP|IP+|IPB}", NULL )
186 ADD_CATEGORY_HINT( "CPU Options Options", NULL )
187 ADD_BOOL ( NOMMX_VAR, NULL, "disable CPU's MMX support", NULL )
188 ADD_BOOL ( NO3DN_VAR, NULL, "disable CPU's 3D Now! support", NULL )
189 ADD_BOOL ( NOMMXEXT_VAR, NULL, "disable CPU's MMX EXT support", NULL )
190 ADD_BOOL ( NOSSE_VAR, NULL, "disable CPU's SSE support", NULL )
191 ADD_BOOL ( NOALTIVEC_VAR, NULL, "disable CPU's AltiVec support", NULL )
193 /* Playlist options */
194 ADD_BOOL ( PLAYLIST_STARTUP_VAR, NULL, "launch playlist on startup", NULL )
195 ADD_BOOL ( PLAYLIST_ENQUEUE_VAR, NULL, "enqueue playlist as default", NULL )
196 ADD_BOOL ( PLAYLIST_LOOP_VAR, NULL, "loop on playlist end", NULL )
199 ADD_CATEGORY_HINT( "Miscellaneous Options", NULL )
200 ADD_PLUGIN ( MEMCPY_METHOD_VAR, MODULE_CAPABILITY_MEMCPY, NULL, NULL,
201 "memory copy method", NULL )
206 SET_DESCRIPTION( "Main program" )
207 ADD_CAPABILITY( MAIN, 100/*whatever*/ )
210 MODULE_ACTIVATE_START
213 MODULE_DEACTIVATE_START
214 MODULE_DEACTIVATE_STOP
215 /*****************************************************************************
217 *****************************************************************************/
219 /*****************************************************************************
220 * Global variables - these are the only ones, see main.h and modules.h
221 *****************************************************************************/
223 module_bank_t *p_module_bank;
224 input_bank_t *p_input_bank;
225 aout_bank_t *p_aout_bank;
226 vout_bank_t *p_vout_bank;
228 /*****************************************************************************
230 *****************************************************************************/
231 static int GetConfigurationFromFile ( void ){return 0;};
232 static int GetConfigurationFromCmdLine ( int *pi_argc, char *ppsz_argv[],
233 boolean_t b_ignore_errors );
234 static int GetFilenames ( int i_argc, char *ppsz_argv[] );
235 static void Usage ( const char *psz_module_name );
236 static void ListModules ( void );
237 static void Version ( void );
239 static void InitSignalHandler ( void );
240 static void SimpleSignalHandler ( int i_signal );
241 static void FatalSignalHandler ( int i_signal );
242 static void IllegalSignalHandler ( int i_signal );
243 static u32 CPUCapabilities ( void );
246 static void ShowConsole ( void );
250 static int i_illegal;
251 static char *psz_capability;
253 /*****************************************************************************
254 * main: parse command line, start interface and spawn threads
255 *****************************************************************************
256 * Steps during program execution are:
257 * -configuration parsing and messages interface initialization
258 * -opening of audio output device and some global modules
259 * -execution of interface, which exit on error or on user request
260 * -closing of audio output device and some global modules
261 * On error, the spawned threads are canceled, and the open devices closed.
262 *****************************************************************************/
263 int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
265 main_t main_data; /* root of all data - see main.h */
266 module_bank_t module_bank;
267 input_bank_t input_bank;
268 aout_bank_t aout_bank;
269 vout_bank_t vout_bank;
272 p_main = &main_data; /* set up the global variables */
273 p_module_bank = &module_bank;
274 p_input_bank = &input_bank;
275 p_aout_bank = &aout_bank;
276 p_vout_bank = &vout_bank;
278 p_main->i_warning_level = 0;
280 #if defined( ENABLE_NLS ) && defined ( HAVE_GETTEXT )
284 #if defined( HAVE_LOCALE_H ) && defined( HAVE_LC_MESSAGES )
285 if( !setlocale( LC_MESSAGES, "" ) )
287 fprintf( stderr, "warning: unsupported locale.\n" );
291 if( !bindtextdomain( PACKAGE, LOCALEDIR ) )
293 fprintf( stderr, "warning: no domain %s in directory %s\n",
294 PACKAGE, LOCALEDIR );
297 textdomain( PACKAGE );
301 * Initialize threads system
306 * Test if our code is likely to run on this CPU
308 p_main->i_cpu_capabilities = CPUCapabilities();
311 * System specific initialization code
313 #if defined( SYS_BEOS ) || defined( SYS_DARWIN ) || defined( WIN32 )
314 system_Init( &i_argc, ppsz_argv, ppsz_env );
316 #elif defined( SYS_LINUX )
318 /* Activate malloc checking routines to detect heap corruptions. */
319 putenv( "MALLOC_CHECK_=2" );
324 * Initialize messages interface
328 intf_Msg( COPYRIGHT_MESSAGE "\n" );
331 /* Get the executable name (similar to the basename command) */
332 p_main->psz_arg0 = p_tmp = ppsz_argv[ 0 ];
335 if( *p_tmp == '/' ) p_main->psz_arg0 = ++p_tmp;
340 * Initialize the module bank and and load the configuration of the main
341 * module. We need to do this at this stage to be able to display a short
342 * help if required by the user. (short help == main module options)
347 if( GetConfigurationFromCmdLine( &i_argc, ppsz_argv, 1 ) )
353 /* Check for short help option */
354 if( config_GetIntVariable( "help" ) )
360 /* Check for version option */
361 if( config_GetIntVariable( "version" ) )
368 * Load the builtins and plugins into the module_bank.
369 * We have to do it before GetConfiguration() because this also gets the
370 * list of configuration options exported by each plugin and loads their
373 module_LoadBuiltins();
374 module_LoadPlugins();
375 intf_WarnMsg( 2, "module: module bank initialized, found %i modules",
376 p_module_bank->i_count );
378 /* Check for help on plugins */
379 if( (p_tmp = config_GetPszVariable( "pluginhelp" )) )
386 /* Check for long help option */
387 if( config_GetIntVariable( "longhelp" ) )
393 /* Check for plugin list option */
394 if( config_GetIntVariable( "list" ) )
401 * Override default configuration with config file settings
403 if( GetConfigurationFromFile() )
410 * Override configuration with command line settings
412 if( GetConfigurationFromCmdLine( &i_argc, ppsz_argv, 0 ) )
418 /* p_main inititalization. FIXME ? */
419 p_main->i_desync = (mtime_t)config_GetIntVariable( AOUT_DESYNC_VAR )
421 p_main->b_stats = config_GetIntVariable( INTF_STATS_VAR );
422 p_main->b_audio = !config_GetIntVariable( AOUT_NOAUDIO_VAR );
423 p_main->b_stereo= !config_GetIntVariable( AOUT_MONO_VAR );
424 p_main->b_video = !config_GetIntVariable( VOUT_NOVIDEO_VAR );
425 if( config_GetIntVariable( NOMMX_VAR ) )
426 p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_MMX;
427 if( config_GetIntVariable( NO3DN_VAR ) )
428 p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_3DNOW;
429 if( config_GetIntVariable( NOMMXEXT_VAR ) )
430 p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_MMXEXT;
431 if( config_GetIntVariable( NOSSE_VAR ) )
432 p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_SSE;
433 if( config_GetIntVariable( NOALTIVEC_VAR ) )
434 p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_ALTIVEC;
437 if( p_main->b_stats )
439 char p_capabilities[200];
440 p_capabilities[0] = '\0';
442 #define PRINT_CAPABILITY( capability, string ) \
443 if( p_main->i_cpu_capabilities & capability ) \
445 strncat( p_capabilities, string " ", \
446 sizeof(p_capabilities) - strlen(p_capabilities) ); \
447 p_capabilities[sizeof(p_capabilities) - 1] = '\0'; \
450 PRINT_CAPABILITY( CPU_CAPABILITY_486, "486" );
451 PRINT_CAPABILITY( CPU_CAPABILITY_586, "586" );
452 PRINT_CAPABILITY( CPU_CAPABILITY_PPRO, "Pentium Pro" );
453 PRINT_CAPABILITY( CPU_CAPABILITY_MMX, "MMX" );
454 PRINT_CAPABILITY( CPU_CAPABILITY_3DNOW, "3DNow!" );
455 PRINT_CAPABILITY( CPU_CAPABILITY_MMXEXT, "MMXEXT" );
456 PRINT_CAPABILITY( CPU_CAPABILITY_SSE, "SSE" );
457 PRINT_CAPABILITY( CPU_CAPABILITY_ALTIVEC, "Altivec" );
458 PRINT_CAPABILITY( CPU_CAPABILITY_FPU, "FPU" );
459 intf_StatMsg( "info: CPU has capabilities : %s", p_capabilities );
463 * Initialize playlist and get commandline files
465 p_main->p_playlist = intf_PlaylistCreate();
466 if( !p_main->p_playlist )
468 intf_ErrMsg( "playlist error: playlist initialization failed" );
472 intf_PlaylistInit( p_main->p_playlist );
475 * Get input filenames given as commandline arguments
477 GetFilenames( i_argc, ppsz_argv );
480 * Initialize input, aout and vout banks
487 * Choose the best memcpy module
489 p_main->p_memcpy_module = module_Need( MODULE_CAPABILITY_MEMCPY, NULL,
491 if( p_main->p_memcpy_module == NULL )
493 intf_ErrMsg( "intf error: no suitable memcpy module, "
494 "using libc default" );
495 p_main->pf_memcpy = memcpy;
499 p_main->pf_memcpy = p_main->p_memcpy_module->p_functions
500 ->memcpy.functions.memcpy.pf_memcpy;
504 * Initialize shared resources and libraries
506 if( config_GetIntVariable( INPUT_NETWORK_CHANNEL_VAR ) &&
507 network_ChannelCreate() )
509 /* On error during Channels initialization, switch off channels */
510 intf_ErrMsg( "intf error: channels initialization failed, "
511 "deactivating channels" );
512 config_PutIntVariable( INPUT_NETWORK_CHANNEL_VAR, 0 );
516 * Try to run the interface
518 p_main->p_intf = intf_Create();
519 if( p_main->p_intf == NULL )
521 intf_ErrMsg( "intf error: interface initialization failed" );
526 * Set signal handling policy for all threads
531 * This is the main loop
533 p_main->p_intf->pf_run( p_main->p_intf );
536 * Finished, destroy the interface
538 intf_Destroy( p_main->p_intf );
541 * Go back into channel 0 which is the network
543 if( config_GetIntVariable( INPUT_NETWORK_CHANNEL_VAR ) )
545 network_ChannelJoin( COMMON_CHANNEL );
550 * Free input, aout and vout banks
559 intf_PlaylistDestroy( p_main->p_playlist );
562 * Free memcpy module if it was allocated
564 if( p_main->p_memcpy_module != NULL )
566 module_Unneed( p_main->p_memcpy_module );
575 * System specific cleaning code
577 #if defined( SYS_BEOS ) || defined( SYS_DARWIN ) || defined( WIN32 )
583 * Terminate messages interface and program
585 intf_WarnMsg( 1, "intf: program terminated" );
589 * Stop threads system
597 /* following functions are local */
599 /*****************************************************************************
600 * GetConfigurationFromCmdLine: parse command line
601 *****************************************************************************
602 * Parse command line for configuration. If the inline help is requested, the
603 * function Usage() is called and the function returns -1 (causing main() to
605 * Now that the module_bank has been initialized, we can dynamically
606 * generate the longopts structure used by getops. We have to do it this way
607 * because we don't know (and don't want to know) in advance the configuration
608 * options used (ie. exported) by each module.
609 *****************************************************************************/
610 static int GetConfigurationFromCmdLine( int *pi_argc, char *ppsz_argv[],
611 boolean_t b_ignore_errors )
613 int i_cmd, i, i_index, i_longopts_size;
615 struct option *p_longopts;
618 const char *psz_shortopts = "hHvl";
621 /* Set default configuration and copy arguments */
622 p_main->i_argc = *pi_argc;
623 p_main->ppsz_argv = ppsz_argv;
625 p_main->p_channel = NULL;
628 /* When vlc.app is run by double clicking in Mac OS X, the 2nd arg
629 * is the PSN - process serial number (a unique PID-ish thingie)
630 * still ok for real Darwin & when run from command line */
631 if ( (*pi_argc > 1) && (strncmp( ppsz_argv[ 1 ] , "-psn" , 4 ) == 0) )
632 /* for example -psn_0_9306113 */
634 /* GDMF!... I can't do this or else the MacOSX window server will
635 * not pick up the PSN and not register the app and we crash...
636 * hence the following kludge otherwise we'll get confused w/ argv[1]
637 * being an input file name */
639 ppsz_argv[ 1 ] = NULL;
641 *pi_argc = *pi_argc - 1;
649 * Generate the longopts structure used by getopt_long
652 for( p_module = p_module_bank->first ;
654 p_module = p_module->next )
656 /* count the number of exported configuration options (to allocate
657 * longopts). The i_config_options we use is an approximation of the
658 * real number of options (it also includes markers like: category ...)
659 * but it is enough for our purpose */
660 i_longopts_size += p_module->i_config_options -1;
663 p_longopts = (struct option *)malloc( sizeof(struct option)
664 * (i_longopts_size + 1) );
665 if( p_longopts == NULL )
667 intf_ErrMsg( "GetConfigurationFromCmdLine error: "
668 "can't allocate p_longopts" );
672 /* Fill the longopts structure */
674 for( p_module = p_module_bank->first ;
676 p_module = p_module->next )
678 for( i = 1; i < (p_module->i_config_options -1); i++ )
680 if( (p_module->p_config[i].i_type == MODULE_CONFIG_ITEM_CATEGORY)||
681 (p_module->p_config[i].i_type ==
682 MODULE_CONFIG_ITEM_SUBCATEGORY)||
683 (p_module->p_config[i].i_type ==
684 MODULE_CONFIG_ITEM_SUBCATEGORY_END) )
686 p_longopts[i_index].name = p_module->p_config[i].psz_name;
687 p_longopts[i_index].has_arg =
688 (p_module->p_config[i].i_type == MODULE_CONFIG_ITEM_BOOL)?
689 no_argument : required_argument;
690 p_longopts[i_index].flag = 0;
691 p_longopts[i_index].val = 0;
695 /* Close the longopts structure */
696 memset( &p_longopts[i_index], 0, sizeof(struct option) );
700 * Parse the command line options
704 while( ( i_cmd = getopt_long( *pi_argc, ppsz_argv, psz_shortopts,
705 p_longopts, &i_index ) ) != EOF )
710 /* A long option has been recognized */
712 module_config_t *p_conf;
714 /* Store the configuration option */
715 p_conf = config_FindConfig( p_longopts[i_index].name );
717 switch( p_conf->i_type )
719 case MODULE_CONFIG_ITEM_STRING:
720 case MODULE_CONFIG_ITEM_FILE:
721 case MODULE_CONFIG_ITEM_PLUGIN:
722 config_PutPszVariable( p_longopts[i_index].name, optarg );
724 case MODULE_CONFIG_ITEM_INTEGER:
725 config_PutIntVariable( p_longopts[i_index].name, atoi(optarg));
727 case MODULE_CONFIG_ITEM_BOOL:
728 config_PutIntVariable( p_longopts[i_index].name, 1 );
735 /* short options handled here for now */
739 /* General/common options */
740 case 'h': /* -h, --help */
741 config_PutIntVariable( "help", 1 );
743 case 'H': /* -H, --longhelp */
744 config_PutIntVariable( "longhelp", 1 );
746 case 'l': /* -l, --list */
747 config_PutIntVariable( "list", 1 );
749 case 'v': /* -v, --verbose */
750 p_main->i_warning_level++;
753 /* Internal error: unknown option */
756 if( !b_ignore_errors )
758 intf_ErrMsg( "intf error: unknown option `%s'",
760 intf_Msg( "Try `%s --help' for more information.\n",
763 #ifdef WIN32 /* Pause the console because it's destroyed when we exit */
764 intf_Msg( "\nPress the RETURN key to continue..." );
775 if( p_main->i_warning_level < 0 )
777 p_main->i_warning_level = 0;
784 /*****************************************************************************
785 * GetFilenames: parse command line options which are not flags
786 *****************************************************************************
787 * Parse command line for input files.
788 *****************************************************************************/
789 static int GetFilenames( int i_argc, char *ppsz_argv[] )
793 /* We assume that the remaining parameters are filenames */
794 for( i_opt = optind; i_opt < i_argc; i_opt++ )
796 intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END,
797 ppsz_argv[ i_opt ] );
803 /*****************************************************************************
804 * Usage: print program usage
805 *****************************************************************************
806 * Print a short inline help. Message interface is initialized at this stage.
807 *****************************************************************************/
808 static void Usage( const char *psz_module_name )
814 memset( psz_spaces, 32, 30 );
821 intf_Msg( "Usage: %s [options] [parameters] [file]...\n",
824 /* Enumerate the config of each module */
825 for( p_module = p_module_bank->first ;
827 p_module = p_module->next )
830 if( psz_module_name && strcmp( psz_module_name, p_module->psz_name ) )
833 /* print module name */
834 intf_Msg( "%s configuration:\n", p_module->psz_name );
836 for( i = 0; i < (p_module->i_config_options -1); i++ )
840 switch( p_module->p_config[i].i_type )
842 case MODULE_CONFIG_ITEM_CATEGORY:
843 intf_Msg( " %s", p_module->p_config[i].psz_text );
846 case MODULE_CONFIG_ITEM_STRING:
847 case MODULE_CONFIG_ITEM_FILE:
848 case MODULE_CONFIG_ITEM_PLUGIN:
849 /* Nasty hack, but right now I'm too tired to think about
851 j = 25 - strlen( p_module->p_config[i].psz_name )
852 - strlen(" <string>") - 1;
853 if( j < 0 ) j = 0; psz_spaces[j] = 0;
855 intf_Msg( " --%s <string>%s %s",
856 p_module->p_config[i].psz_name, psz_spaces,
857 p_module->p_config[i].psz_text );
860 case MODULE_CONFIG_ITEM_INTEGER:
861 /* Nasty hack, but right now I'm too tired to think about
863 j = 25 - strlen( p_module->p_config[i].psz_name )
864 - strlen(" <integer>") - 1;
865 if( j < 0 ) j = 0; psz_spaces[j] = 0;
867 intf_Msg( " --%s <integer>%s %s",
868 p_module->p_config[i].psz_name, psz_spaces,
869 p_module->p_config[i].psz_text );
873 /* Nasty hack, but right now I'm too tired to think about
875 j = 25 - strlen( p_module->p_config[i].psz_name ) - 1;
876 if( j < 0 ) j = 0; psz_spaces[j] = 0;
878 intf_Msg( " --%s%s %s",
879 p_module->p_config[i].psz_name, psz_spaces,
880 p_module->p_config[i].psz_text );
886 /* Yet another nasty hack.
887 * Maybe we could use MODULE_CONFIG_ITEM_END to display tail messages
888 * for each module?? */
889 if( !strcmp( "main", p_module->psz_name ) )
890 intf_Msg( "\nPlaylist items:"
891 "\n *.mpg, *.vob \tPlain MPEG-1/2 files"
892 "\n [dvd:][device][@raw_device][@[title][,[chapter][,angle]]]"
894 "\n vcd:<device> \tVCD device"
895 "\n udpstream:[<server>[:<server port>]][@[<bind address>]"
897 "\n \tUDP stream sent by VLS"
898 "\n vlc:loop \tLoop execution of the "
900 "\n vlc:pause \tPause execution of "
902 "\n vlc:quit \tQuit VLC" );
908 #ifdef WIN32 /* Pause the console because it's destroyed when we exit */
909 intf_Msg( "\nPress the RETURN key to continue..." );
914 /*****************************************************************************
915 * ListModules: list the available modules with their description
916 *****************************************************************************
917 * Print a list of all available modules (builtins and plugins) and a short
918 * description for each one.
919 *****************************************************************************/
920 static void ListModules( void )
925 memset( psz_spaces, 32, 20 );
932 intf_Msg( "Usage: %s [options] [parameters] [file]...\n",
935 intf_Msg( "[plugin] [description]" );
937 /* Enumerate each module */
938 for( p_module = p_module_bank->first ;
940 p_module = p_module->next )
944 /* Nasty hack, but right now I'm too tired to think about a nice
946 i = 20 - strlen( p_module->psz_name ) - 1;
950 intf_Msg( " %s%s %s", p_module->psz_name, psz_spaces,
951 p_module->psz_longname );
957 #ifdef WIN32 /* Pause the console because it's destroyed when we exit */
958 intf_Msg( "\nPress the RETURN key to continue..." );
963 /*****************************************************************************
964 * Version: print complete program version
965 *****************************************************************************
966 * Print complete program version and build number.
967 *****************************************************************************/
968 static void Version( void )
973 intf_Msg( VERSION_MESSAGE
974 "This program comes with NO WARRANTY, to the extent permitted by law.\n"
975 "You may redistribute it under the terms of the GNU General Public License;\n"
976 "see the file named COPYING for details.\n"
977 "Written by the VideoLAN team at Ecole Centrale, Paris." );
978 #ifdef WIN32 /* Pause the console because it's destroyed when we exit */
979 intf_Msg( "\nPress the RETURN key to continue..." );
984 /*****************************************************************************
985 * InitSignalHandler: system signal handler initialization
986 *****************************************************************************
987 * Set the signal handlers. SIGTERM is not intercepted, because we need at
988 * at least a method to kill the program when all other methods failed, and
989 * when we don't want to use SIGKILL.
990 *****************************************************************************/
991 static void InitSignalHandler( void )
993 /* Termination signals */
995 signal( SIGINT, FatalSignalHandler );
996 signal( SIGHUP, FatalSignalHandler );
997 signal( SIGQUIT, FatalSignalHandler );
1000 signal( SIGALRM, SimpleSignalHandler );
1001 signal( SIGPIPE, SimpleSignalHandler );
1005 /*****************************************************************************
1006 * SimpleSignalHandler: system signal handler
1007 *****************************************************************************
1008 * This function is called when a non fatal signal is received by the program.
1009 *****************************************************************************/
1010 static void SimpleSignalHandler( int i_signal )
1012 /* Acknowledge the signal received */
1013 intf_WarnMsg( 0, "intf: ignoring signal %d", i_signal );
1016 /*****************************************************************************
1017 * FatalSignalHandler: system signal handler
1018 *****************************************************************************
1019 * This function is called when a fatal signal is received by the program.
1020 * It tries to end the program in a clean way.
1021 *****************************************************************************/
1022 static void FatalSignalHandler( int i_signal )
1024 /* Once a signal has been trapped, the termination sequence will be
1025 * armed and following signals will be ignored to avoid sending messages
1026 * to an interface having been destroyed */
1028 signal( SIGINT, SIG_IGN );
1029 signal( SIGHUP, SIG_IGN );
1030 signal( SIGQUIT, SIG_IGN );
1033 /* Acknowledge the signal received */
1034 intf_ErrMsg( "intf error: signal %d received, exiting", i_signal );
1036 /* Try to terminate everything - this is done by requesting the end of the
1037 * interface thread */
1038 p_main->p_intf->b_die = 1;
1041 /*****************************************************************************
1042 * IllegalSignalHandler: system signal handler
1043 *****************************************************************************
1044 * This function is called when an illegal instruction signal is received by
1045 * the program. We use this function to test OS and CPU capabilities
1046 *****************************************************************************/
1047 static void IllegalSignalHandler( int i_signal )
1049 /* Acknowledge the signal received */
1052 #ifdef HAVE_SIGRELSE
1053 sigrelse( i_signal );
1056 fprintf( stderr, "warning: your CPU has %s instructions, but not your "
1057 "operating system.\n", psz_capability );
1058 fprintf( stderr, " some optimizations will be disabled unless "
1059 "you upgrade your OS\n" );
1061 fprintf( stderr, " (for instance Linux kernel 2.4.x or later)" );
1067 /*****************************************************************************
1068 * CPUCapabilities: list the processors MMX support and other capabilities
1069 *****************************************************************************
1070 * This function is called to list extensions the CPU may have.
1071 *****************************************************************************/
1072 static u32 CPUCapabilities( void )
1074 volatile u32 i_capabilities = CPU_CAPABILITY_NONE;
1076 #if defined( SYS_DARWIN )
1077 struct host_basic_info hi;
1079 host_name_port_t host;
1082 char *psz_name, *psz_subname;
1084 i_capabilities |= CPU_CAPABILITY_FPU;
1086 /* Should 'never' fail? */
1087 host = mach_host_self();
1089 i_size = sizeof( hi ) / sizeof( int );
1090 ret = host_info( host, HOST_BASIC_INFO, ( host_info_t )&hi, &i_size );
1092 if( ret != KERN_SUCCESS )
1094 fprintf( stderr, "error: couldn't get CPU information\n" );
1095 return( i_capabilities );
1098 slot_name( hi.cpu_type, hi.cpu_subtype, &psz_name, &psz_subname );
1099 /* FIXME: need better way to detect newer proccessors.
1100 * could do strncmp(a,b,5), but that's real ugly */
1101 if( !strcmp(psz_name, "ppc7400") || !strcmp(psz_name, "ppc7450") )
1103 i_capabilities |= CPU_CAPABILITY_ALTIVEC;
1106 return( i_capabilities );
1108 #elif defined( __i386__ )
1109 volatile unsigned int i_eax, i_ebx, i_ecx, i_edx;
1110 volatile boolean_t b_amd;
1112 /* Needed for x86 CPU capabilities detection */
1113 # define cpuid( a ) \
1114 asm volatile ( "pushl %%ebx\n\t" \
1116 "movl %%ebx,%1\n\t" \
1125 i_capabilities |= CPU_CAPABILITY_FPU;
1127 # if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
1128 signal( SIGILL, IllegalSignalHandler );
1131 /* test for a 486 CPU */
1132 asm volatile ( "pushl %%ebx\n\t"
1135 "movl %%eax, %%ebx\n\t"
1136 "xorl $0x200000, %%eax\n\t"
1148 if( i_eax == i_ebx )
1150 # if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
1151 signal( SIGILL, NULL );
1153 return( i_capabilities );
1156 i_capabilities |= CPU_CAPABILITY_486;
1158 /* the CPU supports the CPUID instruction - get its level */
1159 cpuid( 0x00000000 );
1163 # if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
1164 signal( SIGILL, NULL );
1166 return( i_capabilities );
1169 /* FIXME: this isn't correct, since some 486s have cpuid */
1170 i_capabilities |= CPU_CAPABILITY_586;
1172 /* borrowed from mpeg2dec */
1173 b_amd = ( i_ebx == 0x68747541 ) && ( i_ecx == 0x444d4163 )
1174 && ( i_edx == 0x69746e65 );
1176 /* test for the MMX flag */
1177 cpuid( 0x00000001 );
1179 if( ! (i_edx & 0x00800000) )
1181 # if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
1182 signal( SIGILL, NULL );
1184 return( i_capabilities );
1187 i_capabilities |= CPU_CAPABILITY_MMX;
1189 if( i_edx & 0x02000000 )
1191 i_capabilities |= CPU_CAPABILITY_MMXEXT;
1193 # ifdef CAN_COMPILE_SSE
1194 /* We test if OS support the SSE instructions */
1195 psz_capability = "SSE";
1197 if( setjmp( env ) == 0 )
1199 /* Test a SSE instruction */
1200 __asm__ __volatile__ ( "xorps %%xmm0,%%xmm0\n" : : );
1203 if( i_illegal == 0 )
1205 i_capabilities |= CPU_CAPABILITY_SSE;
1210 /* test for additional capabilities */
1211 cpuid( 0x80000000 );
1213 if( i_eax < 0x80000001 )
1215 # if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
1216 signal( SIGILL, NULL );
1218 return( i_capabilities );
1221 /* list these additional capabilities */
1222 cpuid( 0x80000001 );
1224 # ifdef CAN_COMPILE_3DNOW
1225 if( i_edx & 0x80000000 )
1227 psz_capability = "3D Now!";
1229 if( setjmp( env ) == 0 )
1231 /* Test a 3D Now! instruction */
1232 __asm__ __volatile__ ( "pfadd %%mm0,%%mm0\n" "femms\n" : : );
1235 if( i_illegal == 0 )
1237 i_capabilities |= CPU_CAPABILITY_3DNOW;
1242 if( b_amd && ( i_edx & 0x00400000 ) )
1244 i_capabilities |= CPU_CAPABILITY_MMXEXT;
1247 # if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
1248 signal( SIGILL, NULL );
1250 return( i_capabilities );
1252 #elif defined( __powerpc__ )
1254 i_capabilities |= CPU_CAPABILITY_FPU;
1256 # ifdef CAN_COMPILE_ALTIVEC
1257 signal( SIGILL, IllegalSignalHandler );
1259 psz_capability = "AltiVec";
1261 if( setjmp( env ) == 0 )
1263 asm volatile ("mtspr 256, %0\n\t"
1264 "vand %%v0, %%v0, %%v0"
1269 if( i_illegal == 0 )
1271 i_capabilities |= CPU_CAPABILITY_ALTIVEC;
1274 signal( SIGILL, NULL );
1277 return( i_capabilities );
1280 /* default behaviour */
1281 return( i_capabilities );
1286 /*****************************************************************************
1287 * ShowConsole: On Win32, create an output console for debug messages
1288 *****************************************************************************
1289 * This function is usefull only on Win32.
1290 *****************************************************************************/
1292 static void ShowConsole( void )
1295 freopen( "CONOUT$", "w", stdout );
1296 freopen( "CONOUT$", "w", stderr );
1297 freopen( "CONIN$", "r", stdin );