main.c 53.7 KB
Newer Older
1
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
2 3 4
 * main.c: main vlc source
 * Includes the main() function for vlc. Parses command line, start interface
 * and spawn threads.
5
 *****************************************************************************
6
 * Copyright (C) 1998-2001 VideoLAN
Sam Hocevar's avatar
 
Sam Hocevar committed
7
 * $Id: main.c,v 1.151 2002/02/15 13:32:54 sam Exp $
8
 *
Sam Hocevar's avatar
 
Sam Hocevar committed
9 10
 * Authors: Vincent Seguin <seguin@via.ecp.fr>
 *          Samuel Hocevar <sam@zoy.org>
11 12 13 14 15
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
16
 * 
17 18
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
21
 *
22 23 24
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
25
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
26

27
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
28
 * Preamble
29
 *****************************************************************************/
30 31
#include <signal.h>                               /* SIGHUP, SIGINT, SIGKILL */
#include <stdio.h>                                              /* sprintf() */
32
#include <setjmp.h>                                       /* longjmp, setjmp */
33

Sam Hocevar's avatar
 
Sam Hocevar committed
34 35
#include <videolan/vlc.h>

Sam Hocevar's avatar
 
Sam Hocevar committed
36 37 38 39 40 41
#ifdef HAVE_GETOPT_LONG
#   ifdef HAVE_GETOPT_H
#       include <getopt.h>                                       /* getopt() */
#   endif
#else
#   include "GNUgetopt/getopt.h"
Benoit Steiner's avatar
Benoit Steiner committed
42 43
#endif

Sam Hocevar's avatar
 
Sam Hocevar committed
44
#ifdef SYS_DARWIN
Sam Hocevar's avatar
 
Sam Hocevar committed
45 46
#   include <mach/mach.h>                               /* Altivec detection */
#   include <mach/mach_error.h>       /* some day the header files||compiler *
Sam Hocevar's avatar
 
Sam Hocevar committed
47
                                                       will define it for us */
Sam Hocevar's avatar
 
Sam Hocevar committed
48
#   include <mach/bootstrap.h>
Sam Hocevar's avatar
 
Sam Hocevar committed
49
#endif
Sam Hocevar's avatar
 
Sam Hocevar committed
50 51

#ifndef WIN32
Sam Hocevar's avatar
 
Sam Hocevar committed
52
#   include <netinet/in.h>                            /* BSD: struct in_addr */
Sam Hocevar's avatar
 
Sam Hocevar committed
53
#endif
Sam Hocevar's avatar
 
Sam Hocevar committed
54

Sam Hocevar's avatar
 
Sam Hocevar committed
55
#ifdef HAVE_UNISTD_H
Sam Hocevar's avatar
 
Sam Hocevar committed
56 57 58
#   include <unistd.h>
#elif defined( _MSC_VER ) && defined( _WIN32 )
#   include <io.h>
Sam Hocevar's avatar
 
Sam Hocevar committed
59 60
#endif

Sam Hocevar's avatar
 
Sam Hocevar committed
61 62 63 64
#ifdef HAVE_LOCALE_H
#    include <locale.h>
#endif

65 66 67
#include <errno.h>                                                 /* ENOMEM */
#include <stdlib.h>                                  /* getenv(), strtol(),  */
#include <string.h>                                            /* strerror() */
gbazin's avatar
 
gbazin committed
68 69
#include <fcntl.h>                                       /* open(), O_WRONLY */
#include <sys/stat.h>                                             /* S_IREAD */
Vincent Seguin's avatar
Vincent Seguin committed
70

Sam Hocevar's avatar
 
Sam Hocevar committed
71
#include "netutils.h"                                 /* network_ChannelJoin */
Sam Hocevar's avatar
 
Sam Hocevar committed
72

73 74
#include "stream_control.h"
#include "input_ext-intf.h"
75

Sam Hocevar's avatar
 
Sam Hocevar committed
76
#include "intf_playlist.h"
Michel Kaempf's avatar
Michel Kaempf committed
77
#include "interface.h"
78

Vincent Seguin's avatar
Vincent Seguin committed
79
#include "audio_output.h"
80

Sam Hocevar's avatar
 
Sam Hocevar committed
81 82 83
#include "video.h"
#include "video_output.h"

Sam Hocevar's avatar
 
Sam Hocevar committed
84
#include "debug.h"
Henri Fallon's avatar
 
Henri Fallon committed
85

86
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
87 88
 * Command line options constants. If something is changed here, be sure that
 * GetConfiguration and Usage are also changed.
89
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
90 91 92 93

/* Long options return values - note that values corresponding to short options
 * chars, and in general any regular char, should be avoided */
#define OPT_NOAUDIO             150
Sam Hocevar's avatar
 
Sam Hocevar committed
94 95
#define OPT_STEREO              151
#define OPT_MONO                152
96
#define OPT_SPDIF               153
97
#define OPT_VOLUME              154
98
#define OPT_DESYNC              155
Michel Kaempf's avatar
Michel Kaempf committed
99 100

#define OPT_NOVIDEO             160
Sam Hocevar's avatar
 
Sam Hocevar committed
101 102 103 104 105
#define OPT_DISPLAY             161
#define OPT_WIDTH               162
#define OPT_HEIGHT              163
#define OPT_COLOR               164
#define OPT_FULLSCREEN          165
gbazin's avatar
 
