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.168 2002/03/25 02:06:24 jobi 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 */
99 #define INTF_TEXT "interface method"
100 #define INTF_LONGTEXT "This option allows you to select the interface used by"\
101 " vlc.\nNote that the default behaviour is to" \
102 " automatically select the best method available"
104 #define WARNING_TEXT "warning level (or use -v, -vv, etc...)"
105 #define WARNING_LONGTEXT "Increasing the warning level will allow you to see" \
106 " more debug messages and can sometimes help you to" \
107 " troubleshoot a problem"
109 #define STATS_TEXT "output statistics"
110 #define STATS_LONGTEXT "Enabling the stats mode will flood your log console" \
111 " with various statistics messages"
113 #define INTF_PATH_TEXT "interface default search path"
114 #define INTF_PATH_LONGTEXT "This option allows you to set the default path" \
115 "that the interface will open when looking for a" \
118 #define AOUT_TEXT "audio output method"
119 #define AOUT_LONGTEXT "This option allows you to select the audio" \
120 " audio output method used by vlc.\nNote that the" \
121 " default behaviour is to automatically select the best"\
124 #define NOAUDIO_TEXT "disable audio"
125 #define NOAUDIO_LONGTEXT "This will completely disable the audio output. The" \
126 " audio decoding stage shouldn't even be done, so it"\
127 " can allow you to save some processing power"
129 #define MONO_TEXT "mono audio"
130 #define MONO_LONGTEXT "This will force a mono audio output"
132 #define VOLUME_TEXT "audio output volume"
133 #define VOLUME_LONGTEXT "You can set the default audio output volume here," \
134 " in a range from 0 to 1024"
136 #define FORMAT_TEXT "audio output format"
137 #define FORMAT_LONGTEXT "You can force the audio output format here.\n" \
138 "0 -> 16 bits signed native endian (default)\n" \
139 "1 -> 8 bits unsigned\n" \
140 "2 -> 16 bits signed little endian\n" \
141 "3 -> 16 bits signed big endian\n" \
142 "4 -> 8 bits signed\n" \
143 "5 -> 16 bits unsigned little endian\n" \
144 "6 -> 16 bits unsigned big endian\n" \
145 "7 -> mpeg2 audio (unsupported)\n" \
146 "8 -> ac3 pass-through"
148 #define RATE_TEXT "audio output frequency (Hz)"
149 #define RATE_LONGTEXT "You can force the audio output frequency here.\n" \
150 "Common values are 48000, 44100, 32000, 22050," \
151 " 16000, 11025, 8000"
153 #define DESYNC_TEXT "Compensate desynchronization of audio (in ms)"
154 #define DESYNC_LONGTEXT "This option allows you to delay the audio output." \
155 "This can be handy if you notice a lag between the" \
156 " video and the audio"
158 #define VOUT_TEXT "video output method"
159 #define VOUT_LONGTEXT "This option allows you to select the video output" \
160 "method used by vlc.\nNote that the default behaviour" \
161 "is to automatically select the best method available"
163 #define NOVIDEO_TEXT "disable video"
164 #define NOVIDEO_LONGTEXT "This will completely disable the video output. The" \
165 "video decoding stage shouldn't even be done, so it" \
166 "can allow you to save some processing power"
168 #define DISPLAY_TEXT "display identifier"
169 #define DISPLAY_LONGTEXT NULL
171 #define WIDTH_TEXT "video width"
172 #define WIDTH_LONGTEXT "You can enforce the video width here.\nNote" \
173 "that by default vlc will adapt to the video properties"
175 #define HEIGHT_TEXT "video height"
176 #define HEIGHT_LONGTEXT NULL
178 #define GRAYSCALE_TEXT "grayscale video output"
179 #define GRAYSCALE_LONGTEXT NULL
181 #define FULLSCREEN_TEXT "fullscreen video output"
182 #define FULLSCREEN_LONGTEXT NULL
184 #define NOOVERLAY_TEXT "disable accelerated display"
185 #define NOOVERLAY_LONGTEXT NULL
187 #define SPUMARGIN_TEXT "force SPU position"
188 #define SPUMARGIN_LONGTEXT NULL
190 #define FILTER_TEXT "video filter module"
191 #define FILTER_LONGTEXT NULL
193 #define INPUT_TEXT "input method"
194 #define INPUT_LONGTEXT NULL
196 #define SERVER_PORT_TEXT "server port"
197 #define SERVER_PORT_LONGTEXT NULL
199 #define NETCHANNEL_TEXT "enable network channel mode"
200 #define NETCHANNEL_LONGTEXT NULL
202 #define CHAN_SERV_TEXT "channel server address"
203 #define CHAN_SERV_LONGTEXT NULL
205 #define CHAN_PORT_TEXT "channel server port"
206 #define CHAN_PORT_LONGTEXT NULL
208 #define IFACE_TEXT "network interface"
209 #define IFACE_LONGTEXT NULL
211 #define INPUT_AUDIO_TEXT "choose audio"
212 #define INPUT_AUDIO_LONGTEXT NULL
214 #define INPUT_CHAN_TEXT "choose channel"
215 #define INPUT_CHAN_LONGTEXT NULL
217 #define INPUT_SUBT_TEXT "choose subtitles"
218 #define INPUT_SUBT_LONGTEXT NULL
220 #define DVD_DEV_TEXT "DVD device"
221 #define DVD_DEV_LONGTEXT NULL
223 #define VCD_DEV_TEXT "VCD device"
224 #define VCD_DEV_LONGTEXT NULL
226 #define SAT_FREQ_TEXT "Satellite transponder frequency"
227 #define SAT_FREQ_LONGTEXT NULL
229 #define SAT_POL_TEXT "Satellite transponder polarization"
230 #define SAT_POL_LONGTEXT NULL
232 #define SAT_SRATE_TEXT "Satellite transponder symbol rate"
233 #define SAT_SRATE_LONGTEXT NULL
235 #define IPV6_TEXT "force IPv6"
236 #define IPV6_LONGTEXT NULL
238 #define IPV4_TEXT "force IPv4"
239 #define IPV4_LONGTEXT NULL
241 #define ADEC_MPEG_TEXT "choose MPEG audio decoder"
242 #define ADEC_MPEG_LONGTEXT NULL
244 #define ADEC_AC3_TEXT "choose AC3 audio decoder"
245 #define ADEC_AC3_LONGTEXT NULL
247 #define VDEC_SMP_TEXT "use additional processors"
248 #define VDEC_SMP_LONGTEXT NULL
250 #define VPAR_SYNCHRO_TEXT "force synchro algorithm {I|I+|IP|IP+|IPB}"
251 #define VPAR_SYNCHRO_LONGTEXT NULL
253 #define NOMMX_TEXT "disable CPU's MMX support"
254 #define NOMMX_LONGTEXT NULL
256 #define NO3DN_TEXT "disable CPU's 3D Now! support"
257 #define NO3DN_LONGTEXT NULL
259 #define NOMMXEXT_TEXT "disable CPU's MMX EXT support"
260 #define NOMMXEXT_LONGTEXT NULL
262 #define NOSSE_TEXT "disable CPU's SSE support"
263 #define NOSSE_LONGTEXT NULL
265 #define NOALTIVEC_TEXT "disable CPU's AltiVec support"
266 #define NOALTIVEC_LONGTEXT NULL
268 #define PLAYLIST_LAUNCH_TEXT "launch playlist on startup"
269 #define PLAYLIST_LAUNCH_LONGTEXT NULL
271 #define PLAYLIST_ENQUEUE_TEXT "enqeue playlist as default"
272 #define PLAYLIST_ENQUEUE_LONGTEXT NULL
274 #define PLAYLIST_LOOP_TEXT "loop playlist on end"
275 #define PLAYLIST_LOOP_LONGTEXT NULL
277 #define MEMCPY_TEXT "memory copy method"
278 #define MEMCPY_LONGTEXT NULL
283 ADD_CATEGORY_HINT( text, longtext )
284 ADD_SUBCATEGORY_HINT( text, longtext )
285 ADD_STRING( option_name, value, p_callback, text, longtext )
286 ADD_FILE( option_name, psz_value, p_callback, text, longtext )
287 ADD_PLUGIN( option_name, psz_value, i_capability, p_callback, text, longtext )
288 ADD_INTEGER( option_name, i_value, p_callback, text, longtext )
289 ADD_BOOL( option_name, p_callback, text, longtext )
294 /* Interface options */
295 ADD_CATEGORY_HINT( "Interface", NULL)
296 ADD_PLUGIN ( "intf", MODULE_CAPABILITY_INTF, NULL, NULL, INTF_TEXT, INTF_LONGTEXT )
297 ADD_INTEGER ( "warning", 0, NULL, WARNING_TEXT, WARNING_LONGTEXT )
298 ADD_BOOL ( "stats", NULL, STATS_TEXT, STATS_LONGTEXT )
299 ADD_STRING ( "search_path", NULL, NULL, INTF_PATH_TEXT, INTF_PATH_LONGTEXT )
302 ADD_CATEGORY_HINT( "Audio", NULL)
303 ADD_PLUGIN ( "aout", MODULE_CAPABILITY_AOUT, NULL, NULL, AOUT_TEXT, AOUT_LONGTEXT )
304 ADD_BOOL ( "noaudio", NULL, NOAUDIO_TEXT, NOAUDIO_LONGTEXT )
305 ADD_BOOL ( "mono", NULL, MONO_TEXT, MONO_LONGTEXT )
306 ADD_INTEGER ( "volume", VOLUME_DEFAULT, NULL, VOLUME_TEXT, VOLUME_LONGTEXT )
307 ADD_INTEGER ( "rate", 44100, NULL, RATE_TEXT, RATE_LONGTEXT )
308 ADD_INTEGER ( "desync", 0, NULL, DESYNC_TEXT, DESYNC_LONGTEXT )
309 ADD_INTEGER ( "aout_format", 0, NULL, FORMAT_TEXT,
313 ADD_CATEGORY_HINT( "Video", NULL )
314 ADD_PLUGIN ( "vout", MODULE_CAPABILITY_VOUT, NULL, NULL, VOUT_TEXT, VOUT_LONGTEXT )
315 ADD_BOOL ( "novideo", NULL, NOVIDEO_TEXT, NOVIDEO_LONGTEXT )
316 ADD_STRING ( "display", NULL, NULL, DISPLAY_TEXT, DISPLAY_LONGTEXT )
317 ADD_INTEGER ( "width", -1, NULL, WIDTH_TEXT, WIDTH_LONGTEXT )
318 ADD_INTEGER ( "height", -1, NULL, HEIGHT_TEXT, HEIGHT_LONGTEXT )
319 ADD_BOOL ( "grayscale", NULL, GRAYSCALE_TEXT, GRAYSCALE_LONGTEXT )
320 ADD_BOOL ( "fullscreen", NULL, FULLSCREEN_TEXT, FULLSCREEN_LONGTEXT )
321 ADD_BOOL ( "nooverlay", NULL, NOOVERLAY_TEXT, NOOVERLAY_LONGTEXT )
322 ADD_INTEGER ( "spumargin", -1, NULL, SPUMARGIN_TEXT, SPUMARGIN_LONGTEXT )
323 ADD_PLUGIN ( "filter", MODULE_CAPABILITY_VOUT, NULL, NULL, FILTER_TEXT, FILTER_LONGTEXT )
326 ADD_CATEGORY_HINT( "Input", NULL )
327 ADD_STRING ( "input", NULL, NULL, INPUT_TEXT, INPUT_LONGTEXT )
328 ADD_INTEGER ( "server_port", 1234, NULL, SERVER_PORT_TEXT, SERVER_PORT_LONGTEXT )
329 ADD_BOOL ( "network_channel", NULL, NETCHANNEL_TEXT, NETCHANNEL_LONGTEXT )
330 ADD_STRING ( "channel_server", "localhost", NULL, CHAN_SERV_TEXT, CHAN_SERV_LONGTEXT )
331 ADD_INTEGER ( "channel_port", 6010, NULL, CHAN_PORT_TEXT, CHAN_PORT_LONGTEXT )
332 ADD_STRING ( "iface", "eth0", NULL, IFACE_TEXT, IFACE_LONGTEXT )
334 ADD_INTEGER ( "input_audio", -1, NULL, INPUT_AUDIO_TEXT, INPUT_AUDIO_LONGTEXT )
335 ADD_INTEGER ( "input_channel", -1, NULL, INPUT_CHAN_TEXT, INPUT_CHAN_LONGTEXT )
336 ADD_INTEGER ( "input_subtitle", -1, NULL, INPUT_SUBT_TEXT, INPUT_SUBT_LONGTEXT )
338 ADD_STRING ( "dvd_device", "/dev/dvd", NULL, DVD_DEV_TEXT, DVD_DEV_LONGTEXT )
339 ADD_STRING ( "vcd_device", "/dev/cdrom", NULL, VCD_DEV_TEXT, VCD_DEV_LONGTEXT )
340 #ifdef HAVE_SATELLITE
341 ADD_INTEGER ( "sat_frequency", 12553, NULL, SAT_FREQ_TEXT, SAT_FREQ_LONGTEXT )
342 ADD_INTEGER ( "sat_polarization", 0, NULL, SAT_POL_TEXT, SAT_POL_LONGTEXT )
343 ADD_INTEGER ( "sat_symbol_rate", 27500, NULL, SAT_SRATE_TEXT,
347 ADD_BOOL ( "ipv6", NULL, IPV6_TEXT, IPV6_LONGTEXT )
348 ADD_BOOL ( "ipv4", NULL, IPV4_TEXT, IPV4_LONGTEXT )
350 /* Decoder options */
351 ADD_CATEGORY_HINT( "Decoders", NULL )
352 ADD_PLUGIN ( "mpeg_adec", MODULE_CAPABILITY_DECODER, NULL, NULL, ADEC_MPEG_TEXT, ADEC_MPEG_LONGTEXT )
353 ADD_PLUGIN ( "ac3_adec", MODULE_CAPABILITY_DECODER, NULL, NULL, ADEC_AC3_TEXT, ADEC_AC3_LONGTEXT )
354 ADD_INTEGER ( "vdec_smp", 0, NULL, VDEC_SMP_TEXT, VDEC_SMP_LONGTEXT )
355 ADD_STRING ( "vpar_synchro", NULL, NULL, VPAR_SYNCHRO_TEXT, VPAR_SYNCHRO_LONGTEXT )
358 ADD_CATEGORY_HINT( "CPU", NULL )
359 ADD_BOOL ( "nommx", NULL, NOMMX_TEXT, NOMMX_LONGTEXT )
360 ADD_BOOL ( "no3dn", NULL, NO3DN_TEXT, NO3DN_LONGTEXT )
361 ADD_BOOL ( "nommxext", NULL, NOMMXEXT_TEXT, NOMMXEXT_LONGTEXT )
362 ADD_BOOL ( "nosse", NULL, NOSSE_TEXT, NOSSE_LONGTEXT )
363 ADD_BOOL ( "noaltivec", NULL, NOALTIVEC_TEXT, NOALTIVEC_LONGTEXT )
365 /* Playlist options */
366 ADD_CATEGORY_HINT( "Playlist", NULL )
367 ADD_BOOL ( "playlist_launch", NULL, PLAYLIST_LAUNCH_TEXT, PLAYLIST_LAUNCH_LONGTEXT )
368 ADD_BOOL ( "playlist_enqueue", NULL, PLAYLIST_ENQUEUE_TEXT, PLAYLIST_ENQUEUE_LONGTEXT )
369 ADD_BOOL ( "playlist_loop", NULL, PLAYLIST_LOOP_TEXT, PLAYLIST_LOOP_LONGTEXT )
372 ADD_CATEGORY_HINT( "Miscellaneous", NULL )
373 ADD_PLUGIN ( "memcpy", MODULE_CAPABILITY_MEMCPY, NULL, NULL, MEMCPY_TEXT, MEMCPY_LONGTEXT )
378 SET_DESCRIPTION( "Main program" )
379 ADD_CAPABILITY( MAIN, 100/*whatever*/ )
382 MODULE_ACTIVATE_START
385 MODULE_DEACTIVATE_START
386 MODULE_DEACTIVATE_STOP
388 /* Hack for help options */
389 static module_t help_module;
390 static module_config_t p_help_config[] = {
391 { MODULE_CONFIG_ITEM_BOOL, "help", "print help (or use -h)",
392 NULL, NULL, 0, NULL, NULL, 0 },
393 { MODULE_CONFIG_ITEM_BOOL, "longhelp", "print detailed help (or use -H)",
394 NULL, NULL, 0, NULL, NULL, 0 },
395 { MODULE_CONFIG_ITEM_BOOL, "list", "print a list of available plugins "
396 "(or use -l)", NULL, NULL, 0, NULL, NULL, 0 },
397 { MODULE_CONFIG_ITEM_STRING, "plugin", "print help on plugin (or use -p)",
398 NULL, NULL, 0, NULL, &help_module.config_lock, 0 },
399 { MODULE_CONFIG_ITEM_BOOL, "version", "print version information",
400 NULL, NULL, 0, NULL, NULL, 0 },
401 { MODULE_CONFIG_HINT_END, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0 } };
404 /*****************************************************************************
406 *****************************************************************************/
408 /*****************************************************************************
409 * Global variables - these are the only ones, see main.h and modules.h
410 *****************************************************************************/
412 module_bank_t *p_module_bank;
413 input_bank_t *p_input_bank;
414 aout_bank_t *p_aout_bank;
415 vout_bank_t *p_vout_bank;
417 /*****************************************************************************
419 *****************************************************************************/
420 static int GetFilenames ( int i_argc, char *ppsz_argv[] );
421 static void Usage ( const char *psz_module_name );
422 static void ListModules ( void );
423 static void Version ( void );
425 static void InitSignalHandler ( void );
426 static void SimpleSignalHandler ( int i_signal );
427 static void FatalSignalHandler ( int i_signal );
428 static void IllegalSignalHandler ( int i_signal );
429 static u32 CPUCapabilities ( void );
432 static void ShowConsole ( void );
436 static int i_illegal;
437 static char *psz_capability;
439 /*****************************************************************************
440 * main: parse command line, start interface and spawn threads
441 *****************************************************************************
442 * Steps during program execution are:
443 * -configuration parsing and messages interface initialization
444 * -opening of audio output device and some global modules
445 * -execution of interface, which exit on error or on user request
446 * -closing of audio output device and some global modules
447 * On error, the spawned threads are canceled, and the open devices closed.
448 *****************************************************************************/
449 int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
451 main_t main_data; /* root of all data - see main.h */
452 module_bank_t module_bank;
453 input_bank_t input_bank;
454 aout_bank_t aout_bank;
455 vout_bank_t vout_bank;
459 p_main = &main_data; /* set up the global variables */
460 p_module_bank = &module_bank;
461 p_input_bank = &input_bank;
462 p_aout_bank = &aout_bank;
463 p_vout_bank = &vout_bank;
465 p_main->i_warning_level = 0;
467 #if defined( ENABLE_NLS ) && defined ( HAVE_GETTEXT )
471 #if defined( HAVE_LOCALE_H ) && defined( HAVE_LC_MESSAGES )
472 if( !setlocale( LC_MESSAGES, "" ) )
474 fprintf( stderr, "warning: unsupported locale.\n" );
478 if( !bindtextdomain( PACKAGE, LOCALEDIR ) )
480 fprintf( stderr, "warning: no domain %s in directory %s\n",
481 PACKAGE, LOCALEDIR );
484 textdomain( PACKAGE );
488 * Initialize threads system
493 * Test if our code is likely to run on this CPU
495 p_main->i_cpu_capabilities = CPUCapabilities();
498 * System specific initialization code
500 #if defined( SYS_BEOS ) || defined( SYS_DARWIN ) || defined( WIN32 )
501 system_Init( &i_argc, ppsz_argv, ppsz_env );
503 #elif defined( SYS_LINUX )
505 /* Activate malloc checking routines to detect heap corruptions. */
506 putenv( "MALLOC_CHECK_=2" );
507 putenv( "GNOME_DISABLE_CRASH_DIALOG=1" );
512 * Initialize messages interface
516 intf_Msg( COPYRIGHT_MESSAGE "\n" );
519 /* Get the executable name (similar to the basename command) */
520 p_main->psz_arg0 = p_tmp = ppsz_argv[ 0 ];
523 if( *p_tmp == '/' ) p_main->psz_arg0 = ++p_tmp;
528 * Initialize the module bank and and load the configuration of the main
529 * module. We need to do this at this stage to be able to display a short
530 * help if required by the user. (short help == main module options)
535 /* Hack: insert the help module here */
536 help_module.psz_name = "help";
537 help_module.i_config_lines = sizeof(p_help_config) /
538 sizeof(module_config_t);
539 help_module.i_config_items = help_module.i_config_lines - 1;
540 vlc_mutex_init( &help_module.config_lock );
541 help_module.p_config = p_help_config;
542 help_module.next = p_module_bank->first;
543 p_module_bank->first = &help_module;
546 if( config_LoadCmdLine( &i_argc, ppsz_argv, 1 ) )
552 /* Check for short help option */
553 if( config_GetIntVariable( "help" ) )
555 intf_Msg( "Usage: %s [options] [parameters] [file]...\n",
563 /* Check for version option */
564 if( config_GetIntVariable( "version" ) )
570 /* Hack: remove the help module here */
571 p_module_bank->first = help_module.next;
575 * Load the builtins and plugins into the module_bank.
576 * We have to do it before config_Load*() because this also gets the
577 * list of configuration options exported by each plugin and loads their
580 module_LoadBuiltins();
581 module_LoadPlugins();
582 intf_WarnMsg( 2, "module: module bank initialized, found %i modules",
583 p_module_bank->i_count );
585 /* Hack: insert the help module here */
586 help_module.next = p_module_bank->first;
587 p_module_bank->first = &help_module;
590 /* Check for help on plugins */
591 if( (p_tmp = config_GetPszVariable( "plugin" )) )
598 /* Check for long help option */
599 if( config_GetIntVariable( "longhelp" ) )
605 /* Check for plugin list option */
606 if( config_GetIntVariable( "list" ) )
612 /* Hack: remove the help module here */
613 p_module_bank->first = help_module.next;
618 * Override default configuration with config file settings
620 vlc_mutex_init( &p_main->config_lock );
621 p_main->psz_homedir = config_GetHomeDir();
622 config_LoadConfigFile( NULL );
625 * Override configuration with command line settings
627 if( config_LoadCmdLine( &i_argc, ppsz_argv, 0 ) )
631 /* Pause the console because it's destroyed when we exit */
632 intf_Msg( "The command line options couldn't be loaded, check that "
633 "they are valid.\nPress the RETURN key to continue..." );
641 /* p_main inititalization. FIXME ? */
642 p_main->i_desync = (mtime_t)config_GetIntVariable( "desync" )
644 p_main->b_stats = config_GetIntVariable( "stats" );
645 p_main->b_audio = !config_GetIntVariable( "noaudio" );
646 p_main->b_stereo= !config_GetIntVariable( "mono" );
647 p_main->b_video = !config_GetIntVariable( "novideo" );
648 if( config_GetIntVariable( "nommx" ) )
649 p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_MMX;
650 if( config_GetIntVariable( "no3dn" ) )
651 p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_3DNOW;
652 if( config_GetIntVariable( "nommxext" ) )
653 p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_MMXEXT;
654 if( config_GetIntVariable( "nosse" ) )
655 p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_SSE;
656 if( config_GetIntVariable( "noaltivec" ) )
657 p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_ALTIVEC;
660 if( p_main->b_stats )
662 char p_capabilities[200];
663 p_capabilities[0] = '\0';
665 #define PRINT_CAPABILITY( capability, string ) \
666 if( p_main->i_cpu_capabilities & capability ) \
668 strncat( p_capabilities, string " ", \
669 sizeof(p_capabilities) - strlen(p_capabilities) ); \
670 p_capabilities[sizeof(p_capabilities) - 1] = '\0'; \
673 PRINT_CAPABILITY( CPU_CAPABILITY_486, "486" );
674 PRINT_CAPABILITY( CPU_CAPABILITY_586, "586" );
675 PRINT_CAPABILITY( CPU_CAPABILITY_PPRO, "Pentium Pro" );
676 PRINT_CAPABILITY( CPU_CAPABILITY_MMX, "MMX" );
677 PRINT_CAPABILITY( CPU_CAPABILITY_3DNOW, "3DNow!" );
678 PRINT_CAPABILITY( CPU_CAPABILITY_MMXEXT, "MMXEXT" );
679 PRINT_CAPABILITY( CPU_CAPABILITY_SSE, "SSE" );
680 PRINT_CAPABILITY( CPU_CAPABILITY_ALTIVEC, "Altivec" );
681 PRINT_CAPABILITY( CPU_CAPABILITY_FPU, "FPU" );
682 intf_StatMsg( "info: CPU has capabilities : %s", p_capabilities );
686 * Initialize playlist and get commandline files
688 p_main->p_playlist = intf_PlaylistCreate();
689 if( !p_main->p_playlist )
691 intf_ErrMsg( "playlist error: playlist initialization failed" );
695 intf_PlaylistInit( p_main->p_playlist );
698 * Get input filenames given as commandline arguments
700 GetFilenames( i_argc, ppsz_argv );
703 * Initialize input, aout and vout banks
710 * Choose the best memcpy module
712 psz_plugin = config_GetPszVariable( "memcpy" );
713 p_main->p_memcpy_module = module_Need( MODULE_CAPABILITY_MEMCPY, NULL,
715 if( psz_plugin ) free( psz_plugin );
716 if( p_main->p_memcpy_module == NULL )
718 intf_ErrMsg( "intf error: no suitable memcpy module, "
719 "using libc default" );
720 p_main->pf_memcpy = memcpy;
724 p_main->pf_memcpy = p_main->p_memcpy_module->p_functions
725 ->memcpy.functions.memcpy.pf_memcpy;
729 * Initialize shared resources and libraries
731 if( config_GetIntVariable( "network_channel" ) &&
732 network_ChannelCreate() )
734 /* On error during Channels initialization, switch off channels */
735 intf_ErrMsg( "intf error: channels initialization failed, "
736 "deactivating channels" );
737 config_PutIntVariable( "network_channel", 0 );
741 * Try to run the interface
743 p_main->p_intf = intf_Create();
744 if( p_main->p_intf == NULL )
746 intf_ErrMsg( "intf error: interface initialization failed" );
751 * Set signal handling policy for all threads
756 * This is the main loop
758 p_main->p_intf->pf_run( p_main->p_intf );
761 * Finished, destroy the interface
763 intf_Destroy( p_main->p_intf );
766 * Go back into channel 0 which is the network
768 if( config_GetIntVariable( "network_channel" ) )
770 network_ChannelJoin( COMMON_CHANNEL );
775 * Free input, aout and vout banks
784 intf_PlaylistDestroy( p_main->p_playlist );
787 * Free memcpy module if it was allocated
789 if( p_main->p_memcpy_module != NULL )
791 module_Unneed( p_main->p_memcpy_module );
800 * System specific cleaning code
802 #if defined( SYS_BEOS ) || defined( SYS_DARWIN ) || defined( WIN32 )
808 * Terminate messages interface and program
810 intf_WarnMsg( 1, "intf: program terminated" );
814 * Stop threads system
822 /* following functions are local */
824 /*****************************************************************************
825 * GetFilenames: parse command line options which are not flags
826 *****************************************************************************
827 * Parse command line for input files.
828 *****************************************************************************/
829 static int GetFilenames( int i_argc, char *ppsz_argv[] )
833 /* We assume that the remaining parameters are filenames */
834 for( i_opt = optind; i_opt < i_argc; i_opt++ )
836 intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END,
837 ppsz_argv[ i_opt ] );
843 /*****************************************************************************
844 * Usage: print program usage
845 *****************************************************************************
846 * Print a short inline help. Message interface is initialized at this stage.
847 *****************************************************************************/
848 static void Usage( const char *psz_module_name )
854 memset( psz_spaces, 32, 30 );
860 /* Enumerate the config of each module */
861 for( p_module = p_module_bank->first ;
863 p_module = p_module->next )
866 if( psz_module_name && strcmp( psz_module_name, p_module->psz_name ) )
869 /* ignore plugins without config options */
870 if( !p_module->i_config_items ) continue;
872 /* print module name */
873 intf_Msg( "%s options:\n", p_module->psz_name );
875 for( i = 0; i < p_module->i_config_lines; i++ )
879 switch( p_module->p_config[i].i_type )
881 case MODULE_CONFIG_HINT_CATEGORY:
882 intf_Msg( " %s", p_module->p_config[i].psz_text );
885 case MODULE_CONFIG_ITEM_STRING:
886 case MODULE_CONFIG_ITEM_FILE:
887 case MODULE_CONFIG_ITEM_PLUGIN:
888 /* Nasty hack, but right now I'm too tired to think about
890 j = 25 - strlen( p_module->p_config[i].psz_name )
891 - strlen(" <string>") - 1;
892 if( j < 0 ) j = 0; psz_spaces[j] = 0;
894 intf_Msg( " --%s <string>%s %s",
895 p_module->p_config[i].psz_name, psz_spaces,
896 p_module->p_config[i].psz_text );
899 case MODULE_CONFIG_ITEM_INTEGER:
900 /* Nasty hack, but right now I'm too tired to think about
902 j = 25 - strlen( p_module->p_config[i].psz_name )
903 - strlen(" <integer>") - 1;
904 if( j < 0 ) j = 0; psz_spaces[j] = 0;
906 intf_Msg( " --%s <integer>%s %s",
907 p_module->p_config[i].psz_name, psz_spaces,
908 p_module->p_config[i].psz_text );
911 case MODULE_CONFIG_ITEM_BOOL:
912 /* Nasty hack, but right now I'm too tired to think about
914 j = 25 - strlen( p_module->p_config[i].psz_name ) - 1;
915 if( j < 0 ) j = 0; psz_spaces[j] = 0;
917 intf_Msg( " --%s%s %s",
918 p_module->p_config[i].psz_name, psz_spaces,
919 p_module->p_config[i].psz_text );
925 /* Yet another nasty hack.
926 * Maybe we could use MODULE_CONFIG_ITEM_END to display tail messages
927 * for each module?? */
928 if( !strcmp( "main", p_module->psz_name ) )
929 intf_Msg( "\nPlaylist items:"
930 "\n *.mpg, *.vob \tPlain MPEG-1/2 files"
931 "\n [dvd:][device][@raw_device][@[title][,[chapter][,angle]]]"
933 "\n [vcd:][device][@[title][,[chapter]]"
935 "\n udpstream:[<server>[:<server port>]][@[<bind address>]"
937 "\n \tUDP stream sent by VLS"
938 "\n vlc:loop \tLoop execution of the "
940 "\n vlc:pause \tPause execution of "
942 "\n vlc:quit \tQuit VLC" );
948 #ifdef WIN32 /* Pause the console because it's destroyed when we exit */
949 intf_Msg( "\nPress the RETURN key to continue..." );
954 /*****************************************************************************
955 * ListModules: list the available modules with their description
956 *****************************************************************************
957 * Print a list of all available modules (builtins and plugins) and a short
958 * description for each one.
959 *****************************************************************************/
960 static void ListModules( void )
965 memset( psz_spaces, 32, 20 );
972 intf_Msg( "Usage: %s [options] [parameters] [file]...\n",
975 intf_Msg( "[plugin] [description]" );
977 /* Enumerate each module */
978 for( p_module = p_module_bank->first ;
980 p_module = p_module->next )
984 /* Nasty hack, but right now I'm too tired to think about a nice
986 i = 20 - strlen( p_module->psz_name ) - 1;
990 intf_Msg( " %s%s %s", p_module->psz_name, psz_spaces,
991 p_module->psz_longname );
997 #ifdef WIN32 /* Pause the console because it's destroyed when we exit */
998 intf_Msg( "\nPress the RETURN key to continue..." );
1003 /*****************************************************************************
1004 * Version: print complete program version
1005 *****************************************************************************
1006 * Print complete program version and build number.
1007 *****************************************************************************/
1008 static void Version( void )
1014 intf_Msg( VERSION_MESSAGE
1015 "This program comes with NO WARRANTY, to the extent permitted by "
1016 "law.\nYou may redistribute it under the terms of the GNU General "
1017 "Public License;\nsee the file named COPYING for details.\n"
1018 "Written by the VideoLAN team at Ecole Centrale, Paris." );
1020 #ifdef WIN32 /* Pause the console because it's destroyed when we exit */
1021 intf_Msg( "\nPress the RETURN key to continue..." );
1026 /*****************************************************************************
1027 * InitSignalHandler: system signal handler initialization
1028 *****************************************************************************
1029 * Set the signal handlers. SIGTERM is not intercepted, because we need at
1030 * at least a method to kill the program when all other methods failed, and
1031 * when we don't want to use SIGKILL.
1032 *****************************************************************************/
1033 static void InitSignalHandler( void )
1035 /* Termination signals */
1037 signal( SIGINT, FatalSignalHandler );
1038 signal( SIGHUP, FatalSignalHandler );
1039 signal( SIGQUIT, FatalSignalHandler );
1042 signal( SIGALRM, SimpleSignalHandler );
1043 signal( SIGPIPE, SimpleSignalHandler );
1047 /*****************************************************************************
1048 * SimpleSignalHandler: system signal handler
1049 *****************************************************************************
1050 * This function is called when a non fatal signal is received by the program.
1051 *****************************************************************************/
1052 static void SimpleSignalHandler( int i_signal )
1054 /* Acknowledge the signal received */
1055 intf_WarnMsg( 0, "intf: ignoring signal %d", i_signal );
1058 /*****************************************************************************
1059 * FatalSignalHandler: system signal handler
1060 *****************************************************************************
1061 * This function is called when a fatal signal is received by the program.
1062 * It tries to end the program in a clean way.
1063 *****************************************************************************/
1064 static void FatalSignalHandler( int i_signal )
1066 /* Once a signal has been trapped, the termination sequence will be
1067 * armed and following signals will be ignored to avoid sending messages
1068 * to an interface having been destroyed */
1070 signal( SIGINT, SIG_IGN );
1071 signal( SIGHUP, SIG_IGN );
1072 signal( SIGQUIT, SIG_IGN );
1075 /* Acknowledge the signal received */
1076 intf_ErrMsg( "intf error: signal %d received, exiting", i_signal );
1078 /* Try to terminate everything - this is done by requesting the end of the
1079 * interface thread */
1080 p_main->p_intf->b_die = 1;
1083 /*****************************************************************************
1084 * IllegalSignalHandler: system signal handler
1085 *****************************************************************************
1086 * This function is called when an illegal instruction signal is received by
1087 * the program. We use this function to test OS and CPU capabilities
1088 *****************************************************************************/
1089 static void IllegalSignalHandler( int i_signal )
1091 /* Acknowledge the signal received */
1094 #ifdef HAVE_SIGRELSE
1095 sigrelse( i_signal );
1098 fprintf( stderr, "warning: your CPU has %s instructions, but not your "
1099 "operating system.\n", psz_capability );
1100 fprintf( stderr, " some optimizations will be disabled unless "
1101 "you upgrade your OS\n" );
1103 fprintf( stderr, " (for instance Linux kernel 2.4.x or later)" );
1109 /*****************************************************************************
1110 * CPUCapabilities: list the processors MMX support and other capabilities
1111 *****************************************************************************
1112 * This function is called to list extensions the CPU may have.
1113 *****************************************************************************/
1114 static u32 CPUCapabilities( void )
1116 volatile u32 i_capabilities = CPU_CAPABILITY_NONE;
1118 #if defined( SYS_DARWIN )
1119 struct host_basic_info hi;
1121 host_name_port_t host;
1124 char *psz_name, *psz_subname;
1126 i_capabilities |= CPU_CAPABILITY_FPU;
1128 /* Should 'never' fail? */
1129 host = mach_host_self();
1131 i_size = sizeof( hi ) / sizeof( int );
1132 ret = host_info( host, HOST_BASIC_INFO, ( host_info_t )&hi, &i_size );
1134 if( ret != KERN_SUCCESS )
1136 fprintf( stderr, "error: couldn't get CPU information\n" );
1137 return( i_capabilities );
1140 slot_name( hi.cpu_type, hi.cpu_subtype, &psz_name, &psz_subname );
1141 /* FIXME: need better way to detect newer proccessors.
1142 * could do strncmp(a,b,5), but that's real ugly */
1143 if( !strcmp(psz_name, "ppc7400") || !strcmp(psz_name, "ppc7450") )
1145 i_capabilities |= CPU_CAPABILITY_ALTIVEC;
1148 return( i_capabilities );
1150 #elif defined( __i386__ )
1151 volatile unsigned int i_eax, i_ebx, i_ecx, i_edx;
1152 volatile boolean_t b_amd;
1154 /* Needed for x86 CPU capabilities detection */
1155 # define cpuid( a ) \
1156 asm volatile ( "pushl %%ebx\n\t" \
1158 "movl %%ebx,%1\n\t" \
1167 i_capabilities |= CPU_CAPABILITY_FPU;
1169 # if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
1170 signal( SIGILL, IllegalSignalHandler );
1173 /* test for a 486 CPU */
1174 asm volatile ( "pushl %%ebx\n\t"
1177 "movl %%eax, %%ebx\n\t"
1178 "xorl $0x200000, %%eax\n\t"
1190 if( i_eax == i_ebx )
1192 # if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
1193 signal( SIGILL, NULL );
1195 return( i_capabilities );
1198 i_capabilities |= CPU_CAPABILITY_486;
1200 /* the CPU supports the CPUID instruction - get its level */
1201 cpuid( 0x00000000 );
1205 # if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
1206 signal( SIGILL, NULL );
1208 return( i_capabilities );
1211 /* FIXME: this isn't correct, since some 486s have cpuid */
1212 i_capabilities |= CPU_CAPABILITY_586;
1214 /* borrowed from mpeg2dec */
1215 b_amd = ( i_ebx == 0x68747541 ) && ( i_ecx == 0x444d4163 )
1216 && ( i_edx == 0x69746e65 );
1218 /* test for the MMX flag */
1219 cpuid( 0x00000001 );
1221 if( ! (i_edx & 0x00800000) )
1223 # if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
1224 signal( SIGILL, NULL );
1226 return( i_capabilities );
1229 i_capabilities |= CPU_CAPABILITY_MMX;
1231 if( i_edx & 0x02000000 )
1233 i_capabilities |= CPU_CAPABILITY_MMXEXT;
1235 # ifdef CAN_COMPILE_SSE
1236 /* We test if OS support the SSE instructions */
1237 psz_capability = "SSE";
1239 if( setjmp( env ) == 0 )
1241 /* Test a SSE instruction */
1242 __asm__ __volatile__ ( "xorps %%xmm0,%%xmm0\n" : : );
1245 if( i_illegal == 0 )
1247 i_capabilities |= CPU_CAPABILITY_SSE;
1252 /* test for additional capabilities */
1253 cpuid( 0x80000000 );
1255 if( i_eax < 0x80000001 )
1257 # if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
1258 signal( SIGILL, NULL );
1260 return( i_capabilities );
1263 /* list these additional capabilities */
1264 cpuid( 0x80000001 );
1266 # ifdef CAN_COMPILE_3DNOW
1267 if( i_edx & 0x80000000 )
1269 psz_capability = "3D Now!";
1271 if( setjmp( env ) == 0 )
1273 /* Test a 3D Now! instruction */
1274 __asm__ __volatile__ ( "pfadd %%mm0,%%mm0\n" "femms\n" : : );
1277 if( i_illegal == 0 )
1279 i_capabilities |= CPU_CAPABILITY_3DNOW;
1284 if( b_amd && ( i_edx & 0x00400000 ) )
1286 i_capabilities |= CPU_CAPABILITY_MMXEXT;
1289 # if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW )
1290 signal( SIGILL, NULL );
1292 return( i_capabilities );
1294 #elif defined( __powerpc__ )
1296 i_capabilities |= CPU_CAPABILITY_FPU;
1298 # ifdef CAN_COMPILE_ALTIVEC
1299 signal( SIGILL, IllegalSignalHandler );
1301 psz_capability = "AltiVec";
1303 if( setjmp( env ) == 0 )
1305 asm volatile ("mtspr 256, %0\n\t"
1306 "vand %%v0, %%v0, %%v0"
1311 if( i_illegal == 0 )
1313 i_capabilities |= CPU_CAPABILITY_ALTIVEC;
1316 signal( SIGILL, NULL );
1319 return( i_capabilities );
1322 /* default behaviour */
1323 return( i_capabilities );
1328 /*****************************************************************************
1329 * ShowConsole: On Win32, create an output console for debug messages
1330 *****************************************************************************
1331 * This function is usefull only on Win32.
1332 *****************************************************************************/
1334 static void ShowConsole( void )
1337 freopen( "CONOUT$", "w", stdout );
1338 freopen( "CONOUT$", "w", stderr );
1339 freopen( "CONIN$", "r", stdin );