#include "modules/modules.h"
#include "config/configuration.h"
-#include "interface/interface.h"
#include <errno.h> /* ENOMEM */
#include <stdio.h> /* sprintf() */
# include <locale.h>
#endif
+#ifdef ENABLE_NLS
+# include <libintl.h> /* bindtextdomain */
+#endif
+
#ifdef HAVE_DBUS
/* used for one-instance mode */
# include <dbus/dbus.h>
/*****************************************************************************
* The evil global variables. We handle them with care, don't worry.
*****************************************************************************/
-static libvlc_int_t * p_static_vlc = NULL;
static unsigned i_instances = 0;
#ifndef WIN32
assert (refs != (uintptr_t)(-1)); /* reference underflow?! */
if (refs == 0)
{
-#ifdef USE_SYNC
+#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
#elif defined (WIN32) && defined (__GNUC__)
#elif defined(__APPLE__)
#else
#endif
static int ConsoleWidth ( void );
-static int VerboseCallback( vlc_object_t *, char const *,
- vlc_value_t, vlc_value_t, void * );
-
static void InitDeviceValues( libvlc_int_t * );
static vlc_mutex_t global_lock = VLC_STATIC_MUTEX;
priv = libvlc_priv (p_libvlc);
priv->p_playlist = NULL;
- priv->p_interaction = NULL;
+ priv->p_dialog_provider = NULL;
priv->p_vlm = NULL;
- p_libvlc->psz_object_name = strdup( "libvlc" );
/* Initialize message queue */
msg_Create( p_libvlc );
/* Initialize mutexes */
vlc_mutex_init( &priv->timer_lock );
- vlc_mutex_init( &priv->config_lock );
-
- /* Store data for the non-reentrant API */
- p_static_vlc = p_libvlc;
+ vlc_cond_init( &priv->exiting );
return p_libvlc;
}
if( config_LoadCmdLine( p_libvlc, &i_argc, ppsz_argv, true ) )
{
- module_EndBank( p_libvlc );
+ module_EndBank( p_libvlc, false );
return VLC_EGENERIC;
}
/* Announce who we are - Do it only for first instance ? */
msg_Dbg( p_libvlc, "%s", COPYRIGHT_MESSAGE );
msg_Dbg( p_libvlc, "libvlc was configured with %s", CONFIGURE_LINE );
- /* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
+ /*xgettext: Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
msg_Dbg( p_libvlc, "translation test: code is \"%s\"", _("C") );
/* Check for short help option */
i_ret = VLC_EEXITSUCCESS;
}
- /* Set the config file stuff */
- priv->psz_configfile = config_GetCustomConfigFile( p_libvlc );
-
/* Check for plugins cache options */
bool b_cache_delete = config_GetInt( p_libvlc, "reset-plugins-cache" ) > 0;
if( b_exit )
{
- module_EndBank( p_libvlc );
+ module_EndBank( p_libvlc, false );
return i_ret;
}
if( !config_GetInt( p_libvlc, "ignore-config" ) )
config_LoadConfigFile( p_libvlc, "main" );
config_LoadCmdLine( p_libvlc, &i_argc, ppsz_argv, true );
+ priv->i_verbose = config_GetInt( p_libvlc, "verbose" );
/* Check if the user specified a custom language */
psz_language = config_GetPsz( p_libvlc, "language" );
/* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
msg_Dbg( p_libvlc, "translation test: code is \"%s\"", _("C") );
- module_EndBank( p_libvlc );
+ module_EndBank( p_libvlc, false );
module_InitBank( p_libvlc );
if( !config_GetInt( p_libvlc, "ignore-config" ) )
config_LoadConfigFile( p_libvlc, "main" );
config_LoadCmdLine( p_libvlc, &i_argc, ppsz_argv, true );
+ priv->i_verbose = config_GetInt( p_libvlc, "verbose" );
}
free( psz_language );
# endif
* list of configuration options exported by each module and loads their
* default values.
*/
- module_LoadBuiltins( p_libvlc );
module_LoadPlugins( p_libvlc, b_cache_delete );
if( p_libvlc->b_die )
{
if( b_exit )
{
- module_EndBank( p_libvlc );
+ module_EndBank( p_libvlc, true );
return i_ret;
}
"that they are valid.\n" );
PauseConsole();
#endif
- module_EndBank( p_libvlc );
+ module_EndBank( p_libvlc, true );
return VLC_EGENERIC;
}
+ priv->i_verbose = config_GetInt( p_libvlc, "verbose" );
/*
* System specific configuration
{
msg_Err( p_libvlc, "D-Bus problem" );
system_End( p_libvlc );
- exit( VLC_ETIMEOUT );
+ exit( 1 );
}
/* append MRLs */
{
dbus_message_unref( p_dbus_msg );
system_End( p_libvlc );
- exit( VLC_ENOMEM );
+ exit( 1 );
}
b_play = TRUE;
if( config_GetInt( p_libvlc, "playlist-enqueue" ) > 0 )
{
dbus_message_unref( p_dbus_msg );
system_End( p_libvlc );
- exit( VLC_ENOMEM );
+ exit( 1 );
}
/* send message and get a handle for a reply */
msg_Err( p_libvlc, "D-Bus problem" );
dbus_message_unref( p_dbus_msg );
system_End( p_libvlc );
- exit( VLC_ETIMEOUT );
+ exit( 1 );
}
if ( NULL == p_dbus_pending )
msg_Err( p_libvlc, "D-Bus problem" );
dbus_message_unref( p_dbus_msg );
system_End( p_libvlc );
- exit( VLC_ETIMEOUT );
+ exit( 1 );
}
dbus_connection_flush( p_conn );
dbus_message_unref( p_dbus_msg );
/* bye bye */
system_End( p_libvlc );
- exit( VLC_SUCCESS );
+ exit( 0 );
}
}
/* we unreference the connection when we've finished with it */
msg_Err( p_libvlc, "verbose-objects usage: \n"
"--verbose-objects=+printthatobject,"
"-dontprintthatone\n"
- "(keyword 'all' to applies to all objects)\n");
+ "(keyword 'all' to applies to all objects)");
free( psz_verbose_objects );
+ /* FIXME: leaks!!!! */
return VLC_EGENERIC;
}
}
free( psz_verbose_objects );
}
+ /* Last chance to set the verbosity. Once we start interfaces and other
+ * threads, verbosity becomes read-only. */
var_Create( p_libvlc, "verbose", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
if( config_GetInt( p_libvlc, "quiet" ) > 0 )
{
- val.i_int = -1;
- var_Set( p_libvlc, "verbose", val );
+ var_SetInteger( p_libvlc, "verbose", -1 );
+ priv->i_verbose = -1;
}
- var_AddCallback( p_libvlc, "verbose", VerboseCallback, NULL );
- var_TriggerCallback( p_libvlc, "verbose" );
+ vlc_threads_setup( p_libvlc );
if( priv->b_color )
priv->b_color = config_GetInt( p_libvlc, "color" ) > 0;
priv->i_timers = 0;
priv->pp_timers = NULL;
- /* Init stats */
- p_libvlc->p_stats = (global_stats_t *)malloc( sizeof( global_stats_t ) );
- if( !p_libvlc->p_stats )
- {
- vlc_object_release( p_libvlc );
- return VLC_ENOMEM;
- }
- vlc_mutex_init( &p_libvlc->p_stats->lock );
- priv->p_stats_computer = NULL;
-
priv->i_last_input_id = 0; /* Not very safe, should be removed */
/*
*/
var_Create( p_libvlc, "key-pressed", VLC_VAR_INTEGER );
var_Create( p_libvlc, "key-action", VLC_VAR_INTEGER );
- p_libvlc->p_hotkeys = malloc( libvlc_hotkeys_size );
- /* Do a copy (we don't need to modify the strings) */
- memcpy( p_libvlc->p_hotkeys, libvlc_hotkeys, libvlc_hotkeys_size );
- var_AddCallback( p_libvlc, "key-pressed", vlc_key_to_action,
- p_libvlc->p_hotkeys );
+ {
+ struct hotkey *p_keys =
+ malloc( (libvlc_actions_count + 1) * sizeof (*p_keys) );
- /* Initialize interaction */
- priv->p_interaction = interaction_Init( p_libvlc );
+ /* Initialize from configuration */
+ for( size_t i = 0; i < libvlc_actions_count; i++ )
+ {
+ p_keys[i].psz_action = libvlc_actions[i].name;
+ p_keys[i].i_key = config_GetInt( p_libvlc,
+ libvlc_actions[i].name );
+ p_keys[i].i_action = libvlc_actions[i].value;
+ }
+ p_keys[libvlc_actions_count].psz_action = NULL;
+ p_keys[libvlc_actions_count].i_key = 0;
+ p_keys[libvlc_actions_count].i_action = 0;
+ p_libvlc->p_hotkeys = p_keys;
+ var_AddCallback( p_libvlc, "key-pressed", vlc_key_to_action,
+ p_keys );
+ }
/* Initialize playlist and get commandline files */
p_playlist = playlist_Create( VLC_OBJECT(p_libvlc) );
{
module_unneed( p_libvlc, priv->p_memcpy_module );
}
- module_EndBank( p_libvlc );
+ module_EndBank( p_libvlc, true );
return VLC_EGENERIC;
}
playlist_Activate( p_playlist );
if( psz_modules && *psz_modules && psz_control && *psz_control )
{
- psz_modules = (char *)realloc( psz_modules, strlen( psz_modules ) +
- strlen( psz_control ) + 1 );
- sprintf( psz_modules, "%s:%s", psz_modules, psz_control );
+ char* psz_tmp;
+ if( asprintf( &psz_tmp, "%s:%s", psz_modules, psz_control ) != -1 )
+ {
+ free( psz_modules );
+ psz_modules = psz_tmp;
+ }
}
else if( psz_control && *psz_control )
{
}
if( asprintf( &psz_temp, "%s,none", psz_module ) != -1)
{
- libvlc_InternalAddIntf( p_libvlc, psz_temp );
+ intf_Create( p_libvlc, psz_temp );
free( psz_temp );
}
}
/*
* Always load the hotkeys interface if it exists
*/
- libvlc_InternalAddIntf( p_libvlc, "hotkeys,none" );
-#ifdef WIN32
- libvlc_InternalAddIntf( p_libvlc, "globalhotkeys,none" );
-#endif
+ intf_Create( p_libvlc, "hotkeys,none" );
#ifdef HAVE_DBUS
/* loads dbus control interface if in one-instance mode
if( config_GetInt( p_libvlc, "one-instance" ) > 0
|| ( config_GetInt( p_libvlc, "one-instance-when-started-from-file" )
&& config_GetInt( p_libvlc, "started-from-file" ) ) )
- libvlc_InternalAddIntf( p_libvlc, "dbus,none" );
+ intf_Create( p_libvlc, "dbus,none" );
/* Prevents the power management daemon from suspending the system
* when VLC is active */
if( config_GetInt( p_libvlc, "inhibit" ) > 0 )
- libvlc_InternalAddIntf( p_libvlc, "inhibit,none" );
+ intf_Create( p_libvlc, "inhibit,none" );
#endif
/*
#ifdef HAVE_X11_XLIB_H
if( config_GetInt( p_libvlc, "disable-screensaver" ) )
{
- libvlc_InternalAddIntf( p_libvlc, "screensaver,none" );
+ intf_Create( p_libvlc, "screensaver,none" );
}
#endif
if( (config_GetInt( p_libvlc, "file-logging" ) > 0) &&
!config_GetInt( p_libvlc, "syslog" ) )
{
- libvlc_InternalAddIntf( p_libvlc, "logger,none" );
+ intf_Create( p_libvlc, "logger,none" );
}
#ifdef HAVE_SYSLOG_H
if( config_GetInt( p_libvlc, "syslog" ) > 0 )
{
char *logmode = var_CreateGetString( p_libvlc, "logmode" );
var_SetString( p_libvlc, "logmode", "syslog" );
- libvlc_InternalAddIntf( p_libvlc, "logger,none" );
+ intf_Create( p_libvlc, "logger,none" );
if( logmode )
{
}
#endif
- if( config_GetInt( p_libvlc, "show-intf" ) > 0 )
- {
- libvlc_InternalAddIntf( p_libvlc, "showintf,none" );
- }
-
if( config_GetInt( p_libvlc, "network-synchronisation") > 0 )
{
- libvlc_InternalAddIntf( p_libvlc, "netsync,none" );
+ intf_Create( p_libvlc, "netsync,none" );
}
#ifdef WIN32
}
#endif
- /*
- * FIXME: kludge to use a p_libvlc-local variable for the Mozilla plugin
- */
- var_Create( p_libvlc, "drawable", VLC_VAR_INTEGER );
var_Create( p_libvlc, "drawable-view-top", VLC_VAR_INTEGER );
var_Create( p_libvlc, "drawable-view-left", VLC_VAR_INTEGER );
var_Create( p_libvlc, "drawable-view-bottom", VLC_VAR_INTEGER );
/* Create volume callback system. */
var_Create( p_libvlc, "volume-change", VLC_VAR_BOOL );
- /* Create a variable for showing the interface (moved from playlist). */
+ /* Create a variable for showing the fullscreen interface from hotkeys */
var_Create( p_libvlc, "intf-show", VLC_VAR_BOOL );
var_SetBool( p_libvlc, "intf-show", true );
+ /* Create a variable for showing the right click menu */
var_Create( p_libvlc, "intf-popupmenu", VLC_VAR_BOOL );
/*
{
playlist_t *p_playlist = pl_Hold( p_libvlc );
playlist_AddExt( p_playlist, val.psz_string, NULL, PLAYLIST_INSERT, 0,
- -1, NULL, 0, true, pl_Unlocked );
+ -1, 0, NULL, 0, true, pl_Unlocked );
pl_Release( p_libvlc );
}
free( val.psz_string );
* Cleanup a libvlc instance. The instance is not completely deallocated
* \param p_libvlc the instance to clean
*/
-int libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
+void libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
{
libvlc_priv_t *priv = libvlc_priv (p_libvlc);
playlist_t *p_playlist = priv->p_playlist;
/* Ask the interfaces to stop and destroy them */
msg_Dbg( p_libvlc, "removing all interfaces" );
- intf_thread_t *p_intf;
- while( (p_intf = vlc_object_find( p_libvlc, VLC_OBJECT_INTF, FIND_CHILD )) )
- {
- intf_StopThread( p_intf );
- vlc_object_detach( p_intf );
- vlc_object_release( p_intf ); /* for intf_Create() */
- vlc_object_release( p_intf ); /* for vlc_object_find() */
- }
+ libvlc_Quit( p_libvlc );
+ intf_DestroyAll( p_libvlc );
#ifdef ENABLE_VLM
/* Destroy VLM if created in libvlc_InternalInit */
vlc_object_release( p_playlist );
- /* Free interaction */
- msg_Dbg( p_libvlc, "removing interaction" );
- interaction_Destroy( priv->p_interaction );
-
stats_TimersDumpAll( p_libvlc );
stats_TimersCleanAll( p_libvlc );
msg_Dbg( p_libvlc, "removing stats" );
- vlc_mutex_destroy( &p_libvlc->p_stats->lock );
- FREENULL( p_libvlc->p_stats );
-
- return VLC_SUCCESS;
-}
-
-/**
- * Destroy everything.
- * This function requests the running threads to finish, waits for their
- * termination, and destroys their structure.
- * It stops the thread systems: no instance can run after this has run
- * \param p_libvlc the instance to destroy
- */
-int libvlc_InternalDestroy( libvlc_int_t *p_libvlc )
-{
- if( !p_libvlc )
- return VLC_EGENERIC;
-
- libvlc_priv_t *priv = libvlc_priv( p_libvlc );
#ifndef WIN32
char* psz_pidfile = NULL;
}
/* Free module bank. It is refcounted, so we call this each time */
- module_EndBank( p_libvlc );
+ module_EndBank( p_libvlc, true );
- FREENULL( priv->psz_configfile );
var_DelCallback( p_libvlc, "key-pressed", vlc_key_to_action,
- p_libvlc->p_hotkeys );
- FREENULL( p_libvlc->p_hotkeys );
+ (void *)p_libvlc->p_hotkeys );
+ free( (void *)p_libvlc->p_hotkeys );
+}
+
+/**
+ * Destroy everything.
+ * This function requests the running threads to finish, waits for their
+ * termination, and destroys their structure.
+ * It stops the thread systems: no instance can run after this has run
+ * \param p_libvlc the instance to destroy
+ */
+void libvlc_InternalDestroy( libvlc_int_t *p_libvlc )
+{
+ libvlc_priv_t *priv = libvlc_priv( p_libvlc );
vlc_mutex_lock( &global_lock );
i_instances--;
msg_Destroy( p_libvlc );
/* Destroy mutexes */
- vlc_mutex_destroy( &priv->config_lock );
+ vlc_cond_destroy( &priv->exiting );
vlc_mutex_destroy( &priv->timer_lock );
- vlc_object_release( p_libvlc );
- p_libvlc = NULL;
+#ifndef NDEBUG /* Hack to dump leaked objects tree */
+ if( vlc_internals( p_libvlc )->i_refcount > 1 )
+ while( vlc_internals( p_libvlc )->i_refcount > 0 )
+ vlc_object_release( p_libvlc );
+#endif
- return VLC_SUCCESS;
+ assert( vlc_internals( p_libvlc )->i_refcount == 1 );
+ vlc_object_release( p_libvlc );
}
/**
*/
int libvlc_InternalAddIntf( libvlc_int_t *p_libvlc, char const *psz_module )
{
- int i_err;
- intf_thread_t *p_intf = NULL;
-
if( !p_libvlc )
return VLC_EGENERIC;
psz_module = "dummy";
else
#endif
- msg_Info( p_libvlc, _("Running vlc with the default interface. Use 'cvlc' to use vlc without interface.") );
+ msg_Info( p_libvlc, "%s",
+ _("Running vlc with the default interface. "
+ "Use 'cvlc' to use vlc without interface.") );
}
free( psz_interface );
}
/* Try to create the interface */
- p_intf = intf_Create( p_libvlc, psz_module ? psz_module : "$intf" );
- if( p_intf == NULL )
+ if( intf_Create( p_libvlc, psz_module ? psz_module : "$intf" ) )
{
msg_Err( p_libvlc, "interface \"%s\" initialization failed",
- psz_module );
+ psz_module ? psz_module : "default" );
return VLC_EGENERIC;
}
+ return VLC_SUCCESS;
+}
- /* Try to run the interface */
- i_err = intf_RunThread( p_intf );
- if( i_err )
- {
- vlc_object_detach( p_intf );
- vlc_object_release( p_intf );
- return i_err;
- }
+static vlc_mutex_t exit_lock = VLC_STATIC_MUTEX;
- return VLC_SUCCESS;
-};
+/**
+ * Waits until the LibVLC instance gets an exit signal. Normally, this happens
+ * when the user "exits" an interface plugin.
+ */
+void libvlc_InternalWait( libvlc_int_t *p_libvlc )
+{
+ libvlc_priv_t *priv = libvlc_priv( p_libvlc );
+
+ vlc_mutex_lock( &exit_lock );
+ while( vlc_object_alive( p_libvlc ) )
+ vlc_cond_wait( &priv->exiting, &exit_lock );
+ vlc_mutex_unlock( &exit_lock );
+}
+
+/**
+ * Posts an exit signal to LibVLC instance. This will normally initiate the
+ * cleanup and destroy process. It should only be called on behalf of the user.
+ */
+void libvlc_Quit( libvlc_int_t *p_libvlc )
+{
+ libvlc_priv_t *priv = libvlc_priv( p_libvlc );
+
+ vlc_mutex_lock( &exit_lock );
+ vlc_object_kill( p_libvlc );
+ vlc_cond_signal( &priv->exiting );
+ vlc_mutex_unlock( &exit_lock );
+}
#if defined( ENABLE_NLS ) && (defined (__APPLE__) || defined (WIN32)) && \
( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
playlist_t *p_playlist = pl_Hold( p_vlc );
playlist_AddExt( p_playlist, ppsz_argv[i_opt], NULL, PLAYLIST_INSERT,
- 0, -1, ( i_options ? &ppsz_argv[i_opt + 1] : NULL ),
- i_options, true, pl_Unlocked );
+ 0, -1,
+ i_options, ( i_options ? &ppsz_argv[i_opt + 1] : NULL ), VLC_INPUT_OPTION_TRUSTED,
+ true, pl_Unlocked );
pl_Release( p_vlc );
}
utf8_fprintf( stdout, "%s\n", _("To get exhaustive help, use '-H'.") );
}
+static const char vlc_usage[] = N_(
+ "Usage: %s [options] [stream] ..."
+ "\nYou can specify multiple streams on the commandline. They will be enqueued in the playlist."
+ "\nThe first item specified will be played first."
+ "\n"
+ "\nOptions-styles:"
+ "\n --option A global option that is set for the duration of the program."
+ "\n -option A single letter version of a global --option."
+ "\n :option An option that only applies to the stream directly before it"
+ "\n and that overrides previous settings."
+ "\n"
+ "\nStream MRL syntax:"
+ "\n [[access][/demux]://]URL[@[title][:chapter][-[title][:chapter]]] [:option=value ...]"
+ "\n"
+ "\n Many of the global --options can also be used as MRL specific :options."
+ "\n Multiple :option=value pairs can be specified."
+ "\n"
+ "\nURL syntax:"
+ "\n [file://]filename Plain media file"
+ "\n http://ip:port/file HTTP URL"
+ "\n ftp://ip:port/file FTP URL"
+ "\n mms://ip:port/file MMS URL"
+ "\n screen:// Screen capture"
+ "\n [dvd://][device][@raw_device] DVD device"
+ "\n [vcd://][device] VCD device"
+ "\n [cdda://][device] Audio CD device"
+ "\n udp://[[<source address>]@[<bind address>][:<bind port>]]"
+ "\n UDP stream sent by a streaming server"
+ "\n vlc://pause:<seconds> Special item to pause the playlist for a certain time"
+ "\n vlc://quit Special item to quit VLC"
+ "\n");
+
static void Help( libvlc_int_t *p_this, char const *psz_help_name )
{
#ifdef WIN32
{
if( b_color )
utf8_fprintf( stdout, "\n" WHITE "%s" GRAY "\n",
- _( "No matching module found. Use --list or" \
+ _( "No matching module found. Use --list or " \
"--list-verbose to list available modules." ) );
else
utf8_fprintf( stdout, "\n%s\n",
- _( "No matching module found. Use --list or" \
+ _( "No matching module found. Use --list or " \
"--list-verbose to list available modules." ) );
}
*****************************************************************************/
static void Version( void )
{
+ extern const char psz_vlc_changeset[];
#ifdef WIN32
ShowConsole( true );
#endif
- utf8_fprintf( stdout, _("VLC version %s\n"), VLC_Version() );
+ utf8_fprintf( stdout, _("VLC version %s (%s)\n"), VLC_Version(),
+ psz_vlc_changeset );
utf8_fprintf( stdout, _("Compiled by %s@%s.%s\n"),
VLC_CompileBy(), VLC_CompileHost(), VLC_CompileDomain() );
utf8_fprintf( stdout, _("Compiler: %s\n"), VLC_Compiler() );
- if( strcmp( VLC_Changeset(), "exported" ) )
- utf8_fprintf( stdout, _("Based upon Git commit [%s]\n"),
- VLC_Changeset() );
- utf8_fprintf( stdout, LICENSE_MSG );
+ utf8_fprintf( stdout, "%s", LICENSE_MSG );
#ifdef WIN32 /* Pause the console because it's destroyed when we exit */
PauseConsole();
return i_width;
}
-static int VerboseCallback( vlc_object_t *p_this, const char *psz_variable,
- vlc_value_t old_val, vlc_value_t new_val, void *param)
-{
- libvlc_int_t *p_libvlc = (libvlc_int_t *)p_this;
- (void)psz_variable;
- (void)old_val;
- (void)param;
-
- if( new_val.i_int >= -1 )
- {
- libvlc_priv (p_libvlc)->i_verbose = __MIN( new_val.i_int, 2 );
- }
- return VLC_SUCCESS;
-}
-
/*****************************************************************************
* InitDeviceValues: initialize device values
*****************************************************************************
(void)p_vlc;
#endif /* HAVE_HAL */
}
+
+#include <vlc_avcodec.h>
+
+void vlc_avcodec_mutex (bool acquire)
+{
+ static vlc_mutex_t lock = VLC_STATIC_MUTEX;
+
+ if (acquire)
+ vlc_mutex_lock (&lock);
+ else
+ vlc_mutex_unlock (&lock);
+}