gbazin committed
106
#define OPT_NOOVERLAY           166
Sam Hocevar's avatar
 
Sam Hocevar committed
107 108
#define OPT_XVADAPTOR           167
#define OPT_SMP                 168
Sam Hocevar's avatar
 
Sam Hocevar committed
109
#define OPT_SPUMARGIN           169
Michel Kaempf's avatar
Michel Kaempf committed
110

Henri Fallon's avatar
 
Henri Fallon committed
111
#define OPT_CHANNELS            170
112 113
#define OPT_SERVER              171
#define OPT_PORT                172
114
#define OPT_BROADCAST           173
115
#define OPT_CHANNELSERVER       174
116

Sam Hocevar's avatar
 
Sam Hocevar committed
117 118 119 120
#define OPT_INPUT               180
#define OPT_MOTION              181
#define OPT_IDCT                182
#define OPT_YUV                 183
Sam Hocevar's avatar
 
Sam Hocevar committed
121 122
#define OPT_DOWNMIX             184
#define OPT_IMDCT               185
Sam Hocevar's avatar
 
Sam Hocevar committed
123
#define OPT_MEMCPY              186
Sam Hocevar's avatar
 
Sam Hocevar committed
124 125 126
#define OPT_FILTER              187
#define OPT_DVDCSS_METHOD       188
#define OPT_DVDCSS_VERBOSE      189
127

Sam Hocevar's avatar
 
Sam Hocevar committed
128 129
#define OPT_SYNCHRO             190
#define OPT_WARNING             191
Sam Hocevar's avatar
 
Sam Hocevar committed
130
#define OPT_VERSION             192
gbazin's avatar
 
gbazin committed
131
#define OPT_STDOUT              193
132
#define OPT_STATS               194
133

134
#define OPT_MPEG_ADEC           200
gbazin's avatar
 
gbazin committed
135
#define OPT_AC3_ADEC            201
136

gbazin's avatar
 
gbazin committed
137 138 139 140 141
#define OPT_NOMMX               210
#define OPT_NO3DNOW             211
#define OPT_NOMMXEXT            212
#define OPT_NOSSE               213
#define OPT_NOALTIVEC           214
Sam Hocevar's avatar
 
Sam Hocevar committed
142

143
/* Usage fashion */
144 145 146
#define USAGE                     0
#define SHORT_HELP                1
#define LONG_HELP                 2
147

Michel Kaempf's avatar
Michel Kaempf committed
148 149
/* Long options */
static const struct option longopts[] =
150 151
{
    /*  name,               has_arg,    flag,   val */
Michel Kaempf's avatar
Michel Kaempf committed
152 153

    /* General/common options */
154
    {   "help",             0,          0,      'h' },
155
    {   "longhelp",         0,          0,      'H' },
Sam Hocevar's avatar
 
Sam Hocevar committed
156
    {   "version",          0,          0,      OPT_VERSION },
Michel Kaempf's avatar
Michel Kaempf committed
157

Sam Hocevar's avatar
 
Sam Hocevar committed
158
    /* Interface options */
Sam Hocevar's avatar
 
Sam Hocevar committed
159
    {   "intf",             1,          0,      'I' },
Sam Hocevar's avatar
 
Sam Hocevar committed
160
    {   "warning",          1,          0,      OPT_WARNING },
gbazin's avatar
 
gbazin committed
161
    {   "stdout",           1,          0,      OPT_STDOUT },
162
    {   "stats",            0,          0,      OPT_STATS },
Sam Hocevar's avatar
 
Sam Hocevar committed
163

Michel Kaempf's avatar
Michel Kaempf committed
164
    /* Audio options */
165
    {   "noaudio",          0,          0,      OPT_NOAUDIO },
Sam Hocevar's avatar
 
Sam Hocevar committed
166
    {   "aout",             1,          0,      'A' },
Michel Kaempf's avatar
Michel Kaempf committed
167
    {   "stereo",           0,          0,      OPT_STEREO },
168
    {   "mono",             0,          0,      OPT_MONO },
169
    {   "spdif",            0,          0,      OPT_SPDIF },
Sam Hocevar's avatar
 
Sam Hocevar committed
170 171
    {   "downmix",          1,          0,      OPT_DOWNMIX },
    {   "imdct",            1,          0,      OPT_IMDCT },
172
    {   "volume",           1,          0,      OPT_VOLUME },
173
    {   "desync",           1,          0,      OPT_DESYNC },
Michel Kaempf's avatar
Michel Kaempf committed
174 175

    /* Video options */
176
    {   "novideo",          0,          0,      OPT_NOVIDEO },
Sam Hocevar's avatar
 
Sam Hocevar committed
177
    {   "vout",             1,          0,      'V' },
178
    {   "display",          1,          0,      OPT_DISPLAY },
179
    {   "width",            1,          0,      OPT_WIDTH },
180 181 182
    {   "height",           1,          0,      OPT_HEIGHT },
    {   "grayscale",        0,          0,      'g' },
    {   "color",            0,          0,      OPT_COLOR },
Sam Hocevar's avatar
 
Sam Hocevar committed
183
    {   "motion",           1,          0,      OPT_MOTION },
Sam Hocevar's avatar
 
Sam Hocevar committed
184
    {   "idct",             1,          0,      OPT_IDCT },
Sam Hocevar's avatar
Sam Hocevar committed
185
    {   "yuv",              1,          0,      OPT_YUV },
Sam Hocevar's avatar
 
Sam Hocevar committed
186
    {   "fullscreen",       0,          0,      OPT_FULLSCREEN },
gbazin's avatar
 
gbazin committed
187
    {   "nooverlay",        0,          0,      OPT_NOOVERLAY },
Sam Hocevar's avatar
 
Sam Hocevar committed
188
    {   "xvadaptor",        1,          0,      OPT_XVADAPTOR },
189
    {   "smp",              1,          0,      OPT_SMP },
Sam Hocevar's avatar
 
Sam Hocevar committed
190
    {   "spumargin",        1,          0,      OPT_SPUMARGIN },
Michel Kaempf's avatar
Michel Kaempf committed
191

192
    /* DVD options */
193 194
    {   "dvdtitle",         1,          0,      't' },
    {   "dvdchapter",       1,          0,      'T' },
195
    {   "dvdangle",         1,          0,      'u' },
196 197 198
    {   "dvdaudio",         1,          0,      'a' },
    {   "dvdchannel",       1,          0,      'c' },
    {   "dvdsubtitle",      1,          0,      's' },
Sam Hocevar's avatar
 
Sam Hocevar committed
199 200
    {   "dvdcss-method",    1,          0,      OPT_DVDCSS_METHOD },
    {   "dvdcss-verbose",   1,          0,      OPT_DVDCSS_VERBOSE },
Sam Hocevar's avatar
 
Sam Hocevar committed
201

202
    /* Input options */
Sam Hocevar's avatar
 
Sam Hocevar committed
203
    {   "input",            1,          0,      OPT_INPUT },
204
    {   "channels",         0,          0,      OPT_CHANNELS },
205
    {   "channelserver",    1,          0,      OPT_CHANNELSERVER },
Michel Kaempf's avatar
Michel Kaempf committed
206

Sam Hocevar's avatar
 
Sam Hocevar committed
207
    /* Misc options */
208
    {   "synchro",          1,          0,      OPT_SYNCHRO },
Sam Hocevar's avatar
 
Sam Hocevar committed
209
    {   "memcpy",           1,          0,      OPT_MEMCPY },
Sam Hocevar's avatar
 
Sam Hocevar committed
210
    {   "filter",           1,          0,      OPT_FILTER },
211 212 213

    /* Decoder options */
    {   "mpeg_adec",        1,          0,      OPT_MPEG_ADEC },
gbazin's avatar
 
gbazin committed
214
    {   "ac3_adec",         1,          0,      OPT_AC3_ADEC },
215

Sam Hocevar's avatar
 
Sam Hocevar committed
216 217 218 219 220 221 222
    /* CPU options */
    {   "nommx",            0,          0,      OPT_NOMMX },
    {   "no3dnow",          0,          0,      OPT_NO3DNOW },
    {   "nommxext",         0,          0,      OPT_NOMMXEXT },
    {   "nosse",            0,          0,      OPT_NOSSE },
    {   "noaltivec",        0,          0,      OPT_NOALTIVEC },

Michel Kaempf's avatar
Michel Kaempf committed
223 224 225 226
    {   0,                  0,          0,      0 }
};

