libvlc.c 63.5 KB
Newer Older
1 2 3
/*****************************************************************************
 * libvlc.c: main libvlc source
 *****************************************************************************
Clément Stenac's avatar
Clément Stenac committed
4
 * Copyright (C) 1998-2004 VideoLAN
5
 * $Id$
6 7 8 9
 *
 * Authors: Vincent Seguin <seguin@via.ecp.fr>
 *          Samuel Hocevar <sam@zoy.org>
 *          Gildas Bazin <gbazin@netcourrier.com>
10
 *          Derk-Jan Hartman <hartman at videolan dot org>
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * 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.
 *****************************************************************************/

/*****************************************************************************
 * Pretend we are a builtin module
 *****************************************************************************/
#define MODULE_NAME main
31
#define MODULE_PATH main
32 33 34 35 36
#define __BUILTIN__

/*****************************************************************************
 * Preamble
 *****************************************************************************/
37
#include <vlc/vlc.h>
Laurent Aimar's avatar
Laurent Aimar committed
38
#include <vlc/input.h>
39 40 41 42

#ifdef HAVE_ERRNO_H
#   include <errno.h>                                              /* ENOMEM */
#endif
43 44 45 46 47 48 49 50 51 52
#include <stdio.h>                                              /* sprintf() */
#include <string.h>                                            /* strerror() */
#include <stdlib.h>                                                /* free() */

#ifndef WIN32
#   include <netinet/in.h>                            /* BSD: struct in_addr */
#endif

#ifdef HAVE_UNISTD_H
#   include <unistd.h>
Gildas Bazin's avatar
 
Gildas Bazin committed
53
#elif defined( WIN32 ) && !defined( UNDER_CE )
54 55 56
#   include <io.h>
#endif

57
#ifdef WIN32                       /* optind, getopt(), included in unistd.h */
58
#   include "extras/getopt.h"
59 60
#endif

61 62 63 64 65
#ifdef HAVE_LOCALE_H
#   include <locale.h>
#endif

#include "vlc_cpu.h"                                        /* CPU detection */
66
#include "os_specific.h"
67

68
#include "vlc_error.h"
69

70
#include "vlc_playlist.h"
71
#include "vlc_interface.h"
72 73 74

#include "audio_output.h"

75
#include "vlc_video.h"
76 77
#include "video_output.h"

78 79
#include "stream_output.h"

80 81 82
#include "libvlc.h"

/*****************************************************************************
83
 * The evil global variable. We handle it with care, don't worry.
84
 *****************************************************************************/
85 86 87
static libvlc_t   libvlc;
static libvlc_t * p_libvlc;
static vlc_t *    p_static_vlc;
88 89 90 91

/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
92
static void SetLanguage   ( char const * );
93
static int  GetFilenames  ( vlc_t *, int, char *[] );
94
static void Usage         ( vlc_t *, char const *psz_module_name );
95
static void ListModules   ( vlc_t * );
96 97 98 99 100
static void Version       ( void );

#ifdef WIN32
static void ShowConsole   ( void );
#endif
101
static int  ConsoleWidth  ( void );
102

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
103 104
static int  VerboseCallback( vlc_object_t *, char const *,
                             vlc_value_t, vlc_value_t, void * );
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121

/*****************************************************************************
 * vlc_current_object: return the current object.
 *****************************************************************************
 * If i_object is non-zero, return the corresponding object. Otherwise,
 * return the statically allocated p_vlc object.
 *****************************************************************************/
vlc_t * vlc_current_object( int i_object )
{
    if( i_object )
    {
         return vlc_object_get( p_libvlc, i_object );
    }

    return p_static_vlc;
}

122
/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
123
 * VLC_Version: return the libvlc version.
124
 *****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
125
 * This function returns full version string (numeric version and codename).
126
 *****************************************************************************/
127
char const * VLC_Version( void )
128
{
Sam Hocevar's avatar
Sam Hocevar committed
129
    return VERSION_MESSAGE;
130 131
}

132 133 134 135 136 137 138 139 140 141
/*****************************************************************************
 * VLC_Error: strerror() equivalent
 *****************************************************************************
 * This function returns full version string (numeric version and codename).
 *****************************************************************************/
char const * VLC_Error( int i_err )
{
    return vlc_error( i_err );
}

Sam Hocevar's avatar
Sam Hocevar committed
142 143 144 145 146 147 148
/*****************************************************************************
 * VLC_Create: allocate a vlc_t structure, and initialize libvlc if needed.
 *****************************************************************************
 * This function allocates a vlc_t structure and returns a negative value
 * in case of failure. Also, the thread system is initialized.
 *****************************************************************************/
