vlc/src/libvlc.c

582 lines
18 KiB
C
Raw Normal View History

/*****************************************************************************
2008-05-31 21:30:46 +02:00
* libvlc.c: libvlc instances creation and deletion, interfaces handling
*****************************************************************************
LGPL Re-license almost all of libVLC and libVLCcore to LGPLv2.1+ This move was authorized by the developers, either: - by e-mail, - by vote at the VideoLAN Dev Days 2011, - on the license website, - in a contract, oral or written. No objection was raised, so far. The developers agreeing are: Justus Piater Alexis Ballier Alexander Bethke Mohammed Adnène Trojette Alex Converse Alexey Sokolov Alexis de Lattre Andre Pang Anthony Loiseau Cyril Deguet André Weber Boris Dorès Brieuc Jeunhomme Benjamin Drung Hugo Beauzée-Luyssen Benoit Steiner Benjamin Pracht Bernie Purcell Przemyslaw Fiala Arnaud de Bossoreille de Ribou Brad Smith Nick Briggs Christopher Rath Christophe Courtaut Christopher Mueller Clement Chesnin Andres Krapf Damien Fouilleul David Flynn Sebastien Zwickert Antoine Cellerier Jérôme Decoodt Jérome Decoodt Dylan Yudaken Eduard Babayan Eugenio Jarosiewicz Elliot Murphy Eric Petit Erwan Tulou Etienne Membrives Ludovic Fauvet Fabio Ritrovato Tobias Güntner Jakub Wieczorek Frédéric Crozat Francois Cartegnie Laurent Aimar Florian G. Pflug Felix Paul Kühne Frank Enderle Rafaël Carré Simon Latapie Gildas Bazin Geoffroy Couprie Julien / Gellule Gildas Bazin Arnaud Schauly Toralf Niebuhr Vicente Jimenez Aguilar Derk-Jan Hartman Henri Fallon Ilkka Ollakka Olivier Teulière Rémi Duraffort Jakob Leben Jean-Baptiste Kempf Jean-Paul Saman Jean-Philippe Grimaldi Jean-François Massol Gaël Hendryckx Jakob Leben Jean-Marc Dressler Jai Menon Johan Bilien Johann Ransay Joris van Rooij JP Dinger Jean-Philippe André Adrien Grand Juha Jeronen Juho Vähä-Herttua Kaarlo Raiha Kaarlo Raiha Kamil Baldyga Keary Griffin Ken Self KO Myung-Hun Pierre Ynard Filippo Carone Loïc Minier Luca Barbato Lucas C. Villa Real Lukas Durfina Adrien Maglo Marc Ariberti Mark Lee Mark Moriarty Martin Storsjö Christophe Massiot Michel Kaempf Marian Ďurkovič Mirsal Ennaime Carlo Calabrò Damien Lucas Naohiro Koriyama Basos G Pierre Baillet Vincent Penquerc'h Olivier Aubert Pankaj Yadav Paul Corke Pierre d'Herbemont Philippe Morin Antoine Lejeune Michael Ploujnikov Jean-Marc Dressler Michael Hanselmann Rafaël Carré Ramiro Polla Rémi Denis-Courmont Renaud Dartus Richard Shepherd Faustino Osuna Arnaud Vallat Rob Jonson Robert Jedrzejczyk Steve Lhomme Rocky Bernstein Romain Goyet Rov Juvano Sam Hocevar Martin T. H. Sandsmark Sebastian Birk Sébastien Escudier Vincent Seguin Fabio Ritrovato Sigmund Augdal Helberg Casian Andrei Srikanth Raju Hannes Domani Stéphane Borel Stephan Krempel Stephan Assmus Tony Castley Pavlov Konstantin Eric Petit Tanguy Krotoff Dennis van Amerongen Michel Lespinasse Can Wu Xavier Marchesini Sébastien Toque Christophe Mutricy Yoann Peronneau Yohann Martineau Yuval Tze Scott Caudle Clément Stenac It is possible, that some minor piece of code was badly tracked, for some reasons (SVN, mainly) or that some small developers did not answer. However, as an "œuvre collective", defined as in "CPI 113-2 alinéa 3", and seeing "Cour. Cass. 17 Mai 1978", and seeing that the editor and the very vast majority of developers have agreed (> 99.99% of the code, > 99% of developers), we are fine here.
2011-11-27 21:44:15 +01:00
* Copyright (C) 1998-2008 VLC authors and VideoLAN
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
* Gildas Bazin <gbazin@videolan.org>
* Derk-Jan Hartman <hartman at videolan dot org>
2019-09-04 21:10:51 +02:00
* Rémi Denis-Courmont
*
LGPL Re-license almost all of libVLC and libVLCcore to LGPLv2.1+ This move was authorized by the developers, either: - by e-mail, - by vote at the VideoLAN Dev Days 2011, - on the license website, - in a contract, oral or written. No objection was raised, so far. The developers agreeing are: Justus Piater Alexis Ballier Alexander Bethke Mohammed Adnène Trojette Alex Converse Alexey Sokolov Alexis de Lattre Andre Pang Anthony Loiseau Cyril Deguet André Weber Boris Dorès Brieuc Jeunhomme Benjamin Drung Hugo Beauzée-Luyssen Benoit Steiner Benjamin Pracht Bernie Purcell Przemyslaw Fiala Arnaud de Bossoreille de Ribou Brad Smith Nick Briggs Christopher Rath Christophe Courtaut Christopher Mueller Clement Chesnin Andres Krapf Damien Fouilleul David Flynn Sebastien Zwickert Antoine Cellerier Jérôme Decoodt Jérome Decoodt Dylan Yudaken Eduard Babayan Eugenio Jarosiewicz Elliot Murphy Eric Petit Erwan Tulou Etienne Membrives Ludovic Fauvet Fabio Ritrovato Tobias Güntner Jakub Wieczorek Frédéric Crozat Francois Cartegnie Laurent Aimar Florian G. Pflug Felix Paul Kühne Frank Enderle Rafaël Carré Simon Latapie Gildas Bazin Geoffroy Couprie Julien / Gellule Gildas Bazin Arnaud Schauly Toralf Niebuhr Vicente Jimenez Aguilar Derk-Jan Hartman Henri Fallon Ilkka Ollakka Olivier Teulière Rémi Duraffort Jakob Leben Jean-Baptiste Kempf Jean-Paul Saman Jean-Philippe Grimaldi Jean-François Massol Gaël Hendryckx Jakob Leben Jean-Marc Dressler Jai Menon Johan Bilien Johann Ransay Joris van Rooij JP Dinger Jean-Philippe André Adrien Grand Juha Jeronen Juho Vähä-Herttua Kaarlo Raiha Kaarlo Raiha Kamil Baldyga Keary Griffin Ken Self KO Myung-Hun Pierre Ynard Filippo Carone Loïc Minier Luca Barbato Lucas C. Villa Real Lukas Durfina Adrien Maglo Marc Ariberti Mark Lee Mark Moriarty Martin Storsjö Christophe Massiot Michel Kaempf Marian Ďurkovič Mirsal Ennaime Carlo Calabrò Damien Lucas Naohiro Koriyama Basos G Pierre Baillet Vincent Penquerc'h Olivier Aubert Pankaj Yadav Paul Corke Pierre d'Herbemont Philippe Morin Antoine Lejeune Michael Ploujnikov Jean-Marc Dressler Michael Hanselmann Rafaël Carré Ramiro Polla Rémi Denis-Courmont Renaud Dartus Richard Shepherd Faustino Osuna Arnaud Vallat Rob Jonson Robert Jedrzejczyk Steve Lhomme Rocky Bernstein Romain Goyet Rov Juvano Sam Hocevar Martin T. H. Sandsmark Sebastian Birk Sébastien Escudier Vincent Seguin Fabio Ritrovato Sigmund Augdal Helberg Casian Andrei Srikanth Raju Hannes Domani Stéphane Borel Stephan Krempel Stephan Assmus Tony Castley Pavlov Konstantin Eric Petit Tanguy Krotoff Dennis van Amerongen Michel Lespinasse Can Wu Xavier Marchesini Sébastien Toque Christophe Mutricy Yoann Peronneau Yohann Martineau Yuval Tze Scott Caudle Clément Stenac It is possible, that some minor piece of code was badly tracked, for some reasons (SVN, mainly) or that some small developers did not answer. However, as an "œuvre collective", defined as in "CPI 113-2 alinéa 3", and seeing "Cour. Cass. 17 Mai 1978", and seeing that the editor and the very vast majority of developers have agreed (> 99.99% of the code, > 99% of developers), we are fine here.
2011-11-27 21:44:15 +01:00
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 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
LGPL Re-license almost all of libVLC and libVLCcore to LGPLv2.1+ This move was authorized by the developers, either: - by e-mail, - by vote at the VideoLAN Dev Days 2011, - on the license website, - in a contract, oral or written. No objection was raised, so far. The developers agreeing are: Justus Piater Alexis Ballier Alexander Bethke Mohammed Adnène Trojette Alex Converse Alexey Sokolov Alexis de Lattre Andre Pang Anthony Loiseau Cyril Deguet André Weber Boris Dorès Brieuc Jeunhomme Benjamin Drung Hugo Beauzée-Luyssen Benoit Steiner Benjamin Pracht Bernie Purcell Przemyslaw Fiala Arnaud de Bossoreille de Ribou Brad Smith Nick Briggs Christopher Rath Christophe Courtaut Christopher Mueller Clement Chesnin Andres Krapf Damien Fouilleul David Flynn Sebastien Zwickert Antoine Cellerier Jérôme Decoodt Jérome Decoodt Dylan Yudaken Eduard Babayan Eugenio Jarosiewicz Elliot Murphy Eric Petit Erwan Tulou Etienne Membrives Ludovic Fauvet Fabio Ritrovato Tobias Güntner Jakub Wieczorek Frédéric Crozat Francois Cartegnie Laurent Aimar Florian G. Pflug Felix Paul Kühne Frank Enderle Rafaël Carré Simon Latapie Gildas Bazin Geoffroy Couprie Julien / Gellule Gildas Bazin Arnaud Schauly Toralf Niebuhr Vicente Jimenez Aguilar Derk-Jan Hartman Henri Fallon Ilkka Ollakka Olivier Teulière Rémi Duraffort Jakob Leben Jean-Baptiste Kempf Jean-Paul Saman Jean-Philippe Grimaldi Jean-François Massol Gaël Hendryckx Jakob Leben Jean-Marc Dressler Jai Menon Johan Bilien Johann Ransay Joris van Rooij JP Dinger Jean-Philippe André Adrien Grand Juha Jeronen Juho Vähä-Herttua Kaarlo Raiha Kaarlo Raiha Kamil Baldyga Keary Griffin Ken Self KO Myung-Hun Pierre Ynard Filippo Carone Loïc Minier Luca Barbato Lucas C. Villa Real Lukas Durfina Adrien Maglo Marc Ariberti Mark Lee Mark Moriarty Martin Storsjö Christophe Massiot Michel Kaempf Marian Ďurkovič Mirsal Ennaime Carlo Calabrò Damien Lucas Naohiro Koriyama Basos G Pierre Baillet Vincent Penquerc'h Olivier Aubert Pankaj Yadav Paul Corke Pierre d'Herbemont Philippe Morin Antoine Lejeune Michael Ploujnikov Jean-Marc Dressler Michael Hanselmann Rafaël Carré Ramiro Polla Rémi Denis-Courmont Renaud Dartus Richard Shepherd Faustino Osuna Arnaud Vallat Rob Jonson Robert Jedrzejczyk Steve Lhomme Rocky Bernstein Romain Goyet Rov Juvano Sam Hocevar Martin T. H. Sandsmark Sebastian Birk Sébastien Escudier Vincent Seguin Fabio Ritrovato Sigmund Augdal Helberg Casian Andrei Srikanth Raju Hannes Domani Stéphane Borel Stephan Krempel Stephan Assmus Tony Castley Pavlov Konstantin Eric Petit Tanguy Krotoff Dennis van Amerongen Michel Lespinasse Can Wu Xavier Marchesini Sébastien Toque Christophe Mutricy Yoann Peronneau Yohann Martineau Yuval Tze Scott Caudle Clément Stenac It is possible, that some minor piece of code was badly tracked, for some reasons (SVN, mainly) or that some small developers did not answer. However, as an "œuvre collective", defined as in "CPI 113-2 alinéa 3", and seeing "Cour. Cass. 17 Mai 1978", and seeing that the editor and the very vast majority of developers have agreed (> 99.99% of the code, > 99% of developers), we are fine here.
2011-11-27 21:44:15 +01:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
LGPL Re-license almost all of libVLC and libVLCcore to LGPLv2.1+ This move was authorized by the developers, either: - by e-mail, - by vote at the VideoLAN Dev Days 2011, - on the license website, - in a contract, oral or written. No objection was raised, so far. The developers agreeing are: Justus Piater Alexis Ballier Alexander Bethke Mohammed Adnène Trojette Alex Converse Alexey Sokolov Alexis de Lattre Andre Pang Anthony Loiseau Cyril Deguet André Weber Boris Dorès Brieuc Jeunhomme Benjamin Drung Hugo Beauzée-Luyssen Benoit Steiner Benjamin Pracht Bernie Purcell Przemyslaw Fiala Arnaud de Bossoreille de Ribou Brad Smith Nick Briggs Christopher Rath Christophe Courtaut Christopher Mueller Clement Chesnin Andres Krapf Damien Fouilleul David Flynn Sebastien Zwickert Antoine Cellerier Jérôme Decoodt Jérome Decoodt Dylan Yudaken Eduard Babayan Eugenio Jarosiewicz Elliot Murphy Eric Petit Erwan Tulou Etienne Membrives Ludovic Fauvet Fabio Ritrovato Tobias Güntner Jakub Wieczorek Frédéric Crozat Francois Cartegnie Laurent Aimar Florian G. Pflug Felix Paul Kühne Frank Enderle Rafaël Carré Simon Latapie Gildas Bazin Geoffroy Couprie Julien / Gellule Gildas Bazin Arnaud Schauly Toralf Niebuhr Vicente Jimenez Aguilar Derk-Jan Hartman Henri Fallon Ilkka Ollakka Olivier Teulière Rémi Duraffort Jakob Leben Jean-Baptiste Kempf Jean-Paul Saman Jean-Philippe Grimaldi Jean-François Massol Gaël Hendryckx Jakob Leben Jean-Marc Dressler Jai Menon Johan Bilien Johann Ransay Joris van Rooij JP Dinger Jean-Philippe André Adrien Grand Juha Jeronen Juho Vähä-Herttua Kaarlo Raiha Kaarlo Raiha Kamil Baldyga Keary Griffin Ken Self KO Myung-Hun Pierre Ynard Filippo Carone Loïc Minier Luca Barbato Lucas C. Villa Real Lukas Durfina Adrien Maglo Marc Ariberti Mark Lee Mark Moriarty Martin Storsjö Christophe Massiot Michel Kaempf Marian Ďurkovič Mirsal Ennaime Carlo Calabrò Damien Lucas Naohiro Koriyama Basos G Pierre Baillet Vincent Penquerc'h Olivier Aubert Pankaj Yadav Paul Corke Pierre d'Herbemont Philippe Morin Antoine Lejeune Michael Ploujnikov Jean-Marc Dressler Michael Hanselmann Rafaël Carré Ramiro Polla Rémi Denis-Courmont Renaud Dartus Richard Shepherd Faustino Osuna Arnaud Vallat Rob Jonson Robert Jedrzejczyk Steve Lhomme Rocky Bernstein Romain Goyet Rov Juvano Sam Hocevar Martin T. H. Sandsmark Sebastian Birk Sébastien Escudier Vincent Seguin Fabio Ritrovato Sigmund Augdal Helberg Casian Andrei Srikanth Raju Hannes Domani Stéphane Borel Stephan Krempel Stephan Assmus Tony Castley Pavlov Konstantin Eric Petit Tanguy Krotoff Dennis van Amerongen Michel Lespinasse Can Wu Xavier Marchesini Sébastien Toque Christophe Mutricy Yoann Peronneau Yohann Martineau Yuval Tze Scott Caudle Clément Stenac It is possible, that some minor piece of code was badly tracked, for some reasons (SVN, mainly) or that some small developers did not answer. However, as an "œuvre collective", defined as in "CPI 113-2 alinéa 3", and seeing "Cour. Cass. 17 Mai 1978", and seeing that the editor and the very vast majority of developers have agreed (> 99.99% of the code, > 99% of developers), we are fine here.
2011-11-27 21:44:15 +01:00
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
2008-05-31 21:30:46 +02:00
/** \file
* This file contains functions to create and destroy libvlc instances
*/
/*****************************************************************************
* Preamble
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
2011-08-30 22:40:14 +02:00
#include "../lib/libvlc_internal.h"
2008-05-31 21:30:46 +02:00
#include "modules/modules.h"
#include "config/configuration.h"
#include "preparser/preparser.h"
#include "media_source/media_source.h"
2008-05-31 21:30:46 +02:00
#include <stdio.h> /* sprintf() */
#include <string.h>
#include <stdlib.h> /* free() */
#include <errno.h>
#include "config/vlc_getopt.h"
#include <vlc_playlist.h>
2008-05-31 21:30:46 +02:00
#include <vlc_interface.h>
#include <vlc_actions.h>
2008-05-31 21:30:46 +02:00
#include <vlc_charset.h>
#include <vlc_dialog.h>
#include <vlc_keystore.h>
#include <vlc_fs.h>
2009-09-22 17:21:14 +02:00
#include <vlc_cpu.h>
#include <vlc_url.h>
#include <vlc_modules.h>
#include <vlc_media_library.h>
#include <vlc_thumbnailer.h>
2008-05-31 21:30:46 +02:00
#include "libvlc.h"
2008-05-31 21:30:46 +02:00
#include <vlc_vlm.h>
2008-05-31 21:30:46 +02:00
#include <assert.h>
/*****************************************************************************
2008-05-31 21:30:46 +02:00
* Local prototypes
*****************************************************************************/
static void GetFilenames ( libvlc_int_t *, unsigned, const char *const [] );
2008-10-05 10:28:32 +02:00
2008-05-31 21:30:46 +02:00
/**
* Allocate a blank libvlc instance, also setting the exit handler.
* Vlc's threading system must have been initialized first
2008-05-31 21:30:46 +02:00
*/
libvlc_int_t * libvlc_InternalCreate( void )
{
libvlc_int_t *p_libvlc;
libvlc_priv_t *priv;
/* Allocate a libvlc instance object */
p_libvlc = (vlc_custom_create)( NULL, sizeof (*priv), "libvlc" );
2008-05-31 21:30:46 +02:00
if( p_libvlc == NULL )
return NULL;
priv = libvlc_priv (p_libvlc);
vlc_mutex_init(&priv->lock);
2019-03-08 18:31:30 +01:00
priv->interfaces = NULL;
priv->main_playlist = NULL;
2008-05-31 21:30:46 +02:00
priv->p_vlm = NULL;
priv->media_source_provider = NULL;
2008-05-31 21:30:46 +02:00
vlc_ExitInit( &priv->exit );
2008-05-31 21:30:46 +02:00
return p_libvlc;
}
/**
2008-05-31 21:30:46 +02:00
* Initialize a libvlc instance
* This function initializes a previously allocated libvlc instance:
* - CPU detection
* - gettext initialization
* - message queue, module bank and playlist initialization
* - configuration and commandline parsing
*/
2008-05-31 21:30:46 +02:00
int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
const char *ppsz_argv[] )
{
2008-05-31 21:30:46 +02:00
libvlc_priv_t *priv = libvlc_priv (p_libvlc);
char * psz_modules = NULL;
char * psz_parser = NULL;
char * psz_control = NULL;
2009-09-25 12:47:28 +02:00
char *psz_val;
2016-09-20 16:56:35 +02:00
int i_ret = VLC_EGENERIC;
2018-11-18 15:50:30 +01:00
if (unlikely(vlc_LogPreinit(p_libvlc)))
return VLC_ENOMEM;
2008-05-31 21:30:46 +02:00
/* System specific initialization code */
system_Init();
2008-05-31 21:30:46 +02:00
/* Initialize the module bank and load the configuration of the
2013-12-07 00:57:11 +01:00
* core module. We need to do this at this stage to be able to display
* a short help if required by the user. (short help == core module
2008-05-31 21:30:46 +02:00
* options) */
2011-08-15 21:16:51 +02:00
module_InitBank ();
/* Get command line options that affect module loading. */
if( config_LoadCmdLine( p_libvlc, i_argc, ppsz_argv, NULL ) )
{
2011-08-15 21:16:51 +02:00
module_EndBank (false);
2008-05-31 21:30:46 +02:00
return VLC_EGENERIC;
}
vlc_threads_setup (p_libvlc);
/* 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. */
module_LoadPlugins (p_libvlc);
/*
* Override default configuration with config file settings
*/
if( !var_InheritBool( p_libvlc, "ignore-config" ) )
{
if( var_InheritBool( p_libvlc, "reset-config" ) )
config_SaveConfigFile( p_libvlc ); /* Save default config */
else
config_LoadConfigFile( p_libvlc );
}
/*
* Override configuration with command line settings
*/
int vlc_optind;
if( config_LoadCmdLine( p_libvlc, i_argc, ppsz_argv, &vlc_optind ) )
2016-09-20 16:56:35 +02:00
goto error;
vlc_LogInit(p_libvlc);
/*
* Support for gettext
*/
#if defined( ENABLE_NLS ) \
&& ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
vlc_bindtextdomain (PACKAGE_NAME);
#endif
/*xgettext: Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
msg_Dbg( p_libvlc, "translation test: code is \"%s\"", _("C") );
2008-12-28 21:06:14 +01:00
if (config_PrintHelp (VLC_OBJECT(p_libvlc)))
{
2016-09-20 16:56:35 +02:00
libvlc_InternalCleanup (p_libvlc);
exit(0);
2008-05-31 21:30:46 +02:00
}
#ifdef HAVE_DAEMON
/* Check for daemon mode */
if( var_InheritBool( p_libvlc, "daemon" ) )
{
if( daemon( 1, 0) != 0 )
{
msg_Err( p_libvlc, "Unable to fork vlc to daemon mode" );
2016-09-20 16:56:35 +02:00
goto error;
}
/* lets check if we need to write the pidfile */
char *pidfile = var_InheritString( p_libvlc, "pidfile" );
if( pidfile != NULL )
{
FILE *stream = vlc_fopen( pidfile, "w" );
if( stream != NULL )
{
fprintf( stream, "%d", (int)getpid() );
fclose( stream );
msg_Dbg( p_libvlc, "written PID file %s", pidfile );
}
else
msg_Err( p_libvlc, "cannot write PID file %s: %s",
pidfile, vlc_strerror_c(errno) );
free( pidfile );
}
}
#endif
2008-05-31 21:30:46 +02:00
2016-09-20 16:56:35 +02:00
i_ret = VLC_ENOMEM;
if( libvlc_InternalDialogInit( p_libvlc ) != VLC_SUCCESS )
2016-09-20 16:56:35 +02:00
goto error;
if( libvlc_InternalKeystoreInit( p_libvlc ) != VLC_SUCCESS )
msg_Warn( p_libvlc, "memory keystore init failed" );
vlc_CPU_dump( VLC_OBJECT(p_libvlc) );
2008-05-31 21:30:46 +02:00
if( var_InheritBool( p_libvlc, "media-library") )
{
priv->p_media_library = libvlc_MlCreate( p_libvlc );
if ( priv->p_media_library == NULL )
msg_Warn( p_libvlc, "Media library initialization failed" );
}
priv->p_thumbnailer = vlc_thumbnailer_Create( VLC_OBJECT( p_libvlc ) );
if ( priv->p_thumbnailer == NULL )
msg_Warn( p_libvlc, "Failed to instantiate VLC thumbnailer" );
2008-05-31 21:30:46 +02:00
/*
* Initialize hotkey handling
*/
if( libvlc_InternalActionsInit( p_libvlc ) != VLC_SUCCESS )
2016-09-20 16:56:35 +02:00
goto error;
2008-05-31 21:30:46 +02:00
/*
* Meta data handling
*/
priv->parser = input_preparser_New(VLC_OBJECT(p_libvlc));
2016-09-20 16:56:35 +02:00
if( !priv->parser )
goto error;
priv->media_source_provider = vlc_media_source_provider_New( VLC_OBJECT( p_libvlc ) );
if( !priv->media_source_provider )
goto error;
/* variables for signalling creation of new files */
var_Create( p_libvlc, "snapshot-file", VLC_VAR_STRING );
var_Create( p_libvlc, "record-file", VLC_VAR_STRING );
2010-07-08 21:45:43 +02:00
/* some default internal settings */
var_Create( p_libvlc, "window", VLC_VAR_STRING );
/* NOTE: Because the playlist and interfaces start before this function
* returns control to the application (DESIGN BUG!), all these variables
* must be created (in place of libvlc_new()) and set to VLC defaults
* (in place of VLC main()) *here*. */
2010-07-08 21:45:43 +02:00
var_Create( p_libvlc, "user-agent", VLC_VAR_STRING );
var_SetString( p_libvlc, "user-agent",
"VLC media player (LibVLC "VERSION")" );
var_Create( p_libvlc, "http-user-agent", VLC_VAR_STRING );
var_SetString( p_libvlc, "http-user-agent",
"VLC/"PACKAGE_VERSION" LibVLC/"PACKAGE_VERSION );
var_Create( p_libvlc, "app-icon-name", VLC_VAR_STRING );
var_SetString( p_libvlc, "app-icon-name", PACKAGE_NAME );
var_Create( p_libvlc, "app-id", VLC_VAR_STRING );
var_SetString( p_libvlc, "app-id", "org.VideoLAN.VLC" );
var_Create( p_libvlc, "app-version", VLC_VAR_STRING );
var_SetString( p_libvlc, "app-version", PACKAGE_VERSION );
/* System specific configuration */
system_Configure( p_libvlc, i_argc - vlc_optind, ppsz_argv + vlc_optind );
#ifdef ENABLE_VLM
2008-05-31 21:30:46 +02:00
/* Initialize VLM if vlm-conf is specified */
2018-05-31 21:00:34 +02:00
psz_parser = var_InheritString( p_libvlc, "vlm-conf" );
if( psz_parser )
{
2018-05-31 21:00:34 +02:00
priv->p_vlm = vlm_New( p_libvlc, psz_parser );
2008-05-31 21:30:46 +02:00
if( !priv->p_vlm )
msg_Err( p_libvlc, "VLM initialization failed" );
2018-05-31 21:00:34 +02:00
free( psz_parser );
}
2008-05-31 21:30:46 +02:00
#endif
2008-05-31 21:30:46 +02:00
/*
* Load background interfaces
*/
2018-05-31 21:02:46 +02:00
psz_modules = var_InheritString( p_libvlc, "extraintf" );
psz_control = var_InheritString( p_libvlc, "control" );
if( psz_modules && psz_control )
2008-05-31 21:30:46 +02:00
{
char* psz_tmp;
if( asprintf( &psz_tmp, "%s:%s", psz_modules, psz_control ) != -1 )
{
free( psz_modules );
psz_modules = psz_tmp;
}
2008-05-31 21:30:46 +02:00
}
else if( psz_control )
{
2008-05-31 21:30:46 +02:00
free( psz_modules );
psz_modules = strdup( psz_control );
}
2008-05-31 21:30:46 +02:00
psz_parser = psz_modules;
while ( psz_parser && *psz_parser )
{
char *psz_module, *psz_temp;
psz_module = psz_parser;
psz_parser = strchr( psz_module, ':' );
if ( psz_parser )
{
*psz_parser = '\0';
psz_parser++;
}
if( asprintf( &psz_temp, "%s,none", psz_module ) != -1)
2008-05-31 21:30:46 +02:00
{
libvlc_InternalAddIntf( p_libvlc, psz_temp );
2008-05-31 21:30:46 +02:00
free( psz_temp );
}
}
free( psz_modules );
free( psz_control );
if( var_InheritBool( p_libvlc, "network-synchronisation") )
libvlc_InternalAddIntf( p_libvlc, "netsync,none" );
#ifdef __APPLE__
2008-05-31 21:30:46 +02:00
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 );
var_Create( p_libvlc, "drawable-view-right", VLC_VAR_INTEGER );
var_Create( p_libvlc, "drawable-clip-top", VLC_VAR_INTEGER );
var_Create( p_libvlc, "drawable-clip-left", VLC_VAR_INTEGER );
var_Create( p_libvlc, "drawable-clip-bottom", VLC_VAR_INTEGER );
var_Create( p_libvlc, "drawable-clip-right", VLC_VAR_INTEGER );
var_Create( p_libvlc, "drawable-nsobject", VLC_VAR_ADDRESS );
#endif
2008-05-31 21:30:46 +02:00
/*
* Get input filenames given as commandline arguments.
* We assume that the remaining parameters are filenames
* and their input options.
2008-05-31 21:30:46 +02:00
*/
GetFilenames( p_libvlc, i_argc - vlc_optind, ppsz_argv + vlc_optind );
2008-05-31 21:30:46 +02:00
/*
* Get --open argument
*/
2010-01-30 23:46:58 +01:00
psz_val = var_InheritString( p_libvlc, "open" );
2009-12-10 17:46:22 +01:00
if ( psz_val != NULL )
2008-05-31 21:30:46 +02:00
{
intf_InsertItem( p_libvlc, psz_val, 0, NULL, 0 );
2010-01-30 23:46:58 +01:00
free( psz_val );
2008-05-31 21:30:46 +02:00
}
/* Callbacks between interfaces */
/* Create a variable for showing the right click menu */
var_Create(p_libvlc, "intf-popupmenu", VLC_VAR_BOOL);
/* Create a variable for showing the fullscreen interface */
var_Create(p_libvlc, "intf-toggle-fscontrol", VLC_VAR_VOID);
/* Create a variable for the Boss Key */
var_Create(p_libvlc, "intf-boss", VLC_VAR_VOID);
/* Create a variable for showing the main interface */
var_Create(p_libvlc, "intf-show", VLC_VAR_VOID);
2008-05-31 21:30:46 +02:00
return VLC_SUCCESS;
2016-09-20 16:56:35 +02:00
error:
libvlc_InternalCleanup( p_libvlc );
return i_ret;
}
/**
2008-05-31 21:30:46 +02:00
* Cleanup a libvlc instance. The instance is not completely deallocated
* \param p_libvlc the instance to clean
*/
2009-01-17 21:09:40 +01:00
void libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
{
libvlc_priv_t *priv = libvlc_priv (p_libvlc);
if (priv->parser != NULL)
input_preparser_Deactivate(priv->parser);
2008-05-31 21:30:46 +02:00
/* Ask the interfaces to stop and destroy them */
msg_Dbg( p_libvlc, "removing all interfaces" );
intf_DestroyAll( p_libvlc );
2008-05-31 21:30:46 +02:00
if ( priv->p_thumbnailer )
vlc_thumbnailer_Release( priv->p_thumbnailer );
if ( priv->p_media_library )
libvlc_MlRelease( priv->p_media_library );
if( priv->media_source_provider )
vlc_media_source_provider_Delete( priv->media_source_provider );
libvlc_InternalDialogClean( p_libvlc );
libvlc_InternalKeystoreClean( p_libvlc );
#ifdef ENABLE_VLM
2008-05-31 21:30:46 +02:00
/* Destroy VLM if created in libvlc_InternalInit */
if( priv->p_vlm )
{
vlm_Delete( priv->p_vlm );
}
#endif
#if !defined( _WIN32 ) && !defined( __OS2__ )
char *pidfile = var_InheritString( p_libvlc, "pidfile" );
if( pidfile != NULL )
2008-05-31 21:30:46 +02:00
{
msg_Dbg( p_libvlc, "removing PID file %s", pidfile );
if( unlink( pidfile ) )
msg_Warn( p_libvlc, "cannot remove PID file %s: %s",
pidfile, vlc_strerror_c(errno) );
free( pidfile );
2008-05-31 21:30:46 +02:00
}
#endif
Revert "libvlc: delete preparser before interfaces" This reverts commit 9e9b227443831d8c9798b78122a2194053f2b2f1. The preparser must obviously outlive the playlist (and thus interfaces). This fixes use after free: ERROR: AddressSanitizer: heap-use-after-free on address 0x611000005548 at pc 0x7fad5e11bffa bp 0x7fad50daac10 sp 0x7fad50daac08 READ of size 8 at 0x611000005548 thread T1 #0 0x7fad5e11bff9 in playlist_preparser_fetcher_Push ../../src/playlist/preparser.c:128 #1 0x7fad5e0e7640 in libvlc_ArtRequest ../../src/libvlc.c:648 #2 0x7fad5e10ad37 in PlayItem ../../src/playlist/thread.c:232 #3 0x7fad5e10d167 in Next ../../src/playlist/thread.c:478 #4 0x7fad5e10d448 in Thread ../../src/playlist/thread.c:501 #5 0x7fad5fba3463 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7463) #6 0x7fad5f6dce5c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe8e5c) 0x611000005548 is located 8 bytes inside of 208-byte region [0x611000005540,0x611000005610) freed by thread T0 here: #0 0x7fad60ea69d0 in free (/usr/lib/x86_64-linux-gnu/libasan.so.3+0xc19d0) #1 0x7fad5e11cf8f in playlist_preparser_Delete ../../src/playlist/preparser.c:184 #2 0x7fad5e0e6b53 in libvlc_InternalCleanup ../../src/libvlc.c:512 #3 0x7fad60b2ed14 in libvlc_release ../../lib/core.c:105 #4 0x4024da in main ../../bin/vlc.c:275 #5 0x7fad5f6145ef in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x205ef) previously allocated by thread T0 here: #0 0x7fad60ea6ce8 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.3+0xc1ce8) #1 0x7fad5e11b3cd in playlist_preparser_New ../../src/playlist/preparser.c:74 #2 0x7fad5e0e62a2 in libvlc_InternalInit ../../src/libvlc.c:374 #3 0x7fad60b2e6d3 in libvlc_new ../../lib/core.c:59 #4 0x4022dd in main ../../bin/vlc.c:228 #5 0x7fad5f6145ef in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x205ef) Thread T1 created by T0 here: #0 0x7fad60e15f19 in pthread_create (/usr/lib/x86_64-linux-gnu/libasan.so.3+0x30f19) #1 0x7fad5e30d9f6 in vlc_clone_attr ../../src/posix/thread.c:484 #2 0x7fad5e30dbd8 in vlc_clone ../../src/posix/thread.c:496 #3 0x7fad5e1091a9 in playlist_Activate ../../src/playlist/thread.c:54 #4 0x7fad5e1117a0 in playlist_Create ../../src/playlist/engine.c:299 #5 0x7fad5e106139 in intf_GetPlaylist ../../src/interface/interface.c:149 #6 0x7fad5e1061d9 in intf_InsertItem ../../src/interface/interface.c:165 #7 0x7fad5e0e72f7 in GetFilenames ../../src/libvlc.c:605 #8 0x7fad5e0e6979 in libvlc_InternalInit ../../src/libvlc.c:488 #9 0x7fad60b2e6d3 in libvlc_new ../../lib/core.c:59 #10 0x4022dd in main ../../bin/vlc.c:228 #11 0x7fad5f6145ef in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x205ef) SUMMARY: AddressSanitizer: heap-use-after-free ../../src/playlist/preparser.c:128 in playlist_preparser_fetcher_Push
2016-06-16 22:33:07 +02:00
if (priv->parser != NULL)
input_preparser_Delete(priv->parser);
Revert "libvlc: delete preparser before interfaces" This reverts commit 9e9b227443831d8c9798b78122a2194053f2b2f1. The preparser must obviously outlive the playlist (and thus interfaces). This fixes use after free: ERROR: AddressSanitizer: heap-use-after-free on address 0x611000005548 at pc 0x7fad5e11bffa bp 0x7fad50daac10 sp 0x7fad50daac08 READ of size 8 at 0x611000005548 thread T1 #0 0x7fad5e11bff9 in playlist_preparser_fetcher_Push ../../src/playlist/preparser.c:128 #1 0x7fad5e0e7640 in libvlc_ArtRequest ../../src/libvlc.c:648 #2 0x7fad5e10ad37 in PlayItem ../../src/playlist/thread.c:232 #3 0x7fad5e10d167 in Next ../../src/playlist/thread.c:478 #4 0x7fad5e10d448 in Thread ../../src/playlist/thread.c:501 #5 0x7fad5fba3463 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x7463) #6 0x7fad5f6dce5c in clone (/lib/x86_64-linux-gnu/libc.so.6+0xe8e5c) 0x611000005548 is located 8 bytes inside of 208-byte region [0x611000005540,0x611000005610) freed by thread T0 here: #0 0x7fad60ea69d0 in free (/usr/lib/x86_64-linux-gnu/libasan.so.3+0xc19d0) #1 0x7fad5e11cf8f in playlist_preparser_Delete ../../src/playlist/preparser.c:184 #2 0x7fad5e0e6b53 in libvlc_InternalCleanup ../../src/libvlc.c:512 #3 0x7fad60b2ed14 in libvlc_release ../../lib/core.c:105 #4 0x4024da in main ../../bin/vlc.c:275 #5 0x7fad5f6145ef in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x205ef) previously allocated by thread T0 here: #0 0x7fad60ea6ce8 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.3+0xc1ce8) #1 0x7fad5e11b3cd in playlist_preparser_New ../../src/playlist/preparser.c:74 #2 0x7fad5e0e62a2 in libvlc_InternalInit ../../src/libvlc.c:374 #3 0x7fad60b2e6d3 in libvlc_new ../../lib/core.c:59 #4 0x4022dd in main ../../bin/vlc.c:228 #5 0x7fad5f6145ef in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x205ef) Thread T1 created by T0 here: #0 0x7fad60e15f19 in pthread_create (/usr/lib/x86_64-linux-gnu/libasan.so.3+0x30f19) #1 0x7fad5e30d9f6 in vlc_clone_attr ../../src/posix/thread.c:484 #2 0x7fad5e30dbd8 in vlc_clone ../../src/posix/thread.c:496 #3 0x7fad5e1091a9 in playlist_Activate ../../src/playlist/thread.c:54 #4 0x7fad5e1117a0 in playlist_Create ../../src/playlist/engine.c:299 #5 0x7fad5e106139 in intf_GetPlaylist ../../src/interface/interface.c:149 #6 0x7fad5e1061d9 in intf_InsertItem ../../src/interface/interface.c:165 #7 0x7fad5e0e72f7 in GetFilenames ../../src/libvlc.c:605 #8 0x7fad5e0e6979 in libvlc_InternalInit ../../src/libvlc.c:488 #9 0x7fad60b2e6d3 in libvlc_new ../../lib/core.c:59 #10 0x4022dd in main ../../bin/vlc.c:228 #11 0x7fad5f6145ef in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x205ef) SUMMARY: AddressSanitizer: heap-use-after-free ../../src/playlist/preparser.c:128 in playlist_preparser_fetcher_Push
2016-06-16 22:33:07 +02:00
if (priv->main_playlist)
vlc_playlist_Delete(priv->main_playlist);
libvlc_InternalActionsClean( p_libvlc );
/* Save the configuration */
if( !var_InheritBool( p_libvlc, "ignore-config" ) )
config_AutoSaveConfigFile( VLC_OBJECT(p_libvlc) );
vlc_LogDestroy(p_libvlc->obj.logger);
2008-05-31 21:30:46 +02:00
/* Free module bank. It is refcounted, so we call this each time */
2015-02-07 23:02:45 +01:00
module_EndBank (true);
#if defined(_WIN32) || defined(__OS2__)
system_End( );
#endif
}
/**
* 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 );
2008-05-31 21:30:46 +02:00
vlc_ExitDestroy( &priv->exit );
2008-05-31 21:30:46 +02:00
vlc_mutex_destroy(&priv->lock);
vlc_object_delete(p_libvlc);
}
2008-05-31 21:30:46 +02:00
/*****************************************************************************
* GetFilenames: parse command line options which are not flags
*****************************************************************************
* Parse command line for input files as well as their associated options.
* An option always follows its associated input and begins with a ":".
*****************************************************************************/
static void GetFilenames( libvlc_int_t *p_vlc, unsigned n,
const char *const args[] )
2008-05-31 21:30:46 +02:00
{
while( n > 0 )
2008-05-31 21:30:46 +02:00
{
/* Count the input options */
unsigned i_options = 0;
while( args[--n][0] == ':' )
2008-05-31 21:30:46 +02:00
{
i_options++;
if( n == 0 )
{
msg_Warn( p_vlc, "options %s without item", args[n] );
return; /* syntax!? */
}
2008-05-31 21:30:46 +02:00
}
char *mrl = NULL;
if( strstr( args[n], "://" ) == NULL )
{
mrl = vlc_path2uri( args[n], NULL );
if( !mrl )
continue;
}
2008-05-31 21:30:46 +02:00
intf_InsertItem( p_vlc, (mrl != NULL) ? mrl : args[n], i_options,
( i_options ? &args[n + 1] : NULL ),
VLC_INPUT_OPTION_TRUSTED );
free( mrl );
2008-05-31 21:30:46 +02:00
}
}
int vlc_MetadataRequest(libvlc_int_t *libvlc, input_item_t *item,
input_item_meta_request_option_t i_options,
const input_preparser_callbacks_t *cbs,
void *cbs_userdata,
int timeout, void *id)
{
libvlc_priv_t *priv = libvlc_priv(libvlc);
if (unlikely(priv->parser == NULL))
return VLC_ENOMEM;
input_preparser_Push( priv->parser, item, i_options, cbs, cbs_userdata, timeout, id );
return VLC_SUCCESS;
}
/**
* Requests extraction of the meta data for an input item (a.k.a. preparsing).
2016-06-01 11:29:12 +02:00
* The actual extraction is asynchronous. It can be cancelled with
* libvlc_MetadataCancel()
*/
int libvlc_MetadataRequest(libvlc_int_t *libvlc, input_item_t *item,
input_item_meta_request_option_t i_options,
const input_preparser_callbacks_t *cbs,
void *cbs_userdata,
int timeout, void *id)
{
libvlc_priv_t *priv = libvlc_priv(libvlc);
assert(i_options & META_REQUEST_OPTION_SCOPE_ANY);
if (unlikely(priv->parser == NULL))
return VLC_ENOMEM;
vlc_mutex_lock( &item->lock );
if( item->i_preparse_depth == 0 )
item->i_preparse_depth = 1;
vlc_mutex_unlock( &item->lock );
return vlc_MetadataRequest(libvlc, item, i_options, cbs, cbs_userdata, timeout, id);
}
/**
* Requests retrieving/downloading art for an input item.
* The retrieval is performed asynchronously.
*/
int libvlc_ArtRequest(libvlc_int_t *libvlc, input_item_t *item,
input_item_meta_request_option_t i_options,
const input_fetcher_callbacks_t *cbs,
void *cbs_userdata)
{
libvlc_priv_t *priv = libvlc_priv(libvlc);
assert(i_options & META_REQUEST_OPTION_FETCH_ANY);
if (unlikely(priv->parser == NULL))
return VLC_ENOMEM;
input_preparser_fetcher_Push(priv->parser, item, i_options,
cbs, cbs_userdata);
return VLC_SUCCESS;
}
2016-06-01 11:29:12 +02:00
/**
* Cancels extraction of the meta data for an input item.
*
* This does nothing if the input item is already processed or if it was not
* added with libvlc_MetadataRequest()
*/
void libvlc_MetadataCancel(libvlc_int_t *libvlc, void *id)
{
libvlc_priv_t *priv = libvlc_priv(libvlc);
if (unlikely(priv->parser == NULL))
return;
input_preparser_Cancel(priv->parser, id);
2016-06-01 11:29:12 +02:00
}