]> git.sesse.net Git - vlc/blob - src/interface/main.c
* Header cleaning: filled all empty authors fields, added CVS $Id stuff.
[vlc] / src / interface / main.c
1 /*****************************************************************************
2  * main.c: main vlc source
3  * Includes the main() function for vlc. Parses command line, start interface
4  * and spawn threads.
5  *****************************************************************************
6  * Copyright (C) 1998, 1999, 2000 VideoLAN
7  * $Id: main.c,v 1.80 2001/03/21 13:42:34 sam Exp $
8  *
9  * Authors: Vincent Seguin <seguin@via.ecp.fr>
10  *          Samuel Hocevar <sam@zoy.org>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  * 
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
25  *****************************************************************************/
26
27 /*****************************************************************************
28  * Preamble
29  *****************************************************************************/
30 #include "defs.h"
31
32 #include <signal.h>                               /* SIGHUP, SIGINT, SIGKILL */
33 #include <stdio.h>                                              /* sprintf() */
34
35 #ifdef HAVE_GETOPT_H
36 #include <getopt.h>                                              /* getopt() */
37 #endif
38
39 #ifdef SYS_DARWIN1_3
40 #include <mach/mach.h>                                  /* Altivec detection */
41 #include <mach/mach_error.h>          /* some day the header files||compiler *
42                                                        will define it for us */
43 #include <mach/bootstrap.h>
44 #endif
45
46 #include <unistd.h>
47 #include <errno.h>                                                 /* ENOMEM */
48 #include <stdlib.h>                                  /* getenv(), strtol(),  */
49 #include <string.h>                                            /* strerror() */
50
51 #include "config.h"
52 #include "common.h"
53 #include "debug.h"
54 #include "threads.h"
55 #include "mtime.h"
56 #include "tests.h"                                              /* TestCPU() */
57 #include "modules.h"
58
59 #include "stream_control.h"
60 #include "input_ext-intf.h"
61
62 #include "intf_msg.h"
63 #include "intf_playlist.h"
64 #include "interface.h"
65
66 #include "audio_output.h"
67
68 #include "video.h"
69 #include "video_output.h"
70
71 #ifdef SYS_BEOS
72 #include "beos_specific.h"
73 #endif
74
75 #include "main.h"
76
77 /*****************************************************************************
78  * Command line options constants. If something is changed here, be sure that
79  * GetConfiguration and Usage are also changed.
80  *****************************************************************************/
81
82 /* Long options return values - note that values corresponding to short options
83  * chars, and in general any regular char, should be avoided */
84 #define OPT_NOAUDIO             150
85 #define OPT_STEREO              151
86 #define OPT_MONO                152
87
88 #define OPT_NOVIDEO             160
89 #define OPT_DISPLAY             161
90 #define OPT_WIDTH               162
91 #define OPT_HEIGHT              163
92 #define OPT_COLOR               164
93 #define OPT_FULLSCREEN          165
94 #define OPT_OVERLAY             166
95
96 #define OPT_VLANS               170
97 #define OPT_SERVER              171
98 #define OPT_PORT                172
99 #define OPT_BROADCAST           173
100
101 #define OPT_INPUT               180
102 #define OPT_MOTION              181
103 #define OPT_IDCT                182
104 #define OPT_YUV                 183
105
106 #define OPT_SYNCHRO             190
107 #define OPT_WARNING             191
108
109 /* Usage fashion */
110 #define USAGE                     0
111 #define SHORT_HELP                1
112 #define LONG_HELP                 2
113
114 /* Long options */
115 #ifdef HAVE_GETOPT_H
116 static const struct option longopts[] =
117 {
118     /*  name,               has_arg,    flag,   val */
119
120     /* General/common options */
121     {   "help",             0,          0,      'h' },
122     {   "longhelp",         0,          0,      'H' },
123     {   "version",          0,          0,      'v' },
124
125     /* Interface options */
126     {   "intf",             1,          0,      'I' },
127     {   "warning",          1,          0,      OPT_WARNING },
128
129     /* Audio options */
130     {   "noaudio",          0,          0,      OPT_NOAUDIO },
131     {   "aout",             1,          0,      'A' },
132     {   "stereo",           0,          0,      OPT_STEREO },
133     {   "mono",             0,          0,      OPT_MONO },
134
135     /* Video options */
136     {   "novideo",          0,          0,      OPT_NOVIDEO },
137     {   "vout",             1,          0,      'V' },
138     {   "display",          1,          0,      OPT_DISPLAY },
139     {   "width",            1,          0,      OPT_WIDTH },
140     {   "height",           1,          0,      OPT_HEIGHT },
141     {   "grayscale",        0,          0,      'g' },
142     {   "color",            0,          0,      OPT_COLOR },
143     {   "motion",           1,          0,      OPT_MOTION },
144     {   "idct",             1,          0,      OPT_IDCT },
145     {   "yuv",              1,          0,      OPT_YUV },
146     {   "fullscreen",       0,          0,      OPT_FULLSCREEN },
147     {   "overlay",          0,          0,      OPT_OVERLAY },
148
149     /* DVD options */
150     {   "dvdtitle",         1,          0,      't' },
151     {   "dvdchapter",       1,          0,      'T' },
152     {   "dvdaudio",         1,          0,      'a' },
153     {   "dvdchannel",       1,          0,      'c' },
154     {   "dvdsubtitle",      1,          0,      's' },
155     
156     /* Input options */
157     {   "input",            1,          0,      OPT_INPUT },
158     {   "vlans",            0,          0,      OPT_VLANS },
159     {   "server",           1,          0,      OPT_SERVER },
160     {   "port",             1,          0,      OPT_PORT },
161     {   "broadcast",        0,          0,      OPT_BROADCAST },
162
163     /* Synchro options */
164     {   "synchro",          1,          0,      OPT_SYNCHRO },
165     {   0,                  0,          0,      0 }
166 };
167
168 /* Short options */
169 static const char *psz_shortopts = "hHvgt:T:a:s:c:I:A:V:";
170 #endif
171
172
173 /*****************************************************************************
174  * Global variable program_data - this is the one and only, see main.h
175  *****************************************************************************/
176 main_t *p_main;
177
178 /*****************************************************************************
179  * Local prototypes
180  *****************************************************************************/
181 static void SetDefaultConfiguration ( void );
182 static int  GetConfiguration        ( int i_argc, char *ppsz_argv[],
183                                       char *ppsz_env[] );
184 static int  GetFilenames            ( int i_argc, char *ppsz_argv[] );
185 static void Usage                   ( int i_fashion );
186 static void Version                 ( void );
187
188 static void InitSignalHandler       ( void );
189 static void SimpleSignalHandler     ( int i_signal );
190 static void FatalSignalHandler      ( int i_signal );
191
192 static int  CPUCapabilities         ( void );
193
194 /*****************************************************************************
195  * main: parse command line, start interface and spawn threads
196  *****************************************************************************
197  * Steps during program execution are:
198  *      -configuration parsing and messages interface initialization
199  *      -opening of audio output device and some global modules
200  *      -execution of interface, which exit on error or on user request
201  *      -closing of audio output device and some global modules
202  * On error, the spawned threads are canceled, and the open devices closed.
203  *****************************************************************************/
204 int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
205 {
206     main_t  main_data;                      /* root of all data - see main.h */
207
208     p_main = &main_data;                       /* set up the global variable */
209
210     /*
211      * System specific initialization code
212      */
213 #ifdef SYS_BEOS
214     beos_Create();
215 #endif
216
217     p_main->i_cpu_capabilities = CPUCapabilities();
218     
219     /*
220      * Test if our code is likely to run on this CPU 
221      */
222 #if defined( __pentium__ ) || defined( __pentiumpro__ )
223     if( ! TestCPU( CPU_CAPABILITY_586 ) )
224     {
225         fprintf( stderr, "error: this program needs a Pentium CPU,\n"
226                          "please try a version without Pentium support\n" );
227         return( 1 );
228     }
229 #endif
230
231 #ifdef HAVE_MMX
232     if( ! TestCPU( CPU_CAPABILITY_MMX ) )
233     {
234         fprintf( stderr, "error: this program needs MMX extensions,\n"
235                          "please try a version without MMX support\n" );
236         return( 1 );
237     }
238 #endif
239
240     /*
241      * Initialize messages interface
242      */
243     p_main->p_msg = intf_MsgCreate();
244     if( !p_main->p_msg )                         /* start messages interface */
245     {
246         fprintf( stderr, "error: can't initialize messages interface (%s)\n",
247                  strerror(errno) );
248         return( errno );
249     }
250
251     intf_MsgImm( COPYRIGHT_MESSAGE );
252
253     /*
254      * Read configuration
255      */
256     if( GetConfiguration( i_argc, ppsz_argv, ppsz_env ) )  /* parse cmd line */
257     {
258         intf_MsgDestroy();
259         return( errno );
260     }
261
262     p_main->i_warning_level = main_GetIntVariable( INTF_WARNING_VAR,
263                                                    INTF_WARNING_DEFAULT );
264
265     /*
266      * Initialize playlist and get commandline files
267      */
268     p_main->p_playlist = intf_PlaylistCreate( );
269     if( !p_main->p_playlist )
270     {
271         intf_ErrMsg( "playlist error: playlist initialization failed" );
272         intf_MsgDestroy();
273         return( errno );
274     }
275     intf_PlaylistInit( p_main->p_playlist );
276
277     /*
278      * Get input filenames given as commandline arguments
279      */
280     GetFilenames( i_argc, ppsz_argv );
281
282     /*
283      * Initialize module bank
284      */
285     p_main->p_bank = module_CreateBank( );
286     if( !p_main->p_bank )
287     {
288         intf_ErrMsg( "module error: module bank initialization failed" );
289         intf_PlaylistDestroy( p_main->p_playlist );
290         intf_MsgDestroy();
291         return( errno );
292     }
293     module_InitBank( p_main->p_bank );
294
295     /*
296      * Initialize shared resources and libraries
297      */
298     /* FIXME: no VLANs */
299 #if 0
300     if( p_main->b_vlans && input_VlanCreate() )
301     {
302         /* On error during vlans initialization, switch off vlans */
303         intf_Msg( "Virtual LANs initialization failed : "
304                   "vlans management is deactivated" );
305         p_main->b_vlans = 0;
306     }
307 #endif
308
309     /*
310      * Run interface
311      */
312     p_main->p_intf = intf_Create();
313     if( !p_main->p_intf )
314     {
315         intf_ErrMsg( "intf error: interface initialization failed" );
316         module_DestroyBank( p_main->p_bank );
317         intf_PlaylistDestroy( p_main->p_playlist );
318         intf_MsgDestroy();
319         return( errno );
320     }
321
322     /*
323      * Set signal handling policy for all threads
324      */
325     InitSignalHandler();
326
327     /*
328      * Open audio device and start aout thread
329      */
330     if( p_main->b_audio )
331     {
332         p_main->p_aout = aout_CreateThread( NULL );
333         if( p_main->p_aout == NULL )
334         {
335             /* On error during audio initialization, switch off audio */
336             intf_ErrMsg( "aout error: audio initialization failed,"
337                          " audio is deactivated" );
338             p_main->b_audio = 0;
339         }
340     }
341
342     /*
343      * Open video device and start vout thread
344      */
345     if( p_main->b_video )
346     {
347         p_main->p_vout = vout_CreateThread( NULL );
348         if( p_main->p_vout == NULL )
349         {
350             /* On error during video initialization, switch off video */
351             intf_ErrMsg( "vout error: video initialization failed,"
352                          " video is deactivated" );
353             p_main->b_video = 0;
354         }
355     }
356
357     /* Flush messages before entering the main loop */
358     intf_FlushMsg();
359
360     /*
361      * This is the main loop
362      */
363     p_main->p_intf->pf_run( p_main->p_intf );
364
365     intf_Destroy( p_main->p_intf );
366
367     /*
368      * Close video device
369      */
370     if( p_main->b_video )
371     {
372         vout_DestroyThread( p_main->p_vout, NULL );
373     }
374
375     /*
376      * Close audio device
377      */
378     if( p_main->b_audio )
379     {
380         aout_DestroyThread( p_main->p_aout, NULL );
381     }
382
383     /*
384      * Free shared resources and libraries
385      */
386     /* FIXME */
387 #if 0
388     if( p_main->b_vlans )
389     {
390         input_VlanDestroy();
391     }
392 #endif
393
394     /*
395      * Free module bank
396      */
397     module_DestroyBank( p_main->p_bank );
398
399     /*
400      * Free playlist
401      */
402     intf_PlaylistDestroy( p_main->p_playlist );
403
404 #ifdef SYS_BEOS
405     /*
406      * System specific cleaning code
407      */
408     beos_Destroy();
409 #endif
410
411     /*
412      * Terminate messages interface and program
413      */
414     intf_Msg( "intf: program terminated" );
415     intf_MsgDestroy();
416
417     return( 0 );
418 }
419
420 /*****************************************************************************
421  * main_GetIntVariable: get the int value of an environment variable
422  *****************************************************************************
423  * This function is used to read some default parameters in modules.
424  *****************************************************************************/
425 int main_GetIntVariable( char *psz_name, int i_default )
426 {
427     char *      psz_env;                                /* environment value */
428     char *      psz_end;                             /* end of parsing index */
429     long int    i_value;                                            /* value */
430
431     psz_env = getenv( psz_name );
432     if( psz_env )
433     {
434         i_value = strtol( psz_env, &psz_end, 0 );
435         if( (*psz_env != '\0') && (*psz_end == '\0') )
436         {
437             return( i_value );
438         }
439     }
440     return( i_default );
441 }
442
443 /*****************************************************************************
444  * main_GetPszVariable: get the string value of an environment variable
445  *****************************************************************************
446  * This function is used to read some default parameters in modules.
447  *****************************************************************************/
448 char * main_GetPszVariable( char *psz_name, char *psz_default )
449 {
450     char *psz_env;
451
452     psz_env = getenv( psz_name );
453     if( psz_env )
454     {
455         return( psz_env );
456     }
457     return( psz_default );
458 }
459
460 /*****************************************************************************
461  * main_PutPszVariable: set the string value of an environment variable
462  *****************************************************************************
463  * This function is used to set some default parameters in modules. The use of
464  * this function will cause some memory leak: since some systems use the pointer
465  * passed to putenv to store the environment string, it can't be freed.
466  *****************************************************************************/
467 void main_PutPszVariable( char *psz_name, char *psz_value )
468 {
469     char *psz_env;
470
471     psz_env = malloc( strlen(psz_name) + strlen(psz_value) + 2 );
472     if( psz_env == NULL )
473     {
474         intf_ErrMsg( "intf error: cannot create psz_env (%s)",
475                      strerror(ENOMEM) );
476     }
477     else
478     {
479         sprintf( psz_env, "%s=%s", psz_name, psz_value );
480         if( putenv( psz_env ) )
481         {
482             intf_ErrMsg( "intf error: cannot putenv (%s)", strerror(errno) );
483         }
484     }
485 }
486
487 /*****************************************************************************
488  * main_PutIntVariable: set the integer value of an environment variable
489  *****************************************************************************
490  * This function is used to set some default parameters in modules. The use of
491  * this function will cause some memory leak: since some systems use the pointer
492  * passed to putenv to store the environment string, it can't be freed.
493  *****************************************************************************/
494 void main_PutIntVariable( char *psz_name, int i_value )
495 {
496     char psz_value[ 256 ];                               /* buffer for value */
497
498     sprintf( psz_value, "%d", i_value );
499     main_PutPszVariable( psz_name, psz_value );
500 }
501
502 /* following functions are local */
503
504 /*****************************************************************************
505  * SetDefaultConfiguration: set default options
506  *****************************************************************************
507  * This function is called by GetConfiguration before command line is parsed.
508  * It sets all the default values required later by the program. At this stage,
509  * most structure are not yet allocated, so initialization must be done using
510  * environment.
511  *****************************************************************************/
512 static void SetDefaultConfiguration( void )
513 {
514     /*
515      * All features are activated by default except vlans
516      */
517     p_main->b_audio  = 1;
518     p_main->b_video  = 1;
519     p_main->b_vlans  = 0;
520 }
521
522 /*****************************************************************************
523  * GetConfiguration: parse command line
524  *****************************************************************************
525  * Parse command line and configuration file for configuration. If the inline
526  * help is requested, the function Usage() is called and the function returns
527  * -1 (causing main() to exit). The messages interface is initialized at this
528  * stage, but most structures are not allocated, so only environment should
529  * be used.
530  *****************************************************************************/
531 static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
532 {
533     int c;
534     char * p_pointer;
535
536     /* Set default configuration and copy arguments */
537     p_main->i_argc    = i_argc;
538     p_main->ppsz_argv = ppsz_argv;
539     p_main->ppsz_env  = ppsz_env;
540     SetDefaultConfiguration();
541
542     /* Get the executable name (similar to the basename command) */
543     p_main->psz_arg0 = p_pointer = ppsz_argv[ 0 ];
544     while( *p_pointer )
545     {
546         if( *p_pointer == '/' )
547         {
548             p_main->psz_arg0 = ++p_pointer;
549         }
550         else
551         {
552             ++p_pointer;
553         }
554     }
555
556     /* Parse command line options */
557 #ifdef HAVE_GETOPT_H
558     opterr = 0;
559     while( ( c = getopt_long( i_argc, ppsz_argv, psz_shortopts, longopts, 0 ) ) != EOF )
560     {
561         switch( c )
562         {
563         /* General/common options */
564         case 'h':                                              /* -h, --help */
565             Usage( SHORT_HELP );
566             return( -1 );
567             break;
568         case 'H':                                          /* -H, --longhelp */
569             Usage( LONG_HELP );
570             return( -1 );
571             break;
572         case 'v':                                           /* -v, --version */
573             Version();
574             return( -1 );
575             break;
576
577         /* Interface warning messages level */
578         case 'I':                                              /* -I, --intf */
579             main_PutPszVariable( INTF_METHOD_VAR, optarg );
580             break;
581         case OPT_WARNING:                                       /* --warning */
582             main_PutIntVariable( INTF_WARNING_VAR, atoi(optarg) );
583             break;
584
585         /* Audio options */
586         case OPT_NOAUDIO:                                       /* --noaudio */
587             p_main->b_audio = 0;
588             break;
589         case 'A':                                              /* -A, --aout */
590             main_PutPszVariable( AOUT_METHOD_VAR, optarg );
591             break;
592         case OPT_STEREO:                                         /* --stereo */
593             main_PutIntVariable( AOUT_STEREO_VAR, 1 );
594             break;
595         case OPT_MONO:                                             /* --mono */
596             main_PutIntVariable( AOUT_STEREO_VAR, 0 );
597             break;
598
599         /* Video options */
600         case OPT_NOVIDEO:                                       /* --novideo */
601             p_main->b_video = 0;
602             break;
603         case 'V':                                              /* -V, --vout */
604             main_PutPszVariable( VOUT_METHOD_VAR, optarg );
605             break;
606         case OPT_DISPLAY:                                       /* --display */
607             main_PutPszVariable( VOUT_DISPLAY_VAR, optarg );
608             break;
609         case OPT_WIDTH:                                           /* --width */
610             main_PutPszVariable( VOUT_WIDTH_VAR, optarg );
611             break;
612         case OPT_HEIGHT:                                         /* --height */
613             main_PutPszVariable( VOUT_HEIGHT_VAR, optarg );
614             break;
615         case 'g':                                         /* -g, --grayscale */
616             main_PutIntVariable( VOUT_GRAYSCALE_VAR, 1 );
617             break;
618         case OPT_COLOR:                                           /* --color */
619             main_PutIntVariable( VOUT_GRAYSCALE_VAR, 0 );
620             break;
621         case OPT_FULLSCREEN:                                 /* --fullscreen */
622             main_PutIntVariable( VOUT_FULLSCREEN_VAR, 1 );
623             break;
624         case OPT_OVERLAY:                                       /* --overlay */
625             main_PutIntVariable( VOUT_OVERLAY_VAR, 1 );
626             break;
627         case OPT_MOTION:                                         /* --motion */
628             main_PutPszVariable( MOTION_METHOD_VAR, optarg );
629             break;
630         case OPT_IDCT:                                             /* --idct */
631             main_PutPszVariable( IDCT_METHOD_VAR, optarg );
632             break;
633         case OPT_YUV:                                               /* --yuv */
634             main_PutPszVariable( YUV_METHOD_VAR, optarg );
635             break;
636
637         /* DVD options */
638         case 't':
639             main_PutIntVariable( INPUT_TITLE_VAR, atoi(optarg) );
640             break;
641         case 'T':
642             main_PutIntVariable( INPUT_CHAPTER_VAR, atoi(optarg) );
643             break;
644         case 'a':
645             if ( ! strcmp(optarg, "ac3") )
646                 main_PutIntVariable( INPUT_AUDIO_VAR, REQUESTED_AC3 );
647             else if ( ! strcmp(optarg, "lpcm") )
648                 main_PutIntVariable( INPUT_AUDIO_VAR, REQUESTED_LPCM );
649             else if ( ! strcmp(optarg, "mpeg") )
650                 main_PutIntVariable( INPUT_AUDIO_VAR, REQUESTED_MPEG );
651             else
652                 main_PutIntVariable( INPUT_AUDIO_VAR, REQUESTED_NOAUDIO );
653             break;
654         case 'c':
655             main_PutIntVariable( INPUT_CHANNEL_VAR, atoi(optarg) );
656             break;
657         case 's':
658             main_PutIntVariable( INPUT_SUBTITLE_VAR, atoi(optarg) );
659             break;
660
661         /* Input options */
662         case OPT_INPUT:                                           /* --input */
663             main_PutPszVariable( INPUT_METHOD_VAR, optarg );
664             break;
665         case OPT_VLANS:                                           /* --vlans */
666             p_main->b_vlans = 1;
667             break;
668         case OPT_SERVER:                                         /* --server */
669             main_PutPszVariable( INPUT_SERVER_VAR, optarg );
670             break;
671         case OPT_PORT:                                             /* --port */
672             main_PutPszVariable( INPUT_PORT_VAR, optarg );
673             break;
674         case OPT_BROADCAST:                                   /* --broadcast */
675             main_PutIntVariable( INPUT_BROADCAST_VAR, 1 );
676             break;
677
678         /* Synchro options */
679         case OPT_SYNCHRO:                                      
680             main_PutPszVariable( VPAR_SYNCHRO_VAR, optarg );
681             break;
682             
683         /* Internal error: unknown option */
684         case '?':
685         default:
686             intf_ErrMsg( "intf error: unknown option `%s'", ppsz_argv[optind - 1] );
687             Usage( USAGE );
688             return( EINVAL );
689             break;
690         }
691     }
692 #endif
693     return( 0 );
694 }
695
696 /*****************************************************************************
697  * GetFilenames: parse command line options which are not flags
698  *****************************************************************************
699  * Parse command line for input files.
700  *****************************************************************************/
701 static int GetFilenames( int i_argc, char *ppsz_argv[] )
702 {
703     int i_opt;
704
705     /* We assume that the remaining parameters are filenames */
706     for( i_opt = optind; i_opt < i_argc; i_opt++ )
707     {
708         intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END,
709                           ppsz_argv[ i_opt ] );
710     }
711
712     return( 0 );
713 }
714
715 /*****************************************************************************
716  * Usage: print program usage
717  *****************************************************************************
718  * Print a short inline help. Message interface is initialized at this stage.
719  *****************************************************************************/
720 static void Usage( int i_fashion )
721 {
722     /* Usage */
723     intf_MsgImm( "Usage: %s [options] [parameters] [file]...",
724                  p_main->psz_arg0 );
725
726     if( i_fashion == USAGE )
727     {
728         intf_MsgImm( "Try `%s --help' for more information.",
729                      p_main->psz_arg0 );
730         return;
731     }
732
733     /* Options */
734     intf_MsgImm( "\nOptions:"
735           "\n  -I, --intf <module>            \tinterface method"
736           "\n      --warning <level>          \tdisplay warning messages"
737           "\n"
738           "\n      --noaudio                  \tdisable audio"
739           "\n  -A, --aout <module>            \taudio output method"
740           "\n      --stereo, --mono           \tstereo/mono audio"
741           "\n"
742           "\n      --novideo                  \tdisable video"
743           "\n  -V, --vout <module>            \tvideo output method"
744           "\n      --display <display>        \tdisplay string"
745           "\n      --width <w>, --height <h>  \tdisplay dimensions"
746           "\n  -g, --grayscale                \tgrayscale output"
747           "\n      --fullscreen               \tfullscreen output"
748           "\n      --overlay                  \taccelerated display"
749           "\n      --color                    \tcolor output"
750           "\n      --motion <module>          \tmotion compensation method"
751           "\n      --idct <module>            \tIDCT method"
752           "\n      --yuv <module>             \tYUV method"
753           "\n      --synchro <type>           \tforce synchro algorithm"
754           "\n"
755           "\n  -t, --dvdtitle <num>           \tchoose DVD title"
756           "\n  -T, --dvdchapter <num>         \tchoose DVD chapter"
757           "\n  -a, --dvdaudio <type>          \tchoose DVD audio type"
758           "\n  -c, --dvdchannel <channel>     \tchoose DVD audio channel"
759           "\n  -s, --dvdsubtitle <channel>    \tchoose DVD subtitle channel"
760           "\n"
761           "\n      --input                    \tinput method"
762           "\n      --vlans                    \tenable vlans"
763           "\n      --server <host>            \tvideo server address"
764           "\n      --port <port>              \tvideo server port"
765           "\n      --broadcast                \tlisten to a broadcast"
766           "\n"
767           "\n  -h, --help                     \tprint help and exit"
768           "\n  -H, --longhelp                 \tprint long help and exit"
769           "\n  -v, --version                  \toutput version information and exit" );
770
771     if( i_fashion == SHORT_HELP )
772         return;
773
774     /* Interface parameters */
775     intf_MsgImm( "\nInterface parameters:"
776         "\n  " INTF_METHOD_VAR "=<method name>          \tinterface method"
777         "\n  " INTF_INIT_SCRIPT_VAR "=<filename>               \tinitialization script"
778         "\n  " INTF_CHANNELS_VAR "=<filename>            \tchannels list"
779         "\n  " INTF_WARNING_VAR "=<level>                \twarning level" );
780
781     /* Audio parameters */
782     intf_MsgImm( "\nAudio parameters:"
783         "\n  " AOUT_METHOD_VAR "=<method name>        \taudio method"
784         "\n  " AOUT_DSP_VAR "=<filename>              \tdsp device path"
785         "\n  " AOUT_STEREO_VAR "={1|0}                \tstereo or mono output"
786         "\n  " AOUT_RATE_VAR "=<rate>             \toutput rate" );
787
788     /* Video parameters */
789     intf_MsgImm( "\nVideo parameters:"
790         "\n  " VOUT_METHOD_VAR "=<method name>        \tdisplay method"
791         "\n  " VOUT_DISPLAY_VAR "=<display name>      \tdisplay used"
792         "\n  " VOUT_WIDTH_VAR "=<width>               \tdisplay width"
793         "\n  " VOUT_HEIGHT_VAR "=<height>             \tdislay height"
794         "\n  " VOUT_FB_DEV_VAR "=<filename>           \tframebuffer device path"
795         "\n  " VOUT_GRAYSCALE_VAR "={1|0}             \tgrayscale or color output"
796         "\n  " VOUT_FULLSCREEN_VAR "={1|0}            \tfullscreen"
797         "\n  " VOUT_OVERLAY_VAR "={1|0}               \toverlay"
798         "\n  " MOTION_METHOD_VAR "=<method name>      \tmotion compensation method"
799         "\n  " IDCT_METHOD_VAR "=<method name>        \tIDCT method"
800         "\n  " YUV_METHOD_VAR "=<method name>         \tYUV method"
801         "\n  " VPAR_SYNCHRO_VAR "={I|I+|IP|IP+|IPB}   \tsynchro algorithm" );
802
803     /* DVD parameters */
804     intf_MsgImm( "\nDVD parameters:"
805         "\n  " INPUT_DVD_DEVICE_VAR "=<device>           \tDVD device"
806         "\n  " INPUT_TITLE_VAR "=<title>             \ttitle number"
807         "\n  " INPUT_CHAPTER_VAR "=<chapter>         \tchapter number"
808         "\n  " INPUT_AUDIO_VAR "={ac3|lpcm|mpeg|off} \taudio type"
809         "\n  " INPUT_CHANNEL_VAR "=[0-15]            \taudio channel"
810         "\n  " INPUT_SUBTITLE_VAR "=[0-31]           \tsubtitle channel" );
811
812     /* Input parameters */
813     intf_MsgImm( "\nInput parameters:"
814         "\n  " INPUT_SERVER_VAR "=<hostname>          \tvideo server"
815         "\n  " INPUT_PORT_VAR "=<port>            \tvideo server port"
816         "\n  " INPUT_IFACE_VAR "=<interface>          \tnetwork interface"
817         "\n  " INPUT_BROADCAST_VAR "={1|0}            \tbroadcast mode"
818         "\n  " INPUT_VLAN_SERVER_VAR "=<hostname>     \tvlan server"
819         "\n  " INPUT_VLAN_PORT_VAR "=<port>           \tvlan server port" );
820
821 }
822
823 /*****************************************************************************
824  * Version: print complete program version
825  *****************************************************************************
826  * Print complete program version and build number.
827  *****************************************************************************/
828 static void Version( void )
829 {
830     intf_MsgImm( VERSION_MESSAGE
831         "This program comes with NO WARRANTY, to the extent permitted by law.\n"
832         "You may redistribute it under the terms of the GNU General Public License;\n"
833         "see the file named COPYING for details.\n"
834         "Written by the VideoLAN team at Ecole Centrale, Paris." );
835 }
836
837 /*****************************************************************************
838  * InitSignalHandler: system signal handler initialization
839  *****************************************************************************
840  * Set the signal handlers. SIGTERM is not intercepted, because we need at
841  * at least a method to kill the program when all other methods failed, and
842  * when we don't want to use SIGKILL.
843  *****************************************************************************/
844 static void InitSignalHandler( void )
845 {
846     /* Termination signals */
847     signal( SIGHUP,  FatalSignalHandler );
848     signal( SIGINT,  FatalSignalHandler );
849     signal( SIGQUIT, FatalSignalHandler );
850
851     /* Other signals */
852     signal( SIGALRM, SimpleSignalHandler );
853     signal( SIGPIPE, SimpleSignalHandler );
854 }
855
856
857 /*****************************************************************************
858  * SimpleSignalHandler: system signal handler
859  *****************************************************************************
860  * This function is called when a non fatal signal is received by the program.
861  *****************************************************************************/
862 static void SimpleSignalHandler( int i_signal )
863 {
864     /* Acknowledge the signal received */
865     intf_WarnMsg( 0, "intf: ignoring signal %d", i_signal );
866 }
867
868
869 /*****************************************************************************
870  * FatalSignalHandler: system signal handler
871  *****************************************************************************
872  * This function is called when a fatal signal is received by the program.
873  * It tries to end the program in a clean way.
874  *****************************************************************************/
875 static void FatalSignalHandler( int i_signal )
876 {
877     /* Once a signal has been trapped, the termination sequence will be
878      * armed and following signals will be ignored to avoid sending messages
879      * to an interface having been destroyed */
880     signal( SIGHUP,  SIG_IGN );
881     signal( SIGINT,  SIG_IGN );
882     signal( SIGQUIT, SIG_IGN );
883
884     /* Acknowledge the signal received */
885     intf_ErrMsgImm( "intf error: signal %d received, exiting", i_signal );
886
887     /* Try to terminate everything - this is done by requesting the end of the
888      * interface thread */
889     p_main->p_intf->b_die = 1;
890 }
891
892 /*****************************************************************************
893  * CPUCapabilities: list the processors MMX support and other capabilities
894  *****************************************************************************
895  * This function is called to list extensions the CPU may have.
896  *****************************************************************************/
897 static int CPUCapabilities( void )
898 {
899     int i_capabilities = CPU_CAPABILITY_NONE;
900
901 #if defined( SYS_BEOS )
902     i_capabilities |= CPU_CAPABILITY_486
903                       | CPU_CAPABILITY_586
904                       | CPU_CAPABILITY_MMX;
905
906 #elif defined( SYS_DARWIN1_3 )
907
908     struct host_basic_info hi;
909     kern_return_t          ret;
910     host_name_port_t       host;
911
912     int i_size;
913     char *psz_name, *psz_subname;
914
915     /* Should 'never' fail? */
916     host = mach_host_self();
917
918     i_size = sizeof( hi ) / sizeof( int );
919     ret = host_info( host, HOST_BASIC_INFO, ( host_info_t )&hi, &i_size );
920
921     if( ret != KERN_SUCCESS )
922     {
923         intf_ErrMsg( "error: couldn't get CPU information" );
924         return( i_capabilities );
925     }
926
927     slot_name( hi.cpu_type, hi.cpu_subtype, &psz_name, &psz_subname );
928     /* FIXME: need better way to detect newer proccessors.
929      * could do strncmp(a,b,5), but that's real ugly */
930     if( strcmp(psz_name, "ppc7400") || strcmp(psz_name, "ppc7450") )
931     {
932         i_capabilities |= CPU_CAPABILITY_ALTIVEC;
933     }
934
935 #elif defined( __i386__ )
936     unsigned int  i_eax, i_ebx, i_ecx, i_edx;
937     boolean_t     b_amd;
938
939 #   define cpuid( a )              \
940     asm volatile ( "cpuid"         \
941                  : "=a" ( i_eax ), \
942                    "=b" ( i_ebx ), \
943                    "=c" ( i_ecx ), \
944                    "=d" ( i_edx )  \
945                  : "a"  ( a )      \
946                  : "cc" );         \
947
948     /* test for a 486 CPU */
949     asm volatile ( "pushfl
950                     popl %%eax
951                     movl %%eax, %%ebx
952                     xorl $0x200000, %%eax
953                     pushl %%eax
954                     popfl
955                     pushfl
956                     popl %%eax"
957                  : "=a" ( i_eax ),
958                    "=b" ( i_ebx )
959                  :
960                  : "cc" );
961
962     if( i_eax == i_ebx )
963     {
964         return( i_capabilities );
965     }
966
967     i_capabilities |= CPU_CAPABILITY_486;
968
969     /* the CPU supports the CPUID instruction - get its level */
970     cpuid( 0x00000000 );
971
972     if( !i_eax )
973     {
974         return( i_capabilities );
975     }
976
977     /* FIXME: this isn't correct, since some 486s have cpuid */
978     i_capabilities |= CPU_CAPABILITY_586;
979
980     /* borrowed from mpeg2dec */
981     b_amd = ( i_ebx == 0x68747541 ) && ( i_ecx == 0x444d4163 )
982                     && ( i_edx == 0x69746e65 );
983
984     /* test for the MMX flag */
985     cpuid( 0x00000001 );
986
987     if( ! (i_edx & 0x00800000) )
988     {
989         return( i_capabilities );
990     }
991
992     i_capabilities |= CPU_CAPABILITY_MMX;
993
994     if( i_edx & 0x02000000 )
995     {
996         i_capabilities |= CPU_CAPABILITY_MMXEXT;
997     }
998     
999     /* test for additional capabilities */
1000     cpuid( 0x80000000 );
1001
1002     if( i_eax < 0x80000001 )
1003     {
1004         return( i_capabilities );
1005     }
1006
1007     /* list these additional capabilities */
1008     cpuid( 0x80000001 );
1009
1010     if( i_edx & 0x80000000 )
1011     {
1012         i_capabilities |= CPU_CAPABILITY_3DNOW;
1013     }
1014
1015     if( b_amd && ( i_edx & 0x00400000 ) )
1016     {
1017         i_capabilities |= CPU_CAPABILITY_MMXEXT;
1018     }
1019
1020 #else
1021     /* default behaviour */
1022
1023 #endif
1024     return( i_capabilities );
1025 }
1026