int VLC_Create( void )
149
{
150
    int i_ret;
151
    vlc_t * p_vlc = NULL;
152
    vlc_value_t lockval;
153

154 155 156
    /* &libvlc never changes, so we can safely call this multiple times. */
    p_libvlc = &libvlc;

157 158
    /* vlc_threads_init *must* be the first internal call! No other call is
     * allowed before the thread system has been initialized. */
159
    i_ret = vlc_threads_init( p_libvlc );
Sam Hocevar's avatar
Sam Hocevar committed
160
    if( i_ret < 0 )
161
    {
Sam Hocevar's avatar
Sam Hocevar committed
162
        return i_ret;
163 164 165
    }

    /* Now that the thread system is initialized, we don't have much, but
166
     * at least we have var_Create */
167 168
    var_Create( p_libvlc, "libvlc", VLC_VAR_MUTEX );
    var_Get( p_libvlc, "libvlc", &lockval );
169
    vlc_mutex_lock( lockval.p_address );
170 171
    if( !libvlc.b_ready )
    {
172 173
        char *psz_env;

174 175 176
        /* Guess what CPU we have */
        libvlc.i_cpu = CPUCapabilities();

177 178
        /* Find verbosity from VLC_VERBOSE environment variable */
        psz_env = getenv( "VLC_VERBOSE" );
179
        libvlc.i_verbose = psz_env ? atoi( psz_env ) : -1;
180

Gildas Bazin's avatar
 
Gildas Bazin committed
181
#if defined( HAVE_ISATTY ) && !defined( WIN32 )
182 183 184 185 186
        libvlc.b_color = isatty( 2 ); /* 2 is for stderr */
#else
        libvlc.b_color = VLC_FALSE;
#endif

187
        /* Initialize message queue */
188
        msg_Create( p_libvlc );
189 190

        /* Announce who we are */
191 192
        msg_Dbg( p_libvlc, COPYRIGHT_MESSAGE );
        msg_Dbg( p_libvlc, "libvlc was configured with %s", CONFIGURE_LINE );
193

194 195
        /* The module bank will be initialized later */
        libvlc.p_module_bank = NULL;
196 197

        libvlc.b_ready = VLC_TRUE;
198
    }
199
    vlc_mutex_unlock( lockval.p_address );
200
    var_Destroy( p_libvlc, "libvlc" );
201 202

    /* Allocate a vlc object */
203
    p_vlc = vlc_object_create( p_libvlc, VLC_OBJECT_VLC );
204 205
    if( p_vlc == NULL )
    {
Sam Hocevar's avatar
Sam Hocevar committed
206
        return VLC_EGENERIC;
207
    }
208
    p_vlc->thread_id = 0;
209
    vlc_thread_set_priority( p_vlc, VLC_THREAD_PRIORITY_LOW );
210 211 212 213

    p_vlc->psz_object_name = "root";

    /* Initialize mutexes */
214
    vlc_mutex_init( p_vlc, &p_vlc->config_lock );
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
215 216 217
#ifdef SYS_DARWIN
    vlc_mutex_init( p_vlc, &p_vlc->quicktime_lock );
#endif
218 219

    /* Store our newly allocated structure in the global list */
220
    vlc_object_attach( p_vlc, p_libvlc );
221

Sam Hocevar's avatar
Sam Hocevar committed
222 223 224 225
    /* Store data for the non-reentrant API */
    p_static_vlc = p_vlc;

    return p_vlc->i_object_id;
226 227 228
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
229
 * VLC_Init: initialize a vlc_t structure.
230 231 232 233 234 235 236
 *****************************************************************************
 * This function initializes a previously allocated vlc_t structure:
 *  - CPU detection
 *  - gettext initialization
 *  - message queue, module bank and playlist initialization
 *  - configuration and commandline parsing
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
237
int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
238
{
239 240
    char         p_capabilities[200];
    char *       p_tmp;
241 242
    char *       psz_modules;
    char *       psz_parser;
243
    char *       psz_language;
244
    vlc_bool_t   b_exit = VLC_FALSE;
245
    vlc_t *      p_vlc = vlc_current_object( i_object );
246 247
    module_t    *p_help_module;
    playlist_t  *p_playlist;
248

249
    if( !p_vlc )
250
    {
251
        return VLC_ENOOBJ;
252 253 254
    }

    /*
255
     * System specific initialization code
256
     */
257
    system_Init( p_vlc, &i_argc, ppsz_argv );
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273

    /* Get the executable name (similar to the basename command) */
    if( i_argc > 0 )
    {
        p_vlc->psz_object_name = p_tmp = ppsz_argv[ 0 ];
        while( *p_tmp )
        {
            if( *p_tmp == '/' ) p_vlc->psz_object_name = ++p_tmp;
            else ++p_tmp;
        }
    }
    else
    {
        p_vlc->psz_object_name = "vlc";
    }

274 275 276 277
    /*
     * Support for gettext
     */
    SetLanguage( "" );
Sam Hocevar's avatar
Sam Hocevar committed
278 279

    /* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
280 281
    msg_Dbg( p_vlc, "translation test: code is \"%s\"", _("C") );

282 283 284 285
    /* Initialize the module bank and load the configuration of the
     * main module. We need to do this at this stage to be able to display
     * a short help if required by the user. (short help == main module
     * options) */
286
    module_InitBank( p_vlc );
287

288 289 290 291
    /* Hack: insert the help module here */
    p_help_module = vlc_object_create( p_vlc, VLC_OBJECT_MODULE );
    if( p_help_module == NULL )
    {
292
        module_EndBank( p_vlc );
Gildas Bazin's avatar
 
Gildas Bazin committed
293
        if( i_object ) vlc_object_release( p_vlc );
294 295 296
        return VLC_EGENERIC;
    }
    p_help_module->psz_object_name = "help";
Gildas Bazin's avatar
 
Gildas Bazin committed
297
    p_help_module->psz_longname = N_("Help options");
298
    config_Duplicate( p_help_module, p_help_config );
299
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
300 301
    /* End hack */

Sam Hocevar's avatar
Sam Hocevar committed
302
    if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE ) )