/* Short options */
227
static const char *psz_shortopts = "hHvgt:T:u:a:s:c:I:A:V:";
Michel Kaempf's avatar
Michel Kaempf committed
228

229
/*****************************************************************************
Sam Hocevar's avatar
 
Sam Hocevar committed
230
 * Global variables - these are the only ones, see main.h and modules.h
231
 *****************************************************************************/
Sam Hocevar's avatar
 
Sam Hocevar committed
232 233
main_t        *p_main;
module_bank_t *p_module_bank;
Sam Hocevar's avatar
 
Sam Hocevar committed
234
input_bank_t  *p_input_bank;
Sam Hocevar's avatar
 
Sam Hocevar committed
235 236
aout_bank_t   *p_aout_bank;
vout_bank_t   *p_vout_bank;
Michel Kaempf's avatar
Michel Kaempf committed
237

238
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
239
 * Local prototypes
240
 *****************************************************************************/
Sam Hocevar's avatar
 
Sam Hocevar committed
241
static int  GetConfiguration        ( int *pi_argc, char *ppsz_argv[],
242
                                      char *ppsz_env[] );
Sam Hocevar's avatar
 
Sam Hocevar committed
243
static int  GetFilenames            ( int i_argc, char *ppsz_argv[] );
244
static void Usage                   ( int i_fashion );
Vincent Seguin's avatar
Vincent Seguin committed
245
static void Version                 ( void );
Vincent Seguin's avatar
Vincent Seguin committed
246

Michel Kaempf's avatar
Michel Kaempf committed
247
static void InitSignalHandler       ( void );
Benoit Steiner's avatar
 
Benoit Steiner committed
248 249
static void SimpleSignalHandler     ( int i_signal );
static void FatalSignalHandler      ( int i_signal );
Sam Hocevar's avatar
 
Sam Hocevar committed
250
static void IllegalSignalHandler    ( int i_signal );
Sam Hocevar's avatar
 
Sam Hocevar committed
251
static u32  CPUCapabilities         ( void );
gbazin's avatar
 
gbazin committed
252 253 254 255

static int  RedirectSTDOUT          ( void );
static void ShowConsole             ( void );

256
static jmp_buf env;
Sam Hocevar's avatar
 
Sam Hocevar committed
257 258
static int     i_illegal;
static char   *psz_capability;
Sam Hocevar's avatar
 
