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