303
    {
304
        vlc_object_detach( p_help_module );
305 306
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
307
        module_EndBank( p_vlc );
Gildas Bazin's avatar
 
Gildas Bazin committed
308
        if( i_object ) vlc_object_release( p_vlc );
309 310 311 312 313 314
        return VLC_EGENERIC;
    }

    /* Check for short help option */
    if( config_GetInt( p_vlc, "help" ) )
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
315
        fprintf( stdout, _("Usage: %s [options] [items]...\n"),
316
                         p_vlc->psz_object_name );
317
        Usage( p_vlc, "main" );
318 319
        Usage( p_vlc, "help" );
        b_exit = VLC_TRUE;
320 321
    }
    /* Check for version option */
322
    else if( config_GetInt( p_vlc, "version" ) )
323 324
    {
        Version();
325 326 327
        b_exit = VLC_TRUE;
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
328 329 330 331
    /* Set the config file stuff */
    p_vlc->psz_homedir = config_GetHomeDir();
    p_vlc->psz_configfile = config_GetPsz( p_vlc, "config" );

332 333 334 335 336 337
    /* Check for plugins cache options */
    if( config_GetInt( p_vlc, "reset-plugins-cache" ) )
    {
        libvlc.p_module_bank->b_cache_delete = VLC_TRUE;
    }

338 339 340 341 342 343
    /* Hack: remove the help module here */
    vlc_object_detach( p_help_module );
    /* End hack */

    if( b_exit )
    {
344 345
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
346
        module_EndBank( p_vlc );
Gildas Bazin's avatar
 
Gildas Bazin committed
347
        if( i_object ) vlc_object_release( p_vlc );
348 349 350
        return VLC_EEXIT;
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
351
    /* Check for translation config option */
Gildas Bazin's avatar
 
Gildas Bazin committed
352 353 354 355 356 357 358 359
#if defined( ENABLE_NLS ) \
     && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )

    /* This ain't really nice to have to reload the config here but it seems
     * the only way to do it. */
    config_LoadConfigFile( p_vlc, "main" );
    config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );

360 361 362
    /* Check if the user specified a custom language */
    psz_language = config_GetPsz( p_vlc, "language" );
    if( psz_language && *psz_language && strcmp( psz_language, "auto" ) )
Gildas Bazin's avatar
 
Gildas Bazin committed
363
    {
364 365
        vlc_bool_t b_cache_delete = libvlc.p_module_bank->b_cache_delete;

Gildas Bazin's avatar
 
Gildas Bazin committed
366
        /* Reset the default domain */
367
        SetLanguage( psz_language );
Gildas Bazin's avatar
 
Gildas Bazin committed
368

Gildas Bazin's avatar
 
Gildas Bazin committed
369 370 371
        /* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
        msg_Dbg( p_vlc, "translation test: code is \"%s\"", _("C") );

372
        textdomain( PACKAGE );
Gildas Bazin's avatar
 
Gildas Bazin committed
373

Gildas Bazin's avatar
 
Gildas Bazin committed
374
#if defined( ENABLE_UTF8 )
375 376 377
        bind_textdomain_codeset( PACKAGE, "UTF-8" );
#endif

Gildas Bazin's avatar
 
Gildas Bazin committed
378
        module_EndBank( p_vlc );
379
        module_InitBank( p_vlc );
380
        config_LoadConfigFile( p_vlc, "main" );
Gildas Bazin's avatar
 
Gildas Bazin committed
381
        config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
382
        libvlc.p_module_bank->b_cache_delete = b_cache_delete;
Gildas Bazin's avatar
 
Gildas Bazin committed
383
    }
384
    if( psz_language ) free( psz_language );
385
#endif
Gildas Bazin's avatar
 
Gildas Bazin committed
386

387 388 389 390 391 392
    /*
     * Load the builtins and plugins into the module_bank.
     * We have to do it before config_Load*() because this also gets the
     * list of configuration options exported by each module and loads their
     * default values.
     */
393 394 395 396 397 398 399
    module_LoadBuiltins( p_vlc );
    module_LoadPlugins( p_vlc );
    if( p_vlc->b_die )
    {
        b_exit = VLC_TRUE;
    }

400
    msg_Dbg( p_vlc, "module bank initialized, found %i modules",
401
                    libvlc.p_module_bank->i_children );
402 403

    /* Hack: insert the help module here */
404
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
405 406 407 408 409
    /* End hack */

    /* Check for help on modules */
    if( (p_tmp = config_GetPsz( p_vlc, "module" )) )
    {
410
        Usage( p_vlc, p_tmp );
411
        free( p_tmp );
412
        b_exit = VLC_TRUE;
413 414
    }
    /* Check for long help option */
415
    else if( config_GetInt( p_vlc, "longhelp" ) )
416
    {
417
        Usage( p_vlc, NULL );
418
        b_exit = VLC_TRUE;
419 420
    }
    /* Check for module list option */
421
    else if( config_GetInt( p_vlc, "list" ) )
422
    {
423
        ListModules( p_vlc );
424
        b_exit = VLC_TRUE;
425 426
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444
    /* Check for config file options */
    if( config_GetInt( p_vlc, "reset-config" ) )
    {
        vlc_object_detach( p_help_module );
        config_ResetAll( p_vlc );
        config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
        config_SaveConfigFile( p_vlc, NULL );
        vlc_object_attach( p_help_module, libvlc.p_module_bank );
    }
    if( config_GetInt( p_vlc, "save-config" ) )
    {
        vlc_object_detach( p_help_module );
        config_LoadConfigFile( p_vlc, NULL );
        config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
        config_SaveConfigFile( p_vlc, NULL );
        vlc_object_attach( p_help_module, libvlc.p_module_bank );
    }

445
    /* Hack: remove the help module here */
446
    vlc_object_detach( p_help_module );
447 448
    /* End hack */

449 450
    if( b_exit )
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
451 452
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
453
        module_EndBank( p_vlc );
Gildas Bazin's avatar
 
Gildas Bazin committed
454
        if( i_object ) vlc_object_release( p_vlc );
455 456 457
        return VLC_EEXIT;
    }

458 459 460
    /*
     * Override default configuration with config file settings
     */
461
    config_LoadConfigFile( p_vlc, NULL );
462

Gildas Bazin's avatar
 
Gildas Bazin committed
463 464 465 466
    /* Hack: insert the help module here */
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
    /* End hack */

467 468 469
    /*
     * Override configuration with command line settings
     */
Sam Hocevar's avatar
Sam Hocevar committed
470
    if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_FALSE ) )