Sam Hocevar committed
259

260
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
261
 * main: parse command line, start interface and spawn threads
262
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
263 264
 * Steps during program execution are:
 *      -configuration parsing and messages interface initialization
265
 *      -opening of audio output device and some global modules
Michel Kaempf's avatar
Michel Kaempf committed
266
 *      -execution of interface, which exit on error or on user request
Vincent Seguin's avatar
Vincent Seguin committed
267
 *      -closing of audio output device and some global modules
268
 * On error, the spawned threads are canceled, and the open devices closed.
269
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
270 271
int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
{
Sam Hocevar's avatar
 
Sam Hocevar committed
272 273
    main_t        main_data;                /* root of all data - see main.h */
    module_bank_t module_bank;
Sam Hocevar's avatar
 
Sam Hocevar committed
274
    input_bank_t  input_bank;
Sam Hocevar's avatar
 
Sam Hocevar committed
275 276
    aout_bank_t   aout_bank;
    vout_bank_t   vout_bank;
277

Sam Hocevar's avatar
 
Sam Hocevar committed
278 279
    p_main        = &main_data;               /* set up the global variables */
    p_module_bank = &module_bank;
Sam Hocevar's avatar
 
Sam Hocevar committed
280
    p_input_bank  = &input_bank;
Sam Hocevar's avatar
 
Sam Hocevar committed
281 282
    p_aout_bank   = &aout_bank;
    p_vout_bank   = &vout_bank;
Sam Hocevar's avatar
 
Sam Hocevar committed
283

Sam Hocevar's avatar
 
Sam Hocevar committed
284
#if defined( ENABLE_NLS ) && defined ( HAVE_GETTEXT )
Sam Hocevar's avatar
 
Sam Hocevar committed
285
    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
286 287
     * Support for getext
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
288 289
#if defined( HAVE_LOCALE_H ) && defined( HAVE_LC_MESSAGES )
    if( !setlocale( LC_MESSAGES, "" ) )
Sam Hocevar's avatar
 
Sam Hocevar committed
290 291 292
    {
        fprintf( stderr, "warning: unsupported locale.\n" );
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
293
#endif
Sam Hocevar's avatar
 
Sam Hocevar committed
294

Sam Hocevar's avatar
 
Sam Hocevar committed
295
    if( !bindtextdomain( PACKAGE, LOCALEDIR ) )
Sam Hocevar's avatar
 
Sam Hocevar committed
296 297 298 299 300 301 302
    {
        fprintf( stderr, "warning: no domain %s in directory %s\n",
                 PACKAGE, LOCALEDIR );
    }

    textdomain( PACKAGE );
#endif
Sam Hocevar's avatar
 
Sam Hocevar committed
303

Sam Hocevar's avatar
 
Sam Hocevar committed
304
    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
305
     * Initialize threads system
Sam Hocevar's avatar
 
Sam Hocevar committed
306
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
307
    vlc_threads_init( );
Sam Hocevar's avatar
 
Sam Hocevar committed
308

Sam Hocevar's avatar
 
Sam Hocevar committed
309
    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
310
     * Test if our code is likely to run on this CPU
Sam Hocevar's avatar
 
Sam Hocevar committed
311 312
     */
    p_main->i_cpu_capabilities = CPUCapabilities();
Sam Hocevar's avatar
 
Sam Hocevar committed
313

Sam Hocevar's avatar
 
Sam Hocevar committed
314 315 316
    /*
     * System specific initialization code
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
317
#if defined( SYS_BEOS ) || defined( SYS_DARWIN ) || defined( WIN32 )
Sam Hocevar's avatar
 
Sam Hocevar committed
318
    system_Init( &i_argc, ppsz_argv, ppsz_env );
319 320 321 322 323 324

#elif defined( SYS_LINUX )
#   ifdef DEBUG
    /* Activate malloc checking routines to detect heap corruptions. */
    main_PutIntVariable( "MALLOC_CHECK_", 2 );
#   endif
325
#endif
326 327 328 329

    /*
     * Initialize messages interface
     */
Vincent Seguin's avatar
Vincent Seguin committed
330
    p_main->p_msg = intf_MsgCreate();
331
    if( !p_main->p_msg )                         /* start messages interface */
Michel Kaempf's avatar
Michel Kaempf committed
332
    {
333
        fprintf( stderr, "error: can't initialize messages interface (%s)\n",
Sam Hocevar's avatar
 
Sam Hocevar committed
334
                 strerror(errno) );
335
        return( errno );
Michel Kaempf's avatar
Michel Kaempf committed
336
    }
337

338
    intf_MsgImm( COPYRIGHT_MESSAGE "\n" );
Sam Hocevar's avatar
 
Sam Hocevar committed
339

340
    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
341
     * Read configuration
342
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
343
    if( GetConfiguration( &i_argc, ppsz_argv, ppsz_env ) ) /* parse cmd line */
Michel Kaempf's avatar
Michel Kaempf committed
344
    {
Vincent Seguin's avatar
Vincent Seguin committed
345
        intf_MsgDestroy();
346
        return( errno );
Michel Kaempf's avatar
Michel Kaempf committed
347
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
348

gbazin's avatar
 
gbazin committed
349 350 351 352 353 354
    /*
     * Redirect the standard output if required by the user, and on Win32 we
     * also open a console to display the debug messages.
     */
    RedirectSTDOUT();

355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
    if( p_main->b_stats )
    {
        char          p_capabilities[200];
        p_capabilities[0] = '\0';

#define PRINT_CAPABILITY( capability, string )                              \
        if( p_main->i_cpu_capabilities & capability )                       \
        {                                                                   \
            strncat( p_capabilities, string " ",                            \
                     sizeof(p_capabilities) - strlen(p_capabilities) );     \
            p_capabilities[sizeof(p_capabilities) - 1] = '\0';              \
        }

        PRINT_CAPABILITY( CPU_CAPABILITY_486, "486" );
        PRINT_CAPABILITY( CPU_CAPABILITY_586, "586" );
        PRINT_CAPABILITY( CPU_CAPABILITY_PPRO, "Pentium Pro" );
        PRINT_CAPABILITY( CPU_CAPABILITY_MMX, "MMX" );
        PRINT_CAPABILITY( CPU_CAPABILITY_3DNOW, "3DNow!" );
        PRINT_CAPABILITY( CPU_CAPABILITY_MMXEXT, "MMXEXT" );
        PRINT_CAPABILITY( CPU_CAPABILITY_SSE, "SSE" );
        PRINT_CAPABILITY( CPU_CAPABILITY_ALTIVEC, "Altivec" );
Sam Hocevar's avatar
 
Sam Hocevar committed
376
        PRINT_CAPABILITY( CPU_CAPABILITY_FPU, "FPU" );
Sam Hocevar's avatar
 
Sam Hocevar committed
377
        intf_StatMsg( "info: CPU has capabilities : %s", p_capabilities );
378 379
    }

380
    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
381
     * Initialize playlist and get commandline files
382
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
383
    p_main->p_playlist = intf_PlaylistCreate();
Sam Hocevar's avatar
 
Sam Hocevar committed
384
    if( !p_main->p_playlist )
385
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
386
        intf_ErrMsg( "playlist error: playlist initialization failed" );
387 388
        intf_MsgDestroy();
        return( errno );
389
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
390
    intf_PlaylistInit( p_main->p_playlist );
391 392

    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
393
     * Get input filenames given as commandline arguments
394
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
395
    GetFilenames( i_argc, ppsz_argv );
Michel Kaempf's avatar
Michel Kaempf committed
396

Sam Hocevar's avatar
 
Sam Hocevar committed
397
    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
398
     * Initialize module, input, aout and vout banks
Sam Hocevar's avatar
 
Sam Hocevar committed
399
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
400
    module_InitBank();
Sam Hocevar's avatar
 
Sam Hocevar committed
401
    input_InitBank();
Sam Hocevar's avatar
 
Sam Hocevar committed
402 403
    aout_InitBank();
    vout_InitBank();
Sam Hocevar's avatar
 
Sam Hocevar committed
404

Sam Hocevar's avatar
 
Sam Hocevar committed
405 406 407
    /*
     * Choose the best memcpy module
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
408 409 410
    p_main->p_memcpy_module = module_Need( MODULE_CAPABILITY_MEMCPY, NULL,
                                           NULL );
    if( p_main->p_memcpy_module == NULL )
Sam Hocevar's avatar
 
Sam Hocevar committed
411 412 413
    {
        intf_ErrMsg( "intf error: no suitable memcpy module, "
                     "using libc default" );
Sam Hocevar's avatar
 
Sam Hocevar committed
414 415 416 417 418 419
        p_main->pf_memcpy = memcpy;
    }
    else
    {
        p_main->pf_memcpy = p_main->p_memcpy_module->p_functions
                                  ->memcpy.functions.memcpy.pf_memcpy;
Sam Hocevar's avatar
 
Sam Hocevar committed
420
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
421

Michel Kaempf's avatar
Michel Kaempf committed
422 423 424
    /*
     * Initialize shared resources and libraries
     */
425 426 427
    if( main_GetIntVariable( INPUT_NETWORK_CHANNEL_VAR,
                             INPUT_NETWORK_CHANNEL_DEFAULT ) &&
        network_ChannelCreate() )
Michel Kaempf's avatar
Michel Kaempf committed
428
    {
Henri Fallon's avatar
 
Henri Fallon committed
429
        /* On error during Channels initialization, switch off channels */
Sam Hocevar's avatar
 
Sam Hocevar committed
430 431
        intf_ErrMsg( "intf error: channels initialization failed, " 
                                 "deactivating channels" );
432
        main_PutIntVariable( INPUT_NETWORK_CHANNEL_VAR, 0 );
Michel Kaempf's avatar
Michel Kaempf committed
433
    }
434

Michel Kaempf's avatar
Michel Kaempf committed
435
    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
436
     * Try to run the interface
Michel Kaempf's avatar
Michel Kaempf committed
437
     */
438
    p_main->p_intf = intf_Create();
Sam Hocevar's avatar
 
Sam Hocevar committed
439
    if( p_main->p_intf == NULL )
Sam Hocevar's avatar
 
Sam Hocevar committed
440 441 442
    {
        intf_ErrMsg( "intf error: interface initialization failed" );
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
443
    else
444
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462
        /*
         * Set signal handling policy for all threads
         */
        InitSignalHandler();

        /*
         * This is the main loop
         */
        p_main->p_intf->pf_run( p_main->p_intf );

        /*
         * Finished, destroy the interface
         */
        intf_Destroy( p_main->p_intf );

        /*
         * Go back into channel 0 which is the network
         */
463 464
        if( main_GetIntVariable( INPUT_NETWORK_CHANNEL_VAR,
                                 INPUT_NETWORK_CHANNEL_DEFAULT ) )
Sam Hocevar's avatar
 
Sam Hocevar committed
465 466 467
        {
            network_ChannelJoin( COMMON_CHANNEL );
        }
468
    }
Michel Kaempf's avatar
Michel Kaempf committed
469

Sam Hocevar's avatar
 
Sam Hocevar committed
470
    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
471
     * Free input, aout and vout banks
Sam Hocevar's avatar
 
Sam Hocevar committed
472
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
473
    input_EndBank();
Sam Hocevar's avatar
 
Sam Hocevar committed
474 475 476 477 478 479 480 481
    vout_EndBank();
    aout_EndBank();

    /*
     * Free playlist
     */
    intf_PlaylistDestroy( p_main->p_playlist );

Sam Hocevar's avatar
 
Sam Hocevar committed
482
    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
483
     * Free memcpy module if it was allocated
Sam Hocevar's avatar
 
Sam Hocevar committed
484
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
485
    if( p_main->p_memcpy_module != NULL )
Sam Hocevar's avatar
 
Sam Hocevar committed
486
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
487
        module_Unneed( p_main->p_memcpy_module );
Sam Hocevar's avatar
 
Sam Hocevar committed
488
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
489

Sam Hocevar's avatar
 
Sam Hocevar committed
490
    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
491
     * Free module bank
Sam Hocevar's avatar
 
Sam Hocevar committed
492
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
493
    module_EndBank();
494 495 496 497

    /*
     * System specific cleaning code
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
498
#if defined( SYS_BEOS ) || defined( SYS_DARWIN ) || defined( WIN32 )
Sam Hocevar's avatar
 
Sam Hocevar committed
499
    system_End();
500 501
#endif

Sam Hocevar's avatar
 
Sam Hocevar committed
502

Michel Kaempf's avatar
Michel Kaempf committed
503 504 505
    /*
     * Terminate messages interface and program
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
506
    intf_WarnMsg( 1, "intf: program terminated" );
Vincent Seguin's avatar
Vincent Seguin committed
507
    intf_MsgDestroy();
508

Sam Hocevar's avatar
 
Sam Hocevar committed
509 510 511 512
    /*
     * Stop threads system
     */
    vlc_threads_end( );
Sam Hocevar's avatar
 
Sam Hocevar committed
513

Sam Hocevar's avatar
 
Sam Hocevar committed
514
    return 0;
Michel Kaempf's avatar
Michel Kaempf committed
515 516
}

517
/*****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
518
 * main_GetIntVariable: get the int value of an environment variable
519
 *****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
520
 * This function is used to read some default parameters in modules.
521
 *****************************************************************************/
Vincent Seguin's avatar
Vincent Seguin committed
522 523
int main_GetIntVariable( char *psz_name, int i_default )
{
524 525 526
    char *      psz_env;                                /* environment value */
    char *      psz_end;                             /* end of parsing index */
    long int    i_value;                                            /* value */
Vincent Seguin's avatar
Vincent Seguin committed
527 528 529

    psz_env = getenv( psz_name );
    if( psz_env )
530
    {
531 532 533 534
        i_value = strtol( psz_env, &psz_end, 0 );
        if( (*psz_env != '\0') && (*psz_end == '\0') )
        {
            return( i_value );
535
        }
536
    }
Vincent Seguin's avatar
Vincent Seguin committed
537 538 539
    return( i_default );
}

540
/*****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
541
 * main_GetPszVariable: get the string value of an environment variable
542
 *****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
543
 * This function is used to read some default parameters in modules.
544
 *****************************************************************************/
Vincent Seguin's avatar
Vincent Seguin committed
545 546 547 548 549 550 551
char * main_GetPszVariable( char *psz_name, char *psz_default )
{
    char *psz_env;

    psz_env = getenv( psz_name );
    if( psz_env )
    {
552
        return( psz_env );
Vincent Seguin's avatar
Vincent Seguin committed
553
    }
554
    return( psz_default );
Vincent Seguin's avatar
Vincent Seguin committed
555 556
}

557
/*****************************************************************************
558
 * main_PutPszVariable: set the string value of an environment variable
559
 *****************************************************************************
560 561 562
 * This function is used to set some default parameters in modules. The use of
 * this function will cause some memory leak: since some systems use the pointer
 * passed to putenv to store the environment string, it can't be freed.
563
 *****************************************************************************/
564 565 566 567 568 569 570
void main_PutPszVariable( char *psz_name, char *psz_value )
{
    char *psz_env;

    psz_env = malloc( strlen(psz_name) + strlen(psz_value) + 2 );
    if( psz_env == NULL )
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
571 572
        intf_ErrMsg( "intf error: cannot create psz_env (%s)",
                     strerror(ENOMEM) );
573 574 575 576 577 578
    }
    else
    {
        sprintf( psz_env, "%s=%s", psz_name, psz_value );
        if( putenv( psz_env ) )
        {
Sam Hocevar's avatar
 
Sam Hocevar committed
579
            intf_ErrMsg( "intf error: cannot putenv (%s)", strerror(errno) );
580
        }
581 582 583
    }
}

584
/*****************************************************************************
585
 * main_PutIntVariable: set the integer value of an environment variable
586
 *****************************************************************************
587 588 589
 * This function is used to set some default parameters in modules. The use of
 * this function will cause some memory leak: since some systems use the pointer
 * passed to putenv to store the environment string, it can't be freed.
590
 *****************************************************************************/
591 592
void main_PutIntVariable( char *psz_name, int i_value )
{
593
    char psz_value[ 256 ];                               /* buffer for value */
594

595
    sprintf( psz_value, "%d", i_value );
596
    main_PutPszVariable( psz_name, psz_value );
597 598
}

Michel Kaempf's avatar
Michel Kaempf committed
599 600
/* following functions are local */

601
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
602
 * GetConfiguration: parse command line
603
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
604 605
 * Parse command line and configuration file for configuration. If the inline
 * help is requested, the function Usage() is called and the function returns
606
 * -1 (causing main() to exit). The messages interface is initialized at this
Vincent Seguin's avatar
Vincent Seguin committed
607 608
 * stage, but most structures are not allocated, so only environment should
 * be used.
609
 *****************************************************************************/
Sam Hocevar's avatar
 
Sam Hocevar committed
610
static int GetConfiguration( int *pi_argc, char *ppsz_argv[], char *ppsz_env[] )
Michel Kaempf's avatar
Michel Kaempf committed
611
{
Sam Hocevar's avatar
 
Sam Hocevar committed
612 613
    int   i_cmd;
    char *p_tmp;
Michel Kaempf's avatar
Michel Kaempf committed
614 615

    /* Set default configuration and copy arguments */
Sam Hocevar's avatar
 
Sam Hocevar committed
616
    p_main->i_argc    = *pi_argc;
Vincent Seguin's avatar
Vincent Seguin committed
617
    p_main->ppsz_argv = ppsz_argv;
618
    p_main->ppsz_env  = ppsz_env;
Sam Hocevar's avatar
 
Sam Hocevar committed
619

Henri Fallon's avatar
 
Henri Fallon committed
620 621
    p_main->b_audio     = 1;
    p_main->b_video     = 1;
Sam Hocevar's avatar
 
Sam Hocevar committed
622

623
    p_main->i_warning_level = 0;
624
    p_main->b_stats = 0;
625
    p_main->i_desync = 0; /* No desynchronization by default */
Michel Kaempf's avatar
Michel Kaempf committed
626

627 628
    p_main->p_channel = NULL;

629
    /* Get the executable name (similar to the basename command) */
Sam Hocevar's avatar
 
Sam Hocevar committed
630 631
    p_main->psz_arg0 = p_tmp = ppsz_argv[ 0 ];
    while( *p_tmp )
Sam Hocevar's avatar
Sam Hocevar committed
632
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
633
        if( *p_tmp == '/' )
Sam Hocevar's avatar
Sam Hocevar committed
634
        {
Sam Hocevar's avatar
 
Sam Hocevar committed
635
            p_main->psz_arg0 = ++p_tmp;
Sam Hocevar's avatar
Sam Hocevar committed
636 637 638
        }
        else
        {
Sam Hocevar's avatar
 
Sam Hocevar committed
639
            ++p_tmp;
Sam Hocevar's avatar
Sam Hocevar committed
640 641 642
        }
    }

Sam Hocevar's avatar
 
Sam Hocevar committed
643
#ifdef SYS_DARWIN
Sam Hocevar's avatar
 
Sam Hocevar committed
644 645 646
    /* When vlc.app is run by double clicking in Mac OS X, the 2nd arg
     * is the PSN - process serial number (a unique PID-ish thingie)
     * still ok for real Darwin & when run from command line */
Sam Hocevar's avatar
 
Sam Hocevar committed
647 648
    if ( (*pi_argc > 1) && (strncmp( ppsz_argv[ 1 ] , "-psn" , 4 ) == 0) )
                                        /* for example -psn_0_9306113 */
649
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
650 651 652 653 654 655 656 657 658
        /* GDMF!... I can't do this or else the MacOSX window server will
         * not pick up the PSN and not register the app and we crash...
         * hence the following kludge otherwise we'll get confused w/ argv[1]
         * being an input file name */
#if 0
        ppsz_argv[ 1 ] = NULL;
#endif
        *pi_argc = *pi_argc - 1;
        pi_argc--;
659 660 661 662
        return( 0 );
    }