471 472 473 474 475 476 477 478
    {
#ifdef WIN32
        ShowConsole();
        /* Pause the console because it's destroyed when we exit */
        fprintf( stderr, "The command line options couldn't be loaded, check "
                 "that they are valid.\nPress the RETURN key to continue..." );
        getchar();
#endif
Gildas Bazin's avatar
 
Gildas Bazin committed
479 480 481
        vlc_object_detach( p_help_module );
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
482
        module_EndBank( p_vlc );
Gildas Bazin's avatar
 
Gildas Bazin committed
483
        if( i_object ) vlc_object_release( p_vlc );
484 485 486
        return VLC_EGENERIC;
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
487 488 489 490 491 492
    /* Hack: remove the help module here */
    vlc_object_detach( p_help_module );
    config_Free( p_help_module );
    vlc_object_destroy( p_help_module );
    /* End hack */

493 494 495
    /*
     * System specific configuration
     */
Gildas Bazin's avatar
 
Gildas Bazin committed
496
    system_Configure( p_vlc, &i_argc, ppsz_argv );
497

498 499 500
    /*
     * Message queue options
     */
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
501 502

    var_Create( p_vlc, "verbose", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
503 504
    if( config_GetInt( p_vlc, "quiet" ) )
    {
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
505 506 507
        vlc_value_t val;
        val.i_int = -1;
        var_Set( p_vlc, "verbose", val );
508
    }
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
509 510
    var_AddCallback( p_vlc, "verbose", VerboseCallback, NULL );
    var_Change( p_vlc, "verbose", VLC_VAR_TRIGGER_CALLBACKS, NULL, NULL );
Clément Stenac's avatar
Clément Stenac committed
511

Gildas Bazin's avatar
 
Gildas Bazin committed
512
    libvlc.b_color = libvlc.b_color && config_GetInt( p_vlc, "color" );
513

514 515 516 517 518
    /*
     * Output messages that may still be in the queue
     */
    msg_Flush( p_vlc );

519
    /* p_vlc initialization. FIXME ? */
520

521
#if defined( __i386__ )
522
    if( !config_GetInt( p_vlc, "mmx" ) )
523
        libvlc.i_cpu &= ~CPU_CAPABILITY_MMX;
524
    if( !config_GetInt( p_vlc, "3dn" ) )
525
        libvlc.i_cpu &= ~CPU_CAPABILITY_3DNOW;
526
    if( !config_GetInt( p_vlc, "mmxext" ) )
527
        libvlc.i_cpu &= ~CPU_CAPABILITY_MMXEXT;
528
    if( !config_GetInt( p_vlc, "sse" ) )
529
        libvlc.i_cpu &= ~CPU_CAPABILITY_SSE;
Sigmund Augdal Helberg's avatar
Sigmund Augdal Helberg committed
530 531
    if( !config_GetInt( p_vlc, "sse2" ) )
        libvlc.i_cpu &= ~CPU_CAPABILITY_SSE2;
532 533
#endif
#if defined( __powerpc__ ) || defined( SYS_DARWIN )
534
    if( !config_GetInt( p_vlc, "altivec" ) )
535
        libvlc.i_cpu &= ~CPU_CAPABILITY_ALTIVEC;
536
#endif
537 538

#define PRINT_CAPABILITY( capability, string )                              \
539
    if( libvlc.i_cpu & capability )                                         \
540 541 542 543 544 545 546 547 548 549 550 551 552 553
    {                                                                       \
        strncat( p_capabilities, string " ",                                \
                 sizeof(p_capabilities) - strlen(p_capabilities) );         \
        p_capabilities[sizeof(p_capabilities) - 1] = '\0';                  \
    }

    p_capabilities[0] = '\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" );
Sigmund Augdal Helberg's avatar
Sigmund Augdal Helberg committed
554
    PRINT_CAPABILITY( CPU_CAPABILITY_SSE2, "SSE2" );
555 556 557 558 559 560 561
    PRINT_CAPABILITY( CPU_CAPABILITY_ALTIVEC, "AltiVec" );
    PRINT_CAPABILITY( CPU_CAPABILITY_FPU, "FPU" );
    msg_Dbg( p_vlc, "CPU has capabilities %s", p_capabilities );

    /*
     * Choose the best memcpy module
     */
Gildas Bazin's avatar
 
Gildas Bazin committed
562
    p_vlc->p_memcpy_module = module_Need( p_vlc, "memcpy", "$memcpy", 0 );
563

564
    if( p_vlc->pf_memcpy == NULL )
565 566 567
    {
        p_vlc->pf_memcpy = memcpy;
    }
568 569 570 571 572

    if( p_vlc->pf_memset == NULL )
    {
        p_vlc->pf_memset = memset;
    }
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597
    
    /* Check for daemon mode */
    if( config_GetInt( p_vlc, "daemon" ) )
    {
        pid_t i_pid = 0;
        if( ( i_pid = fork() ) < 0 )
        {
            msg_Err( p_vlc, "Unable to fork vlc to daemon mode" );
            exit(1);
        }
        else if( i_pid )
        {
            /* This is the parent, exit right now */
            msg_Dbg( p_vlc, "closing parent process" );
            exit(0);
        }
	else
	{
            /* we are the child */
	    msg_Dbg( p_vlc, "we are the child !!!" );
            close( 0 );
            close( 1 );
            close( 2 );

            p_vlc->p_libvlc->b_daemon = VLC_TRUE;
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
598 599 600
	    var_Create( p_vlc, "interface", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
	    var_SetString( p_vlc, "interface", "dummy" );
    	    VLC_AddIntf( 0, "logger,none", VLC_FALSE, VLC_FALSE );
601 602
	}
    }
603

Sigmund Augdal Helberg's avatar
Sigmund Augdal Helberg committed
604 605 606 607
    /*
     * Initialize hotkey handling
     */
    var_Create( p_vlc, "key-pressed", VLC_VAR_INTEGER );
Gildas Bazin's avatar
 
Gildas Bazin committed
608 609
    p_vlc->p_hotkeys = malloc( sizeof(p_hotkeys) );
    /* Do a copy (we don't need to modify the strings) */
610
    memcpy( p_vlc->p_hotkeys, p_hotkeys, sizeof(p_hotkeys) );
Gildas Bazin's avatar
 
Gildas Bazin committed
611

612 613 614
    /*
     * Initialize playlist and get commandline files
     */
615
    p_playlist = playlist_Create( p_vlc );
616 617 618
    if( !p_playlist )
    {
        msg_Err( p_vlc, "playlist initialization failed" );
619 620
        if( p_vlc->p_memcpy_module != NULL )
        {
621
            module_Unneed( p_vlc, p_vlc->p_memcpy_module );
622
        }
623
        module_EndBank( p_vlc );
Gildas Bazin's avatar
 
Gildas Bazin committed
624
        if( i_object ) vlc_object_release( p_vlc );
625 626 627
        return VLC_EGENERIC;
    }

628 629 630 631 632 633 634
    /*
     * Load background interfaces
     */
    psz_modules = config_GetPsz( p_vlc, "extraintf" );
    psz_parser = psz_modules;
    while ( psz_parser && *psz_parser )
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
635
        char *psz_module, *psz_temp;
636 637 638 639 640 641 642
        psz_module = psz_parser;
        psz_parser = strchr( psz_module, ',' );
        if ( psz_parser )
        {
            *psz_parser = '\0';
            psz_parser++;
        }
Gildas Bazin's avatar
 
Gildas Bazin committed
643 644 645 646
        psz_temp = (char *)malloc( strlen(psz_module) + sizeof(",none") );
        if( psz_temp )
        {
            sprintf( psz_temp, "%s,none", psz_module );
647
            VLC_AddIntf( 0, psz_temp, VLC_FALSE, VLC_FALSE );
Gildas Bazin's avatar
 
Gildas Bazin committed
648 649
            free( psz_temp );
        }
650 651 652 653 654
    }
    if ( psz_modules )
    {
        free( psz_modules );
    }
655

Sigmund Augdal Helberg's avatar
Sigmund Augdal Helberg committed
656 657 658
    /*
     * Allways load the hotkeys interface if it exists
     */
659
    VLC_AddIntf( 0, "hotkeys,none", VLC_FALSE, VLC_FALSE );
Sigmund Augdal Helberg's avatar
Sigmund Augdal Helberg committed
660

661 662 663 664
    /*
     * FIXME: kludge to use a p_vlc-local variable for the Mozilla plugin
     */
    var_Create( p_vlc, "drawable", VLC_VAR_INTEGER );
665 666 667 668 669 670 671 672 673 674 675
    var_Create( p_vlc, "drawableredraw", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawablet", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawablel", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawableb", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawabler", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawablex", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawabley", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawablew", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawableh", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawableportx", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawableporty", VLC_VAR_INTEGER );
676

677 678 679 680 681
    /*
     * Get input filenames given as commandline arguments
     */
    GetFilenames( p_vlc, i_argc, ppsz_argv );

Gildas Bazin's avatar
 
Gildas Bazin committed
682
    if( i_object ) vlc_object_release( p_vlc );
683 684 685 686
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
687
 * VLC_AddIntf: add an interface
688 689
 *****************************************************************************
 * This function opens an interface plugin and runs it. If b_block is set
Sam Hocevar's avatar
Sam Hocevar committed
690 691
 * to 0, VLC_AddIntf will return immediately and let the interface run in a
 * separate thread. If b_block is set to 1, VLC_AddIntf will continue until
692 693
 * user requests to quit. If b_play is set to 1, VLC_AddIntf will start playing
 * the playlist when it is completely initialised.
694
 *****************************************************************************/
695 696
int VLC_AddIntf( int i_object, char const *psz_module,
                 vlc_bool_t b_block, vlc_bool_t b_play )
697
{
Sam Hocevar's avatar
Sam Hocevar committed
698
    int i_err;
699
    intf_thread_t *p_intf;
700
    vlc_t *p_vlc = vlc_current_object( i_object );
Sam Hocevar's avatar
Sam Hocevar committed
701

702
    if( !p_vlc )
703
    {
704
        return VLC_ENOOBJ;
705 706 707
    }

    /* Try to create the interface */
708
    p_intf = intf_Create( p_vlc, psz_module ? psz_module : "$intf" );
709 710 711

    if( p_intf == NULL )
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
712
        msg_Err( p_vlc, "interface \"%s\" initialization failed", psz_module );
Gildas Bazin's avatar
 
Gildas Bazin committed
713
        if( i_object ) vlc_object_release( p_vlc );
714 715 716
        return VLC_EGENERIC;
    }

717 718 719
    /* Interface doesn't handle play on start so do it ourselves */
    if( !p_intf->b_play && b_play ) VLC_Play( i_object );

720
    /* Try to run the interface */
721
    p_intf->b_play = b_play;
722
    p_intf->b_block = b_block;
Sam Hocevar's avatar
Sam Hocevar committed
723 724
    i_err = intf_RunThread( p_intf );
    if( i_err )
725
    {
726
        vlc_object_detach( p_intf );
727
        intf_Destroy( p_intf );
Gildas Bazin's avatar
 
Gildas Bazin committed
728
        if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
729
        return i_err;
730 731
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
732
    if( i_object ) vlc_object_release( p_vlc );
733 734 735 736
    return VLC_SUCCESS;
}

/*****************************************************************************
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838
 * VLC_Die: ask vlc to die.
 *****************************************************************************
 * This function sets p_vlc->b_die to VLC_TRUE, but does not do any other
 * task. It is your duty to call VLC_CleanUp and VLC_Destroy afterwards.
 *****************************************************************************/
int VLC_Die( int i_object )
{
    vlc_t *p_vlc = vlc_current_object( i_object );

    if( !p_vlc )
    {
        return VLC_ENOOBJ;
    }

    p_vlc->b_die = VLC_TRUE;

    if( i_object ) vlc_object_release( p_vlc );
    return VLC_SUCCESS;
}

/*****************************************************************************
 * VLC_CleanUp: CleanUp all the intf, playlist, vout, aout
 *****************************************************************************/
int VLC_CleanUp( int i_object )
{
    intf_thread_t      * p_intf;
    playlist_t         * p_playlist;
    vout_thread_t      * p_vout;
    aout_instance_t    * p_aout;
    announce_handler_t * p_announce;
    vlc_t *p_vlc = vlc_current_object( i_object );

    /* Check that the handle is valid */
    if( !p_vlc )
    {
        return VLC_ENOOBJ;
    }

    /*
     * Ask the interfaces to stop and destroy them
     */
    msg_Dbg( p_vlc, "removing all interfaces" );
    while( (p_intf = vlc_object_find( p_vlc, VLC_OBJECT_INTF, FIND_CHILD )) )
    {
        intf_StopThread( p_intf );
        vlc_object_detach( p_intf );
        vlc_object_release( p_intf );
        intf_Destroy( p_intf );
    }

    /*
     * Free playlists
     */
    msg_Dbg( p_vlc, "removing all playlists" );
    while( (p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST,
                                          FIND_CHILD )) )
    {
        vlc_object_detach( p_playlist );
        vlc_object_release( p_playlist );
        playlist_Destroy( p_playlist );
    }

    /*
     * Free video outputs
     */
    msg_Dbg( p_vlc, "removing all video outputs" );
    while( (p_vout = vlc_object_find( p_vlc, VLC_OBJECT_VOUT, FIND_CHILD )) )
    {
        vlc_object_detach( p_vout );
        vlc_object_release( p_vout );
        vout_Destroy( p_vout );
    }

    /*
     * Free audio outputs
     */
    msg_Dbg( p_vlc, "removing all audio outputs" );
    while( (p_aout = vlc_object_find( p_vlc, VLC_OBJECT_AOUT, FIND_CHILD )) )
    {
        vlc_object_detach( (vlc_object_t *)p_aout );
        vlc_object_release( (vlc_object_t *)p_aout );
        aout_Delete( p_aout );
    }

    /*
     * Free announce handler(s?)
     */
    msg_Dbg( p_vlc, "removing announce handler" );
    while( (p_announce = vlc_object_find( p_vlc, VLC_OBJECT_ANNOUNCE,
                                                 FIND_CHILD ) ) )
   {
        vlc_object_detach( p_announce );
        vlc_object_release( p_announce );
        announce_HandlerDestroy( p_announce );
   }

    if( i_object ) vlc_object_release( p_vlc );
    return VLC_SUCCESS;
}

/*****************************************************************************
 * VLC_Destroy: Destroy everything.
839
 *****************************************************************************
840
 * This function requests the running threads to finish, waits for their
841 842
 * termination, and destroys their structure.
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
843
int VLC_Destroy( int i_object )
844
{
845
    vlc_t *p_vlc = vlc_current_object( i_object );
846

847
    if( !p_vlc )
848
    {
849
        return VLC_ENOOBJ;
850 851
    }

852 853 854 855 856 857 858
    /*
     * Free allocated memory
     */
    if( p_vlc->p_memcpy_module )
    {
        module_Unneed( p_vlc, p_vlc->p_memcpy_module );
        p_vlc->p_memcpy_module = NULL;
859 860
    }

861
    /*
862
     * Free module bank !
863 864 865
     */
    module_EndBank( p_vlc );

866 867 868 869 870
    if( p_vlc->psz_homedir )
    {
        free( p_vlc->psz_homedir );
        p_vlc->psz_homedir = NULL;
    }
871

Gildas Bazin's avatar
 
Gildas Bazin committed
872 873 874 875 876 877
    if( p_vlc->psz_configfile )
    {
        free( p_vlc->psz_configfile );
        p_vlc->psz_configfile = NULL;
    }

878 879 880 881 882 883
    if( p_vlc->p_hotkeys )
    {
        free( p_vlc->p_hotkeys );
        p_vlc->p_hotkeys = NULL;
    }

884 885 886 887
    /*
     * System specific cleaning code
     */
    system_End( p_vlc );
888

889 890 891
    /* Destroy mutexes */
    vlc_mutex_destroy( &p_vlc->config_lock );

892 893
    vlc_object_detach( p_vlc );

894 895 896
    /* Release object before destroying it */
    if( i_object ) vlc_object_release( p_vlc );

897 898
    vlc_object_destroy( p_vlc );

899
    /* Stop thread system: last one out please shut the door! */
900
    vlc_threads_end( p_libvlc );
901

902 903 904
    return VLC_SUCCESS;
}

905
/*****************************************************************************
906
 * VLC_VariableSet: set a vlc variable
907
 *****************************************************************************/
908
int VLC_VariableSet( int i_object, char const *psz_var, vlc_value_t value )
909
{
910
    vlc_t *p_vlc = vlc_current_object( i_object );
Gildas Bazin's avatar
 
Gildas Bazin committed
911
    int i_ret;
912 913 914

    if( !p_vlc )
    {
915
        return VLC_ENOOBJ;
916 917
    }

Sam Hocevar's avatar
Sam Hocevar committed
918 919 920
    /* FIXME: Temporary hack for Mozilla, if variable starts with conf:: then
     * we handle it as a configuration variable. Don't tell Gildas :) -- sam */
    if( !strncmp( psz_var, "conf::", 6 ) )
921
    {
Sam Hocevar's avatar
Sam Hocevar committed
922
        module_config_t *p_item;
923
        char const *psz_newvar = psz_var + 6;
924

Sam Hocevar's avatar
Sam Hocevar committed
925
        p_item = config_FindConfig( VLC_OBJECT(p_vlc), psz_newvar );
926

Sam Hocevar's avatar
Sam Hocevar committed
927
        if( p_item )
928
        {
Sam Hocevar's avatar
Sam Hocevar committed
929
            switch( p_item->i_type )
930
            {
Sam Hocevar's avatar
Sam Hocevar committed
931 932 933 934 935 936 937 938 939 940 941 942
                case CONFIG_ITEM_BOOL:
                    config_PutInt( p_vlc, psz_newvar, value.b_bool );
                    break;
                case CONFIG_ITEM_INTEGER:
                    config_PutInt( p_vlc, psz_newvar, value.i_int );
                    break;
                case CONFIG_ITEM_FLOAT:
                    config_PutFloat( p_vlc, psz_newvar, value.f_float );
                    break;
                default:
                    config_PutPsz( p_vlc, psz_newvar, value.psz_string );
                    break;
943
            }
Gildas Bazin's avatar
 
Gildas Bazin committed
944
            if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
945
            return VLC_SUCCESS;
946 947 948
        }
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
949 950 951 952
    i_ret = var_Set( p_vlc, psz_var, value );

    if( i_object ) vlc_object_release( p_vlc );
    return i_ret;
Sam Hocevar's avatar
Sam Hocevar committed
953 954 955
}

/*****************************************************************************
956
 * VLC_VariableGet: get a vlc variable
Sam Hocevar's avatar
Sam Hocevar committed
957
 *****************************************************************************/
958
int VLC_Get( int i_object, char const *psz_var, vlc_value_t *p_value )
Sam Hocevar's avatar
Sam Hocevar committed
959
{
960
    vlc_t *p_vlc = vlc_current_object( i_object );
Gildas Bazin's avatar
 
Gildas Bazin committed
961
    int i_ret;
Sam Hocevar's avatar
Sam Hocevar committed
962 963

    if( !p_vlc )
964
    {
965
        return VLC_ENOOBJ;
966 967
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
968 969 970 971
    i_ret = var_Get( p_vlc, psz_var, p_value );

    if( i_object ) vlc_object_release( p_vlc );
    return i_ret;
972 973
}

974
/*****************************************************************************
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
975 976 977 978
 * VLC_AddTarget: adds a target for playing.
 *****************************************************************************
 * This function adds psz_target to the current playlist. If a playlist does
 * not exist, it will create one.
979
 *****************************************************************************/
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
980 981 982
int VLC_AddTarget( int i_object, char const *psz_target,
                   char const **ppsz_options, int i_options,
                   int i_mode, int i_pos )
983
{
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
984 985
    int i_err;
    playlist_t *p_playlist;
986 987 988 989 990 991 992
    vlc_t *p_vlc = vlc_current_object( i_object );

    if( !p_vlc )
    {
        return VLC_ENOOBJ;
    }

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
993
    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
994

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
995
    if( p_playlist == NULL )
996
    {
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
997 998 999 1000 1001 1002 1003 1004 1005 1006
        msg_Dbg( p_vlc, "no playlist present, creating one" );
        p_playlist = playlist_Create( p_vlc );

        if( p_playlist == NULL )
        {
            if( i_object ) vlc_object_release( p_vlc );
            return VLC_EGENERIC;
        }

        vlc_object_yield( p_playlist );
1007 1008
    }

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1009 1010
    i_err = playlist_AddExt( p_playlist, psz_target, psz_target,
                             i_mode, i_pos, -1, ppsz_options, i_options);
1011 1012 1013 1014

    vlc_object_release( p_playlist );

    if( i_object ) vlc_object_release( p_vlc );
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1015
    return i_err;
1016 1017 1018
}

/*****************************************************************************
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1019
 * VLC_Play: play
1020
 *****************************************************************************/
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1021
int VLC_Play( int i_object )
1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039
{
    playlist_t * p_playlist;
    vlc_t *p_vlc = vlc_current_object( i_object );

    /* Check that the handle is valid */
    if( !p_vlc )
    {
        return VLC_ENOOBJ;
    }

    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );

    if( !p_playlist )
    {
        if( i_object ) vlc_object_release( p_vlc );
        return VLC_ENOOBJ;
    }

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1040
    playlist_Play( p_playlist );
1041 1042 1043
    vlc_object_release( p_playlist );

    if( i_object ) vlc_object_release( p_vlc );
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1044
    return VLC_SUCCESS;
1045 1046
}

1047
/*****************************************************************************
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1048
 * VLC_Pause: toggle pause
1049
 *****************************************************************************/
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1050
int VLC_Pause( int i_object )
1051 1052
{
    playlist_t * p_playlist;
1053
    vlc_t *p_vlc = vlc_current_object( i_object );
1054 1055

    /* Check that the handle is valid */
1056
    if( !p_vlc )
1057
    {
1058
        return VLC_ENOOBJ;
1059
    }
1060

1061 1062 1063 1064
    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );

    if( !p_playlist )
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
1065
        if( i_object ) vlc_object_release( p_vlc );
1066
        return VLC_ENOOBJ;
1067 1068
    }

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1069
    playlist_Pause( p_playlist );