#endif

Vincent Seguin's avatar
Vincent Seguin committed
663
    /* Parse command line options */
Michel Kaempf's avatar
Michel Kaempf committed
664
    opterr = 0;
Sam Hocevar's avatar
 
Sam Hocevar committed
665 666
    while( ( i_cmd = getopt_long( *pi_argc, ppsz_argv,
                                   psz_shortopts, longopts, 0 ) ) != EOF )
Michel Kaempf's avatar
Michel Kaempf committed
667
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
668
        switch( i_cmd )
Michel Kaempf's avatar
Michel Kaempf committed
669
        {
670 671
        /* General/common options */
        case 'h':                                              /* -h, --help */
gbazin's avatar
 
gbazin committed
672 673
            ShowConsole();
            RedirectSTDOUT();
674
            Usage( SHORT_HELP );
gbazin's avatar
 
gbazin committed
675 676 677 678 679 680 681 682 683
#ifdef WIN32        /* Pause the console because it's destroyed when we exit */
            if( strcmp( "", main_GetPszVariable( INTF_STDOUT_VAR,
                                                 INTF_STDOUT_DEFAULT ) ) == 0 )
            {
                /* No stdout redirection has been asked for */
                intf_MsgImm( "\nPress the RETURN key to continue..." );
                getchar();
            }
#endif
684 685
            return( -1 );
            break;
686
        case 'H':                                          /* -H, --longhelp */
gbazin's avatar
 
gbazin committed
687 688
            ShowConsole();
            RedirectSTDOUT();
689
            Usage( LONG_HELP );
gbazin's avatar
 
gbazin committed
690 691 692 693 694 695 696 697 698
#ifdef WIN32        /* Pause the console because it's destroyed when we exit */
            if( strcmp( "", main_GetPszVariable( INTF_STDOUT_VAR,
                                                 INTF_STDOUT_DEFAULT ) ) == 0 )
            {
                /* No stdout redirection has been asked for */
                intf_MsgImm( "\nPress the RETURN key to continue..." );
                getchar();
            }
#endif
Michel Kaempf's avatar
Michel Kaempf committed
699 700
            return( -1 );
            break;
Sam Hocevar's avatar
 
Sam Hocevar committed
701
        case OPT_VERSION:                                       /* --version */
gbazin's avatar
 
gbazin committed
702 703
            ShowConsole();
            RedirectSTDOUT();
Vincent Seguin's avatar
Vincent Seguin committed
704
            Version();
gbazin's avatar
 
gbazin committed
705 706 707 708 709 710 711 712 713
#ifdef WIN32        /* Pause the console because it's destroyed when we exit */
            if( strcmp( "", main_GetPszVariable( INTF_STDOUT_VAR,
                                                 INTF_STDOUT_DEFAULT ) ) == 0 )
            {
                /* No stdout redirection has been asked for */
                intf_MsgImm( "\nPress the RETURN key to continue..." );
                getchar();
            }
#endif
Vincent Seguin's avatar
Vincent Seguin committed
714
            return( -1 );
715
            break;
Sam Hocevar's avatar
 
Sam Hocevar committed
716
        case 'v':                                           /* -v, --verbose */
717
            p_main->i_warning_level++;
Sam Hocevar's avatar
 
Sam Hocevar committed
718
            break;
Michel Kaempf's avatar
Michel Kaempf committed
719

Sam Hocevar's avatar
 
Sam Hocevar committed
720
        /* Interface warning messages level */
Sam Hocevar's avatar
 
Sam Hocevar committed
721
        case 'I':                                              /* -I, --intf */
Sam Hocevar's avatar
 
Sam Hocevar committed
722 723 724
            main_PutPszVariable( INTF_METHOD_VAR, optarg );
            break;
        case OPT_WARNING:                                       /* --warning */
Sam Hocevar's avatar
 
Sam Hocevar committed
725 726
            intf_ErrMsg( "intf error: `--warning' is deprecated, use `-v'" );
            p_main->i_warning_level = atoi(optarg);
Sam Hocevar's avatar
 
Sam Hocevar committed
727 728
            break;

gbazin's avatar
 
gbazin committed
729 730 731 732
        case OPT_STDOUT:                                         /* --stdout */
            main_PutPszVariable( INTF_STDOUT_VAR, optarg );
            break;

733 734 735 736
        case OPT_STATS:
            p_main->b_stats = 1;
            break;

Michel Kaempf's avatar
Michel Kaempf committed
737
        /* Audio options */
738
        case OPT_NOAUDIO:                                       /* --noaudio */
739
            p_main->b_audio = 0;
Michel Kaempf's avatar
Michel Kaempf committed
740
            break;
Sam Hocevar's avatar
 
Sam Hocevar committed
741
        case 'A':                                              /* -A, --aout */
742 743
            main_PutPszVariable( AOUT_METHOD_VAR, optarg );
            break;
744
        case OPT_STEREO:                                         /* --stereo */
745
            main_PutIntVariable( AOUT_STEREO_VAR, 1 );
Michel Kaempf's avatar
Michel Kaempf committed
746
            break;
747
        case OPT_MONO:                                             /* --mono */
748
            main_PutIntVariable( AOUT_STEREO_VAR, 0 );
Michel Kaempf's avatar
Michel Kaempf committed
749
            break;
750
        case OPT_SPDIF:                                           /* --spdif */
Sam Hocevar's avatar
 
Sam Hocevar committed
751
            main_PutIntVariable( AOUT_SPDIF_VAR, 1 );
752
            break;
gbazin's avatar
 
gbazin committed
753
        case OPT_DOWNMIX:                                       /* --downmix */
Sam Hocevar's avatar
 
Sam Hocevar committed
754 755 756 757 758
            main_PutPszVariable( DOWNMIX_METHOD_VAR, optarg );
            break;
        case OPT_IMDCT:                                           /* --imdct */
            main_PutPszVariable( IMDCT_METHOD_VAR, optarg );
            break;
759 760 761
        case OPT_VOLUME:                                         /* --volume */
            main_PutIntVariable( AOUT_VOLUME_VAR, atoi(optarg) );
            break;
762
        case OPT_DESYNC:                                         /* --desync */
Sam Hocevar's avatar
 
Sam Hocevar committed
763
            p_main->i_desync = (mtime_t)atoi(optarg) * (mtime_t)1000;
764
            break;
Michel Kaempf's avatar
Michel Kaempf committed
765 766

        /* Video options */
767
        case OPT_NOVIDEO:                                       /* --novideo */
Vincent Seguin's avatar
Vincent Seguin committed
768
            p_main->b_video = 0;
769