1070 1071
    vlc_object_release( p_playlist );

Gildas Bazin's avatar
 
Gildas Bazin committed
1072
    if( i_object ) vlc_object_release( p_vlc );
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1073
    return VLC_SUCCESS;
1074 1075 1076
}

/*****************************************************************************
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1077
 * VLC_Pause: toggle pause
1078
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
1079
int VLC_Stop( int i_object )
1080
{
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1081
    playlist_t * p_playlist;
1082
    vlc_t *p_vlc = vlc_current_object( i_object );
1083 1084

    /* Check that the handle is valid */
1085
    if( !p_vlc )
1086
    {
1087
        return VLC_ENOOBJ;
1088 1089
    }

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1090
    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
1091

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1092
    if( !p_playlist )
1093
    {
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1094 1095
        if( i_object ) vlc_object_release( p_vlc );
        return VLC_ENOOBJ;
1096 1097
    }

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1098
    playlist_Stop( p_playlist );
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1099
    vlc_object_release( p_playlist );
Clément Stenac's avatar
Clément Stenac committed
1100

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1101
    if( i_object ) vlc_object_release( p_vlc );
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1102
    return VLC_SUCCESS;
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1103
}
Clément Stenac's avatar
Clément Stenac committed
1104

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116
/*****************************************************************************
 * VLC_IsPlaying: Query for Playlist Status
 *****************************************************************************/
vlc_bool_t VLC_IsPlaying( int i_object )
{
    playlist_t * p_playlist;
    vlc_bool_t   b_playing;

    vlc_t *p_vlc = vlc_current_object( i_object );

    /* Check that the handle is valid */
    if( !p_vlc )
1117
    {
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1118
        return VLC_ENOOBJ;
1119 1120
    }

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1121 1122 1123
    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );

    if( !p_playlist )
1124
    {
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1125 1126
        if( i_object ) vlc_object_release( p_vlc );
        return VLC_ENOOBJ;
1127 1128
    }